Merge "Allow skipping manila tempest tests."
diff --git a/manila_tempest_tests/config.py b/manila_tempest_tests/config.py
index 9314da0..1cd553e 100644
--- a/manila_tempest_tests/config.py
+++ b/manila_tempest_tests/config.py
@@ -30,7 +30,7 @@
                help="The minimum api microversion is configured to be the "
                     "value of the minimum microversion supported by Manila."),
     cfg.StrOpt("max_api_microversion",
-               default="2.23",
+               default="2.25",
                help="The maximum api microversion is configured to be the "
                     "value of the latest microversion supported by Manila."),
     cfg.StrOpt("region",
@@ -96,6 +96,13 @@
                      "capability called 'snapshot_support' and will be used "
                      "for setting up custom share type. Defaults to value of "
                      "other config option 'run_snapshot_tests'."),
+    cfg.BoolOpt("capability_create_share_from_snapshot_support",
+                help="Defines extra spec that satisfies specific back end "
+                     "capability called 'create_share_from_snapshot_support' "
+                     "and will be used for setting up a custom share type. "
+                     "Defaults to the value of run_snapshot_tests. Set it to "
+                     "False if the driver being tested does not support "
+                     "creating shares from snapshots."),
 
     cfg.StrOpt("share_network_id",
                default="",
@@ -189,7 +196,7 @@
                      "careful enabling this opt."),
 
     cfg.StrOpt("image_with_share_tools",
-               default="manila-service-image",
+               default="manila-service-image-master",
                help="Image name for vm booting with nfs/smb clients tool."),
     cfg.StrOpt("image_username",
                default="manila",
diff --git a/manila_tempest_tests/plugin.py b/manila_tempest_tests/plugin.py
index 0a97747..dfec0b1 100644
--- a/manila_tempest_tests/plugin.py
+++ b/manila_tempest_tests/plugin.py
@@ -35,14 +35,21 @@
         conf.register_group(config_share.share_group)
         conf.register_opts(config_share.ShareGroup, group='share')
 
-        # NOTE(vponomaryov): set opt 'capability_snapshot_support' by
-        # default equal to opt 'run_snapshot_tests'.
+        # NOTE(vponomaryov): Set options 'capability_snapshot_support' and
+        # 'capability_create_share_from_snapshot_support' to opt
+        # 'run_snapshot_tests' if not configured.
         if conf.share.capability_snapshot_support is None:
             conf.set_default(
                 "capability_snapshot_support",
                 conf.share.run_snapshot_tests,
                 group="share",
             )
+        if conf.share.capability_create_share_from_snapshot_support is None:
+            conf.set_default(
+                "capability_create_share_from_snapshot_support",
+                conf.share.run_snapshot_tests,
+                group="share",
+            )
 
     def get_opt_lists(self):
         return [(config_share.share_group.name, config_share.ShareGroup),
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 0ccc18b..cbc26b5 100644
--- a/manila_tempest_tests/services/share/v2/json/shares_client.py
+++ b/manila_tempest_tests/services/share/v2/json/shares_client.py
@@ -726,6 +726,13 @@
         self.expected_success(200, resp.status)
         return self._parse_resp(body)
 
+    def delete_share_type_extra_spec(self, share_type_id, extra_spec_name,
+                                     version=LATEST_MICROVERSION):
+        uri = "types/%s/extra_specs/%s" % (share_type_id, extra_spec_name)
+        resp, body = self.delete(uri, version=version)
+        self.expected_success(202, resp.status)
+        return body
+
     def list_access_to_share_type(self, share_type_id,
                                   version=LATEST_MICROVERSION,
                                   action_name=None):
@@ -778,6 +785,17 @@
         self.expected_success(202, resp.status)
         return body
 
+    def detail_quotas(self, tenant_id, user_id=None, url=None,
+                      version=LATEST_MICROVERSION):
+        if url is None:
+            url = self._get_quotas_url(version)
+        url += '/%s/detail' % tenant_id
+        if user_id is not None:
+            url += "?user_id=%s" % user_id
+        resp, body = self.get(url, version=version)
+        self.expected_success(200, resp.status)
+        return self._parse_resp(body)
+
     def update_quotas(self, tenant_id, user_id=None, shares=None,
                       snapshots=None, gigabytes=None, snapshot_gigabytes=None,
                       share_networks=None, force=True, url=None,
diff --git a/manila_tempest_tests/tests/api/admin/test_consistency_group_actions.py b/manila_tempest_tests/tests/api/admin/test_consistency_group_actions.py
index b9d349c..8b2a21c 100644
--- a/manila_tempest_tests/tests/api/admin/test_consistency_group_actions.py
+++ b/manila_tempest_tests/tests/api/admin/test_consistency_group_actions.py
@@ -32,7 +32,7 @@
         super(ConsistencyGroupActionsTest, cls).resource_setup()
         # Create 2 share_types
         name = data_utils.rand_name("tempest-manila")
-        extra_specs = cls.add_required_extra_specs_to_dict()
+        extra_specs = cls.add_extra_specs_to_dict()
         share_type = cls.create_share_type(name, extra_specs=extra_specs)
         cls.share_type = share_type['share_type']
 
diff --git a/manila_tempest_tests/tests/api/admin/test_consistency_groups.py b/manila_tempest_tests/tests/api/admin/test_consistency_groups.py
index efa2471..22678e5 100644
--- a/manila_tempest_tests/tests/api/admin/test_consistency_groups.py
+++ b/manila_tempest_tests/tests/api/admin/test_consistency_groups.py
@@ -34,7 +34,7 @@
         super(ConsistencyGroupsTest, cls).resource_setup()
         # Create 2 share_types
         name = data_utils.rand_name("tempest-manila")
-        extra_specs = cls.add_required_extra_specs_to_dict()
+        extra_specs = cls.add_extra_specs_to_dict()
         share_type = cls.create_share_type(name, extra_specs=extra_specs)
         cls.share_type = share_type['share_type']
 
diff --git a/manila_tempest_tests/tests/api/admin/test_consistency_groups_negative.py b/manila_tempest_tests/tests/api/admin/test_consistency_groups_negative.py
index 0a0d0f4..a850379 100644
--- a/manila_tempest_tests/tests/api/admin/test_consistency_groups_negative.py
+++ b/manila_tempest_tests/tests/api/admin/test_consistency_groups_negative.py
@@ -33,7 +33,7 @@
         super(ConsistencyGroupsNegativeTest, cls).resource_setup()
         # Create share_type
         name = data_utils.rand_name("tempest-manila")
-        extra_specs = cls.add_required_extra_specs_to_dict()
+        extra_specs = cls.add_extra_specs_to_dict()
         share_type = cls.create_share_type(name, extra_specs=extra_specs)
         cls.share_type = share_type['share_type']
 
diff --git a/manila_tempest_tests/tests/api/admin/test_multi_backend.py b/manila_tempest_tests/tests/api/admin/test_multi_backend.py
index 8b7e078..8aeabc3 100644
--- a/manila_tempest_tests/tests/api/admin/test_multi_backend.py
+++ b/manila_tempest_tests/tests/api/admin/test_multi_backend.py
@@ -48,7 +48,7 @@
             }
             st = cls.create_share_type(
                 name=st_name,
-                extra_specs=cls.add_required_extra_specs_to_dict(extra_specs))
+                extra_specs=cls.add_extra_specs_to_dict(extra_specs))
             cls.sts.append(st["share_type"])
             st_id = st["share_type"]["id"]
             share_data_list.append({"kwargs": {"share_type_id": st_id}})
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 d6c47e5..b8557e1 100644
--- a/manila_tempest_tests/tests/api/admin/test_quotas_negative.py
+++ b/manila_tempest_tests/tests/api/admin/test_quotas_negative.py
@@ -203,3 +203,15 @@
             self.shares_v2_client.tenant_id,
             version=version, url=url,
         )
