Merge "Drop empty documentation sections"
diff --git a/manila_tempest_tests/config.py b/manila_tempest_tests/config.py
index decf2ac..4afa4e7 100644
--- a/manila_tempest_tests/config.py
+++ b/manila_tempest_tests/config.py
@@ -40,7 +40,7 @@
                     "This value is only used to validate the versions "
                     "response from Manila."),
     cfg.StrOpt("max_api_microversion",
-               default="2.85",
+               default="2.88",
                help="The maximum api microversion is configured to be the "
                     "value of the latest microversion supported by Manila."),
     cfg.StrOpt("region",
diff --git a/manila_tempest_tests/services/share/json/shares_client.py b/manila_tempest_tests/services/share/json/shares_client.py
index fb03afc..63a634c 100644
--- a/manila_tempest_tests/services/share/json/shares_client.py
+++ b/manila_tempest_tests/services/share/json/shares_client.py
@@ -304,37 +304,41 @@
                 return True
             else:
                 return self._is_resource_deleted(
-                    self.get_share, kwargs.get("share_id"))
+                    self.get_share, kwargs.get("share_id"), "share")
         elif "snapshot_id" in kwargs:
             return self._is_resource_deleted(
-                self.get_snapshot, kwargs.get("snapshot_id"))
+                self.get_snapshot, kwargs.get("snapshot_id"), "snapshot")
         elif "sn_id" in kwargs:
             return self._is_resource_deleted(
-                self.get_share_network, kwargs.get("sn_id"))
+                self.get_share_network, kwargs.get("sn_id"), "share_network")
         elif "ss_id" in kwargs:
             return self._is_resource_deleted(
-                self.get_security_service, kwargs.get("ss_id"))
+                self.get_security_service, kwargs.get("ss_id"),
+                "security_service")
         elif "vt_id" in kwargs:
             return self._is_resource_deleted(
-                self.get_volume_type, kwargs.get("vt_id"))
+                self.get_volume_type, kwargs.get("vt_id"), "volume_type")
         elif "st_id" in kwargs:
             return self._is_resource_deleted(
-                self.get_share_type, kwargs.get("st_id"))
+                self.get_share_type, kwargs.get("st_id"), "share_type")
         elif "server_id" in kwargs:
             return self._is_resource_deleted(
-                self.show_share_server, kwargs.get("server_id"))
+                self.show_share_server, kwargs.get("server_id"),
+                "share_server")
         elif "backup_id" in kwargs:
             return self._is_resource_deleted(
-                self.get_share_backup, kwargs.get("backup_id"))
+                self.get_share_backup, kwargs.get("backup_id"),
+                "share_backup")
         else:
             raise share_exceptions.InvalidResource(
                 message=str(kwargs))
 
-    def _is_resource_deleted(self, func, res_id, **kwargs):
+    def _is_resource_deleted(self, func, res_id, resource_name, **kwargs):
         try:
-            res = func(res_id, **kwargs)
+            res = func(res_id, **kwargs)[resource_name]
         except exceptions.NotFound:
             return True
