Merge "Return appropriate data on share create"
diff --git a/manila_tempest_tests/config.py b/manila_tempest_tests/config.py
index ddf11cd..fb85fe3 100644
--- a/manila_tempest_tests/config.py
+++ b/manila_tempest_tests/config.py
@@ -36,7 +36,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.8",
+               default="2.9",
                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/v2/json/shares_client.py b/manila_tempest_tests/services/share/v2/json/shares_client.py
index 806f108..d017b91 100644
--- a/manila_tempest_tests/services/share/v2/json/shares_client.py
+++ b/manila_tempest_tests/services/share/v2/json/shares_client.py
@@ -238,6 +238,23 @@
         self.expected_success(200, resp.status)
         return self._parse_resp(body)
 
+    def get_share_export_location(
+            self, share_id, export_location_uuid, version=LATEST_MICROVERSION):
+        resp, body = self.get(
+            "shares/%(share_id)s/export_locations/%(el_uuid)s" % {
+                "share_id": share_id, "el_uuid": export_location_uuid},
+            version=version)
+        self.expected_success(200, resp.status)
+        return self._parse_resp(body)
+
+    def list_share_export_locations(
+            self, share_id, version=LATEST_MICROVERSION):
+        resp, body = self.get(
+            "shares/%(share_id)s/export_locations" % {"share_id": share_id},
+            version=version)
+        self.expected_success(200, resp.status)
+        return self._parse_resp(body)
+
     def delete_share(self, share_id, params=None,
                      version=LATEST_MICROVERSION):
         uri = "shares/%s" % share_id
@@ -265,6 +282,24 @@
         self.expected_success(200, resp.status)
         return self._parse_resp(body)
 
+    def get_share_instance_export_location(
+            self, instance_id, export_location_uuid,
+            version=LATEST_MICROVERSION):
+        resp, body = self.get(
+            "share_instances/%(instance_id)s/export_locations/%(el_uuid)s" % {
+                "instance_id": instance_id, "el_uuid": export_location_uuid},
+            version=version)
+        self.expected_success(200, resp.status)
+        return self._parse_resp(body)
+
+    def list_share_instance_export_locations(
+            self, instance_id, version=LATEST_MICROVERSION):
+        resp, body = self.get(
+            "share_instances/%s/export_locations" % instance_id,
+            version=version)
+        self.expected_success(200, resp.status)
+        return self._parse_resp(body)
+
     def wait_for_share_instance_status(self, instance_id, status,
                                        version=LATEST_MICROVERSION):
         """Waits for a share to reach a given status."""
@@ -377,16 +412,16 @@
 
 ###############
 
-    def _get_access_action_name(self, version):
+    def _get_access_action_name(self, version, action):
         if utils.is_microversion_gt(version, "2.6"):