+
+    @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
+    def test_show_quota_detail_with_wrong_versions(self):
+        version = '2.24'
+        url = 'quota-sets'
+
+        self.assertRaises(
+            lib_exc.NotFound,
+            self.shares_v2_client.detail_quotas,
+            self.shares_v2_client.tenant_id,
+            version=version, url=url,
+        )
diff --git a/manila_tempest_tests/tests/api/admin/test_replication.py b/manila_tempest_tests/tests/api/admin/test_replication.py
index 38546e3..e41c92b 100644
--- a/manila_tempest_tests/tests/api/admin/test_replication.py
+++ b/manila_tempest_tests/tests/api/admin/test_replication.py
@@ -48,7 +48,7 @@
         cls.share_zone = cls.zones[0]
         cls.replica_zone = cls.zones[-1]
 
-        cls.extra_specs = cls.add_required_extra_specs_to_dict(
+        cls.extra_specs = cls.add_extra_specs_to_dict(
             {"replication_type": cls.replication_type})
         share_type = cls.create_share_type(
             name,
diff --git a/manila_tempest_tests/tests/api/admin/test_replication_actions.py b/manila_tempest_tests/tests/api/admin/test_replication_actions.py
index 377bb41..5b56533 100644
--- a/manila_tempest_tests/tests/api/admin/test_replication_actions.py
+++ b/manila_tempest_tests/tests/api/admin/test_replication_actions.py
@@ -49,7 +49,7 @@
         cls.share_zone = cls.zones[0]
         cls.replica_zone = cls.zones[-1]
 
-        cls.extra_specs = cls.add_required_extra_specs_to_dict(
+        cls.extra_specs = cls.add_extra_specs_to_dict(
             {"replication_type": cls.replication_type})
         share_type = cls.create_share_type(
             name,
diff --git a/manila_tempest_tests/tests/api/admin/test_scheduler_stats.py b/manila_tempest_tests/tests/api/admin/test_scheduler_stats.py
index d77b7ea..aa29828 100644
--- a/manila_tempest_tests/tests/api/admin/test_scheduler_stats.py
+++ b/manila_tempest_tests/tests/api/admin/test_scheduler_stats.py
@@ -12,7 +12,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import ddt
 from tempest import config
+from tempest.lib.common.utils import data_utils
 from testtools import testcase as tc
 
 from manila_tempest_tests.tests.api import base
@@ -20,8 +22,29 @@
 CONF = config.CONF
 
 
+@ddt.ddt
 class SchedulerStatsAdminTest(base.BaseSharesAdminTest):
 
+    @classmethod
+    def _create_share_type(cls, negative=False):
+        name = data_utils.rand_name("unique_st_name")
+        extra_specs = None
+
+        if negative:
+            extra_specs = {
+                'share_backend_name': data_utils.rand_name("fake_name"),
+            }
+
+        extra_specs = cls.add_extra_specs_to_dict(extra_specs=extra_specs)
+        return cls.create_share_type(
+            name, extra_specs=extra_specs,
+            client=cls.admin_client)
+
+    @classmethod
+    def resource_setup(cls):
+        super(SchedulerStatsAdminTest, cls).resource_setup()
+        cls.admin_client = cls.shares_v2_client
+
     @tc.attr(base.TAG_POSITIVE, base.TAG_API)
     def test_pool_list(self):
 
@@ -138,5 +161,44 @@
         # Ensure we got no pools
         self.assertEmpty(pool_list)
 
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
+    @base.skip_if_microversion_not_supported("2.23")
+    @ddt.data((True, "name"), (True, "id"), (False, "name"), (False, "id"))
+    @ddt.unpack
+    def test_pool_list_with_share_type_filter_with_detail(
+            self, detail, share_type_key):
+        st = self._create_share_type()
+        search_opts = {"share_type": st["share_type"][share_type_key]}
+        kwargs = {'search_opts': search_opts}
+
+        if detail:
+            kwargs.update({'detail': True})
+
+        pools = self.admin_client.list_pools(**kwargs)['pools']
+
+        self.assertIsNotNone(pools, 'No pools returned from pools API')
+        self.assertNotEmpty(pools)
+        for pool in pools:
+            pool_keys = list(pool.keys())
+            self.assertIn("name", pool_keys)
+            self.assertIn("host", pool_keys)
+            self.assertIn("backend", pool_keys)
+            self.assertIn("pool", pool_keys)
+            self.assertIs(detail, "capabilities" in pool_keys)
+
+    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
+    @base.skip_if_microversion_not_supported("2.23")
+    @ddt.data((True, "name"), (True, "id"), (False, "name"), (False, "id"))
+    @ddt.unpack
+    def test_pool_list_with_share_type_filter_with_detail_negative(
+            self, detail, share_type_key):
+        st_negative = self._create_share_type(negative=True)
+        search_opts = {"share_type": st_negative["share_type"][share_type_key]}
+
+        pools = self.admin_client.list_pools(
+            detail=detail, search_opts=search_opts)['pools']
+
+        self.assertEmpty(pools)
+
     def _wrap_regex_for_exact_match(self, regex):
         return '^%s$' % regex
diff --git a/manila_tempest_tests/tests/api/admin/test_share_manage.py b/manila_tempest_tests/tests/api/admin/test_share_manage.py
index 8100040..f943284 100644
--- a/manila_tempest_tests/tests/api/admin/test_share_manage.py
+++ b/manila_tempest_tests/tests/api/admin/test_share_manage.py
@@ -54,12 +54,16 @@
             'driver_handles_share_servers': False,
             'snapshot_support': six.text_type(
                 CONF.share.capability_snapshot_support),
+            'create_share_from_snapshot_support': six.text_type(
+                CONF.share.capability_create_share_from_snapshot_support)
         }
         cls.extra_specs_invalid = {
             'storage_protocol': CONF.share.capability_storage_protocol,
             'driver_handles_share_servers': True,
             'snapshot_support': six.text_type(
                 CONF.share.capability_snapshot_support),
+            'create_share_from_snapshot_support': six.text_type(
+                CONF.share.capability_create_share_from_snapshot_support),
         }
 
         cls.st = cls.create_share_type(
diff --git a/manila_tempest_tests/tests/api/admin/test_share_type_filter.py b/manila_tempest_tests/tests/api/admin/test_share_type_filter.py
deleted file mode 100644
index e34f943..0000000
--- a/manila_tempest_tests/tests/api/admin/test_share_type_filter.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#    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.
-
-import ddt
-from tempest.lib.common.utils import data_utils
-from testtools import testcase as tc
-
-from manila_tempest_tests.tests.api import base
-
-
-@ddt.ddt
-class ShareTypeFilterTest(base.BaseSharesAdminTest):
-
-    @classmethod
-    def _create_share_type(cls):
-        name = data_utils.rand_name("unique_st_name")
-        extra_specs = cls.add_required_extra_specs_to_dict()
-        return cls.create_share_type(
-            name, extra_specs=extra_specs,
-            client=cls.admin_client)
-
-    @classmethod
-    def resource_setup(cls):
-        super(ShareTypeFilterTest, cls).resource_setup()
-        cls.admin_client = cls.shares_v2_client
-        cls.st = cls._create_share_type()
-
-    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
-    @base.skip_if_microversion_not_supported("2.23")
-    @ddt.data(True, False)
-    def test_get_pools_with_share_type_filter_with_detail(self, detail):
-        share_type = self.st["share_type"]["id"]
-        search_opts = {"share_type": share_type}
-        kwargs = {'search_opts': search_opts}
-
-        if detail:
-            kwargs.update({'detail': True})
-
-        pools = self.admin_client.list_pools(**kwargs)['pools']
-        for pool in pools:
-            pool_keys = pool.keys()
-            self.assertIn("name", pool_keys)
-            self.assertIn("host", pool_keys)
-            self.assertIn("backend", pool_keys)
-            self.assertIn("pool", pool_keys)
-            self.assertIs(detail, "capabilities" in pool_keys)
diff --git a/manila_tempest_tests/tests/api/admin/test_share_type_filter_negative.py b/manila_tempest_tests/tests/api/admin/test_share_type_filter_negative.py
deleted file mode 100644
index 80f8d66..0000000
--- a/manila_tempest_tests/tests/api/admin/test_share_type_filter_negative.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#    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.
-
-import ddt
-from oslo_utils import uuidutils
-from tempest import config
-from tempest.lib.common.utils import data_utils
-from testtools import testcase as tc
-
-from manila_tempest_tests.tests.api import base
-
-CONF = config.CONF
-
-
-@ddt.ddt
-class ShareTypeFilterNegativeTest(base.BaseSharesAdminTest):
-
-    @classmethod
-    def _create_share_type(cls):
-        name = data_utils.rand_name("unique_st_name")
-        extra_specs = {
-            'share_backend_name': uuidutils.generate_uuid(),
-        }
-        extra_specs = cls.add_required_extra_specs_to_dict(
-            extra_specs=extra_specs)
-        return cls.create_share_type(
-            name, extra_specs=extra_specs,
-            client=cls.admin_client)
-
-    @classmethod
-    def resource_setup(cls):
-        super(ShareTypeFilterNegativeTest, cls).resource_setup()
-        cls.admin_client = cls.shares_v2_client
-        cls.st = cls._create_share_type()
-
-    @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
-    @base.skip_if_microversion_not_supported("2.23")
-    @ddt.data(True, False)
-    def test_get_pools_invalid_share_type_filter_with_detail(self, detail):
-        share_type = self.st["share_type"]["name"]
-        search_opts = {"share_type": share_type}
-        pools = self.admin_client.list_pools(
-            detail=detail, search_opts=search_opts)['pools']
-
-        self.assertEmpty(pools)
diff --git a/manila_tempest_tests/tests/api/admin/test_share_types.py b/manila_tempest_tests/tests/api/admin/test_share_types.py
index af354bb..076e4bc 100644
--- a/manila_tempest_tests/tests/api/admin/test_share_types.py
+++ b/manila_tempest_tests/tests/api/admin/test_share_types.py
@@ -31,7 +31,7 @@
     @tc.attr(base.TAG_POSITIVE, base.TAG_API)
     def test_share_type_create_delete(self):
         name = data_utils.rand_name("tempest-manila")
-        extra_specs = self.add_required_extra_specs_to_dict()
+        extra_specs = self.add_extra_specs_to_dict()
 
         # Create share type
         st_create = self.shares_v2_client.create_share_type(
@@ -64,7 +64,7 @@
         self.skip_if_microversion_not_supported(version)
 
         name = data_utils.rand_name("tempest-manila")
-        extra_specs = self.add_required_extra_specs_to_dict({"key": "value", })
+        extra_specs = self.add_extra_specs_to_dict({"key": "value", })
 
         # Create share type
         st_create = self.create_share_type(
@@ -89,7 +89,7 @@
         self.skip_if_microversion_not_supported(version)
 
         name = data_utils.rand_name("tempest-manila")
-        extra_specs = self.add_required_extra_specs_to_dict()
+        extra_specs = self.add_extra_specs_to_dict()
 
         # Create share type
         st_create = self.create_share_type(
@@ -117,7 +117,7 @@
         # Data
         share_name = data_utils.rand_name("share")
         shr_type_name = data_utils.rand_name("share-type")
-        extra_specs = self.add_required_extra_specs_to_dict({
+        extra_specs = self.add_extra_specs_to_dict({
             "storage_protocol": CONF.share.capability_storage_protocol,
         })
 
@@ -144,7 +144,7 @@
     @tc.attr(base.TAG_POSITIVE, base.TAG_API)
     def test_private_share_type_access(self):
         name = data_utils.rand_name("tempest-manila")
-        extra_specs = self.add_required_extra_specs_to_dict({"key": "value", })
+        extra_specs = self.add_extra_specs_to_dict({"key": "value", })
         project_id = self.shares_client.tenant_id
 
         # Create private share type
diff --git a/manila_tempest_tests/tests/api/admin/test_share_types_extra_specs.py b/manila_tempest_tests/tests/api/admin/test_share_types_extra_specs.py
index 81d130f..f4c21b8 100644
--- a/manila_tempest_tests/tests/api/admin/test_share_types_extra_specs.py
+++ b/manila_tempest_tests/tests/api/admin/test_share_types_extra_specs.py
@@ -15,19 +15,25 @@
 
 import copy
 
+import ddt
+from tempest import config
 from tempest.lib.common.utils import data_utils
 from testtools import testcase as tc
 
 from manila_tempest_tests.tests.api import base
 
 
+CONF = config.CONF
+LATEST_MICROVERSION = CONF.share.max_api_microversion
+
+
 class ExtraSpecsReadAdminTest(base.BaseSharesAdminTest):
 
     @classmethod
     def resource_setup(cls):
         super(ExtraSpecsReadAdminTest, cls).resource_setup()
         cls.share_type_name = data_utils.rand_name("share-type")
-        cls.required_extra_specs = cls.add_required_extra_specs_to_dict()
+        cls.required_extra_specs = cls.add_extra_specs_to_dict()
 
         cls.share_type = cls.create_share_type(
             cls.share_type_name, extra_specs=cls.required_extra_specs)
@@ -54,11 +60,12 @@
         self.assertEqual(self.expected_extra_specs, es_get_all)
 
 
+@ddt.ddt
 class ExtraSpecsWriteAdminTest(base.BaseSharesAdminTest):
 
     def setUp(self):
         super(ExtraSpecsWriteAdminTest, self).setUp()
-        self.required_extra_specs = self.add_required_extra_specs_to_dict()
+        self.required_extra_specs = self.add_extra_specs_to_dict()
         self.custom_extra_specs = {"key1": "value1", "key2": "value2"}
         self.share_type_name = data_utils.rand_name("share-type")
 
@@ -109,3 +116,17 @@
         get = self.shares_client.get_share_type_extra_specs(self.st_id)
 
         self.assertNotIn('key1', get)
+
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API)
+    @ddt.data(*set(['2.24', LATEST_MICROVERSION]))
+    def test_delete_snapshot_support_extra_spec(self, version):
+        self.skip_if_microversion_not_supported(version)
+        # Delete one extra spec for share type
+        self.shares_v2_client.delete_share_type_extra_spec(
+            self.st_id, 'snapshot_support', version=version)
+
+        # Get metadata
+        share_type_extra_specs = self.shares_client.get_share_type_extra_specs(
+            self.st_id)
+
+        self.assertNotIn('snapshot_support', share_type_extra_specs)
diff --git a/manila_tempest_tests/tests/api/admin/test_share_types_extra_specs_negative.py b/manila_tempest_tests/tests/api/admin/test_share_types_extra_specs_negative.py
index 34e5009..85cbc5d 100644
--- a/manila_tempest_tests/tests/api/admin/test_share_types_extra_specs_negative.py
+++ b/manila_tempest_tests/tests/api/admin/test_share_types_extra_specs_negative.py
@@ -13,6 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import ddt
 from tempest.lib.common.utils import data_utils
 from tempest.lib import exceptions as lib_exc
 from testtools import testcase as tc
@@ -20,11 +21,12 @@
 from manila_tempest_tests.tests.api import base
 
 
+@ddt.ddt
 class ExtraSpecsAdminNegativeTest(base.BaseSharesMixedTest):
 
     def _create_share_type(self):
         name = data_utils.rand_name("unique_st_name")
-        extra_specs = self.add_required_extra_specs_to_dict({"key": "value"})
+        extra_specs = self.add_extra_specs_to_dict({"key": "value"})
         return self.create_share_type(
             name, extra_specs=extra_specs, client=self.admin_shares_v2_client)
 
@@ -35,7 +37,7 @@
             lib_exc.Forbidden,
             self.shares_v2_client.create_share_type_extra_specs,
             st["share_type"]["id"],
-            self.add_required_extra_specs_to_dict({"key": "new_value"}))
+            self.add_extra_specs_to_dict({"key": "new_value"}))
 
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
     def test_try_list_extra_specs_with_user(self):
@@ -67,7 +69,8 @@
         share_type = self.shares_v2_client.get_share_type(
             st['share_type']['id'])
         # Verify a non-admin can only read the required extra-specs
-        expected_keys = ['driver_handles_share_servers', 'snapshot_support']
+        expected_keys = ['driver_handles_share_servers', 'snapshot_support',
+                         'create_share_from_snapshot_support']
         actual_keys = share_type['share_type']['extra_specs'].keys()
         self.assertEqual(sorted(expected_keys), sorted(actual_keys),
                          'Incorrect extra specs visible to non-admin user; '
@@ -105,7 +108,7 @@
             lib_exc.BadRequest,
             self.admin_shares_v2_client.create_share_type_extra_specs,
             st["share_type"]["id"],
-            self.add_required_extra_specs_to_dict({too_big_key: "value"}))
+            self.add_extra_specs_to_dict({too_big_key: "value"}))
 
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
     def test_try_set_too_long_value_with_creation(self):
@@ -115,7 +118,7 @@
             lib_exc.BadRequest,
             self.admin_shares_v2_client.create_share_type_extra_specs,
             st["share_type"]["id"],
-            self.add_required_extra_specs_to_dict({"key": too_big_value}))
+            self.add_extra_specs_to_dict({"key": too_big_value}))
 
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
     def test_try_set_too_long_value_with_update(self):
@@ -123,12 +126,12 @@
         st = self._create_share_type()
         self.admin_shares_v2_client.create_share_type_extra_specs(
             st["share_type"]["id"],
-            self.add_required_extra_specs_to_dict({"key": "value"}))
+            self.add_extra_specs_to_dict({"key": "value"}))
         self.assertRaises(
             lib_exc.BadRequest,
             self.admin_shares_v2_client.update_share_type_extra_specs,
             st["share_type"]["id"],
-            self.add_required_extra_specs_to_dict({"key": too_big_value}))
+            self.add_extra_specs_to_dict({"key": too_big_value}))
 
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
     def test_try_set_too_long_value_with_update_of_one_key(self):
@@ -136,7 +139,7 @@
         st = self._create_share_type()
         self.admin_shares_v2_client.create_share_type_extra_specs(
             st["share_type"]["id"],
-            self.add_required_extra_specs_to_dict({"key": "value"}))
+            self.add_extra_specs_to_dict({"key": "value"}))
         self.assertRaises(
             lib_exc.BadRequest,
             self.admin_shares_v2_client.update_share_type_extra_spec,
@@ -286,12 +289,12 @@
             "driver_handles_share_servers")
 
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
-    def test_try_delete_spec_snapshot_support(self):
+    @ddt.data('2.0', '2.23')
+    def test_try_delete_required_spec_snapshot_support_version(self, version):
+        self.skip_if_microversion_not_supported(version)
         st = self._create_share_type()
