Merge "Drop explicit dependency on python-subunit"
diff --git a/manila_tempest_tests/services/share/v2/json/shares_client.py b/manila_tempest_tests/services/share/v2/json/shares_client.py
index a9ab199..4b35687 100644
--- a/manila_tempest_tests/services/share/v2/json/shares_client.py
+++ b/manila_tempest_tests/services/share/v2/json/shares_client.py
@@ -2108,7 +2108,8 @@
 
     def create_subnet(
             self, share_network_id, availability_zone=None,
-            neutron_net_id=None, neutron_subnet_id=None):
+            neutron_net_id=None, neutron_subnet_id=None,
+            metadata=None, version=LATEST_MICROVERSION):
         body = {'share_network_id': share_network_id}
 
         if availability_zone:
@@ -2117,6 +2118,9 @@
             body['neutron_net_id'] = neutron_net_id
         if neutron_subnet_id:
             body['neutron_subnet_id'] = neutron_subnet_id
+
+        if utils.is_microversion_ge(version, "2.78") and metadata:
+            body["metadata"] = metadata
         body = json.dumps({"share-network-subnet": body})
         url = '/share-networks/%s/subnets' % share_network_id
         resp, body = self.post(url, body, version=LATEST_MICROVERSION)
@@ -2312,6 +2316,7 @@
         else:
             uri = (f'{parent_resource}/{parent_id}'
                    f'/{resource}s/{resource_id}/metadata')
+
         resp, body = self.get(uri)
         self.expected_success(200, resp.status)
         body = json.loads(body)
diff --git a/manila_tempest_tests/tests/api/admin/test_share_servers_migration.py b/manila_tempest_tests/tests/api/admin/test_share_servers_migration.py
index d3ec3f1..3864e57 100644
--- a/manila_tempest_tests/tests/api/admin/test_share_servers_migration.py
+++ b/manila_tempest_tests/tests/api/admin/test_share_servers_migration.py
@@ -21,6 +21,7 @@
 
 from manila_tempest_tests.common import constants
 from manila_tempest_tests.common import waiters
+from manila_tempest_tests import share_exceptions
 from manila_tempest_tests.tests.api import base
 from manila_tempest_tests import utils
 
@@ -57,7 +58,15 @@
             raise cls.skipException(msg)
 
         # create share type (generic)
-        extra_specs = {}
+        replication_type = CONF.share.backend_replication_type
+        if replication_type not in constants.REPLICATION_TYPE_CHOICES:
+            raise share_exceptions.ShareReplicationTypeException(
+                replication_type=replication_type
+            )
+        extra_specs = {
+            "replication_type": replication_type,
+            "driver_handles_share_servers": CONF.share.multitenancy_enabled,
+        }
         if CONF.share.capability_snapshot_support:
             extra_specs.update({'snapshot_support': True})
         cls.share_type = cls.create_share_type(extra_specs=extra_specs)
@@ -318,8 +327,14 @@
 
     @decorators.idempotent_id('99e439a8-a716-4205-bf5b-af50128cb908')
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
-    @ddt.data(False, True)
-    def test_share_server_migration_complete(self, new_share_network):
+    @ddt.data(
+        (False, False),
+        (True, False),
+        (True, True)
+    )
+    @ddt.unpack
+    def test_share_server_migration_complete(self, new_share_network,
+                                             check_with_replica):
         """Test the share server migration complete."""
         share_network_id = self.provide_share_network(
             self.shares_v2_client, self.networks_client)
@@ -346,6 +361,12 @@
 
         preserve_snapshots = True if snapshot_id else False
 
+        replica = {}
+        if check_with_replica:
+            replica = self.create_share_replica(
+                share['id'],
+                cleanup_in_class=False)
+
         # Start share server migration.
         self.shares_v2_client.share_server_migration_start(
             src_server_id, dest_host,
@@ -393,6 +414,12 @@
             self.admin_shares_client.wait_for_resource_deletion(
                 server_id=src_server_id)
 
+        if check_with_replica:
+            replica = self.shares_v2_client.get_share_replica(
+                replica["id"])['share_replica']
+            self.assertEqual(constants.REPLICATION_STATE_IN_SYNC,
+                             replica["replica_state"])
+
     @decorators.idempotent_id('52e154eb-2d39-45af-b5c1-49ea569ab804')
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
     @ddt.data(True, False)
diff --git a/manila_tempest_tests/tests/api/base.py b/manila_tempest_tests/tests/api/base.py
index 9583de8..c23e3be 100644
--- a/manila_tempest_tests/tests/api/base.py
+++ b/manila_tempest_tests/tests/api/base.py
@@ -169,7 +169,7 @@
                     "CONF.share.create_networks_when_multitenancy_enabled "
                     "is set to True")
             share_network_id = cls.provide_share_network(
-                cls.shares_client, cls.networks_client)
+                cls.shares_v2_client, cls.networks_client)
             cls.shares_client.share_network_id = share_network_id
             cls.shares_v2_client.share_network_id = share_network_id
 