-            return 'allow_access'
-        return 'os-allow_access'
+            return action.split('os-')[-1]
+        return action
 
     def create_access_rule(self, share_id, access_type="ip",
                            access_to="0.0.0.0", access_level=None,
                            version=LATEST_MICROVERSION, action_name=None):
         post_body = {
-            self._get_access_action_name(version): {
+            self._get_access_action_name(version, 'os-allow_access'): {
                 "access_type": access_type,
                 "access_to": access_to,
                 "access_level": access_level,
@@ -400,7 +435,7 @@
 
     def list_access_rules(self, share_id, version=LATEST_MICROVERSION,
                           action_name=None):
-        body = {self._get_access_action_name(version): None}
+        body = {self._get_access_action_name(version, 'os-access_list'): None}
         resp, body = self.post(
             "shares/%s/action" % share_id, json.dumps(body), version=version)
         self.expected_success(200, resp.status)
@@ -409,7 +444,7 @@
     def delete_access_rule(self, share_id, rule_id,
                            version=LATEST_MICROVERSION, action_name=None):
         post_body = {
-            self._get_access_action_name(version): {
+            self._get_access_action_name(version, 'os-deny_access'): {
                 "access_id": rule_id,
             }
         }
diff --git a/manila_tempest_tests/tests/api/admin/test_export_locations.py b/manila_tempest_tests/tests/api/admin/test_export_locations.py
new file mode 100644
index 0000000..9c759fc
--- /dev/null
+++ b/manila_tempest_tests/tests/api/admin/test_export_locations.py
@@ -0,0 +1,143 @@
+# Copyright 2015 Mirantis Inc.
+# All Rights Reserved.
+#
+#    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 oslo_utils import timeutils
+from oslo_utils import uuidutils
+import six
+from tempest import config
+from tempest import test
+
+from manila_tempest_tests import clients_share as clients
+from manila_tempest_tests.tests.api import base
+
+CONF = config.CONF
+
+
+@base.skip_if_microversion_not_supported("2.9")
+class ExportLocationsTest(base.BaseSharesAdminTest):
+
+    @classmethod
+    def resource_setup(cls):
+        super(ExportLocationsTest, cls).resource_setup()
+        cls.admin_client = cls.shares_v2_client
+        cls.member_client = clients.Manager().shares_v2_client
+        cls.share = cls.create_share()
+        cls.share = cls.shares_v2_client.get_share(cls.share['id'])
+        cls.share_instances = cls.shares_v2_client.get_instances_of_share(
+            cls.share['id'])
+
+    def _verify_export_location_structure(self, export_locations,
+                                          role='admin'):
+        expected_keys = [
+            'created_at', 'updated_at', 'path', 'uuid',
+        ]
+        if role == 'admin':
+            expected_keys.extend(['is_admin_only', 'share_instance_id'])
+
+        if not isinstance(export_locations, (list, tuple, set)):
+            export_locations = (export_locations, )
+
+        for export_location in export_locations:
+            self.assertEqual(len(expected_keys), len(export_location))
+            for key in expected_keys:
+                self.assertIn(key, export_location)
+            if role == 'admin':
+                self.assertIn(export_location['is_admin_only'], (True, False))
+                self.assertTrue(
+                    uuidutils.is_uuid_like(
+                        export_location['share_instance_id']))
+            self.assertTrue(uuidutils.is_uuid_like(export_location['uuid']))
+            self.assertTrue(
+                isinstance(export_location['path'], six.string_types))
+            for time in (export_location['created_at'],
+                         export_location['updated_at']):
+                # If var 'time' has incorrect value then ValueError exception
+                # is expected to be raised. So, just try parse it making
+                # assertion that it has proper date value.
+                timeutils.parse_strtime(time)
+
+    @test.attr(type=["gate", ])
+    def test_list_share_export_locations(self):
+        export_locations = self.admin_client.list_share_export_locations(
+            self.share['id'])
+
+        self._verify_export_location_structure(export_locations)
+
+    @test.attr(type=["gate", ])
+    def test_get_share_export_location(self):
+        export_locations = self.admin_client.list_share_export_locations(
+            self.share['id'])
+
+        for export_location in export_locations:
+            el = self.admin_client.get_share_export_location(
+                self.share['id'], export_location['uuid'])
+            self._verify_export_location_structure(el)
+
+    @test.attr(type=["gate", ])
+    def test_list_share_export_locations_by_member(self):
+        export_locations = self.member_client.list_share_export_locations(
+            self.share['id'])
+
+        self._verify_export_location_structure(export_locations, 'member')
+
+    @test.attr(type=["gate", ])
+    def test_get_share_export_location_by_member(self):
+        export_locations = self.admin_client.list_share_export_locations(
+            self.share['id'])
+
+        for export_location in export_locations:
+            el = self.member_client.get_share_export_location(
+                self.share['id'], export_location['uuid'])
+            self._verify_export_location_structure(el, 'member')
+
+    @test.attr(type=["gate", ])
+    def test_list_share_instance_export_locations(self):
+        for share_instance in self.share_instances:
+            export_locations = (
+                self.admin_client.list_share_instance_export_locations(
+                    share_instance['id']))
+            self._verify_export_location_structure(export_locations)
+
+    @test.attr(type=["gate", ])
+    def test_get_share_instance_export_location(self):
+        for share_instance in self.share_instances:
+            export_locations = (
+                self.admin_client.list_share_instance_export_locations(
+                    share_instance['id']))
+            for el in export_locations:
+                el = self.admin_client.get_share_instance_export_location(
+                    share_instance['id'], el['uuid'])
+                self._verify_export_location_structure(el)
+
+    @test.attr(type=["gate", ])
+    def test_share_contains_all_export_locations_of_all_share_instances(self):
+        share_export_locations = self.admin_client.list_share_export_locations(
+            self.share['id'])
+        share_instances_export_locations = []
+        for share_instance in self.share_instances:
+            share_instance_export_locations = (
+                self.admin_client.list_share_instance_export_locations(
+                    share_instance['id']))
+            share_instances_export_locations.extend(
+                share_instance_export_locations)
+
+        self.assertEqual(
+            len(share_export_locations),
+            len(share_instances_export_locations)
+        )
+        self.assertEqual(
+            sorted(share_export_locations, key=lambda el: el['uuid']),
+            sorted(share_instances_export_locations, key=lambda el: el['uuid'])
+        )
diff --git a/manila_tempest_tests/tests/api/admin/test_export_locations_negative.py b/manila_tempest_tests/tests/api/admin/test_export_locations_negative.py
new file mode 100644
index 0000000..9d53373
--- /dev/null
+++ b/manila_tempest_tests/tests/api/admin/test_export_locations_negative.py
@@ -0,0 +1,94 @@
+# Copyright 2015 Mirantis Inc.
+# All Rights Reserved.
+#
+#    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 import test
+from tempest_lib import exceptions as lib_exc
+
+from manila_tempest_tests import clients_share as clients
+from manila_tempest_tests.tests.api import base
+
+CONF = config.CONF
+
+
+@base.skip_if_microversion_not_supported("2.9")
+class ExportLocationsNegativeTest(base.BaseSharesAdminTest):
+
+    @classmethod
+    def resource_setup(cls):
+        super(ExportLocationsNegativeTest, cls).resource_setup()
+        cls.admin_client = cls.shares_v2_client
+        cls.member_client = clients.Manager().shares_v2_client
+        cls.share = cls.create_share()
+        cls.share = cls.shares_v2_client.get_share(cls.share['id'])
+        cls.share_instances = cls.shares_v2_client.get_instances_of_share(
+            cls.share['id'])
+
+    @test.attr(type=["gate", "negative"])
+    def test_get_export_locations_by_inexistent_share(self):
+        self.assertRaises(
+            lib_exc.NotFound,
+            self.admin_client.list_share_export_locations,
+            "fake-inexistent-share-id",
+        )
+
+    @test.attr(type=["gate", "negative"])
+    def test_get_inexistent_share_export_location(self):
+        self.assertRaises(
+            lib_exc.NotFound,
+            self.admin_client.get_share_export_location,
+            self.share['id'],
+            "fake-inexistent-share-instance-id",
+        )
+
+    @test.attr(type=["gate", "negative"])
+    def test_get_export_locations_by_inexistent_share_instance(self):
+        self.assertRaises(
+            lib_exc.NotFound,
+            self.admin_client.list_share_instance_export_locations,
+            "fake-inexistent-share-instance-id",
+        )
+
+    @test.attr(type=["gate", "negative"])
+    def test_get_inexistent_share_instance_export_location(self):
+        for share_instance in self.share_instances:
+            self.assertRaises(
+                lib_exc.NotFound,
+                self.admin_client.get_share_instance_export_location,
+                share_instance['id'],
+                "fake-inexistent-share-instance-id",
+            )
+
+    @test.attr(type=["gate", "negative"])
+    def test_list_share_instance_export_locations_by_member(self):
+        for share_instance in self.share_instances:
+            self.assertRaises(
+                lib_exc.Forbidden,
+                self.member_client.list_share_instance_export_locations,
+                "fake-inexistent-share-instance-id",
+            )
+
+    @test.attr(type=["gate", "negative"])
+    def test_get_share_instance_export_location_by_member(self):
+        for share_instance in self.share_instances:
+            export_locations = (
+                self.admin_client.list_share_instance_export_locations(
+                    share_instance['id']))
+            for el in export_locations:
+                self.assertRaises(
+                    lib_exc.Forbidden,
+                    self.member_client.get_share_instance_export_location,
+                    share_instance['id'], el['uuid'],
+                )
diff --git a/manila_tempest_tests/tests/api/admin/test_share_instances.py b/manila_tempest_tests/tests/api/admin/test_share_instances.py
index 1202b9d..c5f96c8 100644
--- a/manila_tempest_tests/tests/api/admin/test_share_instances.py
+++ b/manila_tempest_tests/tests/api/admin/test_share_instances.py
@@ -17,6 +17,7 @@
 from tempest import test
 
 from manila_tempest_tests.tests.api import base
+from manila_tempest_tests import utils
 
 CONF = config.CONF
 
@@ -58,21 +59,31 @@
         msg = 'Share instance for share %s was not found.' % self.share['id']
         self.assertIn(self.share['id'], share_ids, msg)
 
-    @test.attr(type=["gate", ])
-    def test_get_share_instance_v2_3(self):
+    def _get_share_instance(self, version):
         """Test that we get the proper keys back for the instance."""
         share_instances = self.shares_v2_client.get_instances_of_share(
-            self.share['id'], version='2.3'
+            self.share['id'], version=version,
         )
-        si = self.shares_v2_client.get_share_instance(share_instances[0]['id'],
-                                                      version='2.3')
+        si = self.shares_v2_client.get_share_instance(
+            share_instances[0]['id'], version=version)
 
-        expected_keys = ['host', 'share_id', 'id', 'share_network_id',
-                         'status', 'availability_zone', 'share_server_id',
-                         'export_locations', 'export_location', 'created_at']
-        actual_keys = si.keys()
-        self.assertEqual(sorted(expected_keys), sorted(actual_keys),
+        expected_keys = [
+            'host', 'share_id', 'id', 'share_network_id', 'status',
+            'availability_zone', 'share_server_id', 'created_at',
+        ]
+        if utils.is_microversion_lt(version, '2.9'):
+            expected_keys.extend(["export_location", "export_locations"])
+        expected_keys = sorted(expected_keys)
+        actual_keys = sorted(si.keys())
+        self.assertEqual(expected_keys, actual_keys,
                          'Share instance %s returned incorrect keys; '
-                         'expected %s, got %s.' % (si['id'],
-                                                   sorted(expected_keys),
-                                                   sorted(actual_keys)))
+                         'expected %s, got %s.' % (
+                             si['id'], expected_keys, actual_keys))
+
+    @test.attr(type=["gate", ])
+    def test_get_share_instance_v2_3(self):
+        self._get_share_instance('2.3')
+
+    @test.attr(type=["gate", ])
+    def test_get_share_instance_v2_9(self):
+        self._get_share_instance('2.9')
diff --git a/manila_tempest_tests/tests/api/base.py b/manila_tempest_tests/tests/api/base.py
index b9763fb..f9a678d 100644
--- a/manila_tempest_tests/tests/api/base.py
+++ b/manila_tempest_tests/tests/api/base.py
@@ -208,8 +208,8 @@
 
     def setUp(self):
         super(BaseSharesTest, self).setUp()
-        self.addCleanup(self.clear_resources)
         self.addCleanup(self.clear_isolated_creds)
+        self.addCleanup(self.clear_resources)
 
     @classmethod
     def resource_cleanup(cls):
@@ -338,7 +338,8 @@
     def migrate_share(cls, share_id, dest_host, client=None, **kwargs):
         client = client or cls.shares_v2_client
         client.migrate_share(share_id, dest_host, **kwargs)
-        share = client.wait_for_migration_completed(share_id, dest_host)
+        share = client.wait_for_migration_completed(
+            share_id, dest_host, version=kwargs.get('version'))
         return share
 
     @classmethod
diff --git a/manila_tempest_tests/tests/api/test_rules.py b/manila_tempest_tests/tests/api/test_rules.py
index 0399d27..6f323d9 100644
--- a/manila_tempest_tests/tests/api/test_rules.py
+++ b/manila_tempest_tests/tests/api/test_rules.py
@@ -13,6 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import ddt
 from tempest import config  # noqa
 from tempest import test  # noqa
 from tempest_lib import exceptions as lib_exc  # noqa
@@ -23,24 +24,25 @@
 CONF = config.CONF
 
 
-def _create_delete_ro_access_rule(self):
+def _create_delete_ro_access_rule(self, client_name):
     """Common test case for usage in test suites with different decorators.
 
     :param self: instance of test class
     """
-    rule = self.shares_client.create_access_rule(
+    rule = getattr(self, client_name).create_access_rule(
         self.share["id"], self.access_type, self.access_to, 'ro')
 
     self.assertEqual('ro', rule['access_level'])
     for key in ('deleted', 'deleted_at', 'instance_mappings'):
         self.assertNotIn(key, rule.keys())
-    self.shares_client.wait_for_access_rule_status(
+    getattr(self, client_name).wait_for_access_rule_status(
         self.share["id"], rule["id"], "active")
-    self.shares_client.delete_access_rule(self.share["id"], rule["id"])
-    self.shares_client.wait_for_resource_deletion(
+    getattr(self, client_name).delete_access_rule(self.share["id"], rule["id"])
+    getattr(self, client_name).wait_for_resource_deletion(
         rule_id=rule["id"], share_id=self.share['id'])
 
 
+@ddt.ddt
 class ShareIpRulesForNFSTest(base.BaseSharesTest):
     protocol = "nfs"
 
@@ -56,55 +58,61 @@
         cls.access_to = "2.2.2.2"
 
     @test.attr(type=["gate", ])
-    def test_create_delete_access_rules_with_one_ip(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_delete_access_rules_with_one_ip(self, client_name):
 
         # test data
         access_to = "1.1.1.1"
 
         # create rule
-        rule = self.shares_client.create_access_rule(
+        rule = getattr(self, client_name).create_access_rule(
             self.share["id"], self.access_type, access_to)
 
         self.assertEqual('rw', rule['access_level'])
         for key in ('deleted', 'deleted_at', 'instance_mappings'):
             self.assertNotIn(key, rule.keys())
-        self.shares_client.wait_for_access_rule_status(
+        getattr(self, client_name).wait_for_access_rule_status(
             self.share["id"], rule["id"], "active")
 
         # delete rule and wait for deletion
-        self.shares_client.delete_access_rule(self.share["id"], rule["id"])
-        self.shares_client.wait_for_resource_deletion(
+        getattr(self, client_name).delete_access_rule(self.share["id"],
+                                                      rule["id"])
+        getattr(self, client_name).wait_for_resource_deletion(
             rule_id=rule["id"], share_id=self.share['id'])
 
     @test.attr(type=["gate", ])
-    def test_create_delete_access_rule_with_cidr(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_delete_access_rule_with_cidr(self, client_name):
 
         # test data
         access_to = "1.2.3.4/32"
 
         # create rule
-        rule = self.shares_client.create_access_rule(
+        rule = getattr(self, client_name).create_access_rule(
             self.share["id"], self.access_type, access_to)
 
         for key in ('deleted', 'deleted_at', 'instance_mappings'):
             self.assertNotIn(key, rule.keys())
         self.assertEqual('rw', rule['access_level'])
-        self.shares_client.wait_for_access_rule_status(
+        getattr(self, client_name).wait_for_access_rule_status(
             self.share["id"], rule["id"], "active")
 
         # delete rule and wait for deletion
-        self.shares_client.delete_access_rule(self.share["id"], rule["id"])
-        self.shares_client.wait_for_resource_deletion(
+        getattr(self, client_name).delete_access_rule(self.share["id"],
+                                                      rule["id"])
+        getattr(self, client_name).wait_for_resource_deletion(
             rule_id=rule["id"], share_id=self.share['id'])
 
     @test.attr(type=["gate", ])
     @testtools.skipIf(
         "nfs" not in CONF.share.enable_ro_access_level_for_protocols,
         "RO access rule tests are disabled for NFS protocol.")
-    def test_create_delete_ro_access_rule(self):
-        _create_delete_ro_access_rule(self)
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_delete_ro_access_rule(self, client_name):
+        _create_delete_ro_access_rule(self, client_name)
 
 
+@ddt.ddt
 class ShareIpRulesForCIFSTest(ShareIpRulesForNFSTest):
     protocol = "cifs"
 
@@ -112,10 +120,12 @@
     @testtools.skipIf(
         "cifs" not in CONF.share.enable_ro_access_level_for_protocols,
         "RO access rule tests are disabled for CIFS protocol.")
-    def test_create_delete_ro_access_rule(self):
-        _create_delete_ro_access_rule(self)
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_delete_ro_access_rule(self, client_name):
+        _create_delete_ro_access_rule(self, client_name)
 
 
+@ddt.ddt
 class ShareUserRulesForNFSTest(base.BaseSharesTest):
     protocol = "nfs"
 
@@ -132,31 +142,35 @@
         cls.access_to = CONF.share.username_for_user_rules
 
     @test.attr(type=["gate", ])
-    def test_create_delete_user_rule(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_delete_user_rule(self, client_name):
 
         # create rule
-        rule = self.shares_client.create_access_rule(
+        rule = getattr(self, client_name).create_access_rule(
             self.share["id"], self.access_type, self.access_to)
 
         self.assertEqual('rw', rule['access_level'])
         for key in ('deleted', 'deleted_at', 'instance_mappings'):
             self.assertNotIn(key, rule.keys())
-        self.shares_client.wait_for_access_rule_status(
+        getattr(self, client_name).wait_for_access_rule_status(
             self.share["id"], rule["id"], "active")
 
         # delete rule and wait for deletion
-        self.shares_client.delete_access_rule(self.share["id"], rule["id"])
-        self.shares_client.wait_for_resource_deletion(
+        getattr(self, client_name).delete_access_rule(self.share["id"],
+                                                      rule["id"])
+        getattr(self, client_name).wait_for_resource_deletion(
             rule_id=rule["id"], share_id=self.share['id'])
 
     @test.attr(type=["gate", ])
     @testtools.skipIf(
         "nfs" not in CONF.share.enable_ro_access_level_for_protocols,
         "RO access rule tests are disabled for NFS protocol.")
-    def test_create_delete_ro_access_rule(self):
-        _create_delete_ro_access_rule(self)
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_delete_ro_access_rule(self, client_name):
+        _create_delete_ro_access_rule(self, client_name)
 
 
+@ddt.ddt
 class ShareUserRulesForCIFSTest(ShareUserRulesForNFSTest):
     protocol = "cifs"
 
@@ -164,10 +178,12 @@
     @testtools.skipIf(
         "cifs" not in CONF.share.enable_ro_access_level_for_protocols,
         "RO access rule tests are disabled for CIFS protocol.")
-    def test_create_delete_ro_access_rule(self):
-        _create_delete_ro_access_rule(self)
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_delete_ro_access_rule(self, client_name):
+        _create_delete_ro_access_rule(self, client_name)
 
 
+@ddt.ddt
 class ShareCertRulesForGLUSTERFSTest(base.BaseSharesTest):
     protocol = "glusterfs"
 
@@ -186,37 +202,42 @@
         cls.access_to = "client1.com"
 
     @test.attr(type=["gate", ])
-    def test_create_delete_cert_rule(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_delete_cert_rule(self, client_name):
 
         # create rule
-        rule = self.shares_client.create_access_rule(
+        rule = getattr(self, client_name).create_access_rule(
             self.share["id"], self.access_type, self.access_to)
 
         self.assertEqual('rw', rule['access_level'])
         for key in ('deleted', 'deleted_at', 'instance_mappings'):
             self.assertNotIn(key, rule.keys())
-        self.shares_client.wait_for_access_rule_status(
+        getattr(self, client_name).wait_for_access_rule_status(
             self.share["id"], rule["id"], "active")
 
         # delete rule
-        self.shares_client.delete_access_rule(self.share["id"], rule["id"])
+        getattr(self, client_name).delete_access_rule(self.share["id"],
+                                                      rule["id"])
 
     @test.attr(type=["gate", ])
     @testtools.skipIf(
         "glusterfs" not in CONF.share.enable_ro_access_level_for_protocols,
         "RO access rule tests are disabled for GLUSTERFS protocol.")
-    def test_create_delete_cert_ro_access_rule(self):
-        rule = self.shares_client.create_access_rule(
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_delete_cert_ro_access_rule(self, client_name):
+        rule = getattr(self, client_name).create_access_rule(
             self.share["id"], 'cert', 'client2.com', 'ro')
 
         self.assertEqual('ro', rule['access_level'])
         for key in ('deleted', 'deleted_at', 'instance_mappings'):
             self.assertNotIn(key, rule.keys())
-        self.shares_client.wait_for_access_rule_status(
+        getattr(self, client_name).wait_for_access_rule_status(
             self.share["id"], rule["id"], "active")
-        self.shares_client.delete_access_rule(self.share["id"], rule["id"])
+        getattr(self, client_name).delete_access_rule(self.share["id"],
+                                                      rule["id"])
 
 
+@ddt.ddt
 class ShareRulesTest(base.BaseSharesTest):
 
     @classmethod
@@ -246,17 +267,18 @@
         cls.share = cls.create_share()
 
     @test.attr(type=["gate", ])
-    def test_list_access_rules(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_list_access_rules(self, client_name):
 
         # create rule
-        rule = self.shares_client.create_access_rule(
+        rule = getattr(self, client_name).create_access_rule(
             self.share["id"], self.access_type, self.access_to)
 
-        self.shares_client.wait_for_access_rule_status(
+        getattr(self, client_name).wait_for_access_rule_status(
             self.share["id"], rule["id"], "active")
 
         # list rules
-        rules = self.shares_client.list_access_rules(self.share["id"])
+        rules = getattr(self, client_name).list_access_rules(self.share["id"])
 
         # verify keys
         for key in ("state", "id", "access_type", "access_to", "access_level"):
@@ -275,23 +297,31 @@
         msg = "expected id lists %s times in rule list" % (len(gen))
         self.assertEqual(len(gen), 1, msg)
 
+        getattr(self, client_name).delete_access_rule(
+            self.share['id'], rule['id'])
+
+        getattr(self, client_name).wait_for_resource_deletion(
+            rule_id=rule["id"], share_id=self.share['id'])
+
     @test.attr(type=["gate", ])
-    def test_access_rules_deleted_if_share_deleted(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_access_rules_deleted_if_share_deleted(self, client_name):
 
         # create share
         share = self.create_share()
 
         # create rule
-        rule = self.shares_client.create_access_rule(
+        rule = getattr(self, client_name).create_access_rule(
             share["id"], self.access_type, self.access_to)
-        self.shares_client.wait_for_access_rule_status(
+        getattr(self, client_name).wait_for_access_rule_status(
             share["id"], rule["id"], "active")
 
         # delete share
-        self.shares_client.delete_share(share['id'])
-        self.shares_client.wait_for_resource_deletion(share_id=share['id'])
+        getattr(self, client_name).delete_share(share['id'])
+        getattr(self, client_name).wait_for_resource_deletion(
+            share_id=share['id'])
 
         # verify absence of rules for nonexistent share id
         self.assertRaises(lib_exc.NotFound,
-                          self.shares_client.list_access_rules,
+                          getattr(self, client_name).list_access_rules,
                           share['id'])
diff --git a/manila_tempest_tests/tests/api/test_rules_negative.py b/manila_tempest_tests/tests/api/test_rules_negative.py
index 6ad36ba..71b5244 100644
--- a/manila_tempest_tests/tests/api/test_rules_negative.py
+++ b/manila_tempest_tests/tests/api/test_rules_negative.py
@@ -13,6 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import ddt
 from tempest import config  # noqa
 from tempest import test  # noqa
 from tempest_lib import exceptions as lib_exc  # noqa
@@ -23,6 +24,7 @@
 CONF = config.CONF
 
 
+@ddt.ddt
 class ShareIpRulesForNFSNegativeTest(base.BaseSharesTest):
     protocol = "nfs"
 
@@ -40,84 +42,102 @@
             cls.snap = cls.create_snapshot_wait_for_active(cls.share["id"])
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_ip_with_wrong_target_1(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_ip_with_wrong_target_1(self, client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], "ip", "1.2.3.256")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_ip_with_wrong_target_2(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_ip_with_wrong_target_2(self, client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], "ip", "1.1.1.-")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_ip_with_wrong_target_3(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_ip_with_wrong_target_3(self, client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], "ip", "1.2.3.4/33")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_ip_with_wrong_target_4(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_ip_with_wrong_target_4(self, client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], "ip", "1.2.3.*")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_ip_with_wrong_target_5(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_ip_with_wrong_target_5(self, client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], "ip", "1.2.3.*/23")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_ip_with_wrong_target_6(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_ip_with_wrong_target_6(self, client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], "ip", "1.2.3.1|23")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_ip_with_wrong_target_7(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_ip_with_wrong_target_7(self, client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], "ip", "1.2.3.1/-1")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_ip_with_wrong_target_8(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_ip_with_wrong_target_8(self, client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], "ip", "1.2.3.1/")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_with_wrong_level(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_with_wrong_level(self, client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"],
                           'ip',
                           '2.2.2.2',
                           'su')
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_duplicate_of_ip_rule(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_duplicate_of_ip_rule(self, client_name):
         # test data
         access_type = "ip"
         access_to = "1.2.3.4"
 
         # create rule
-        rule = self.shares_client.create_access_rule(
+        rule = getattr(self, client_name).create_access_rule(
             self.share["id"], access_type, access_to)
-        self.shares_client.wait_for_access_rule_status(
+        getattr(self, client_name).wait_for_access_rule_status(
             self.share["id"], rule["id"], "active")
 
         # try create duplicate of rule
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], access_type, access_to)
 
+        # delete rule and wait for deletion
+        getattr(self, client_name).delete_access_rule(self.share["id"],
+                                                      rule["id"])
+        getattr(self, client_name).wait_for_resource_deletion(
+            rule_id=rule["id"], share_id=self.share['id'])
 
+
+@ddt.ddt
 class ShareIpRulesForCIFSNegativeTest(ShareIpRulesForNFSNegativeTest):
     protocol = "cifs"
 
 
+@ddt.ddt
 class ShareUserRulesForNFSNegativeTest(base.BaseSharesTest):
     protocol = "nfs"
 
@@ -135,69 +155,79 @@
             cls.snap = cls.create_snapshot_wait_for_active(cls.share["id"])
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_user_with_wrong_input_2(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_user_with_wrong_input_2(self, client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], "user",
                           "try+")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_user_with_empty_key(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_user_with_empty_key(self, client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], "user", "")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_user_with_too_little_key(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_user_with_too_little_key(self, client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], "user", "abc")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_user_with_too_big_key(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_user_with_too_big_key(self, client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], "user", "a" * 33)
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_user_with_wrong_input_1(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_user_with_wrong_input_1(self, client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], "user",
                           "try+")
 
     @test.attr(type=["negative", "gate", ])
+    @ddt.data('shares_client', 'shares_v2_client')
     @testtools.skipUnless(CONF.share.run_snapshot_tests,
                           "Snapshot tests are disabled.")
-    def test_create_access_rule_user_to_snapshot(self):
+    def test_create_access_rule_user_to_snapshot(self, client_name):
         self.assertRaises(lib_exc.NotFound,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.snap["id"],
                           access_type="user",
                           access_to="fakeuser")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_user_with_wrong_share_id(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_user_with_wrong_share_id(self, client_name):
         self.assertRaises(lib_exc.NotFound,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           "wrong_share_id",
                           access_type="user",
                           access_to="fakeuser")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_with_wrong_level(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_with_wrong_level(self, client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"],
                           'user',
                           CONF.share.username_for_user_rules,
                           'su')
 
 
+@ddt.ddt
 class ShareUserRulesForCIFSNegativeTest(ShareUserRulesForNFSNegativeTest):
     protocol = "cifs"
 
 
+@ddt.ddt
 class ShareCertRulesForGLUSTERFSNegativeTest(base.BaseSharesTest):
     protocol = "glusterfs"
 
@@ -215,43 +245,51 @@
             cls.snap = cls.create_snapshot_wait_for_active(cls.share["id"])
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_cert_with_empty_common_name(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_cert_with_empty_common_name(self, client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], "cert", "")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_cert_with_whitespace_common_name(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_cert_with_whitespace_common_name(self,
+                                                                 client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], "cert", " ")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_cert_with_too_big_common_name(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_cert_with_too_big_common_name(self,
+                                                              client_name):
         # common name cannot be more than 64 characters long
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], "cert", "a" * 65)
 
     @test.attr(type=["negative", "gate", ])
     @testtools.skipUnless(CONF.share.run_snapshot_tests,
                           "Snapshot tests are disabled.")
-    def test_create_access_rule_cert_to_snapshot(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_cert_to_snapshot(self, client_name):
         self.assertRaises(lib_exc.NotFound,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.snap["id"],
                           access_type="cert",
                           access_to="fakeclient1.com")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_cert_with_wrong_share_id(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_cert_with_wrong_share_id(self, client_name):
         self.assertRaises(lib_exc.NotFound,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           "wrong_share_id",
                           access_type="cert",
                           access_to="fakeclient2.com")
 
 
+@ddt.ddt
 class ShareRulesNegativeTest(base.BaseSharesTest):
     # Tests independent from rule type and share protocol
 
@@ -273,27 +311,31 @@
             cls.snap = cls.create_snapshot_wait_for_active(cls.share["id"])
 
     @test.attr(type=["negative", "gate", ])
-    def test_delete_access_rule_with_wrong_id(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_delete_access_rule_with_wrong_id(self, client_name):
         self.assertRaises(lib_exc.NotFound,
-                          self.shares_client.delete_access_rule,
+                          getattr(self, client_name).delete_access_rule,
                           self.share["id"], "wrong_rule_id")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_ip_with_wrong_type(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_ip_with_wrong_type(self, client_name):
         self.assertRaises(lib_exc.BadRequest,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.share["id"], "wrong_type", "1.2.3.4")
 
     @test.attr(type=["negative", "gate", ])
-    def test_create_access_rule_ip_with_wrong_share_id(self):
+    @ddt.data('shares_client', 'shares_v2_client')
+    def test_create_access_rule_ip_with_wrong_share_id(self, client_name):
         self.assertRaises(lib_exc.NotFound,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           "wrong_share_id")
 
     @test.attr(type=["negative", "gate", ])
+    @ddt.data('shares_client', 'shares_v2_client')
     @testtools.skipUnless(CONF.share.run_snapshot_tests,
                           "Snapshot tests are disabled.")
-    def test_create_access_rule_ip_to_snapshot(self):
+    def test_create_access_rule_ip_to_snapshot(self, client_name):
         self.assertRaises(lib_exc.NotFound,
-                          self.shares_client.create_access_rule,
+                          getattr(self, client_name).create_access_rule,
                           self.snap["id"])
diff --git a/manila_tempest_tests/tests/api/test_shares.py b/manila_tempest_tests/tests/api/test_shares.py
index 84b3f97..2527aa9 100644
--- a/manila_tempest_tests/tests/api/test_shares.py
+++ b/manila_tempest_tests/tests/api/test_shares.py
@@ -19,6 +19,7 @@
 import testtools  # noqa
 
 from manila_tempest_tests.tests.api import base
+from manila_tempest_tests import utils
 
 CONF = config.CONF
 
@@ -40,7 +41,7 @@
 
         share = self.create_share(self.protocol)
         detailed_elements = {'name', 'id', 'availability_zone',
-                             'description', 'export_location', 'project_id',
+                             'description', 'project_id',
                              'host', 'created_at', 'share_proto', 'metadata',
                              'size', 'snapshot_id', 'share_network_id',
                              'status', 'share_type', 'volume_type', 'links',
@@ -61,6 +62,7 @@
 
         # Get share using v 2.1 - we expect key 'snapshot_support' to be absent
         share_get = self.shares_v2_client.get_share(share['id'], version='2.1')
+        detailed_elements.add('export_location')
         self.assertTrue(detailed_elements.issubset(share_get.keys()), msg)
 
         # Get share using v 2.2 - we expect key 'snapshot_support' to exist
@@ -68,6 +70,14 @@
         detailed_elements.add('snapshot_support')
         self.assertTrue(detailed_elements.issubset(share_get.keys()), msg)
 
+        if utils.is_microversion_supported('2.9'):
+            # Get share using v 2.9 - key 'export_location' is expected
+            # to be absent
+            share_get = self.shares_v2_client.get_share(
+                share['id'], version='2.9')
+            detailed_elements.remove('export_location')
+            self.assertTrue(detailed_elements.issubset(share_get.keys()), msg)
+
         # Delete share
         self.shares_v2_client.delete_share(share['id'])
         self.shares_v2_client.wait_for_resource_deletion(share_id=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 42a7589..f09cc6b 100644
--- a/manila_tempest_tests/tests/api/test_shares_actions.py
+++ b/manila_tempest_tests/tests/api/test_shares_actions.py
@@ -82,11 +82,12 @@
         # verify keys
         expected_keys = [
             "status", "description", "links", "availability_zone",
-            "created_at", "export_location", "project_id",
-            "export_locations", "volume_type", "share_proto", "name",
+            "created_at", "project_id", "volume_type", "share_proto", "name",
             "snapshot_id", "id", "size", "share_network_id", "metadata",
             "host", "snapshot_id", "is_public",
         ]
+        if utils.is_microversion_lt(version, '2.9'):
+            expected_keys.extend(["export_location", "export_locations"])
         if utils.is_microversion_ge(version, '2.2'):
             expected_keys.append("snapshot_support")
         if utils.is_microversion_ge(version, '2.4'):
@@ -131,10 +132,15 @@
         self._get_share('2.6')
 
     @test.attr(type=["gate", ])
+    @utils.skip_if_microversion_not_supported('2.9')
+    def test_get_share_export_locations_removed(self):
+        self._get_share('2.9')
+
+    @test.attr(type=["gate", ])
     def test_list_shares(self):
 
         # list shares
-        shares = self.shares_client.list_shares()
+        shares = self.shares_v2_client.list_shares()
 
         # verify keys
         keys = ["name", "id", "links"]
@@ -155,11 +161,12 @@
         # verify keys
         keys = [
             "status", "description", "links", "availability_zone",
-            "created_at", "export_location", "project_id",
-            "export_locations", "volume_type", "share_proto", "name",
+            "created_at", "project_id", "volume_type", "share_proto", "name",
             "snapshot_id", "id", "size", "share_network_id", "metadata",
             "host", "snapshot_id", "is_public", "share_type",
         ]
+        if utils.is_microversion_lt(version, '2.9'):
+            keys.extend(["export_location", "export_locations"])
         if utils.is_microversion_ge(version, '2.2'):
             keys.append("snapshot_support")
         if utils.is_microversion_ge(version, '2.4'):
@@ -195,6 +202,11 @@
         self._list_shares_with_detail('2.6')
 
     @test.attr(type=["gate", ])
+    @utils.skip_if_microversion_not_supported('2.9')
+    def test_list_shares_with_detail_export_locations_removed(self):
+        self._list_shares_with_detail('2.9')
+
+    @test.attr(type=["gate", ])
     def test_list_shares_with_detail_filter_by_metadata(self):
         filters = {'metadata': self.metadata}
 
diff --git a/manila_tempest_tests/tests/scenario/manager_share.py b/manila_tempest_tests/tests/scenario/manager_share.py
index 51e65ca..3a942e0 100644
--- a/manila_tempest_tests/tests/scenario/manager_share.py
+++ b/manila_tempest_tests/tests/scenario/manager_share.py
@@ -38,6 +38,7 @@
 
         # Manila clients
         cls.shares_client = clients_share.Manager().shares_client
+        cls.shares_v2_client = clients_share.Manager().shares_v2_client
         cls.shares_admin_client = clients_share.AdminManager().shares_client
         cls.shares_admin_v2_client = (
             clients_share.AdminManager().shares_v2_client)
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 7de8870..fe66787 100644
--- a/manila_tempest_tests/tests/scenario/test_share_basic_ops.py
+++ b/manila_tempest_tests/tests/scenario/test_share_basic_ops.py
@@ -20,6 +20,7 @@
 from tempest_lib import exceptions
 
 from manila_tempest_tests.tests.scenario import manager_share as manager
+from manila_tempest_tests import utils
 
 CONF = config.CONF
 
@@ -47,7 +48,7 @@
         if not hasattr(self, 'flavor_ref'):
             self.flavor_ref = CONF.share.client_vm_flavor_ref
         if CONF.share.image_with_share_tools:
-            images = self.images_client.list_images()["images"]
+            images = self.compute_images_client.list_images()["images"]
             for img in images:
                 if img["name"] == CONF.share.image_with_share_tools:
                     self.image_ref = img['id']
@@ -68,12 +69,12 @@
         create_kwargs = {
             'key_name': self.keypair['name'],
             'security_groups': security_groups,
+            'wait_until': 'ACTIVE',
         }
         if CONF.share.multitenancy_enabled:
             create_kwargs['networks'] = [{'uuid': self.net['id']}, ]
-        instance = self.create_server(image=self.image_ref,
-                                      create_kwargs=create_kwargs,
-                                      flavor=self.flavor_ref)
+        instance = self.create_server(
+            image_id=self.image_ref, flavor=self.flavor_ref, **create_kwargs)
         return instance
 
     def init_ssh(self, instance, do_ping=False):
@@ -190,6 +191,9 @@
         instance1 = self.boot_instance()
         self.allow_access_ip(self.share['id'], instance=instance1)
         ssh_client_inst1 = self.init_ssh(instance1)
+
+        # TODO(vponomaryov): use separate API for getting export location for
+        # share when "v2" client is used.
         first_location = self.share['export_locations'][0]
         self.mount_share(first_location, ssh_client_inst1)
         self.addCleanup(self.umount_share,
@@ -235,12 +239,13 @@
 
         dest_pool = dest_pool['name']
 
-        old_export_location = share['export_locations'][0]
-
         instance1 = self.boot_instance()
         self.allow_access_ip(self.share['id'], instance=instance1,
                              cleanup=False)
         ssh_client = self.init_ssh(instance1)
+
+        # TODO(vponomaryov): use separate API for getting export location for
+        # share when "v2" client is used.
         first_location = self.share['export_locations'][0]
         self.mount_share(first_location, ssh_client)
 
@@ -266,12 +271,19 @@
         self.umount_share(ssh_client)
 
         share = self.migrate_share(share['id'], dest_pool)
+        if utils.is_microversion_supported("2.9"):
+            second_location = (
+                self.shares_v2_client.list_share_export_locations(
+                    share['id'])[0]['path'])
+        else:
+            # NOTE(vponomaryov): following approach is valid for picking up
+            # export location only using microversions lower than '2.9'.
+            second_location = share['export_locations'][0]
 
         self.assertEqual(dest_pool, share['host'])
-        self.assertNotEqual(old_export_location, share['export_locations'][0])
+        self.assertNotEqual(first_location, second_location)
         self.assertEqual('migration_success', share['task_state'])
 
-        second_location = share['export_locations'][0]
         self.mount_share(second_location, ssh_client)
 
         output = ssh_client.exec_command("ls -lRA --ignore=lost+found /mnt")