-
         # Try delete extra spec 'snapshot_support'
         self.assertRaises(
             lib_exc.Forbidden,
             self.admin_shares_v2_client.delete_share_type_extra_spec,
-            st["share_type"]["id"],
-            "snapshot_support")
+            st["share_type"]["id"], "snapshot_support", version=version)
diff --git a/manila_tempest_tests/tests/api/admin/test_share_types_negative.py b/manila_tempest_tests/tests/api/admin/test_share_types_negative.py
index b0fb9db..b3bf855 100644
--- a/manila_tempest_tests/tests/api/admin/test_share_types_negative.py
+++ b/manila_tempest_tests/tests/api/admin/test_share_types_negative.py
@@ -24,7 +24,7 @@
 
     def _create_share_type(self):
         name = data_utils.rand_name("unique_st_name")
-        extra_specs = self.add_required_extra_specs_to_dict({"key": "value"})
+        extra_specs = self.add_extra_specs_to_dict({"key": "value"})
         return self.create_share_type(
             name, extra_specs=extra_specs, client=self.admin_shares_v2_client)
 
@@ -66,7 +66,7 @@
         self.assertRaises(lib_exc.Conflict,
                           self.create_share_type,
                           st["share_type"]["name"],
-                          extra_specs=self.add_required_extra_specs_to_dict(),
+                          extra_specs=self.add_extra_specs_to_dict(),
                           client=self.admin_shares_v2_client)
 
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API)
diff --git a/manila_tempest_tests/tests/api/admin/test_shares_actions.py b/manila_tempest_tests/tests/api/admin/test_shares_actions.py
index eb049c6..779cd18 100644
--- a/manila_tempest_tests/tests/api/admin/test_shares_actions.py
+++ b/manila_tempest_tests/tests/api/admin/test_shares_actions.py
@@ -34,7 +34,7 @@
 
         # create share type for share filtering purposes
         cls.st_name = data_utils.rand_name("tempest-st-name")