@@ -779,11 +779,12 @@
     def create_share_network_subnet(cls,
                                     client=None,
                                     cleanup_in_class=False,
+                                    metadata=None,
                                     **kwargs):
         if client is None:
             client = cls.shares_v2_client
         share_network_subnet = client.create_subnet(
-            **kwargs)['share_network_subnet']
+            metadata=metadata, **kwargs)['share_network_subnet']
         resource = {
             "type": "share_network_subnet",
             "id": share_network_subnet["id"],
diff --git a/manila_tempest_tests/tests/api/test_access_rules_metadata_negative.py b/manila_tempest_tests/tests/api/test_access_rules_metadata_negative.py
index c212095..a351422 100644
--- a/manila_tempest_tests/tests/api/test_access_rules_metadata_negative.py
+++ b/manila_tempest_tests/tests/api/test_access_rules_metadata_negative.py
@@ -67,7 +67,7 @@
         cls.share = cls.create_share(share_type_id=cls.share_type_id)
         cls.access = cls.shares_v2_client.create_access_rule(
             cls.share["id"], cls.access_type, cls.access_to,
-            'rw', metadata={u"key1": u"value1"})['access']
+            'rw', metadata={"key1": "value1"})['access']
         waiters.wait_for_resource_status(
             cls.shares_v2_client, cls.share["id"], "active",
             resource_name='access_rule', rule_id=cls.access["id"])
diff --git a/manila_tempest_tests/tests/api/test_metadata.py b/manila_tempest_tests/tests/api/test_metadata.py
index be5b1cf..3574d64 100644
--- a/manila_tempest_tests/tests/api/test_metadata.py
+++ b/manila_tempest_tests/tests/api/test_metadata.py
@@ -46,7 +46,7 @@
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_set_metadata_in_share_creation(self):
 
