Fix availability zones tests

Whenever creating a resource in an availability zone,
the positive test cases must ensure that the AZ supports
the characteristics needed by the resource.

Add a new helper method to filter AZs by share types
to facilitate such a check.

Change-Id: Ia721c434ceae5f02fc51bef5ec48b356da0de98d
Closes-Bug: #1811739
diff --git a/manila_tempest_tests/tests/api/admin/test_replication.py b/manila_tempest_tests/tests/api/admin/test_replication.py
index 2837dad..a0c0d84 100644
--- a/manila_tempest_tests/tests/api/admin/test_replication.py
+++ b/manila_tempest_tests/tests/api/admin/test_replication.py
@@ -41,14 +41,16 @@
             raise share_exceptions.ShareReplicationTypeException(
                 replication_type=cls.replication_type
             )
-        cls.zones = cls.get_availability_zones(client=cls.admin_client)
-        cls.share_zone = cls.zones[0]
-        cls.replica_zone = cls.zones[-1]
 
         extra_specs = {"replication_type": cls.replication_type}
         cls.share_type = cls._create_share_type(extra_specs)
         cls.share_type_id = cls.share_type['id']
 
+        cls.zones = cls.get_availability_zones_matching_share_type(
+            cls.share_type, client=cls.admin_client)
+        cls.share_zone = cls.zones[0]
+        cls.replica_zone = cls.zones[-1]
+
         # Create share with above share_type
         cls.share = cls.create_share(share_type_id=cls.share_type_id,
                                      availability_zone=cls.share_zone,
@@ -71,7 +73,8 @@
             raise self.skipException(
                 msg % ','.join(constants.REPLICATION_PROMOTION_CHOICES))
         share = self.create_share(
-            share_type_id=self.share_type_id, client=self.admin_client)
+            share_type_id=self.share_type_id, client=self.admin_client,
+            availability_zone=self.share_zone)
         original_replica = self.admin_client.list_share_replicas(
             share_id=share['id'])[0]
 
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 069f400..a278751 100644
--- a/manila_tempest_tests/tests/api/admin/test_replication_actions.py
+++ b/manila_tempest_tests/tests/api/admin/test_replication_actions.py
@@ -42,14 +42,17 @@
             raise share_exceptions.ShareReplicationTypeException(
                 replication_type=cls.replication_type
             )
-        cls.zones = cls.get_availability_zones(client=cls.admin_client)
-        cls.share_zone = cls.zones[0]
-        cls.replica_zone = cls.zones[-1]
 
         # create share type
         extra_specs = {"replication_type": cls.replication_type}
         cls.share_type = cls._create_share_type(extra_specs)
         cls.share_type_id = cls.share_type['id']
+
+        cls.zones = cls.get_availability_zones_matching_share_type(
+            cls.share_type, client=cls.admin_client)
+        cls.share_zone = cls.zones[0]
+        cls.replica_zone = cls.zones[-1]
+
         # create share
         cls.share = cls.create_share(size=CONF.share.share_size + 1,
                                      share_type_id=cls.share_type_id,
diff --git a/manila_tempest_tests/tests/api/base.py b/manila_tempest_tests/tests/api/base.py
index a4892a8..fefdc81 100644
--- a/manila_tempest_tests/tests/api/base.py
+++ b/manila_tempest_tests/tests/api/base.py
@@ -687,18 +687,56 @@
         return sg_snapshot
 
     @classmethod
-    def get_availability_zones(cls, client=None):
+    def get_availability_zones(cls, client=None, backends=None):
         """List the availability zones for "manila-share" services
 
          that are currently in "up" state.
          """
-        client = client or cls.shares_v2_client
+        client = client or cls.admin_shares_v2_client
+        backends = (
+            '|'.join(['^%s$' % backend for backend in backends])
+            if backends else '.*'
+        )
         cls.services = client.list_services()
         zones = [service['zone'] for service in cls.services if
-                 service['binary'] == "manila-share" and
-                 service['state'] == 'up']
+                 service['binary'] == 'manila-share' and
+                 service['state'] == 'up' and
+                 re.search(backends, service['host'])]
         return zones
 