-        cls.extra_specs = cls.add_required_extra_specs_to_dict(
+        cls.extra_specs = cls.add_extra_specs_to_dict(
             {'storage_protocol': CONF.share.capability_storage_protocol})
         cls.st = cls.create_share_type(
             name=cls.st_name,
@@ -64,20 +64,23 @@
             cls.snap = cls.create_snapshot_wait_for_active(
                 cls.shares[0]["id"], cls.snap_name, cls.snap_desc)
 
-            # create second share from snapshot for purposes of sorting and
-            # snapshot filtering
-            cls.share_name2 = data_utils.rand_name("tempest-share-name")
-            cls.share_desc2 = data_utils.rand_name("tempest-share-description")
-            cls.metadata2 = {
-                'foo_key_share_2': 'foo_value_share_2',
-                'bar_key_share_2': 'foo_value_share_2',
-            }
-            cls.shares.append(cls.create_share(
-                name=cls.share_name2,
-                description=cls.share_desc2,
-                metadata=cls.metadata2,
-                snapshot_id=cls.snap['id'],
-            ))
+            if CONF.share.capability_create_share_from_snapshot_support:
+
+                # create second share from snapshot for purposes of sorting and
+                # snapshot filtering
+                cls.share_name2 = data_utils.rand_name("tempest-share-name")
+                cls.share_desc2 = data_utils.rand_name(
+                    "tempest-share-description")
+                cls.metadata2 = {
+                    'foo_key_share_2': 'foo_value_share_2',
+                    'bar_key_share_2': 'foo_value_share_2',
+                }
+                cls.shares.append(cls.create_share(
+                    name=cls.share_name2,
+                    description=cls.share_desc2,
+                    metadata=cls.metadata2,
+                    snapshot_id=cls.snap['id'],
+                ))
 
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_get_share(self):
@@ -154,7 +157,7 @@
         for share in shares:
             self.assertDictContainsSubset(
                 filters['metadata'], share['metadata'])
-        if CONF.share.run_snapshot_tests:
+        if CONF.share.capability_create_share_from_snapshot_support:
             self.assertFalse(self.shares[1]['id'] in [s['id'] for s in shares])
 
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
@@ -250,8 +253,9 @@
                 filters['share_network_id'], share['share_network_id'])
 
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
-    @testtools.skipUnless(CONF.share.run_snapshot_tests,
-                          "Snapshot tests are disabled.")
+    @testtools.skipUnless(
+        CONF.share.capability_create_share_from_snapshot_support,
+        "Create share from snapshot tests are disabled.")
     def test_list_shares_with_detail_filter_by_snapshot_id(self):
         filters = {'snapshot_id': self.snap['id']}
 
diff --git a/manila_tempest_tests/tests/api/admin/test_snapshot_manage.py b/manila_tempest_tests/tests/api/admin/test_snapshot_manage.py
index 3cde3e6..6436e5b 100644
--- a/manila_tempest_tests/tests/api/admin/test_snapshot_manage.py
+++ b/manila_tempest_tests/tests/api/admin/test_snapshot_manage.py
@@ -55,6 +55,8 @@
             'driver_handles_share_servers': False,
             'snapshot_support': six.text_type(
                 CONF.share.capability_snapshot_support),
+            'create_share_from_snapshot_support': six.text_type(
+                CONF.share.capability_create_share_from_snapshot_support)
         }
 
         cls.st = cls.create_share_type(
diff --git a/manila_tempest_tests/tests/api/admin/test_snapshot_manage_negative.py b/manila_tempest_tests/tests/api/admin/test_snapshot_manage_negative.py
index dfd892c..3825be1 100644
--- a/manila_tempest_tests/tests/api/admin/test_snapshot_manage_negative.py
+++ b/manila_tempest_tests/tests/api/admin/test_snapshot_manage_negative.py
@@ -49,6 +49,8 @@
             'driver_handles_share_servers': False,
             'snapshot_support': six.text_type(
                 CONF.share.capability_snapshot_support),
+            'create_share_from_snapshot_support': six.text_type(
+                CONF.share.capability_create_share_from_snapshot_support),
         }
 
         cls.st = cls.create_share_type(
diff --git a/manila_tempest_tests/tests/api/base.py b/manila_tempest_tests/tests/api/base.py
index d5d1175..5810a7e 100644
--- a/manila_tempest_tests/tests/api/base.py
+++ b/manila_tempest_tests/tests/api/base.py
@@ -733,17 +733,30 @@
         return share_type
 
     @staticmethod
-    def add_required_extra_specs_to_dict(extra_specs=None):
+    def add_extra_specs_to_dict(extra_specs=None):
+        """Add any required extra-specs to share type dictionary"""
         dhss = six.text_type(CONF.share.multitenancy_enabled)
         snapshot_support = six.text_type(
             CONF.share.capability_snapshot_support)
-        required = {
+        create_from_snapshot_support = six.text_type(
+            CONF.share.capability_create_share_from_snapshot_support)
+
+        extra_specs_dict = {
             "driver_handles_share_servers": dhss,
-            "snapshot_support": snapshot_support,
         }
+
+        optional = {
+            "snapshot_support": snapshot_support,
+            "create_share_from_snapshot_support": create_from_snapshot_support,
+        }
+        # NOTE(gouthamr): In micro-versions < 2.24, snapshot_support is a
+        # required extra-spec
+        extra_specs_dict.update(optional)
+
         if extra_specs:
-            required.update(extra_specs)
-        return required
+            extra_specs_dict.update(extra_specs)
+
+        return extra_specs_dict
 
     @classmethod
     def clear_isolated_creds(cls, creds=None):
diff --git a/manila_tempest_tests/tests/api/test_quotas.py b/manila_tempest_tests/tests/api/test_quotas.py
index e9f5042..a7540ed 100644
--- a/manila_tempest_tests/tests/api/test_quotas.py
+++ b/manila_tempest_tests/tests/api/test_quotas.py
@@ -64,3 +64,28 @@
         self.assertGreater(int(quotas["shares"]), -2)
         self.assertGreater(int(quotas["snapshots"]), -2)
         self.assertGreater(int(quotas["share_networks"]), -2)
+
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API)
+    @base.skip_if_microversion_not_supported("2.25")
+    def test_show_quotas_detail(self):
+        quotas = self.shares_v2_client.detail_quotas(self.tenant_id)
+        quota_keys = list(quotas.keys())
+        for outer in ('gigabytes', 'snapshot_gigabytes', 'shares',
+                      'snapshots', 'share_networks'):
+            self.assertIn(outer, quota_keys)
+            for inner in ('in_use', 'limit', 'reserved'):
+                self.assertIn(inner, list(quotas[outer].keys()))
+                self.assertGreater(int(quotas[outer][inner]), -2)
+
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API)
+    @base.skip_if_microversion_not_supported("2.25")
+    def test_show_quotas_detail_for_user(self):
+        quotas = self.shares_v2_client.detail_quotas(self.tenant_id,
+                                                     self.user_id)
+        quota_keys = list(quotas.keys())
+        for outer in ('gigabytes', 'snapshot_gigabytes', 'shares',
+                      'snapshots', 'share_networks'):
+            self.assertIn(outer, quota_keys)
+            for inner in ('in_use', 'limit', 'reserved'):
+                self.assertIn(inner, list(quotas[outer].keys()))
+                self.assertGreater(int(quotas[outer][inner]), -2)
diff --git a/manila_tempest_tests/tests/api/test_replication.py b/manila_tempest_tests/tests/api/test_replication.py
index 0bdb7ad..1738e87 100644
--- a/manila_tempest_tests/tests/api/test_replication.py
+++ b/manila_tempest_tests/tests/api/test_replication.py
@@ -51,7 +51,7 @@
         cls.share_zone = cls.zones[0]
         cls.replica_zone = cls.zones[-1]
 
