Merge "Update .mailmap email addresses"
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index bf46320..7a3bfdf 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -209,17 +209,19 @@
         az_name = data_utils.rand_name(self.az_name_prefix)
         aggregate = self._create_test_aggregate(availability_zone=az_name)
 
-        # Find a host that has not been added to other zone,
-        # for one host can't be added to different zones.
+        # Find a host that has not been added to other availability zone,
+        # for one host can't be added to different availability zones.
         aggregates = self.client.list_aggregates()['aggregates']
         hosts_in_zone = []
-        for v in aggregates:
-            if v['availability_zone']:
-                hosts_in_zone.extend(v['hosts'])
+        for agg in aggregates:
+            if agg['availability_zone']:
+                hosts_in_zone.extend(agg['hosts'])
         hosts = [v for v in self.hosts_available if v not in hosts_in_zone]
         if not hosts:
-            raise self.skipException("All hosts are already in other zones, "
-                                     "so can't add host to aggregate.")
+            raise self.skipException("All hosts are already in other "
+                                     "availability zones, so can't add "
+                                     "host to aggregate. \nAggregates list: "
+                                     "%s" % aggregates)
         host = hosts[0]
 
         self.client.add_host(aggregate['id'], host=host)
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index 8350f7c..5a60dc6 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -29,13 +29,11 @@
 LOG = logging.getLogger(__name__)
 
 
-class LiveMigrationTest(base.BaseV2ComputeAdminTest):
-    max_microversion = '2.24'
-    block_migration = None
+class LiveMigrationTestBase(base.BaseV2ComputeAdminTest):
 
     @classmethod
     def skip_checks(cls):