+    @classmethod
+    def get_pools_matching_share_type(cls, share_type, client=None):
+        client = client or cls.admin_shares_v2_client
+        if utils.is_microversion_supported('2.23'):
+            return client.list_pools(
+                search_opts={'share_type': share_type['id']})['pools']
+
+        pools = client.list_pools(detail=True)['pools']
+        share_type = client.get_share_type(share_type['id'])['share_type']
+        extra_specs = {}
+        for k, v in share_type['extra_specs'].items():
+            extra_specs[k] = (
+                True if six.text_type(v).lower() == 'true'
+                else False if six.text_type(v).lower() == 'false' else v
+            )
+        return [
+            pool for pool in pools if all(y in pool['capabilities'].items()
+                                          for y in extra_specs.items())
+        ]
+
+    @classmethod
+    def get_availability_zones_matching_share_type(cls, share_type,
+                                                   client=None):
+
+        client = client or cls.admin_shares_v2_client
+        pools_matching_share_type = cls.get_pools_matching_share_type(
+            share_type, client=client)
+        backends_matching_share_type = set(
+            [pool['name'].split("#")[0] for pool in pools_matching_share_type]
+        )
+        azs = cls.get_availability_zones(backends=backends_matching_share_type)
+        return azs
+
     def get_pools_for_replication_domain(self):
         # Get the list of pools for the replication domain
         pools = self.admin_client.list_pools(detail=True)['pools']
diff --git a/manila_tempest_tests/tests/api/test_replication.py b/manila_tempest_tests/tests/api/test_replication.py
index 589f47c..41ad287 100644
--- a/manila_tempest_tests/tests/api/test_replication.py
+++ b/manila_tempest_tests/tests/api/test_replication.py
@@ -46,10 +46,6 @@
             raise share_exceptions.ShareReplicationTypeException(
                 replication_type=cls.replication_type
             )
-        cls.zones = cls.get_availability_zones(client=cls.admin_client)
-        cls.share_zone = cls.zones[0]
-        cls.replica_zone = cls.zones[-1]
-
         cls.extra_specs = cls.add_extra_specs_to_dict(
             {"replication_type": cls.replication_type})
         share_type = cls.create_share_type(
@@ -57,6 +53,12 @@
             extra_specs=cls.extra_specs,
             client=cls.admin_client)
         cls.share_type = share_type["share_type"]