-        md = {u"key1": u"value1", u"key2": u"value2", }
+        md = {"key1": "value1", "key2": "value2", }
 
         # create share with metadata
         share = self.create_share(share_type_id=self.share_type_id,
@@ -60,7 +60,7 @@
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_set_get_delete_metadata(self):
 
-        md = {u"key3": u"value3", u"key4": u"value4", u"key.5.1": u"value.5"}
+        md = {"key3": "value3", "key4": "value4", "key.5.1": "value.5"}
 
         # create share
         share = self.create_share(share_type_id=self.share_type_id,
@@ -85,8 +85,8 @@
     @decorators.idempotent_id('4e5f8159-62b6-4d5c-f729-d8b1f029d7de')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_set_metadata_not_delete_pre_metadata(self):
-        md1 = {u"key9": u"value9", u"key10": u"value10", }
-        md2 = {u"key11": u"value11", u"key12": u"value12", }
+        md1 = {"key9": "value9", "key10": "value10", }
+        md2 = {"key11": "value11", "key12": "value12", }
 
         # create share
         share = self.create_share(share_type_id=self.share_type_id,
@@ -121,8 +121,8 @@
     @decorators.idempotent_id('2ec70ba5-050b-3b17-c862-c149e53543c0')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_set_metadata_key_already_exist(self):
-        md1 = {u"key9": u"value9", u"key10": u"value10", }
-        md2 = {u"key9": u"value13", u"key11": u"value11", }
+        md1 = {"key9": "value9", "key10": "value10", }
+        md2 = {"key9": "value13", "key11": "value11", }
 
         # create share
         share = self.create_share(share_type_id=self.share_type_id,
@@ -138,8 +138,8 @@
         self.shares_v2_client.set_metadata(share["id"], md2)
 
         # verify metadata
-        md = {u"key9": u"value13", u"key10": u"value10",
-              u"key11": u"value11"}
+        md = {"key9": "value13", "key10": "value10",
+              "key11": "value11"}
         self._verify_share_metadata(share, md)
 
         # delete metadata
@@ -156,8 +156,8 @@
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_set_and_update_metadata_by_key(self):
 
-        md1 = {u"key5": u"value5", u"key6": u"value6", }
-        md2 = {u"key7": u"value7", u"key8": u"value8", }
+        md1 = {"key5": "value5", "key6": "value6", }
+        md2 = {"key7": "value7", "key8": "value8", }
 
         # create share
         share = self.create_share(share_type_id=self.share_type_id,
diff --git a/manila_tempest_tests/tests/api/test_metadata_negative.py b/manila_tempest_tests/tests/api/test_metadata_negative.py
index 5caca5e..38ae739 100644
--- a/manila_tempest_tests/tests/api/test_metadata_negative.py
+++ b/manila_tempest_tests/tests/api/test_metadata_negative.py
@@ -28,7 +28,7 @@
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
     @ddt.data(True, False)
     def test_try_set_metadata_to_unexisting_share(self, is_v2_client):
-        md = {u"key1": u"value1", u"key2": u"value2", }
+        md = {"key1": "value1", "key2": "value2", }
         client = self.shares_v2_client if is_v2_client else self.shares_client
         self.assertRaises(lib_exc.NotFound,
                           client.set_metadata,
@@ -38,7 +38,7 @@
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
     @ddt.data(True, False)
     def test_try_update_all_metadata_for_unexisting_share(self, is_v2_client):
-        md = {u"key1": u"value1", u"key2": u"value2", }
+        md = {"key1": "value1", "key2": "value2", }
         client = self.shares_v2_client if is_v2_client else self.shares_client
         self.assertRaises(lib_exc.NotFound,
                           client.update_all_metadata,
diff --git a/manila_tempest_tests/tests/api/test_rules_negative.py b/manila_tempest_tests/tests/api/test_rules_negative.py
index 0757c8e..2b62ad5 100644
--- a/manila_tempest_tests/tests/api/test_rules_negative.py
+++ b/manila_tempest_tests/tests/api/test_rules_negative.py
@@ -492,7 +492,7 @@
 
     @decorators.idempotent_id('7b33c073-353e-4952-97dc-c3948a3cd037')
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
-    @ddt.data('jane.doe', u"bj\u00F6rn")
+    @ddt.data('jane.doe', "bj\u00F6rn")
     def test_create_access_rule_cephx_with_invalid_cephx_id(self, access_to):
         self.assertRaises(lib_exc.BadRequest,
                           self.shares_v2_client.create_access_rule,
diff --git a/manila_tempest_tests/tests/api/test_share_network_subnet_metadata.py b/manila_tempest_tests/tests/api/test_share_network_subnet_metadata.py
new file mode 100644
index 0000000..0f2c7c7
--- /dev/null
+++ b/manila_tempest_tests/tests/api/test_share_network_subnet_metadata.py
@@ -0,0 +1,386 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest import config
+from tempest.lib import decorators
+from testtools import testcase as tc
+
+from manila_tempest_tests.tests.api import base
+from manila_tempest_tests import utils
+
+CONF = config.CONF
+LATEST_MICROVERSION = CONF.share.max_api_microversion
+
+
+class ShareNetworkSubnetMetadataTest(base.BaseSharesMixedTest):
+
+    @classmethod
+    def skip_checks(cls):
+        super(ShareNetworkSubnetMetadataTest, cls).skip_checks()
+        utils.check_skip_if_microversion_not_supported("2.78")
+
+    @classmethod
+    def resource_setup(cls):
+        super(ShareNetworkSubnetMetadataTest, cls).resource_setup()
+        # create share_network and subnet
+        cls.share_network = cls.create_share_network(cleanup_in_class=True)
+        az = cls.shares_v2_client.list_availability_zones(
+            )['availability_zones'][0]
+        cls.az_name = az['name']
+
+        cls.data = utils.generate_subnet_data()
+        cls.data['share_network_id'] = cls.share_network['id']
+        cls.data['availability_zone'] = cls.az_name
+
+        cls.subnet = cls.create_share_network_subnet(cleanup_in_class=True,
+                                                     **cls.data)
+
+    def _verify_subnet_metadata(self, subnet, md):
+        # get metadata of share-network-subnet
+        metadata = self.shares_v2_client.get_metadata(
+            subnet['id'], resource="subnet",
+            parent_resource="share-networks",
+            parent_id=subnet['share_network_id'])['metadata']
+
+        # verify metadata
+        self.assertEqual(md, metadata)
+
+        # verify metadata items
+        for key in md:
+            get_value = self.shares_v2_client.get_metadata_item(
+                subnet['id'], key, resource="subnet",
+                parent_resource="share-networks",
+                parent_id=subnet['share_network_id'])['meta']
+            self.assertEqual(md[key], get_value[key])
+
+    @decorators.idempotent_id('260744c2-c062-4ce3-a57e-cce475650e7b')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API)
+    def test_set_metadata_in_subnet_creation(self):
+        share_network = self.create_share_network()
+        az = self.shares_v2_client.list_availability_zones(
+            )['availability_zones'][0]
+        az_name = az['name']
+
+        # Generate subnet data
+        data = utils.generate_subnet_data()
+        data['share_network_id'] = share_network['id']
+        data['availability_zone'] = az_name
+
+        md = {"key1": "value1", "key2": "value2", }
+
+        # create network subnet with metadata
+        subnet = self.create_share_network_subnet(metadata=md,
+                                                  cleanup_in_class=False,
+                                                  **data)
+
+        # verify metadata
+        self._verify_subnet_metadata(subnet, md)
+
+        # Delete the subnets
+        self.shares_v2_client.delete_subnet(share_network['id'], subnet['id'])
+
+    @decorators.idempotent_id('ec5c02e9-fcee-4890-87bc-7937a247afe9')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API)
+    def test_set_get_delete_metadata(self):
+        md = {"key3": "value3", "key4": "value4", "key.5.1": "value.5"}
+
+        # create subnet
+        subnet = self.create_share_network_subnet(**self.data)
+
+        # set metadata
+        self.shares_v2_client.set_metadata(
+            subnet['id'], md, resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])
+
+        # verify metadata
+        self._verify_subnet_metadata(subnet, md)
+
+        # delete metadata
+        for key in md.keys():
+            self.shares_v2_client.delete_metadata(
+                subnet['id'], key, resource="subnet",
+                parent_resource="share-networks",
+                parent_id=self.share_network['id'])
+
+        # verify deletion of metadata
+        get_metadata = self.shares_v2_client.get_metadata(
+            subnet['id'], resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])['metadata']
+        self.assertEmpty(get_metadata)
+
+        # Delete the subnet
+        self.shares_v2_client.delete_subnet(self.share_network['id'],
+                                            subnet['id'])
+
+    @decorators.idempotent_id('9ff9c3b4-9bd0-4e8a-a317-726cab640a67')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API)
+    def test_set_metadata_not_delete_pre_metadata(self):
+        md1 = {"key9": "value9", "key10": "value10", }
+        md2 = {"key11": "value11", "key12": "value12", }
+
+        # create subnet
+        subnet = self.create_share_network_subnet(**self.data)
+
+        # set metadata
+        self.shares_v2_client.set_metadata(
+            subnet['id'], md1, resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])
+
+        # verify metadata
+        self._verify_subnet_metadata(subnet, md1)
+
+        # set metadata again
+        self.shares_v2_client.set_metadata(
+            subnet['id'], md2, resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])
+
+        md1.update(md2)
+        md = md1
+
+        # verify metadata
+        self._verify_subnet_metadata(subnet, md)
+
+        # delete metadata
+        for key in md.keys():
+            self.shares_v2_client.delete_metadata(
+                subnet['id'], key, resource="subnet",
+                parent_resource="share-networks",
+                parent_id=self.share_network['id'])
+
+        # verify deletion of metadata
+        get_metadata = self.shares_v2_client.get_metadata(
+            subnet['id'], resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])['metadata']
+        self.assertEmpty(get_metadata)
+
+        # Delete the subnet
+        self.shares_v2_client.delete_subnet(self.share_network['id'],
+                                            subnet['id'])
+
+    @decorators.idempotent_id('1973bcb0-93a5-49a5-84fb-a03f6f6ff43b')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API)
+    def test_set_metadata_key_already_exist(self):
+        md1 = {"key9": "value9", "key10": "value10", }
+        md2 = {"key9": "value13", "key11": "value11", }
+
+        # create subnet
+        subnet = self.create_share_network_subnet(**self.data)
+
+        # set metadata
+        self.shares_v2_client.set_metadata(
+            subnet['id'], md1, resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])
+
+        # verify metadata
+        self._verify_subnet_metadata(subnet, md1)
+
+        # set metadata again
+        self.shares_v2_client.set_metadata(
+            subnet['id'], md2, resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])
+
+        # verify metadata
+        md1.update(md2)
+        self._verify_subnet_metadata(subnet, md1)
+
+        # delete metadata
+        for key in md1.keys():
+            self.shares_v2_client.delete_metadata(
+                subnet['id'], key, resource="subnet",
+                parent_resource="share-networks",
+                parent_id=self.share_network['id'])
+
+        # verify deletion of metadata
+        get_metadata = self.shares_v2_client.get_metadata(
+            subnet['id'], resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])['metadata']
+        self.assertEmpty(get_metadata)
+
+        # Delete the subnets
+        self.shares_v2_client.delete_subnet(self.share_network['id'],
+                                            subnet['id'])
+
+    @decorators.idempotent_id('d37ea163-7215-4c35-996a-1bc165e554de')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API)
+    def test_set_and_update_metadata_by_key(self):
+        md1 = {"key5": "value5", "key6": "value6", }
+        md2 = {"key7": "value7", "key8": "value8", }
+
+        # create subnet
+        subnet = self.create_share_network_subnet(**self.data)
+
+        # set metadata
+        self.shares_v2_client.set_metadata(
+            subnet['id'], md1, resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])
+
+        # update metadata
+        self.shares_v2_client.update_all_metadata(
+            subnet['id'], md2, resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])
+
+        # verify metadata
+        self._verify_subnet_metadata(subnet, md2)
+
+        # Delete the subnets
+        self.shares_v2_client.delete_subnet(self.share_network['id'],
+                                            subnet['id'])
+
+    @decorators.idempotent_id('20b96e7e-33cf-41f2-8f00-357170fa27f9')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API)
+    def test_set_metadata_min_size_key(self):
+        data = {"k": "value"}
+
+        self.shares_v2_client.set_metadata(self.subnet['id'],
+                                           data, resource="subnet",
+                                           parent_resource="share-networks",
+                                           parent_id=self.share_network['id'])
+
+        body_get = self.shares_v2_client.get_metadata(
+            self.subnet['id'], resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])['metadata']
+        self.assertEqual(data['k'], body_get.get('k'))
+
+    @decorators.idempotent_id('b7933b35-04e7-4487-8e6a-730f7261a736')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API)
+    def test_set_metadata_max_size_key(self):
+        max_key = "k" * 255
+        data = {max_key: "value"}
+
+        self.shares_v2_client.set_metadata(self.subnet['id'],
+                                           data, resource="subnet",
+                                           parent_resource="share-networks",
+                                           parent_id=self.share_network['id'])
+
+        body_get = self.shares_v2_client.get_metadata(
+            self.subnet['id'], resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])['metadata']
+
+        self.assertIn(max_key, body_get)
+        self.assertEqual(data[max_key], body_get.get(max_key))
+
+    @decorators.idempotent_id('469cd8ca-5846-4ff7-9a94-1087fc369e0f')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API)
+    def test_set_metadata_min_size_value(self):
+        data = {"key": "v"}
+
+        self.shares_v2_client.set_metadata(self.subnet['id'],
+                                           data, resource="subnet",
+                                           parent_resource="share-networks",
+                                           parent_id=self.share_network['id'])
+
+        body_get = self.shares_v2_client.get_metadata(
+            self.subnet['id'], resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])['metadata']
+
+        self.assertEqual(data['key'], body_get['key'])
+
+    @decorators.idempotent_id('5aa3b4a2-79d3-4fa4-b923-eb120bbe2f29')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API)
+    def test_set_metadata_max_size_value(self):
+        max_value = "v" * 1023
+        data = {"key": max_value}
+
+        self.shares_v2_client.set_metadata(self.subnet['id'],
+                                           data, resource="subnet",
+                                           parent_resource="share-networks",
+                                           parent_id=self.share_network['id'])
+
+        body_get = self.shares_v2_client.get_metadata(
+            self.subnet['id'], resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])['metadata']
+
+        self.assertEqual(data['key'], body_get['key'])
+
+    @decorators.idempotent_id('336970cb-eb04-4d08-9941-44c1267c1d5a')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API)
+    def test_upd_metadata_min_size_key(self):
+        data = {"k": "value"}
+
+        self.shares_v2_client.update_all_metadata(
+            self.subnet['id'], data, resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])
+
+        body_get = self.shares_v2_client.get_metadata(
+            self.subnet['id'], resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])['metadata']
+
+        self.assertEqual(data, body_get)
+
+    @decorators.idempotent_id('93ec3f28-4cd7-48da-8418-e945b9ec4530')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API)
+    def test_upd_metadata_max_size_key(self):
+        max_key = "k" * 255
+        data = {max_key: "value"}
+
+        self.shares_v2_client.update_all_metadata(
+            self.subnet['id'], data, resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])
+
+        body_get = self.shares_v2_client.get_metadata(
+            self.subnet['id'], resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])['metadata']
+
+        self.assertEqual(data, body_get)
+
+    @decorators.idempotent_id('f9372c69-559a-47b8-b6a2-0b2876d7a985')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API)
+    def test_upd_metadata_min_size_value(self):
+        data = {"key": "v"}
+
+        self.shares_v2_client.update_all_metadata(
+            self.subnet['id'], data, resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])
+
+        body_get = self.shares_v2_client.get_metadata(
+            self.subnet['id'], resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])['metadata']
+
+        self.assertEqual(data, body_get)
+
+    @decorators.idempotent_id('fdb6696f-910a-41a7-aab3-79addad86936')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API)
+    def test_upd_metadata_max_size_value(self):
+        max_value = "v" * 1023
+        data = {"key": max_value}
+
+        self.shares_v2_client.update_all_metadata(
+            self.subnet['id'], data, resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])
+
+        body_get = self.shares_v2_client.get_metadata(
+            self.subnet['id'], resource="subnet",
+            parent_resource="share-networks",
+            parent_id=self.share_network['id'])['metadata']
+
+        self.assertEqual(data, body_get)
diff --git a/manila_tempest_tests/tests/api/test_share_network_subnet_metadata_negative.py b/manila_tempest_tests/tests/api/test_share_network_subnet_metadata_negative.py
new file mode 100644
index 0000000..4e4f2cd
--- /dev/null
+++ b/manila_tempest_tests/tests/api/test_share_network_subnet_metadata_negative.py
@@ -0,0 +1,138 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest import config
+from tempest.lib import decorators
+from tempest.lib import exceptions as lib_exc
+from testtools import testcase as tc
+
+from manila_tempest_tests.tests.api import base
+from manila_tempest_tests import utils
+
+CONF = config.CONF
+LATEST_MICROVERSION = CONF.share.max_api_microversion
+
+
+class ShareNetworkSubnetMetadataNegativeTest(base.BaseSharesMixedTest):
+
+    @classmethod
+    def skip_checks(cls):
+        super(ShareNetworkSubnetMetadataNegativeTest, cls).skip_checks()
+        utils.check_skip_if_microversion_not_supported("2.78")
+
+    @classmethod
+    def resource_setup(cls):
+        super(ShareNetworkSubnetMetadataNegativeTest, cls).resource_setup()
+        # create share_network and subnet
+        cls.share_network = cls.create_share_network()
+        az = cls.shares_v2_client.list_availability_zones(
+            )['availability_zones'][0]
+        cls.az_name = az['name']
+
+        data = utils.generate_subnet_data()
+        data['share_network_id'] = cls.share_network['id']
+        data['availability_zone'] = cls.az_name
+
+        cls.subnet = cls.create_share_network_subnet(**data)
+
+    @decorators.idempotent_id('852d080f-16f3-48c4-af26-d8440be9801b')
+    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
+    def test_try_set_metadata_to_unexisting_subnet(self):
+        share_network = self.create_share_network()
+        md = {"key1": "value1", "key2": "value2", }
+        self.assertRaises(lib_exc.NotFound,
+                          self.shares_v2_client.set_metadata,
+                          "wrong_subnet_id", md, resource="subnet",
+                          parent_resource="share-networks",
+                          parent_id=share_network['id'])
+
+    @decorators.idempotent_id('dfe93a02-43cc-458c-92e5-ede6c2c2e597')
+    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
+    def test_try_update_all_metadata_to_unexisting_subnet(self):
+        share_network = self.create_share_network()
+        md = {"key1": "value1", "key2": "value2", }
+        self.assertRaises(lib_exc.NotFound,
+                          self.shares_v2_client.update_all_metadata,
+                          "wrong_subnet_id", md, resource="subnet",
+                          parent_resource="share-networks",
+                          parent_id=share_network['id'])
+
+    @decorators.idempotent_id('fc561d8e-a2df-468f-a760-7b5d340b4b29')
+    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
+    def test_try_set_metadata_with_empty_key(self):
+        self.assertRaises(lib_exc.BadRequest,
+                          self.shares_v2_client.set_metadata,
+                          self.subnet['id'], {"": "value"}, resource="subnet",
+                          parent_resource="share-networks",
+                          parent_id=self.share_network['id'])
+
+    @decorators.idempotent_id('b6066659-d635-4f24-9a65-fa3a132fd5ad')
+    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
+    def test_try_upd_metadata_with_empty_key(self):
+        self.assertRaises(lib_exc.BadRequest,
+                          self.shares_v2_client.update_all_metadata,
+                          self.subnet['id'], {"": "value"}, resource="subnet",
+                          parent_resource="share-networks",
+                          parent_id=self.share_network['id'])
+
+    @decorators.idempotent_id('a1ea51a6-01a4-4b12-8508-04e45fdabb13')
+    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
+    def test_try_set_metadata_with_too_big_key(self):
+        too_big_key = "x" * 256
+        md = {too_big_key: "value"}
+        self.assertRaises(lib_exc.BadRequest,
+                          self.shares_v2_client.set_metadata,
+                          self.subnet['id'], md, resource="subnet",
+                          parent_resource="share-networks",
+                          parent_id=self.share_network['id'])
+
+    @decorators.idempotent_id('a02e3970-a3d3-4c0f-a7b8-2ea3f4459214')
+    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
+    def test_try_upd_metadata_with_too_big_key(self):
+        too_big_key = "x" * 256
+        md = {too_big_key: "value"}
+        self.assertRaises(lib_exc.BadRequest,
+                          self.shares_v2_client.update_all_metadata,
+                          self.subnet['id'], md, resource="subnet",
+                          parent_resource="share-networks",
+                          parent_id=self.share_network['id'])
+
+    @decorators.idempotent_id('f086589e-81a2-4d73-9fb0-9dd235cd35f1')
+    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
+    def test_try_set_metadata_with_too_big_value(self):
+        too_big_value = "x" * 1024
+        md = {"key": too_big_value}
+        self.assertRaises(lib_exc.BadRequest,
+                          self.shares_v2_client.set_metadata,
+                          self.subnet['id'], md, resource="subnet",
+                          parent_resource="share-networks",
+                          parent_id=self.share_network['id'])
+
+    @decorators.idempotent_id('4693e944-4b85-4655-8245-f1da2b5f9ff3')
+    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
+    def test_try_upd_metadata_with_too_big_value(self):
+        too_big_value = "x" * 1024
+        md = {"key": too_big_value}
+        self.assertRaises(lib_exc.BadRequest,
+                          self.shares_v2_client.update_all_metadata,
+                          self.subnet['id'], md, resource="subnet",
+                          parent_resource="share-networks",
+                          parent_id=self.share_network['id'])
+
+    @decorators.idempotent_id('30e82c73-edd3-4f23-8b8f-c38e67668381')
+    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
+    def test_try_delete_unexisting_metadata(self):
+        self.assertRaises(lib_exc.NotFound,
+                          self.shares_v2_client.delete_metadata,
+                          self.subnet['id'], "wrong_key", resource="subnet",
+                          parent_resource="share-networks",
+                          parent_id=self.share_network['id'])
diff --git a/manila_tempest_tests/tests/api/test_snapshot_metadata.py b/manila_tempest_tests/tests/api/test_snapshot_metadata.py
index 0596213..e5df030 100644
--- a/manila_tempest_tests/tests/api/test_snapshot_metadata.py
+++ b/manila_tempest_tests/tests/api/test_snapshot_metadata.py
@@ -79,7 +79,7 @@
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_set_metadata_in_snapshot_creation(self):
 