-        super(LiveMigrationTest, cls).skip_checks()
+        super(LiveMigrationTestBase, cls).skip_checks()
 
         if not CONF.compute_feature_enabled.live_migration:
             skip_msg = ("%s skipped as live-migration is "
@@ -55,11 +53,11 @@
         # TODO(mriedem): SSH validation before and after the instance is
         # live migrated would be a nice test wrinkle addition.
         cls.set_network_resources(network=True, subnet=True)
-        super(LiveMigrationTest, cls).setup_credentials()
+        super(LiveMigrationTestBase, cls).setup_credentials()
 
     @classmethod
     def setup_clients(cls):
-        super(LiveMigrationTest, cls).setup_clients()
+        super(LiveMigrationTestBase, cls).setup_clients()
         cls.admin_migration_client = cls.os_admin.migrations_client
 
     def _migrate_server_to(self, server_id, dest_host, volume_backed=False):
@@ -91,6 +89,11 @@
         self.assertEqual(target_host, self.get_host_for_server(server_id),
                          msg)
 
+
+class LiveMigrationTest(LiveMigrationTestBase):
+    max_microversion = '2.24'
+    block_migration = None
+
     def _test_live_migration(self, state='ACTIVE', volume_backed=False):
         """Tests live migration between two hosts.
 
@@ -168,7 +171,7 @@
         self.assertEqual(volume_id1, volume_id2)
 
 
-class LiveMigrationRemoteConsolesV26Test(LiveMigrationTest):
+class LiveMigrationRemoteConsolesV26Test(LiveMigrationTestBase):
     min_microversion = '2.6'
     max_microversion = 'latest'
 
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 50691ad..6c2fee8 100644
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -279,6 +279,9 @@
     if not results.get(service):
         results[service] = {}
     extensions_opt = get_enabled_extensions(service)
+    if not extensions_opt:
+        LOG.info("'%s' has no api_extensions set.", service)
+        return results
     if extensions_opt[0] == 'all':
         results[service]['extensions'] = extensions
         return results
diff --git a/tempest/config.py b/tempest/config.py
index 8314e1e..a8a3bc3 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -470,7 +470,7 @@
                      "entry 'all' indicates all filters that are included "
                      "with nova are enabled. Empty list indicates all filters "
                      "are disabled. The full list of available filters is in "
-                     "nova.conf: DEFAULT.scheduler_available_filters. If the "
+                     "nova.conf: filter_scheduler.enabled_filters. If the "
                      "default value is overridden in nova.conf by the test "
                      "environment (which means that a different set of "
                      "filters is enabled than what is included in Nova by "
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 32d6224..c260343 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -343,6 +343,24 @@
         self.assertEqual(sorted(['fake1', 'fake2', 'not_fake']),
                          sorted(results['neutron']['extensions']))
 
+    def test_verify_extensions_neutron_none(self):
+        def fake_list_extensions():
+            return {'extensions': []}
+        fake_os = mock.MagicMock()
+        fake_client = mock.MagicMock()
+        fake_client.list_extensions = fake_list_extensions
+        self.useFixture(fixtures.MockPatchObject(
+            verify_tempest_config, 'get_extension_client',
+            return_value=fake_client))
+        self.useFixture(fixtures.MockPatchObject(
+            verify_tempest_config, 'get_enabled_extensions',
+            return_value=(['all'])))
+        results = verify_tempest_config.verify_extensions(fake_os,
+                                                          'neutron', {})
+        self.assertIn('neutron', results)
+        self.assertIn('extensions', results['neutron'])
+        self.assertEqual([], results['neutron']['extensions'])
+
     def test_verify_extensions_cinder(self):
         def fake_list_extensions():
             return {'extensions': [{'alias': 'fake1'},
@@ -391,6 +409,24 @@
         self.assertEqual(sorted(['fake1', 'fake2', 'not_fake']),
                          sorted(results['cinder']['extensions']))
 
+    def test_verify_extensions_cinder_none(self):
+        def fake_list_extensions():
+            return {'extensions': []}
+        fake_os = mock.MagicMock()
+        fake_client = mock.MagicMock()
+        fake_client.list_extensions = fake_list_extensions
+        self.useFixture(fixtures.MockPatchObject(
+            verify_tempest_config, 'get_extension_client',
+            return_value=fake_client))
+        self.useFixture(fixtures.MockPatchObject(
+            verify_tempest_config, 'get_enabled_extensions',
+            return_value=(['all'])))
+        results = verify_tempest_config.verify_extensions(fake_os,
+                                                          'cinder', {})
+        self.assertIn('cinder', results)
+        self.assertIn('extensions', results['cinder'])
+        self.assertEqual([], results['cinder']['extensions'])
+
     def test_verify_extensions_nova(self):
         def fake_list_extensions():
             return ([{'alias': 'fake1'}, {'alias': 'fake2'},
@@ -437,6 +473,24 @@
         self.assertEqual(sorted(['fake1', 'fake2', 'not_fake']),
                          sorted(results['nova']['extensions']))
 
+    def test_verify_extensions_nova_none(self):
+        def fake_list_extensions():
+            return ({'extensions': []})
+        fake_os = mock.MagicMock()
+        fake_client = mock.MagicMock()
+        fake_client.list_extensions = fake_list_extensions
+        self.useFixture(fixtures.MockPatchObject(
+            verify_tempest_config, 'get_extension_client',
+            return_value=fake_client))
+        self.useFixture(fixtures.MockPatchObject(
+            verify_tempest_config, 'get_enabled_extensions',
+            return_value=(['all'])))
+        results = verify_tempest_config.verify_extensions(fake_os,
+                                                          'nova', {})
+        self.assertIn('nova', results)
+        self.assertIn('extensions', results['nova'])
+        self.assertEqual([], results['nova']['extensions'])
+
     def test_verify_extensions_swift(self):
         def fake_list_extensions():
             return {'fake1': 'metadata',
@@ -485,6 +539,24 @@
         self.assertEqual(sorted(['not_fake', 'fake1', 'fake2']),
                          sorted(results['swift']['extensions']))
 
+    def test_verify_extensions_swift_none(self):
+        def fake_list_extensions():
+            return {'swift': 'metadata'}
+        fake_os = mock.MagicMock()
+        fake_client = mock.MagicMock()
+        fake_client.list_capabilities = fake_list_extensions
+        self.useFixture(fixtures.MockPatchObject(
+            verify_tempest_config, 'get_extension_client',
+            return_value=fake_client))
+        self.useFixture(fixtures.MockPatchObject(
+            verify_tempest_config, 'get_enabled_extensions',
+            return_value=(['all'])))
+        results = verify_tempest_config.verify_extensions(fake_os,
+                                                          'swift', {})
+        self.assertIn('swift', results)
+        self.assertIn('extensions', results['swift'])
+        self.assertEqual([], results['swift']['extensions'])
+
     def test_get_extension_client(self):
         creds = credentials_factory.get_credentials(
             fill_in=False, username='fake_user', project_name='fake_project',