+
         if res.get('status') in ['error_deleting', 'error']:
             # Resource has "error_deleting" status and can not be deleted.
             resource_type = func.__name__.split('_', 1)[-1]
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 e3a022e..4b35687 100644
--- a/manila_tempest_tests/services/share/v2/json/shares_client.py
+++ b/manila_tempest_tests/services/share/v2/json/shares_client.py
@@ -208,29 +208,33 @@
         """
         if "share_instance_id" in kwargs:
             return self._is_resource_deleted(
-                self.get_share_instance, kwargs.get("share_instance_id"))
+                self.get_share_instance, kwargs.get("share_instance_id"),
+                "share_instance")
         elif "share_group_id" in kwargs:
             return self._is_resource_deleted(
-                self.get_share_group, kwargs.get("share_group_id"))
+                self.get_share_group, kwargs.get("share_group_id"),
+                "share_group")
         elif "share_group_snapshot_id" in kwargs:
             return self._is_resource_deleted(
                 self.get_share_group_snapshot,
-                kwargs.get("share_group_snapshot_id"))
+                kwargs.get("share_group_snapshot_id"), "share_group_snapshot")
         elif "share_group_type_id" in kwargs:
             return self._is_resource_deleted(
-                self.get_share_group_type, kwargs.get("share_group_type_id"))
+                self.get_share_group_type, kwargs.get("share_group_type_id"),
+                "share_group_type")
         elif "replica_id" in kwargs:
             return self._is_resource_deleted(
-                self.get_share_replica, kwargs.get("replica_id"))
+                self.get_share_replica, kwargs.get("replica_id"),
+                "share_replica")
         elif "message_id" in kwargs:
             return self._is_resource_deleted(
-                self.get_message, kwargs.get("message_id"))
+                self.get_message, kwargs.get("message_id"), "message")
         elif "share_network_subnet_id" in kwargs:
             subnet_kwargs = {
-                "sn_id": kwargs["extra_params"]["share_network_id"]}
+                "share_network_id": kwargs["sn_id"]}
             return self._is_resource_deleted(
                 self.get_subnet, kwargs.get("share_network_subnet_id"),
-                **subnet_kwargs
+                "share_network_subnet", **subnet_kwargs
             )
         else:
             return super(SharesV2Client, self).is_resource_deleted(
@@ -899,6 +903,15 @@
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
+    def update_access_rule(self, access_id, access_level,
+                           version=LATEST_MICROVERSION):
+        url = 'share-access-rules/%s' % access_id
+        body = {'update_access': {"access_level": access_level}}
+        resp, body = self.put(url, json.dumps(body), version=version)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return rest_client.ResponseBody(resp, body)
+
     def update_access_metadata(self, access_id, metadata,
                                version=LATEST_MICROVERSION):
         url = 'share-access-rules/%s/metadata' % access_id
@@ -2095,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:
@@ -2104,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)
@@ -2299,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_quotas_negative.py b/manila_tempest_tests/tests/api/admin/test_quotas_negative.py
index 20e359a..5b4ff1d 100644
--- a/manila_tempest_tests/tests/api/admin/test_quotas_negative.py
+++ b/manila_tempest_tests/tests/api/admin/test_quotas_negative.py
@@ -130,6 +130,7 @@
         # try schedule share with size, bigger than gigabytes quota
         self.assertRaises(lib_exc.OverLimit,
                           self.create_share,
+                          share_type_id=self.share_type_id,
                           size=overquota)
 
     @decorators.idempotent_id('37dd40a8-375e-454b-8b80-229cb0eecb01')
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
old mode 100755
new mode 100644
index 5afe11c..c23e3be
--- 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"],
@@ -898,69 +899,80 @@
                 res["deleted"] = False
             if "client" not in res.keys():
                 res["client"] = cls.shares_client
-            if not res["deleted"]:
-                res_id = res['id']
-                client = res["client"]
-                with handle_cleanup_exceptions():
-                    if res["type"] == "share":
-                        cls.clear_share_replicas(res_id)
-                        share_group_id = res.get('share_group_id')
-                        if share_group_id:
-                            params = {'share_group_id': share_group_id}
-                            client.delete_share(res_id, params=params)
+            if not (res["deleted"]):
+                try:
+                    res_id = res['id']
+                    client = res["client"]
+                    with handle_cleanup_exceptions():
+                        if res["type"] == "share":
+                            cls.clear_share_replicas(res_id)
+                            share_group_id = res.get('share_group_id')
+                            if share_group_id:
+                                params = {'share_group_id': share_group_id}
+                                client.delete_share(res_id, params=params)
+                            else:
+                                client.delete_share(res_id)
+                            client.wait_for_resource_deletion(share_id=res_id)
+                        elif res["type"] == "snapshot":
+                            client.delete_snapshot(res_id)
+                            client.wait_for_resource_deletion(
+                                snapshot_id=res_id)
+                        elif (res["type"] == "share_network" and
+                                res_id != CONF.share.share_network_id):
+                            client.delete_share_network(res_id)
+                            client.wait_for_resource_deletion(sn_id=res_id)
+                        elif res["type"] == "dissociate_security_service":
+                            sn_id = res["extra_params"]["share_network_id"]
+                            client.remove_sec_service_from_share_network(
+                                sn_id=sn_id, ss_id=res_id
+                            )
+                        elif res["type"] == "security_service":
+                            client.delete_security_service(res_id)
+                            client.wait_for_resource_deletion(ss_id=res_id)
+                        elif res["type"] == "share_type":
+                            client.delete_share_type(res_id)
+                            client.wait_for_resource_deletion(st_id=res_id)
+                        elif res["type"] == "share_group":
+                            client.delete_share_group(res_id)
+                            client.wait_for_resource_deletion(
+                                share_group_id=res_id)
+                        elif res["type"] == "share_group_type":
+                            client.delete_share_group_type(res_id)
+                            client.wait_for_resource_deletion(
+                                share_group_type_id=res_id)
+                        elif res["type"] == "share_group_snapshot":
+                            client.delete_share_group_snapshot(res_id)
+                            client.wait_for_resource_deletion(
+                                share_group_snapshot_id=res_id)
+                        elif res["type"] == "share_replica":
+                            client.delete_share_replica(res_id)
+                            client.wait_for_resource_deletion(
+                                replica_id=res_id)
+                        elif res["type"] == "share_backup":
+                            client.delete_share_backup(res_id)
+                            client.wait_for_resource_deletion(backup_id=res_id)
+                        elif res["type"] == "share_network_subnet":
+                            sn_id = res["extra_params"]["share_network_id"]
+                            client.delete_subnet(sn_id, res_id)
+                            client.wait_for_resource_deletion(
+                                share_network_subnet_id=res_id,
+                                sn_id=sn_id)
+                        elif res["type"] == "quotas":
+                            user_id = res.get('user_id')
+                            client.reset_quotas(res_id, user_id=user_id)
+                        elif res["type"] == "resource_lock":
+                            client.delete_resource_lock(res_id)
                         else:
-                            client.delete_share(res_id)
-                        client.wait_for_resource_deletion(share_id=res_id)
-                    elif res["type"] == "snapshot":
-                        client.delete_snapshot(res_id)
-                        client.wait_for_resource_deletion(snapshot_id=res_id)
-                    elif (res["type"] == "share_network" and
-                            res_id != CONF.share.share_network_id):
-                        client.delete_share_network(res_id)
-                        client.wait_for_resource_deletion(sn_id=res_id)
-                    elif res["type"] == "dissociate_security_service":
-                        sn_id = res["extra_params"]["share_network_id"]
-                        client.remove_sec_service_from_share_network(
-                            sn_id=sn_id, ss_id=res_id
-                        )
-                    elif res["type"] == "security_service":
-                        client.delete_security_service(res_id)
-                        client.wait_for_resource_deletion(ss_id=res_id)
-                    elif res["type"] == "share_type":
-                        client.delete_share_type(res_id)
-                        client.wait_for_resource_deletion(st_id=res_id)
-                    elif res["type"] == "share_group":
-                        client.delete_share_group(res_id)
-                        client.wait_for_resource_deletion(
-                            share_group_id=res_id)
-                    elif res["type"] == "share_group_type":
-                        client.delete_share_group_type(res_id)
-                        client.wait_for_resource_deletion(
-                            share_group_type_id=res_id)
-                    elif res["type"] == "share_group_snapshot":
-                        client.delete_share_group_snapshot(res_id)
-                        client.wait_for_resource_deletion(
-                            share_group_snapshot_id=res_id)
-                    elif res["type"] == "share_replica":
-                        client.delete_share_replica(res_id)
-                        client.wait_for_resource_deletion(replica_id=res_id)
-                    elif res["type"] == "share_backup":
-                        client.delete_share_backup(res_id)
-                        client.wait_for_resource_deletion(backup_id=res_id)
-                    elif res["type"] == "share_network_subnet":
-                        sn_id = res["extra_params"]["share_network_id"]
-                        client.delete_subnet(sn_id, res_id)
-                        client.wait_for_resource_deletion(
-                            share_network_subnet_id=res_id,
-                            sn_id=sn_id)
-                    elif res["type"] == "quotas":
-                        user_id = res.get('user_id')
-                        client.reset_quotas(res_id, user_id=user_id)
-                    elif res["type"] == "resource_lock":
-                        client.delete_resource_lock(res_id)
-                    else:
-                        LOG.warning("Provided unsupported resource type for "
-                                    "cleanup '%s'. Skipping.", res["type"])
+                            LOG.warning("Provided unsupported resource type "
+                                        "for cleanup '%s'. Skipping.",
+                                        res["type"])
+                except share_exceptions.ResourceReleaseFailed as e:
+                    # Resource is on error deleting state, so we remove it from
+                    # the list to delete, since it cannot be deleted anymore.
+                    # It raises because the current cleanup class or method
+                    # must fail.
+                    res["deleted"] = True
+                    raise e
                 res["deleted"] = True
 
     # Useful assertions
@@ -1283,12 +1295,18 @@
         cls.admin_project = cls.os_admin.auth_provider.auth_data[1]['project']
         identity_clients = getattr(
             cls.os_admin, 'identity_%s' % CONF.identity.auth_version)
-        cls.os_admin.identity_client = identity_clients.IdentityClient()
-        cls.os_admin.projects_client = identity_clients.ProjectsClient()
-        cls.os_admin.users_client = identity_clients.UsersClient()
-        cls.os_admin.roles_client = identity_clients.RolesClient()
+        endpoint_type = CONF.share.endpoint_type
+        cls.os_admin.identity_client = identity_clients.IdentityClient(
+            endpoint_type=endpoint_type)
+        cls.os_admin.projects_client = identity_clients.ProjectsClient(
+            endpoint_type=endpoint_type)
+        cls.os_admin.users_client = identity_clients.UsersClient(
+            endpoint_type=endpoint_type)
+        cls.os_admin.roles_client = identity_clients.RolesClient(
+            endpoint_type=endpoint_type)
         cls.os_admin.domains_client = (
-            cls.os_admin.identity_v3.DomainsClient() if
+            cls.os_admin.identity_v3.DomainsClient(
+                endpoint_type=endpoint_type) if
             CONF.identity.auth_version == 'v3' else None)
         cls.admin_project_member_client = cls.create_user_and_get_client(
             project=cls.admin_project, add_member_role=True)
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 862de50..3574d64 100644
--- a/manila_tempest_tests/tests/api/test_metadata.py
+++ b/manila_tempest_tests/tests/api/test_metadata.py
@@ -13,11 +13,14 @@
 #    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
 
+CONF = config.CONF
+
 
 class SharesMetadataTest(base.BaseSharesMixedTest):
 
@@ -43,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,
@@ -57,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,
@@ -82,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,
@@ -118,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,
@@ -135,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
@@ -153,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,
@@ -263,3 +266,35 @@
         body_get = self.shares_v2_client.get_metadata(
             self.share["id"])['metadata']
         self.assertEqual(max_value, body_get["key"])
+
+
+class SharesMetadataCEPHFSTest(base.BaseSharesMixedTest):
+
+    protocol = "cephfs"
+
+    @classmethod
+    def resource_setup(cls):
+        super(SharesMetadataCEPHFSTest, cls).resource_setup()
+        # create share type
+        cls.share_type = cls.create_share_type()
+        cls.share_type_id = cls.share_type['id']
+        # create share
+        cls.share = cls.create_share(share_type_id=cls.share_type_id)
+
+    @classmethod
+    def skip_checks(cls):
+        super(SharesMetadataCEPHFSTest, cls).skip_checks()
+        if not (cls.protocol in CONF.share.enable_protocols):
+            msg = (
+                "CEPHFS filesystem metadata tests are disabled "
+                "for the %s protocol." % cls.protocol)
+            raise cls.skipException(msg)
+
+    @decorators.idempotent_id('58edc9c8-8b85-49aa-80aa-209fc8f40a13')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
+    def test_cephfs_share_contains_mount_option(self):
+        body_get = self.shares_v2_client.get_metadata(
+            self.share["id"])['metadata']
+
+        self.assertIn("__mount_options", body_get)
+        self.assertIn("fs", body_get["__mount_options"])
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.py b/manila_tempest_tests/tests/api/test_rules.py
index 5f39852..99ac254 100644
--- a/manila_tempest_tests/tests/api/test_rules.py
+++ b/manila_tempest_tests/tests/api/test_rules.py
@@ -22,6 +22,7 @@
 import testtools
 from testtools import testcase as tc
 
+from manila_tempest_tests.common import waiters
 from manila_tempest_tests.tests.api import base
 from manila_tempest_tests import utils
 
@@ -62,6 +63,7 @@
             self.share['id'])['access_list']
         rule = [r for r in rules if r['id'] == rule['id']][0]
         self.assertEqual("active", rule['state'])
+    return rule
 
 
 @ddt.ddt
@@ -162,8 +164,23 @@
         "RO access rule tests are disabled for NFS protocol.")
     @ddt.data(*utils.deduplicate(['1.0', '2.9', '2.27', '2.28',
                                  LATEST_MICROVERSION]))
-    def test_create_delete_ro_access_rule(self, client_name):
-        _create_delete_ro_access_rule(self, client_name)
+    def test_create_delete_ro_access_rule(self, version):
+        _create_delete_ro_access_rule(self, version)
+
+    @utils.skip_if_microversion_not_supported('2.88')
+    @decorators.idempotent_id('01940881-6f95-77f8-b47d-0941c4e6bafb')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
+    @testtools.skipIf(
+        "nfs" not in CONF.share.enable_ro_access_level_for_protocols,
+        "RO access rule tests are disabled for NFS protocol.")
+    def test_update_access_rule(self):
+        rule = _create_delete_ro_access_rule(self, LATEST_MICROVERSION)
+        rule = self.shares_v2_client.update_access_rule(
+            access_id=rule['id'], access_level='rw')['access']
+        waiters.wait_for_resource_status(
+            self.shares_v2_client, self.share['id'], status='active',
+            resource_name='access_rule', rule_id=rule['id'])
+        self.assertEqual(rule['access_level'], 'rw')
 
 
 @ddt.ddt
@@ -180,6 +197,18 @@
     def test_create_delete_ro_access_rule(self, version):
         _create_delete_ro_access_rule(self, version)
 
+    @utils.skip_if_microversion_not_supported('2.88')
+    @decorators.idempotent_id('02940881-6f95-77f8-b47d-0941c4e6bafb')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
+    @testtools.skipIf(
+        "cifs" not in CONF.share.enable_ro_access_level_for_protocols,
+        "RO access rule tests are disabled for CIFS protocol.")
+    def test_update_access_rule(self):
+        super(
+            ShareIpRulesForCIFSTest,
+            self
+        ).test_update_access_rule()
+
 
 @ddt.ddt
 class ShareUserRulesForNFSTest(base.BaseSharesMixedTest):
diff --git a/manila_tempest_tests/tests/api/test_rules_negative.py b/manila_tempest_tests/tests/api/test_rules_negative.py
index 84b416d..2b62ad5 100644
--- a/manila_tempest_tests/tests/api/test_rules_negative.py
+++ b/manila_tempest_tests/tests/api/test_rules_negative.py
@@ -368,6 +368,27 @@
                           CONF.share.username_for_user_rules,
                           'su')
 
+    @utils.skip_if_microversion_not_supported('2.88')
+    @decorators.idempotent_id('d5b1e7c9-7e6b-4918-a1c4-e03c8d82c46a')
+    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
+    def test_update_access_rule_with_wrong_level(self):
+        access_type, access_to = utils.get_access_rule_data_from_config(
+            self.protocol)
+        if access_type != 'ip':
+            msg = "Access rule updates supported only for 'ip' access."
+            raise self.skipException(msg)
+
+        rule = self.allow_access(
+            self.share["id"], client=self.shares_v2_client,
+            access_type=access_type, access_to=access_to)
+
+        self.assertRaises(
+            lib_exc.BadRequest,
+            self.shares_v2_client.update_access_rule,
+            rule['id'],
+            access_level='fake_level'
+        )
+
 
 @ddt.ddt
 class ShareUserRulesForCIFSNegativeTest(ShareUserRulesForNFSNegativeTest):
@@ -471,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,
@@ -499,22 +520,24 @@
     @decorators.idempotent_id('4ffed391-d7cc-481b-bb74-9f3406ddd75f')
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
     def test_different_tenants_cannot_use_same_cephx_id(self):
+        scheduler_hint = {"same_host": "%s" % self.share["id"]}
+
         # Grant access to the share
         self.allow_access(self.share['id'], access_to=self.access_to)
-
         # Create second share by the new user
-        share2 = self.create_share(client=self.alt_shares_v2_client,
+        share2 = self.create_share(client=self.admin_shares_v2_client,
                                    share_protocol=self.protocol,
-                                   share_type_id=self.share_type_id)
+                                   share_type_id=self.share_type_id,
+                                   scheduler_hints=scheduler_hint)
 
         # Try grant access to the second share using the same cephx id as used
         # on the first share.
         # Rule must be set to "error" status.
-        self.allow_access(share2['id'], client=self.alt_shares_v2_client,
+        self.allow_access(share2['id'], client=self.admin_shares_v2_client,
                           access_to=self.access_to, status='error',
                           raise_rule_in_error_state=False)
 
-        share_alt_updated = self.alt_shares_v2_client.get_share(
+        share_alt_updated = self.admin_shares_v2_client.get_share(
             share2['id'])['share']
         self.assertEqual('error', share_alt_updated['access_rules_status'])
 
@@ -522,35 +545,39 @@
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
     def test_can_apply_new_cephx_rules_when_one_is_in_error_state(self):
         # Create share on "primary" tenant
-        share_primary = self.create_share(share_type_id=self.share_type_id)
+        share_primary = self.create_share(
+            share_type_id=self.share_type_id)
         # Add access rule to "Joe" by "primary" user
         self.allow_access(share_primary['id'], access_to='Joe')
 
-        # Create share on "alt" tenant
-        share_alt = self.create_share(
-            client=self.alt_shares_v2_client, share_type_id=self.share_type_id)
-        # Add access rule to "Joe" by "alt" user.
+        scheduler_hint = {"same_host": "%s" % share_primary["id"]}
+        # Create share on "admin" tenant
+        share_adm = self.create_share(
+            client=self.admin_shares_v2_client,
+            share_type_id=self.share_type_id,
+            scheduler_hints=scheduler_hint)
+        # Add access rule to "Joe" by "admin" user.
         # Rule must be set to "error" status.
-        rule1 = self.allow_access(share_alt['id'],
-                                  client=self.alt_shares_v2_client,
+        rule1 = self.allow_access(share_adm['id'],
+                                  client=self.admin_shares_v2_client,
                                   access_to='Joe',
                                   status='error',
                                   raise_rule_in_error_state=False,
                                   cleanup=False)
 
         # Share's "access_rules_status" must be in "error" status
-        share_alt_updated = self.alt_shares_v2_client.get_share(
-            share_alt['id'])['share']
-        self.assertEqual('error', share_alt_updated['access_rules_status'])
+        share_adm_updated = self.admin_shares_v2_client.get_share(
+            share_adm['id'])['share']
+        self.assertEqual('error', share_adm_updated['access_rules_status'])
 
-        # Add second access rule to different client by "alt" user.
-        self.allow_access(share_alt['id'], client=self.alt_shares_v2_client)
+        # Add second access rule to different client by "admin" user.
+        self.allow_access(share_adm['id'], client=self.admin_shares_v2_client)
 
         # Check share's access_rules_status has transitioned to "active" status
-        self.alt_shares_v2_client.delete_access_rule(
-            share_alt['id'], rule1['id'])
+        self.admin_shares_v2_client.delete_access_rule(
+            share_adm['id'], rule1['id'])
         waiters.wait_for_resource_status(
-            self.alt_shares_v2_client, share_alt['id'], 'active',
+            self.admin_shares_v2_client, share_adm['id'], 'active',
             status_attr='access_rules_status')
 
 
diff --git a/manila_tempest_tests/tests/api/test_scheduler_hints.py b/manila_tempest_tests/tests/api/test_scheduler_hints.py
index 5012f17..e5e51a5 100644
--- a/manila_tempest_tests/tests/api/test_scheduler_hints.py
+++ b/manila_tempest_tests/tests/api/test_scheduler_hints.py
@@ -72,14 +72,17 @@
         # get metadata of share
         metadata_a = self.shares_v2_client.get_metadata(
             self.share_a["id"])['metadata']
-        md_a = {"__affinity_same_host": "%s" % share_b["id"]}
+        expected_md_a = {"__affinity_same_host": "%s" % share_b["id"]}
         metadata_b = self.shares_v2_client.get_metadata(
             share_b["id"])['metadata']
-        md_b = {"__affinity_same_host": "%s" % self.share_a["id"]}
+        expected_md_b = {"__affinity_same_host": "%s" % self.share_a["id"]}
 
         # verify metadata
-        self.assertEqual(md_a, metadata_a)
-        self.assertEqual(md_b, metadata_b)
+        for key, value in expected_md_a.items():
+            self.assertEqual(value, metadata_a.get(key))
+
+        for key, value in expected_md_b.items():
+            self.assertEqual(value, metadata_b.get(key))
 
     @decorators.idempotent_id('6569e0c3-43c9-4ee2-84ff-ea7fa8da8110')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
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/manila_tempest_tests/tests/rbac/test_rules.py b/manila_tempest_tests/tests/rbac/test_rules.py
index 8a6d46f..2c6a019 100644
--- a/manila_tempest_tests/tests/rbac/test_rules.py
+++ b/manila_tempest_tests/tests/rbac/test_rules.py
@@ -48,7 +48,7 @@
     @classmethod
     def resource_setup(cls):
         super(ShareRbacRulesTests, cls).resource_setup()
-        cls.metadata = {u'key': u'value'}
+        cls.metadata = {'key': 'value'}
 
     def access(self, share_id, access_type, access_to, access_level='rw'):
         access = {}
@@ -58,10 +58,10 @@
         access['access_level'] = access_level
         return access
 
-    def allow_access(self, client, share_id, access_type, access_to,
-                     access_level='rw', metadata=None, status='active',
-                     cleanup=True):
-
+    def allow_access(self, client, share_id, access_level='rw', metadata=None,
+                     status='active', cleanup=True):
+        access_type, access_to = (
+            utils.get_access_rule_data_from_config(self.protocol))
         kwargs = {
             'access_type': access_type,
             'access_to': access_to,
@@ -93,6 +93,10 @@
         pass
 
     @abc.abstractmethod
+    def test_update_access(self):
+        pass
+
+    @abc.abstractmethod
     def test_delete_access(self):
         pass
 
@@ -127,35 +131,27 @@
     @decorators.idempotent_id('5b6897d1-4b2a-490c-990e-941ea4893f47')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_get_access(self):
-        access_type, access_to = (
-            utils.get_access_rule_data_from_config(self.protocol))
         access = self.allow_access(
-            self.share_member_client, self.share['id'],
-            access_type=access_type, access_to=access_to)
+            self.share_member_client, self.share['id'])
         self.do_request(
             'get_access_rule', expected_status=200, access_id=access['id'])
 
         alt_access = self.allow_access(
-            self.alt_project_share_v2_client, self.alt_share['id'],
-            access_type=access_type, access_to=access_to)
+            self.alt_project_share_v2_client, self.alt_share['id'])
         self.do_request(
             'get_access_rule', expected_status=200, access_id=alt_access['id'])
 
     @decorators.idempotent_id('f8e9a2bb-ccff-4fc5-8d61-2930f87406cd')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_list_access(self):
-        access_type, access_to = (
-            utils.get_access_rule_data_from_config(self.protocol))
         access = self.allow_access(
-            self.share_member_client, self.share['id'],
-            access_type=access_type, access_to=access_to)
+            self.share_member_client, self.share['id'])
         access_list = self.do_request(
             'list_access_rules', expected_status=200,
             share_id=self.share['id'])['access_list'][0]['id']
 
         alt_access = self.allow_access(
-            self.alt_project_share_v2_client, self.alt_share['id'],
-            access_type=access_type, access_to=access_to)
+            self.alt_project_share_v2_client, self.alt_share['id'])
         alt_access_list = self.do_request(
             'list_access_rules', expected_status=200,
             share_id=self.share['id'])['access_list'][0]['id']
@@ -163,6 +159,33 @@
         self.assertIn(access['id'], access_list)
         self.assertNotIn(alt_access['id'], alt_access_list)
 
+    @utils.skip_if_microversion_not_supported('2.88')
+    @decorators.idempotent_id('01939b69-ef9b-75cf-abf7-5171fec7c397')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
+    def test_update_access(self):
+        access_type, access_to = (
+            utils.get_access_rule_data_from_config(self.protocol))
+        if access_type != 'ip':
+            msg = "Access rule updates supported only for 'ip' access."
+            raise self.skipException(msg)
+
+        access = self.allow_access(self.share_member_client, self.share['id'])
+        rule = self.do_request(
+            'update_access_rule', expected_status=200,
+            access_id=access['id'], access_level='ro')['access']
+        waiters.wait_for_resource_status(
+            self.share_member_client, self.share['id'], status='active',
+            resource_name='access_rule', rule_id=rule['id'])
+
+        alt_access = self.allow_access(
+            self.alt_project_share_v2_client, self.alt_share['id'])
+        rule = self.do_request(
+            'update_access_rule', expected_status=200,
+            access_id=alt_access['id'], access_level='ro')['access']
+        waiters.wait_for_resource_status(
+            self.alt_project_share_v2_client, self.alt_share['id'],
+            status='active', resource_name='access_rule', rule_id=rule['id'])
+
     @decorators.idempotent_id('b4d7a91c-a75e-4ad9-93cb-8e5234fea97a')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_grant_access_rule(self):
@@ -180,6 +203,8 @@
         self.addCleanup(
             self.client.delete_access_rule, self.share['id'], access['id'])
 
+        access_type, access_to = (
+            utils.get_access_rule_data_from_config(self.protocol))
         alt_access = self.do_request(
             'create_access_rule', expected_status=200,
             **self.access(
@@ -197,12 +222,8 @@
     @decorators.idempotent_id('e24d7018-cb49-4306-9947-716b4e4250c5')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_delete_access(self):
-        access_type, access_to = (
-            utils.get_access_rule_data_from_config(self.protocol))
         access = self.allow_access(
-            self.share_member_client, self.share['id'],
-            access_type=access_type,
-            access_to=access_to, cleanup=False)
+            self.share_member_client, self.share['id'], cleanup=False)
         self.do_request(
             'delete_access_rule', expected_status=202,
             share_id=self.share['id'], rule_id=access['id'])
@@ -211,7 +232,6 @@
 
         alt_access = self.allow_access(
             self.alt_project_share_v2_client, self.alt_share['id'],
-            access_type=access_type, access_to=access_to,
             cleanup=False)
         self.do_request(
             'delete_access_rule', expected_status=202,
@@ -222,18 +242,14 @@
     @decorators.idempotent_id('ffc07445-d0d1-4bf9-9fbc-4f409d48bccd')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_update_access_rule_metadata(self):
-        access_type, access_to = (
-            utils.get_access_rule_data_from_config(self.protocol))
         access = self.allow_access(
-            self.share_member_client, self.share['id'],
-            access_type=access_type, access_to=access_to)
+            self.share_member_client, self.share['id'])
         self.do_request(
             'update_access_metadata', expected_status=200,
             access_id=access['id'], metadata=self.metadata)
 
         alt_access = self.allow_access(
-            self.alt_project_share_v2_client, self.alt_share['id'],
-            access_type=access_type, access_to=access_to)
+            self.alt_project_share_v2_client, self.alt_share['id'])
         self.do_request(
             'update_access_metadata', expected_status=200,
             access_id=alt_access['id'], metadata=self.metadata)
@@ -241,19 +257,14 @@
     @decorators.idempotent_id('fd580d91-1d8d-4dd0-8484-01c412ddb768')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_delete_access_rule_metadata(self):
-        access_type, access_to = (
-            utils.get_access_rule_data_from_config(self.protocol))
         access = self.allow_access(
-            self.share_member_client, self.share['id'],
-            access_type=access_type, access_to=access_to,
-            metadata=self.metadata)
+            self.share_member_client, self.share['id'], metadata=self.metadata)
         self.do_request(
             'delete_access_metadata', expected_status=200,
             access_id=access['id'], key='key')
 
         alt_access = self.allow_access(
             self.alt_project_share_v2_client, self.alt_share['id'],
-            access_type=access_type, access_to=access_to,
             metadata=self.metadata)
         self.do_request(
             'delete_access_metadata', expected_status=200,
@@ -276,18 +287,13 @@
     @decorators.idempotent_id('de643909-88a2-470b-8a14-0417696ec451')
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
     def test_get_access(self):
-        access_type, access_to = (
-            utils.get_access_rule_data_from_config(self.protocol))
         share_client = getattr(self, 'share_member_client', self.client)
-        access = self.allow_access(
-            share_client, self.share['id'], access_type=access_type,
-            access_to=access_to)
+        access = self.allow_access(share_client, self.share['id'])
         self.do_request(
             'get_access_rule', expected_status=200, access_id=access['id'])
 
         alt_access = self.allow_access(
-            self.alt_project_share_v2_client, self.alt_share['id'],
-            access_type=access_type, access_to=access_to)
+            self.alt_project_share_v2_client, self.alt_share['id'])
         self.do_request(
             'get_access_rule', expected_status=lib_exc.NotFound,
             access_id=alt_access['id'])
@@ -295,15 +301,10 @@
     @decorators.idempotent_id('7c6c4262-5095-4cd7-9d9c-8064009a9055')
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_list_access(self):
-        access_type, access_to = (
-            utils.get_access_rule_data_from_config(self.protocol))
         share_client = getattr(self, 'share_member_client', self.client)
-        access = self.allow_access(
-            share_client, self.share['id'], access_type=access_type,
-            access_to=access_to)
+        access = self.allow_access(share_client, self.share['id'])
         alt_access = self.allow_access(
-            self.alt_project_share_v2_client, self.alt_share['id'],
-            access_type=access_type, access_to=access_to)
+            self.alt_project_share_v2_client, self.alt_share['id'])
 
         access_list = self.do_request(
             'list_access_rules', expected_status=200,
@@ -315,6 +316,31 @@
         self.assertIn(access['id'], access_id_list)
         self.assertNotIn(alt_access['id'], access_id_list)
 
+    @utils.skip_if_microversion_not_supported('2.88')
+    @decorators.idempotent_id('02939b69-ef9b-75cf-abf7-5171fec7c397')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
+    def test_update_access(self):
+        access_type, access_to = (
+            utils.get_access_rule_data_from_config(self.protocol))
+        if access_type != 'ip':
+            msg = "Access rule updates supported only for 'ip' access."
+            raise self.skipException(msg)
+
+        share_client = getattr(self, 'share_member_client', self.client)
+        access = self.allow_access(share_client, self.share['id'])
+        rule = self.do_request(
+            'update_access_rule', client=share_client, expected_status=200,
+            access_id=access['id'], access_level='ro')['access']
+        waiters.wait_for_resource_status(
+            share_client, self.share['id'], status='active',
+            resource_name='access_rule', rule_id=rule['id'])
+
+        alt_access = self.allow_access(
+            self.alt_project_share_v2_client, self.alt_share['id'])
+        self.do_request(
+            'update_access_rule', expected_status=lib_exc.NotFound,
+            access_id=alt_access['id'], access_level='ro')
+
     @decorators.idempotent_id('61cf6f6c-5d7c-48d7-9d5a-e6ea288afdbc')
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
     def test_grant_access_rule(self):
@@ -333,6 +359,8 @@
         self.addCleanup(
             self.client.delete_access_rule, self.share['id'], access['id'])
 
+        access_type, access_to = (
+            utils.get_access_rule_data_from_config(self.protocol))
         self.do_request(
             'create_access_rule', client=share_client,
             expected_status=lib_exc.NotFound,
@@ -341,12 +369,9 @@
     @decorators.idempotent_id('8665d1b1-de4c-42d4-93ff-8dc6d2b73a2d')
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
     def test_delete_access(self):
-        access_type, access_to = (
-            utils.get_access_rule_data_from_config(self.protocol))
         share_client = getattr(self, 'share_member_client', self.client)
         access = self.allow_access(
-            share_client, self.share['id'], access_type=access_type,
-            access_to=access_to, cleanup=False)
+            share_client, self.share['id'], cleanup=False)
         self.do_request(
             'delete_access_rule', expected_status=202,
             share_id=self.share['id'], rule_id=access['id'])
@@ -354,8 +379,7 @@
             rule_id=access['id'], share_id=self.share['id'])
 
         alt_access = self.allow_access(
-            self.alt_project_share_v2_client, self.alt_share['id'],
-            access_type=access_type, access_to=access_to)
+            self.alt_project_share_v2_client, self.alt_share['id'])
         self.do_request(
             'delete_access_rule', expected_status=lib_exc.NotFound,
             share_id=self.alt_share['id'], rule_id=alt_access['id'])
@@ -363,19 +387,14 @@
     @decorators.idempotent_id('c5e84362-6075-425b-bfa3-898abfd9d5a0')
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
     def test_update_access_rule_metadata(self):
-        access_type, access_to = (
-            utils.get_access_rule_data_from_config(self.protocol))
         share_client = getattr(self, 'share_member_client', self.client)
-        access = self.allow_access(
-            share_client, self.share['id'], access_type=access_type,
-            access_to=access_to)
+        access = self.allow_access(share_client, self.share['id'])
         self.do_request(
             'update_access_metadata', expected_status=200,
             access_id=access['id'], metadata=self.metadata)
 
         alt_access = self.allow_access(
-            self.alt_project_share_v2_client, self.alt_share['id'],
-            access_type=access_type, access_to=access_to)
+            self.alt_project_share_v2_client, self.alt_share['id'])
         self.do_request(
             'update_access_metadata', expected_status=lib_exc.NotFound,
             access_id=alt_access['id'], metadata=self.metadata)
@@ -383,19 +402,15 @@
     @decorators.idempotent_id('abb17315-6510-4b6e-ae6c-dd99a6088954')
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
     def test_delete_access_rule_metadata(self):
-        access_type, access_to = (
-            utils.get_access_rule_data_from_config(self.protocol))
         share_client = getattr(self, 'share_member_client', self.client)
         access = self.allow_access(
-            share_client, self.share['id'], access_type=access_type,
-            access_to=access_to, metadata=self.metadata)
+            share_client, self.share['id'], metadata=self.metadata)
         self.do_request(
             'delete_access_metadata', expected_status=200,
             access_id=access['id'], key='key')
 
         alt_access = self.allow_access(
             self.alt_project_share_v2_client, self.alt_share['id'],
-            access_type=access_type, access_to=access_to,
             metadata=self.metadata)
         self.do_request(
             'delete_access_metadata', expected_status=lib_exc.NotFound,
@@ -432,6 +447,20 @@
     def test_list_access(self):
         super(TestProjectReaderTestsNFS, self).test_list_access()
 
+    @decorators.idempotent_id('03939b69-ef9b-75cf-abf7-5171fec7c397')
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
+    def test_update_access(self):
+        access = self.allow_access(self.share_member_client, self.share['id'])
+        self.do_request(
+            'update_access_rule', expected_status=lib_exc.Forbidden,
+            access_id=access['id'], access_level='ro')
+
+        alt_access = self.allow_access(
+            self.alt_project_share_v2_client, self.alt_share['id'])
+        self.do_request(
+            'update_access_rule', expected_status=lib_exc.Forbidden,
+            access_id=alt_access['id'], access_level='ro')
+
     @decorators.idempotent_id('ace870f9-af91-4259-8760-dc7d7107b7ff')
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
     def test_grant_access_rule(self):
@@ -441,6 +470,8 @@
             'create_access_rule', expected_status=lib_exc.Forbidden,
             **self.access(self.share['id'], access_type, access_to))
 
+        access_type, access_to = (
+            utils.get_access_rule_data_from_config(self.protocol))
         self.do_request(
             'create_access_rule', expected_status=lib_exc.Forbidden,
             **self.access(self.alt_share['id'], access_type, access_to))
@@ -448,18 +479,13 @@
     @decorators.idempotent_id('7a702c74-8d31-49e3-859a-cc8a78d7915e')
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
     def test_delete_access(self):
-        access_type, access_to = (
-            utils.get_access_rule_data_from_config(self.protocol))
-        access = self.allow_access(
-            self.share_member_client, self.share['id'],
-            access_type=access_type, access_to=access_to)
+        access = self.allow_access(self.share_member_client, self.share['id'])
         self.do_request(
             'delete_access_rule', expected_status=lib_exc.Forbidden,
             share_id=self.share['id'], rule_id=access['id'])
 
         alt_access = self.allow_access(
-            self.alt_project_share_v2_client, self.alt_share['id'],
-            access_type=access_type, access_to=access_to)
+            self.alt_project_share_v2_client, self.alt_share['id'])
         self.do_request(
             'delete_access_rule', expected_status=lib_exc.Forbidden,
             share_id=self.alt_share['id'], rule_id=alt_access['id'])
@@ -467,18 +493,13 @@
     @decorators.idempotent_id('a61d7f06-6f0e-4da3-b11d-1c3a0b5bd416')
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
     def test_update_access_rule_metadata(self):
-        access_type, access_to = (
-            utils.get_access_rule_data_from_config(self.protocol))
-        access = self.allow_access(
-            self.share_member_client, self.share['id'],
-            access_type=access_type, access_to=access_to)
+        access = self.allow_access(self.share_member_client, self.share['id'])
         self.do_request(
             'update_access_metadata', expected_status=lib_exc.Forbidden,
             access_id=access['id'], metadata=self.metadata)
 
         alt_access = self.allow_access(
-            self.alt_project_share_v2_client, self.alt_share['id'],
-            access_type=access_type, access_to=access_to)
+            self.alt_project_share_v2_client, self.alt_share['id'])
         self.do_request(
             'update_access_metadata', expected_status=lib_exc.Forbidden,
             access_id=alt_access['id'], metadata=self.metadata)
@@ -486,19 +507,14 @@
     @decorators.idempotent_id('5faf0e0b-b246-4392-901d-9e7d628f0d6e')
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
     def test_delete_access_rule_metadata(self):
-        access_type, access_to = (
-            utils.get_access_rule_data_from_config(self.protocol))
         access = self.allow_access(
-            self.share_member_client, self.share['id'],
-            access_type=access_type, access_to=access_to,
-            metadata=self.metadata)
+            self.share_member_client, self.share['id'], metadata=self.metadata)
         self.do_request(
             'delete_access_metadata', expected_status=lib_exc.Forbidden,
             access_id=access['id'], key='key')
 
         alt_access = self.allow_access(
             self.alt_project_share_v2_client, self.alt_share['id'],
-            access_type=access_type, access_to=access_to,
             metadata=self.metadata)
         self.do_request(
             'delete_access_metadata', expected_status=lib_exc.Forbidden,
diff --git a/manila_tempest_tests/tests/rbac/test_share_group_types.py b/manila_tempest_tests/tests/rbac/test_share_group_types.py
index ac2f54b..6886cc1 100644
--- a/manila_tempest_tests/tests/rbac/test_share_group_types.py
+++ b/manila_tempest_tests/tests/rbac/test_share_group_types.py
@@ -51,8 +51,8 @@
     @classmethod
     def resource_setup(cls):
         super(ShareRbacShareGroupTypesTests, cls).resource_setup()
-        cls.group_specs1 = {u'key1': u'value1'}
-        cls.group_specs2 = {u'key2': u'value2'}
+        cls.group_specs1 = {'key1': 'value1'}
+        cls.group_specs2 = {'key2': 'value2'}
         cls.share_type = cls.create_share_type()
         cls.share_group_type = cls.create_share_group_type(
             cls.share_type['id'], group_specs=cls.group_specs1)
diff --git a/manila_tempest_tests/tests/rbac/test_share_type_extra_specs.py b/manila_tempest_tests/tests/rbac/test_share_type_extra_specs.py
index 0fae6f0..725fefd 100644
--- a/manila_tempest_tests/tests/rbac/test_share_type_extra_specs.py
+++ b/manila_tempest_tests/tests/rbac/test_share_type_extra_specs.py
@@ -40,7 +40,7 @@
     @classmethod
     def resource_setup(cls):
         super(ShareRbacExtraSpecsTests, cls).resource_setup()
-        cls.extra_specs = {u'key': u'value'}
+        cls.extra_specs = {'key': 'value'}
         cls.share_type = cls.create_share_type()
 
     @abc.abstractmethod
diff --git a/manila_tempest_tests/tests/rbac/test_snapshots.py b/manila_tempest_tests/tests/rbac/test_snapshots.py
index 1978415..f5114bf 100644
--- a/manila_tempest_tests/tests/rbac/test_snapshots.py
+++ b/manila_tempest_tests/tests/rbac/test_snapshots.py
@@ -221,7 +221,7 @@
     def test_set_snapshot_metadata(self):
         snap = self.create_snapshot(
             self.share_member_client, self.share['id'])
-        metadata = {u'key': u'value'}
+        metadata = {'key': 'value'}
         self.do_request(
             'set_metadata', expected_status=200,
             resource_id=snap['id'], resource='snapshot', metadata=metadata)
@@ -236,7 +236,7 @@
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     @utils.skip_if_microversion_not_supported("2.73")
     def test_get_snapshot_metadata(self):
-        metadata = {u'key': u'value'}
+        metadata = {'key': 'value'}
         snap = self.create_snapshot(
             self.share_member_client, self.share['id'],
             metadata=metadata)
@@ -255,7 +255,7 @@
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     @utils.skip_if_microversion_not_supported("2.73")
     def test_delete_snapshot_metadata(self):
-        metadata = {u'key': u'value'}
+        metadata = {'key': 'value'}
         snap = self.create_snapshot(
             self.share_member_client, self.share['id'], metadata=metadata)
         self.do_request(
@@ -392,7 +392,7 @@
     @utils.skip_if_microversion_not_supported("2.73")
     def test_set_snapshot_metadata(self):
         snap = self.create_snapshot(self.client, self.share['id'])
-        metadata = {u'key': u'value'}
+        metadata = {'key': 'value'}
         self.do_request(
             'set_metadata', expected_status=200,
             resource_id=snap['id'], resource='snapshot', metadata=metadata)
@@ -407,7 +407,7 @@
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     @utils.skip_if_microversion_not_supported("2.73")
     def test_get_snapshot_metadata(self):
-        metadata = {u'key': u'value'}
+        metadata = {'key': 'value'}
         share_client = getattr(self, 'share_member_client', self.client)
         snap = self.create_snapshot(
             share_client, self.share['id'], metadata=metadata)
@@ -426,7 +426,7 @@
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     @utils.skip_if_microversion_not_supported("2.73")
     def test_delete_snapshot_metadata(self):
-        metadata = {u'key': u'value'}
+        metadata = {'key': 'value'}
         snap = self.create_snapshot(
             self.client, self.share['id'], metadata=metadata)
         self.do_request(
@@ -531,7 +531,7 @@
     def test_set_snapshot_metadata(self):
         snap = self.create_snapshot(
             self.share_member_client, self.share['id'])
-        metadata = {u'key': u'value'}
+        metadata = {'key': 'value'}
         self.do_request(
             'set_metadata', expected_status=lib_exc.Forbidden,
             resource_id=snap['id'], resource='snapshot', metadata=metadata)
@@ -552,7 +552,7 @@
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
     @utils.skip_if_microversion_not_supported("2.73")
     def test_delete_snapshot_metadata(self):
-        metadata = {u'key': u'value'}
+        metadata = {'key': 'value'}
         snap = self.create_snapshot(
             self.share_member_client, self.share['id'], metadata=metadata)
         self.do_request(
diff --git a/manila_tempest_tests/tests/scenario/manager_share.py b/manila_tempest_tests/tests/scenario/manager_share.py
index 49fa20e..f9df340 100644
--- a/manila_tempest_tests/tests/scenario/manager_share.py
+++ b/manila_tempest_tests/tests/scenario/manager_share.py
@@ -186,7 +186,7 @@
                         storage_net_nic[0]['addr']
                     )
             # Attach a floating IP
-            self.associate_floating_ip(floating_ip, instance)
+            self.associate_floating_ip(floating_ip, instance, ip_addr=ip_addr)
 
         self.assertIsNotNone(server_ip)
         # Check ssh
diff --git a/manila_tempest_tests/tests/scenario/test_share_basic_ops.py b/manila_tempest_tests/tests/scenario/test_share_basic_ops.py
index fbcc87f..e7402ef 100644
--- a/manila_tempest_tests/tests/scenario/test_share_basic_ops.py
+++ b/manila_tempest_tests/tests/scenario/test_share_basic_ops.py
@@ -432,24 +432,26 @@
 class TestShareBasicOpsCIFS(manager.BaseShareScenarioCIFSTest,
                             ShareBasicOpsBase):
 
+    @testtools.skipIf(
+        "cifs" not in CONF.share.enable_ro_access_level_for_protocols,
+        "RO access rule tests are disabled for CIFS protocol.")
     @decorators.idempotent_id('4344a47a-d316-496b-97a4-12a59297950a')
     @tc.attr(base.TAG_NEGATIVE, base.TAG_BACKEND)
     def test_write_with_ro_access(self):
-        msg = ("Skipped for CIFS protocol because RO access is not "
-               "supported for shares by IP.")
-        raise self.skipException(msg)
+        super(TestShareBasicOpsCIFS, self).test_write_with_ro_access()
 
+    @decorators.skip_because(bug='1649573')
     @decorators.idempotent_id('a691332b-dd7a-4041-9bbd-3893e168aefa')
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
     def test_read_mountable_snapshot(self):
-        msg = "Skipped for CIFS protocol because of bug/1649573"
-        raise self.skipException(msg)
+        super(TestShareBasicOpsCIFS, self).test_read_mountable_snapshot()
 
+    @decorators.skip_because(bug='1649573')
     @decorators.idempotent_id('8c936c3e-4793-49d2-8409-4038f03e7012')
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
     def test_write_data_to_share_created_from_snapshot(self):
-        msg = "Skipped for CIFS protocol because of bug/1649573"
-        raise self.skipException(msg)
+        super(TestShareBasicOpsCIFS,
+              self).test_write_data_to_share_created_from_snapshot()
 
 
 class TestBaseShareBasicOpsScenarioCEPHFS(manager.BaseShareScenarioCEPHFSTest,
diff --git a/releasenotes/notes/add-update-access-rules-e43b4d0fbabdb596.yaml b/releasenotes/notes/add-update-access-rules-e43b4d0fbabdb596.yaml
new file mode 100644
index 0000000..29b2936
--- /dev/null
+++ b/releasenotes/notes/add-update-access-rules-e43b4d0fbabdb596.yaml
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    Added tests to verify share access rule update operation. Update is
+    allowed only for admin and project member. Also supported microversion is
+    increased to 2.88.
diff --git a/releasenotes/notes/bug-2006792-fix-stop-cleanup-error-2a314862576f655b.yaml b/releasenotes/notes/bug-2006792-fix-stop-cleanup-error-2a314862576f655b.yaml
new file mode 100644
index 0000000..aaa3105
--- /dev/null
+++ b/releasenotes/notes/bug-2006792-fix-stop-cleanup-error-2a314862576f655b.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+  - |
+    Fixed bug #2006792. Now the clear resources function has an error
+    treatment to avoid time out exceptions. Also fix the returned
+    object in the _is_resource_deleted function
diff --git a/test-requirements.txt b/test-requirements.txt
index 1a63b32..37e9c36 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,7 +1,6 @@
 hacking>=6.1.0,<6.2.0 # Apache-2.0
 
 coverage>=4.4.1 # Apache-2.0
-python-subunit>=1.0.0 # Apache-2.0/BSD
 oslotest>=3.2.0 # Apache-2.0
 stestr>=1.0.0 # Apache-2.0
 testtools>=2.2.0 # MIT
diff --git a/tox.ini b/tox.ini
index 907516f..1cf0c94 100644
--- a/tox.ini
+++ b/tox.ini
@@ -6,7 +6,6 @@
 basepython = python3
 usedevelop = True
 setenv =
-   VIRTUAL_ENV={envdir}
    PYTHONWARNINGS=default::DeprecationWarning
    OS_STDOUT_CAPTURE=1
    OS_STDERR_CAPTURE=1
diff --git a/zuul.d/manila-tempest-jobs.yaml b/zuul.d/manila-tempest-jobs.yaml
index 02357b6..3c28cb5 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
@@ -261,6 +259,8 @@
     description: This is integrated job testing on Ubuntu jammy(22.04)
     parent: manila-tempest-plugin-lvm
     nodeset: openstack-single-node-jammy
+    branches:
+      - stable/2025.1
 
 - job:
     name: manila-tempest-plugin-container
@@ -283,7 +283,7 @@
         SHARE_BACKING_FILE_SIZE: 64000M
         MANILA_CONFIGURE_DEFAULT_TYPES: false
         MANILA_DEFAULT_SHARE_TYPE_EXTRA_SPECS: 'snapshot_support=false'
-        TEMPEST_USE_TEST_ACCOUNTS: true
+        TEMPEST_USE_TEST_ACCOUNTS: false
       devstack_services:
         mysql: false
         postgresql: true
@@ -524,11 +524,9 @@
         TARGET_DEV_OSD_DIR: /opt/stack
         ENABLED_SHARE_PROTOCOLS: NFS
         MANILA_OPTGROUP_cephfsnfs_cephfs_ganesha_server_ip: "{{ hostvars[inventory_hostname]['nodepool']['private_ipv4'] }}"
-        CEPH_RELEASE: "reef"
         MANILA_SETUP_IPV6: false
         NEUTRON_CREATE_INITIAL_NETWORKS: true
         IP_VERSION: 4
-        CEPH_INGRESS_IP: "{{hostvars['controller'].ansible_default_ipv6.address}}"
 
 - job:
     name: manila-tempest-plugin-multinode-base
@@ -589,6 +587,7 @@
       devstack_localrc:
         MYSQL_REDUCE_MEMORY: True
         CEPHADM_DEPLOY: True
+        ENABLE_INGRESS: False
         CEPHADM_DEV_OSD: true
         CEPH_LOOPBACK_DISK_SIZE: 40GB
         ENABLED_SHARE_PROTOCOLS: NFS
@@ -608,7 +607,6 @@
         MANILA_SETUP_IPV6: false
         SHARE_DRIVER: manila.share.drivers.cephfs.driver.CephFSDriver
         TARGET_DEV_OSD_DIR: /opt/stack
-        CEPH_INGRESS_IP: "{{hostvars['controller'].ansible_default_ipv6.address}}"
       devstack_local_conf:
         test-config:
           $TEMPEST_CONFIG:
@@ -879,6 +877,13 @@
       regex: ^stable/(yoga|xena|wallaby|victoria|ussuri)$
       negate: true
 
+- job:
+    name: manila-tempest-plugin-lvm-fips-py311
+    parent: manila-tempest-plugin-lvm-fips
+    vars:
+      devstack_localrc:
+        PYTHON3_VERSION: 3.11
+
 - project-template:
     name: manila-tempest-plugin-jobs-using-service-image
     description: |
diff --git a/zuul.d/manila-tempest-stable-jobs.yaml b/zuul.d/manila-tempest-stable-jobs.yaml
index c5a692b..07f013a 100644
--- a/zuul.d/manila-tempest-stable-jobs.yaml
+++ b/zuul.d/manila-tempest-stable-jobs.yaml
@@ -69,6 +69,19 @@
     vars: *manila_tempest_image_pinned_vars
 
 - job:
+    name: manila-tempest-plugin-lvm-2025.1
+    parent: manila-tempest-plugin-lvm-base
+    override-checkout: stable/2025.1
+    vars:
+      # TODO(gouthamr): some tests are disabled due to bugs
+      # IPv6 Tests: https://bugs.launchpad.net/manila/+bug/1998489
+      # drop these overrides once we address that bug.
+      tempest_exclude_regex: '(^manila_tempest_tests.tests.scenario.*IPv6.*)'
+      devstack_localrc:
+        MANILA_SETUP_IPV6: false
+        NEUTRON_CREATE_INITIAL_NETWORKS: true
+
+- job:
     name: manila-tempest-plugin-lvm-2024.2
     parent: manila-tempest-plugin-lvm-base
     override-checkout: stable/2024.2
@@ -94,19 +107,6 @@
         MANILA_SETUP_IPV6: false
         NEUTRON_CREATE_INITIAL_NETWORKS: true
 
-- job:
-    name: manila-tempest-plugin-lvm-2023.2
-    parent: manila-tempest-plugin-lvm-base
-    override-checkout: stable/2023.2
-    vars:
-      # TODO(gouthamr): some tests are disabled due to bugs
-      # IPv6 Tests: https://bugs.launchpad.net/manila/+bug/1998489
-      # drop these overrides once we address that bug.
-      tempest_exclude_regex: '(^manila_tempest_tests.tests.scenario.*IPv6.*)'
-      devstack_localrc:
-        MANILA_SETUP_IPV6: false
-        NEUTRON_CREATE_INITIAL_NETWORKS: true
-
 - project-template:
     name: manila-tempest-plugin-jobs-using-service-image-stable
     description: |
diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml
index d2a654e..3ca5092 100644
--- a/zuul.d/project.yaml
+++ b/zuul.d/project.yaml
@@ -8,9 +8,9 @@
       jobs:
         - manila-tempest-plugin-dummy-no-dhss
         - manila-tempest-plugin-dummy-dhss
+        - manila-tempest-plugin-lvm-2025.1
         - manila-tempest-plugin-lvm-2024.2
         - manila-tempest-plugin-lvm-2024.1
-        - manila-tempest-plugin-lvm-2023.2
         - manila-tempest-plugin-dummy-no-dhss-rbac
         - manila-tempest-plugin-container:
             voting: false