-        md = {u"key1": u"value1", u"key2": u"value2", }
+        md = {"key1": "value1", "key2": "value2", }
 
         # create snapshot with metadata
         snapshot = self.create_snapshot_wait_for_active(
@@ -93,7 +93,7 @@
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_set_get_delete_metadata(self):
 
-        md = {u"key3": u"value3", u"key4": u"value4", u"key.5.1": u"value.5"}
+        md = {"key3": "value3", "key4": "value4", "key.5.1": "value.5"}
 
         # create snapshot
         snapshot = self.create_snapshot_wait_for_active(
@@ -120,8 +120,8 @@
     @decorators.idempotent_id('23ec837d-1b50-499c-bbb9-a7bde843c9e8')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_set_metadata_not_delete_pre_metadata(self):
-        md1 = {u"key9": u"value9", u"key10": u"value10", }
-        md2 = {u"key11": u"value11", u"key12": u"value12", }
+        md1 = {"key9": "value9", "key10": "value10", }
+        md2 = {"key11": "value11", "key12": "value12", }
 
         # create snapshot
         snapshot = self.create_snapshot_wait_for_active(
@@ -159,8 +159,8 @@
     @decorators.idempotent_id('b7a00be5-3dd1-4d25-8723-c662581c923f')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_set_metadata_key_already_exist(self):
-        md1 = {u"key9": u"value9", u"key10": u"value10", }
-        md2 = {u"key9": u"value13", u"key11": u"value11", }
+        md1 = {"key9": "value9", "key10": "value10", }
+        md2 = {"key9": "value13", "key11": "value11", }
 
         # create snapshot
         snapshot = self.create_snapshot_wait_for_active(
@@ -196,8 +196,8 @@
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_set_and_update_metadata_by_key(self):
 
-        md1 = {u"key5": u"value5", u"key6": u"value6", }
-        md2 = {u"key7": u"value7", u"key8": u"value8", }
+        md1 = {"key5": "value5", "key6": "value6", }
+        md2 = {"key7": "value7", "key8": "value8", }
 
         # create snapshot
         snapshot = self.create_snapshot_wait_for_active(
diff --git a/manila_tempest_tests/tests/api/test_snapshot_metadata_negative.py b/manila_tempest_tests/tests/api/test_snapshot_metadata_negative.py
index 7a80e4a..53a05c6 100644
--- a/manila_tempest_tests/tests/api/test_snapshot_metadata_negative.py
+++ b/manila_tempest_tests/tests/api/test_snapshot_metadata_negative.py
@@ -71,7 +71,7 @@
     @decorators.idempotent_id('8be4773b-6af9-413f-97e2-8acdb6149e7a')
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
     def test_try_set_metadata_to_unexisting_snapshot(self):
-        md = {u"key1": u"value1", u"key2": u"value2", }
+        md = {"key1": "value1", "key2": "value2", }
         self.assertRaises(lib_exc.NotFound,
                           self.shares_v2_client.set_metadata,
                           "wrong_snapshot_id", md, resource="snapshot")
@@ -79,7 +79,7 @@
     @decorators.idempotent_id('03a7f6e9-de8b-4669-87e1-b179308b477d')
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
     def test_try_update_all_metadata_to_unexisting_snapshot(self):
-        md = {u"key1": u"value1", u"key2": u"value2", }
+        md = {"key1": "value1", "key2": "value2", }
         self.assertRaises(lib_exc.NotFound,
                           self.shares_v2_client.update_all_metadata,
                           "wrong_snapshot_id", md, resource="snapshot")
diff --git a/zuul.d/manila-tempest-jobs.yaml b/zuul.d/manila-tempest-jobs.yaml
index 36a1faf..8952b88 100644
--- a/zuul.d/manila-tempest-jobs.yaml
+++ b/zuul.d/manila-tempest-jobs.yaml
@@ -38,7 +38,6 @@
         horizon: false
         tls-proxy: true
       devstack_localrc:
-        USE_PYTHON3: true
         MYSQL_REDUCE_MEMORY: True
         MANILA_USE_DOWNGRADE_MIGRATIONS: true
         MANILA_INSTALL_TEMPEST_PLUGIN_SYSTEMWIDE: false
@@ -102,7 +101,6 @@
         yaml: true
         yml: true
       devstack_localrc:
-        USE_PYTHON3: true
         MANILA_INSTALL_TEMPEST_PLUGIN_SYSTEMWIDE: false
         MANILA_SERVICE_IMAGE_ENABLED: false
         MANILA_SHARE_MIGRATION_PERIOD_TASK_INTERVAL: 1