-        cls.extra_specs = cls.add_required_extra_specs_to_dict(
+        cls.extra_specs = cls.add_extra_specs_to_dict(
             {"replication_type": cls.replication_type})
         share_type = cls.create_share_type(
             name,
@@ -307,7 +307,7 @@
         cls.share_zone = cls.zones[0]
         cls.replica_zone = cls.zones[-1]
 
-        cls.extra_specs = cls.add_required_extra_specs_to_dict(
+        cls.extra_specs = cls.add_extra_specs_to_dict(
             {"replication_type": cls.replication_type})
         share_type = cls.create_share_type(
             name,
diff --git a/manila_tempest_tests/tests/api/test_replication_negative.py b/manila_tempest_tests/tests/api/test_replication_negative.py
index cfbf210..48b8d5c 100644
--- a/manila_tempest_tests/tests/api/test_replication_negative.py
+++ b/manila_tempest_tests/tests/api/test_replication_negative.py
@@ -48,7 +48,7 @@
         cls.share_zone = cls.zones[0]
         cls.replica_zone = cls.zones[-1]
 
-        cls.extra_specs = cls.add_required_extra_specs_to_dict(
+        cls.extra_specs = cls.add_extra_specs_to_dict(
             {"replication_type": cls.replication_type})
         share_type = cls.create_share_type(
             name,
@@ -80,7 +80,7 @@
         # Create share without replication type
         share_type = self.create_share_type(
             data_utils.rand_name(constants.TEMPEST_MANILA_PREFIX),
-            extra_specs=self.add_required_extra_specs_to_dict(),
+            extra_specs=self.add_extra_specs_to_dict(),
             client=self.admin_client)["share_type"]
         share = self.create_share(share_type_id=share_type["id"])
         self.assertRaises(lib_exc.BadRequest,
diff --git a/manila_tempest_tests/tests/api/test_replication_snapshots.py b/manila_tempest_tests/tests/api/test_replication_snapshots.py
index e3081cc..331437c 100644
--- a/manila_tempest_tests/tests/api/test_replication_snapshots.py
+++ b/manila_tempest_tests/tests/api/test_replication_snapshots.py
@@ -49,7 +49,7 @@
         cls.share_zone = cls.zones[0]
         cls.replica_zone = cls.zones[-1]
 
-        cls.extra_specs = cls.add_required_extra_specs_to_dict(
+        cls.extra_specs = cls.add_extra_specs_to_dict(
             {"replication_type": cls.replication_type})
         share_type = cls.create_share_type(
             name,
@@ -86,7 +86,12 @@
         snapshot = self.create_snapshot_wait_for_active(share["id"])
         self.promote_share_replica(share_replica['id'])
         self.delete_share_replica(original_replica['id'])
-        self.create_share(snapshot_id=snapshot['id'])
+
+        snapshot = self.shares_v2_client.get_snapshot(snapshot['id'])
+        self.assertEqual(constants.STATUS_AVAILABLE, snapshot['status'])
+
+        if CONF.share.capability_create_share_from_snapshot_support:
+            self.create_share(snapshot_id=snapshot['id'])
 
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
     def test_snapshot_before_share_replica(self):
@@ -116,7 +121,12 @@
 
         self.promote_share_replica(share_replica['id'])
         self.delete_share_replica(original_replica['id'])
-        self.create_share(snapshot_id=snapshot['id'])
+
+        snapshot = self.shares_v2_client.get_snapshot(snapshot['id'])
+        self.assertEqual(constants.STATUS_AVAILABLE, snapshot['status'])
+
+        if CONF.share.capability_create_share_from_snapshot_support:
+            self.create_share(snapshot_id=snapshot['id'])
 
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
     def test_snapshot_before_and_after_share_replica(self):
@@ -152,8 +162,15 @@
         # still being created successfully.
         self.delete_share_replica(original_replica['id'])
 
-        self.create_share(snapshot_id=snapshot1['id'])
-        self.create_share(snapshot_id=snapshot2['id'])
+        snapshot1 = self.shares_v2_client.get_snapshot(snapshot1['id'])
+        self.assertEqual(constants.STATUS_AVAILABLE, snapshot1['status'])
+
+        snapshot2 = self.shares_v2_client.get_snapshot(snapshot2['id'])
+        self.assertEqual(constants.STATUS_AVAILABLE, snapshot2['status'])
+
+        if CONF.share.capability_create_share_from_snapshot_support:
+            self.create_share(snapshot_id=snapshot1['id'])
+            self.create_share(snapshot_id=snapshot2['id'])
 
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
     def test_delete_snapshot_after_adding_replica(self):
@@ -176,6 +193,9 @@
             snapshot_id=snapshot["id"])
 
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
+    @testtools.skipUnless(
+        CONF.share.capability_create_share_from_snapshot_support,
+        "Create share from snapshot tests are disabled.")
     def test_create_replica_from_snapshot_share(self):
         """Test replica for a share that was created from snapshot."""
 
diff --git a/manila_tempest_tests/tests/api/test_share_types_negative.py b/manila_tempest_tests/tests/api/test_share_types_negative.py
index 9c7883b..8a24325 100644
--- a/manila_tempest_tests/tests/api/test_share_types_negative.py
+++ b/manila_tempest_tests/tests/api/test_share_types_negative.py
@@ -25,7 +25,7 @@
     @classmethod
     def _create_share_type(cls):
         name = data_utils.rand_name("unique_st_name")
-        extra_specs = cls.add_required_extra_specs_to_dict()
+        extra_specs = cls.add_extra_specs_to_dict()
         return cls.create_share_type(
             name, extra_specs=extra_specs,
             client=cls.admin_client)
diff --git a/manila_tempest_tests/tests/api/test_shares.py b/manila_tempest_tests/tests/api/test_shares.py
index af4a54a..d78c913 100644
--- a/manila_tempest_tests/tests/api/test_shares.py
+++ b/manila_tempest_tests/tests/api/test_shares.py
@@ -92,6 +92,12 @@
             detailed_elements.add('user_id')
             self.assertTrue(detailed_elements.issubset(share.keys()), msg)
 
+        # In v 2.24 and beyond, we add create_share_from_snapshot_support in
+        # show/create/manage share echo.
+        if utils.is_microversion_supported('2.24'):
+            detailed_elements.add('create_share_from_snapshot_support')
+            self.assertTrue(detailed_elements.issubset(share.keys()), msg)
+
         # Delete share
         self.shares_v2_client.delete_share(share['id'])
         self.shares_v2_client.wait_for_resource_deletion(share_id=share['id'])
@@ -136,6 +142,9 @@
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
     @testtools.skipUnless(CONF.share.run_snapshot_tests,
                           "Snapshot tests are disabled.")
+    @testtools.skipUnless(
+        CONF.share.capability_create_share_from_snapshot_support,
+        "Create share from snapshot tests are disabled.")
     def test_create_share_from_snapshot(self):
         # If multitenant driver used, share_network will be provided by default
 
@@ -164,9 +173,13 @@
                       "Only for multitenancy.")
     @testtools.skipUnless(CONF.share.run_snapshot_tests,
                           "Snapshot tests are disabled.")
+    @testtools.skipUnless(
+        CONF.share.capability_create_share_from_snapshot_support,
+        "Create share from snapshot tests are disabled.")
     def test_create_share_from_snapshot_share_network_not_provided(self):
         # We expect usage of share network from parent's share
-        # when creating share from snapshot using multitenant driver.
+        # when creating share from snapshot using a driver that supports
+        # multi-tenancy.
 
         # get parent share
         parent = self.shares_client.get_share(self.share["id"])
diff --git a/manila_tempest_tests/tests/api/test_shares_actions.py b/manila_tempest_tests/tests/api/test_shares_actions.py
index da44c7c..d03df33 100644
--- a/manila_tempest_tests/tests/api/test_shares_actions.py
+++ b/manila_tempest_tests/tests/api/test_shares_actions.py
@@ -58,20 +58,23 @@
             cls.snap = cls.create_snapshot_wait_for_active(
                 cls.shares[0]["id"], cls.snap_name, cls.snap_desc)
 
-            # create second share from snapshot for purposes of sorting and
-            # snapshot filtering
-            cls.share_name2 = data_utils.rand_name("tempest-share-name")
-            cls.share_desc2 = data_utils.rand_name("tempest-share-description")
-            cls.metadata2 = {
-                'foo_key_share_2': 'foo_value_share_2',
-                'bar_key_share_2': 'foo_value_share_2',
-            }
-            cls.shares.append(cls.create_share(
-                name=cls.share_name2,
-                description=cls.share_desc2,
-                metadata=cls.metadata2,
-                snapshot_id=cls.snap['id'],
-            ))
+            if CONF.share.capability_create_share_from_snapshot_support:
+
+                # create second share from snapshot for purposes of sorting and
+                # snapshot filtering
+                cls.share_name2 = data_utils.rand_name("tempest-share-name")
+                cls.share_desc2 = data_utils.rand_name(
+                    "tempest-share-description")
+                cls.metadata2 = {
+                    'foo_key_share_2': 'foo_value_share_2',
+                    'bar_key_share_2': 'foo_value_share_2',
+                }
+                cls.shares.append(cls.create_share(
+                    name=cls.share_name2,
+                    description=cls.share_desc2,
+                    metadata=cls.metadata2,
+                    snapshot_id=cls.snap['id'],
+                ))
 
     def _get_share(self, version):
 
@@ -101,6 +104,8 @@
             expected_keys.append("replication_type")
         if utils.is_microversion_ge(version, '2.16'):
             expected_keys.append("user_id")
+        if utils.is_microversion_ge(version, '2.24'):
+            expected_keys.append("create_share_from_snapshot_support")
         actual_keys = list(share.keys())
         [self.assertIn(key, actual_keys) for key in expected_keys]
 
@@ -158,6 +163,11 @@
         self._get_share('2.16')
 
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
+    @utils.skip_if_microversion_not_supported('2.24')
+    def test_get_share_with_create_share_from_snapshot_support(self):
+        self._get_share('2.24')
+
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_list_shares(self):
 
         # list shares
@@ -201,6 +211,8 @@
             keys.append("replication_type")
         if utils.is_microversion_ge(version, '2.16'):
             keys.append("user_id")
+        if utils.is_microversion_ge(version, '2.24'):
+            keys.append("create_share_from_snapshot_support")
         [self.assertIn(key, sh.keys()) for sh in shares for key in keys]
 
         # our shares in list and have no duplicates
@@ -248,6 +260,11 @@
         self._list_shares_with_detail('2.16')
 
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
+    def test_list_shares_with_detail_and_create_share_from_snapshot_support(
+            self):
+        self._list_shares_with_detail('2.24')
+
+    @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     def test_list_shares_with_detail_filter_by_metadata(self):
         filters = {'metadata': self.metadata}
 
@@ -259,7 +276,7 @@
         for share in shares:
             self.assertDictContainsSubset(
                 filters['metadata'], share['metadata'])
-        if CONF.share.run_snapshot_tests:
+        if CONF.share.capability_create_share_from_snapshot_support:
             self.assertFalse(self.shares[1]['id'] in [s['id'] for s in shares])
 
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
@@ -294,6 +311,9 @@
     @tc.attr(base.TAG_POSITIVE, base.TAG_API_WITH_BACKEND)
     @testtools.skipUnless(CONF.share.run_snapshot_tests,
                           "Snapshot tests are disabled.")
+    @testtools.skipUnless(
+        CONF.share.capability_create_share_from_snapshot_support,
+        "Create share from snapshot tests are disabled.")
     def test_list_shares_with_detail_filter_by_snapshot_id(self):
         filters = {'snapshot_id': self.snap['id']}
 
diff --git a/manila_tempest_tests/tests/api/test_shares_negative.py b/manila_tempest_tests/tests/api/test_shares_negative.py
index 7c5619e..42204e1 100644
--- a/manila_tempest_tests/tests/api/test_shares_negative.py
+++ b/manila_tempest_tests/tests/api/test_shares_negative.py
@@ -60,6 +60,9 @@
     @tc.attr(base.TAG_NEGATIVE, base.TAG_API_WITH_BACKEND)
     @testtools.skipUnless(CONF.share.run_snapshot_tests,
                           "Snapshot tests are disabled.")
+    @testtools.skipUnless(
+        CONF.share.capability_create_share_from_snapshot_support,
+        "Create share from snapshot tests are disabled.")
     def test_create_share_from_snap_with_less_size(self):
         # requires minimum 5Gb available space
 
@@ -96,7 +99,13 @@
                       "Only for multitenancy.")
     @testtools.skipUnless(CONF.share.run_snapshot_tests,
                           "Snapshot tests are disabled.")
+    @testtools.skipUnless(
+        CONF.share.capability_create_share_from_snapshot_support,
+        "Create share from snapshot tests are disabled.")
     def test_create_share_from_snap_with_different_share_network(self):
+        # We can't create a share from a snapshot whose base share does not
+        # have 'create_share_from_snapshot_support'.
+
         # create share
         share = self.create_share(cleanup_in_class=False)
 
diff --git a/manila_tempest_tests/tests/scenario/manager_share.py b/manila_tempest_tests/tests/scenario/manager_share.py
index 116d0e3..e019733 100644
--- a/manila_tempest_tests/tests/scenario/manager_share.py
+++ b/manila_tempest_tests/tests/scenario/manager_share.py
@@ -103,6 +103,15 @@
         client.wait_for_share_status(share['id'], 'available')
         return share
 
+    def _create_snapshot(self, share_id, client=None, **kwargs):
+        client = client or self.shares_v2_client
+        snapshot = client.create_snapshot(share_id, **kwargs)
+        self.addCleanup(
+            client.wait_for_resource_deletion, snapshot_id=snapshot['id'])
+        self.addCleanup(client.delete_snapshot, snapshot['id'])
+        client.wait_for_snapshot_status(snapshot["id"], "available")
+        return snapshot
+
     def _wait_for_share_server_deletion(self, sn_id, client=None):
         """Wait for a share server to be deleted
 
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 10218a5..71ed0e3 100644
--- a/manila_tempest_tests/tests/scenario/test_share_basic_ops.py
+++ b/manila_tempest_tests/tests/scenario/test_share_basic_ops.py
@@ -49,9 +49,17 @@
     def setUp(self):
         super(ShareBasicOpsBase, self).setUp()
         base.verify_test_has_appropriate_tags(self)
+        self.image_ref = None
         # Setup image and flavor the test instance
         # Support both configured and injected values
-        self.image_ref = None
+        self.floatings = {}
+        if self.protocol not in CONF.share.enable_protocols:
+            message = "%s tests are disabled" % self.protocol
+            raise self.skipException(message)
+        if self.protocol not in CONF.share.enable_ip_rules_for_protocols:
+            message = ("%s tests for access rules other than IP are disabled" %
+                       self.protocol)
+            raise self.skipException(message)
         if not hasattr(self, 'flavor_ref'):
             self.flavor_ref = CONF.share.client_vm_flavor_ref
         if CONF.share.image_with_share_tools:
@@ -70,8 +78,7 @@
                       image=self.image_ref, flavor=self.flavor_ref,
                       ssh_user=self.ssh_user))
         self.security_group = self._create_security_group()
-        if CONF.share.multitenancy_enabled:
-            self.create_share_network()
+        self.create_share_network()
 
     def boot_instance(self, wait_until="ACTIVE"):
         self.keypair = self.create_keypair()
@@ -91,6 +98,7 @@
         # Obtain a floating IP
         floating_ip = (self.compute_floating_ips_client.create_floating_ip()
                        ['floating_ip'])
+        self.floatings[instance['id']] = floating_ip
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
                         self.compute_floating_ips_client.delete_floating_ip,
                         floating_ip['id'])
@@ -112,11 +120,12 @@
             ssh_client.exec_command("ping -c 1 %s" % server_ip)
         return ssh_client
 
-    def mount_share(self, location, ssh_client):
+    def mount_share(self, location, ssh_client, target_dir=None):
         raise NotImplementedError
 
-    def umount_share(self, ssh_client):
-        ssh_client.exec_command("sudo umount /mnt")
+    def umount_share(self, ssh_client, target_dir=None):
+        target_dir = target_dir or "/mnt"
+        ssh_client.exec_command("sudo umount %s" % target_dir)
 
     def write_data(self, data, ssh_client):
         ssh_client.exec_command("echo \"%s\" | sudo tee /mnt/t1 && sudo sync" %
@@ -151,17 +160,20 @@
         return self._create_share_type(
             data_utils.rand_name("share_type"),
             extra_specs={
+                'snapshot_support': CONF.share.capability_snapshot_support,
                 'driver_handles_share_servers': CONF.share.multitenancy_enabled
             },)['share_type']
 
-    def create_share(self):
-        kwargs = {
+    def create_share(self, **kwargs):
+        kwargs.update({
             'share_protocol': self.protocol,
-            'share_type_id': self._get_share_type()['id'],
-        }
+        })
+        if not ('share_type_id' in kwargs or 'snapshot_id' in kwargs):
+            kwargs.update({'share_type_id': self._get_share_type()['id']})
         if CONF.share.multitenancy_enabled:
             kwargs.update({'share_network_id': self.share_net['id']})
         self.share = self._create_share(**kwargs)
+        return self.share
 
     def allow_access_ip(self, share_id, ip=None, instance=None, cleanup=True):
         if instance and not ip:
@@ -179,6 +191,18 @@
         self._allow_access(share_id, access_type='ip', access_to=ip,
                            cleanup=cleanup)
 
+    def provide_access_to_auxiliary_instance(self, instance, share=None):
+        share = share or self.share
+        if self.protocol.lower() == 'cifs':
+            self.allow_access_ip(share['id'], instance=instance, cleanup=False)
+        elif not CONF.share.multitenancy_enabled:
+            self.allow_access_ip(
+                share['id'], ip=self.floatings[instance['id']]['ip'],
+                instance=instance, cleanup=False)
+        elif (CONF.share.multitenancy_enabled and
+              self.protocol.lower() == 'nfs'):
+            self.allow_access_ip(share['id'], instance=instance, cleanup=False)
+
     def wait_for_active_instance(self, instance_id):
         waiters.wait_for_server_status(
             self.manager.servers_client, instance_id, "ACTIVE")
@@ -189,10 +213,10 @@
         instance = self.boot_instance(wait_until="BUILD")
         self.create_share()
         instance = self.wait_for_active_instance(instance["id"])
-        self.allow_access_ip(self.share['id'], instance=instance,
-                             cleanup=False)
         ssh_client = self.init_ssh(instance)
 
+        self.provide_access_to_auxiliary_instance(instance)
+
         if utils.is_microversion_lt(CONF.share.max_api_microversion, "2.9"):
             locations = self.share['export_locations']
         else:
@@ -217,9 +241,8 @@
         instance2 = self.wait_for_active_instance(instance2["id"])
 
         # Write data to first VM
-        self.allow_access_ip(self.share['id'], instance=instance1,
-                             cleanup=False)
         ssh_client_inst1 = self.init_ssh(instance1)
+        self.provide_access_to_auxiliary_instance(instance1)
 
         if utils.is_microversion_lt(CONF.share.max_api_microversion, "2.9"):
             locations = self.share['export_locations']
@@ -234,9 +257,8 @@
         self.write_data(test_data, ssh_client_inst1)
 
         # Read from second VM
-        self.allow_access_ip(
-            self.share['id'], instance=instance2, cleanup=False)
         ssh_client_inst2 = self.init_ssh(instance2)
+        self.provide_access_to_auxiliary_instance(instance2)
         self.mount_share(locations[0], ssh_client_inst2)
         self.addCleanup(self.umount_share,
                         ssh_client_inst2)
@@ -249,7 +271,7 @@
                           "Share migration tests are disabled.")
     def test_migration_files(self):
 
-        if self.protocol != "NFS":
+        if self.protocol != "nfs":
             raise self.skipException("Only NFS protocol supported "
                                      "at this moment.")
 
@@ -275,9 +297,8 @@
 
         dest_pool = dest_pool['name']
 
-        self.allow_access_ip(
-            self.share['id'], instance=instance, cleanup=False)
         ssh_client = self.init_ssh(instance)
+        self.provide_access_to_auxiliary_instance(instance)
 
         if utils.is_microversion_lt(CONF.share.max_api_microversion, "2.9"):
             exports = self.share['export_locations']
@@ -290,24 +311,24 @@
 
         self.mount_share(exports[0], ssh_client)
 
-        ssh_client.exec_command("mkdir -p /mnt/f1")
-        ssh_client.exec_command("mkdir -p /mnt/f2")
-        ssh_client.exec_command("mkdir -p /mnt/f3")
-        ssh_client.exec_command("mkdir -p /mnt/f4")
-        ssh_client.exec_command("mkdir -p /mnt/f1/ff1")
+        ssh_client.exec_command("sudo mkdir -p /mnt/f1")
+        ssh_client.exec_command("sudo mkdir -p /mnt/f2")
+        ssh_client.exec_command("sudo mkdir -p /mnt/f3")
+        ssh_client.exec_command("sudo mkdir -p /mnt/f4")
+        ssh_client.exec_command("sudo mkdir -p /mnt/f1/ff1")
         ssh_client.exec_command("sleep 1")
-        ssh_client.exec_command("dd if=/dev/zero of=/mnt/f1/1m1.bin bs=1M"
-                                " count=1")
-        ssh_client.exec_command("dd if=/dev/zero of=/mnt/f2/1m2.bin bs=1M"
-                                " count=1")
-        ssh_client.exec_command("dd if=/dev/zero of=/mnt/f3/1m3.bin bs=1M"
-                                " count=1")
-        ssh_client.exec_command("dd if=/dev/zero of=/mnt/f4/1m4.bin bs=1M"
-                                " count=1")
-        ssh_client.exec_command("dd if=/dev/zero of=/mnt/f1/ff1/1m5.bin bs=1M"
-                                " count=1")
-        ssh_client.exec_command("chmod -R 555 /mnt/f3")
-        ssh_client.exec_command("chmod -R 777 /mnt/f4")
+        ssh_client.exec_command(
+            "sudo dd if=/dev/zero of=/mnt/f1/1m1.bin bs=1M count=1")
+        ssh_client.exec_command(
+            "sudo dd if=/dev/zero of=/mnt/f2/1m2.bin bs=1M count=1")
+        ssh_client.exec_command(
+            "sudo dd if=/dev/zero of=/mnt/f3/1m3.bin bs=1M count=1")
+        ssh_client.exec_command(
+            "sudo dd if=/dev/zero of=/mnt/f4/1m4.bin bs=1M count=1")
+        ssh_client.exec_command(
+            "sudo dd if=/dev/zero of=/mnt/f1/ff1/1m5.bin bs=1M count=1")
+        ssh_client.exec_command("sudo chmod -R 555 /mnt/f3")
+        ssh_client.exec_command("sudo chmod -R 777 /mnt/f4")
 
         self.umount_share(ssh_client)
 
@@ -343,21 +364,114 @@
         self.assertIn('1m4.bin', output)
         self.assertIn('1m5.bin', output)
 
+    def _get_user_export_location(self, share):
+        if utils.is_microversion_lt(CONF.share.max_api_microversion, "2.9"):
+            user_export_location = share['export_locations'][0]
+        else:
+            exports = self.shares_v2_client.list_share_export_locations(
+                share['id'])
+            locations = [x['path'] for x in exports]
+            user_export_location = locations[0]
+        return user_export_location
+
+    @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
+    @testtools.skipUnless(
+        CONF.share.run_snapshot_tests, "Snapshot tests are disabled.")
+    def test_write_data_to_share_created_from_snapshot(self):
+        if self.protocol.upper() == 'CIFS':
+            msg = "Skipped for CIFS protocol because of bug/1649573"
+            raise self.skipException(msg)
+
+        # 1 - Create UVM, ok, created
+        instance = self.boot_instance(wait_until="BUILD")
+
+        # 2 - Create share S1, ok, created
+        parent_share = self.create_share()
+        instance = self.wait_for_active_instance(instance["id"])
+        self.addCleanup(self.servers_client.delete_server, instance['id'])
+
+        # 3 - SSH to UVM, ok, connected
+        ssh_client = self.init_ssh(instance)
+
+        # 4 - Provide RW access to S1, ok, provided
+        self.provide_access_to_auxiliary_instance(instance, parent_share)
+
+        # 5 - Try mount S1 to UVM, ok, mounted
+        user_export_location = self._get_user_export_location(parent_share)
+        parent_share_dir = "/mnt/parent"
+        ssh_client.exec_command("sudo mkdir -p %s" % parent_share_dir)
+        self.mount_share(user_export_location, ssh_client, parent_share_dir)
+        self.addCleanup(self.umount_share, ssh_client, parent_share_dir)
+
+        # 6 - Create "file1", ok, created
+        ssh_client.exec_command("sudo touch %s/file1" % parent_share_dir)
+
+        # 7 - Create snapshot SS1 from S1, ok, created
+        snapshot = self._create_snapshot(parent_share['id'])
+
+        # 8 - Create "file2" in share S1 - ok, created. We expect that
+        # snapshot will not contain any data created after snapshot creation.
+        ssh_client.exec_command("sudo touch %s/file2" % parent_share_dir)
+
+        # 9 - Create share S2 from SS1, ok, created
+        child_share = self.create_share(snapshot_id=snapshot["id"])
+
+        # 10 - Try mount S2 - fail, access denied. We test that child share
+        #      did not get access rules from parent share.
+        user_export_location = self._get_user_export_location(child_share)
+        child_share_dir = "/mnt/child"
+        ssh_client.exec_command("sudo mkdir -p %s" % child_share_dir)
+        self.assertRaises(
+            exceptions.SSHExecCommandFailed,
+            self.mount_share,
+            user_export_location, ssh_client, child_share_dir,
+        )
+
+        # 11 - Provide RW access to S2, ok, provided
+        self.provide_access_to_auxiliary_instance(instance, child_share)
+
+        # 12 - Try mount S2, ok, mounted
+        self.mount_share(user_export_location, ssh_client, child_share_dir)
+        self.addCleanup(self.umount_share, ssh_client, child_share_dir)
+
+        # 13 - List files on S2, only "file1" exists
+        output = ssh_client.exec_command("sudo ls -lRA %s" % child_share_dir)
+        self.assertIn('file1', output)
+        self.assertNotIn('file2', output)
+
+        # 14 - Create file3 on S2, ok, file created
+        ssh_client.exec_command("sudo touch %s/file3" % child_share_dir)
+
+        # 15 - List files on S1, two files exist - "file1" and "file2"
+        output = ssh_client.exec_command("sudo ls -lRA %s" % parent_share_dir)
+        self.assertIn('file1', output)
+        self.assertIn('file2', output)
+        self.assertNotIn('file3', output)
+
+        # 16 - List files on S2, two files exist - "file1" and "file3"
+        output = ssh_client.exec_command("sudo ls -lRA %s" % child_share_dir)
+        self.assertIn('file1', output)
+        self.assertNotIn('file2', output)
+        self.assertIn('file3', output)
+
 
 class TestShareBasicOpsNFS(ShareBasicOpsBase):
-    protocol = "NFS"
+    protocol = "nfs"
 
-    def mount_share(self, location, ssh_client):
-        ssh_client.exec_command("sudo mount -vt nfs \"%s\" /mnt" % location)
+    def mount_share(self, location, ssh_client, target_dir=None):
+        target_dir = target_dir or "/mnt"
+        ssh_client.exec_command(
+            "sudo mount -vt nfs \"%s\" %s" % (location, target_dir))
 
 
 class TestShareBasicOpsCIFS(ShareBasicOpsBase):
-    protocol = "CIFS"
+    protocol = "cifs"
 
-    def mount_share(self, location, ssh_client):
+    def mount_share(self, location, ssh_client, target_dir=None):
         location = location.replace("\\", "/")
+        target_dir = target_dir or "/mnt"
         ssh_client.exec_command(
-            "sudo mount.cifs \"%s\" /mnt -o guest" % location
+            "sudo mount.cifs \"%s\" %s -o guest" % (location, target_dir)
         )