+
+        cls.zones = cls.get_availability_zones_matching_share_type(
+            cls.share_type, client=cls.admin_client)
+        cls.share_zone = cls.zones[0]
+        cls.replica_zone = cls.zones[-1]
+
         # Create share with above share_type
         cls.creation_data = {'kwargs': {
             'share_type_id': cls.share_type['id'],
@@ -309,10 +311,6 @@
             raise share_exceptions.ShareReplicationTypeException(
                 replication_type=cls.replication_type
             )
-        cls.zones = cls.get_availability_zones(client=cls.admin_client)
-        cls.share_zone = cls.zones[0]
-        cls.replica_zone = cls.zones[-1]
-
         cls.extra_specs = cls.add_extra_specs_to_dict(
             {"replication_type": cls.replication_type})
         share_type = cls.create_share_type(
@@ -320,6 +318,12 @@
             extra_specs=cls.extra_specs,
             client=cls.admin_client)
         cls.share_type = share_type["share_type"]
+
+        cls.zones = cls.get_availability_zones_matching_share_type(
+            cls.share_type, client=cls.admin_client)
+        cls.share_zone = cls.zones[0]
+        cls.replica_zone = cls.zones[-1]
+
         # Create share with above share_type
         cls.creation_data = {'kwargs': {
             'share_type_id': cls.share_type['id'],
diff --git a/manila_tempest_tests/tests/api/test_replication_negative.py b/manila_tempest_tests/tests/api/test_replication_negative.py
index 7b596fb..30feeb6 100644
--- a/manila_tempest_tests/tests/api/test_replication_negative.py
+++ b/manila_tempest_tests/tests/api/test_replication_negative.py
@@ -42,15 +42,17 @@
             raise share_exceptions.ShareReplicationTypeException(
                 replication_type=cls.replication_type
             )
-        cls.zones = cls.get_availability_zones(client=cls.admin_client)
-        cls.share_zone = cls.zones[0]
-        cls.replica_zone = cls.zones[-1]
 
         # create share type
         extra_specs = {"replication_type": cls.replication_type}
         cls.share_type = cls._create_share_type(extra_specs)
         cls.share_type_id = cls.share_type['id']
 
+        cls.zones = cls.get_availability_zones_matching_share_type(
+            cls.share_type, client=cls.admin_client)
+        cls.share_zone = cls.zones[0]
+        cls.replica_zone = cls.zones[-1]
+
         # create share with above share_type
         cls.share1, cls.instance_id1 = cls._create_share_get_instance()
 
diff --git a/manila_tempest_tests/tests/api/test_replication_snapshots.py b/manila_tempest_tests/tests/api/test_replication_snapshots.py
index 773f74a..e1902f7 100644
--- a/manila_tempest_tests/tests/api/test_replication_snapshots.py
+++ b/manila_tempest_tests/tests/api/test_replication_snapshots.py
@@ -42,19 +42,16 @@
             raise share_exceptions.ShareReplicationTypeException(
                 replication_type=cls.replication_type
             )
-        cls.zones = cls.get_availability_zones(client=cls.admin_client)
-        cls.share_zone = cls.zones[0]
-        cls.replica_zone = cls.zones[-1]
 
         # create share type
         extra_specs = {"replication_type": cls.replication_type}
         cls.share_type = cls._create_share_type(extra_specs)
         cls.share_type_id = cls.share_type['id']
-        # Create share with above share_type
-        cls.creation_data = {'kwargs': {
-            'share_type_id': cls.share_type_id,
-            'availability_zone': cls.share_zone,
-        }}
+
+        cls.zones = cls.get_availability_zones_matching_share_type(
+            cls.share_type, client=cls.admin_client)
+        cls.share_zone = cls.zones[0]
+        cls.replica_zone = cls.zones[-1]
 
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
     def test_snapshot_after_share_replica(self):
diff --git a/manila_tempest_tests/tests/api/test_revert_to_snapshot.py b/manila_tempest_tests/tests/api/test_revert_to_snapshot.py
index 156a396..c4b72a0 100644
--- a/manila_tempest_tests/tests/api/test_revert_to_snapshot.py
+++ b/manila_tempest_tests/tests/api/test_revert_to_snapshot.py
@@ -78,10 +78,6 @@
                 raise share_exceptions.ShareReplicationTypeException(
                     replication_type=cls.replication_type
                 )
-            cls.zones = cls.get_availability_zones(client=cls.admin_client)
-            cls.share_zone = cls.zones[0]
-            cls.replica_zone = cls.zones[-1]
-
             extra_specs = cls.add_extra_specs_to_dict({
                 "replication_type": cls.replication_type,
                 constants.REVERT_TO_SNAPSHOT_SUPPORT: True,
@@ -91,6 +87,10 @@
                 extra_specs=extra_specs,
                 client=cls.admin_client)
             cls.replicated_share_type = share_type["share_type"]
+            cls.zones = cls.get_availability_zones_matching_share_type(
+                cls.replicated_share_type, client=cls.admin_client)
+            cls.share_zone = cls.zones[0]
+            cls.replica_zone = cls.zones[-1]
 
     @tc.attr(base.TAG_POSITIVE, base.TAG_BACKEND)
     @ddt.data(
diff --git a/manila_tempest_tests/tests/api/test_share_groups.py b/manila_tempest_tests/tests/api/test_share_groups.py
index f438732..4e8499f 100644
--- a/manila_tempest_tests/tests/api/test_share_groups.py
+++ b/manila_tempest_tests/tests/api/test_share_groups.py
@@ -195,7 +195,8 @@
     def test_create_sg_and_share_specifying_az(self, where_specify_az):
         # Get list of existing availability zones, at least one always
         # should exist
-        azs = self.shares_v2_client.list_availability_zones()
+        azs = self.get_availability_zones_matching_share_type(
+            self.share_type)
 
         sg_kwargs = {
             'share_group_type_id': self.share_group_type_id,
@@ -204,7 +205,7 @@
             'cleanup_in_class': False,
         }
         if where_specify_az in ('sg', 'sg_and_share'):
-            sg_kwargs['availability_zone'] = azs[0]['name']
+            sg_kwargs['availability_zone'] = azs[0]
 
         # Create share group
         share_group = self.create_share_group(**sg_kwargs)
@@ -215,10 +216,9 @@
 
         self.assertIn('availability_zone', share_group)
         if where_specify_az in ('sg', 'sg_and_share'):
-            self.assertEqual(azs[0]['name'], share_group['availability_zone'])
+            self.assertEqual(azs[0], share_group['availability_zone'])
         else:
-            self.assertIn(
-                share_group['availability_zone'], [az['name'] for az in azs])
+            self.assertIn(share_group['availability_zone'], azs)
 
         # Test 'consistent_snapshot_support' as part of 2.33 API change
         self.assertIn('consistent_snapshot_support', share_group)
@@ -233,7 +233,7 @@
             'experimental': True,
         }
         if where_specify_az == 'sg_and_share':
-            s_kwargs['availability_zone'] = azs[0]['name']
+            s_kwargs['availability_zone'] = azs[0]
 
         # Create share in share group
         share = self.create_share(**s_kwargs)