Skip test early to improve memory footprint and time

When we skip the test class using skip_checks(), it check
the conditions and skip the test class at first step
without creating any keystone credentials. But when
tests are skipped with other decorator at test level then
it does create keystone credentials, setup network resources
and service clients.

Wehn all the tests in test class are skipped based on common
condition then it is better to skip them using the skip_check
so that we do not create any keystone, network resources which
will improve the DB queries keystone, neutron does and also
speed up the test skip.

Related-Bug: #2004780
Change-Id: Id5e6ddcb83aaa6133c28ef188183d98e26e4925b
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index 19026d3..a02820a 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -304,13 +304,17 @@
     min_microversion = '2.6'
     max_microversion = 'latest'
 
+    @classmethod
+    def skip_checks(cls):
+        super(LiveMigrationRemoteConsolesV26Test, cls).skip_checks()
+        if not CONF.compute_feature_enabled.serial_console:
+            skip_msg = ("Serial console not supported.")
+            raise cls.skipException(skip_msg)
+        if not compute.is_scheduler_filter_enabled("DifferentHostFilter"):
+            raise cls.skipException("DifferentHostFilter is not available.")
+
     @decorators.attr(type='multinode')
     @decorators.idempotent_id('6190af80-513e-4f0f-90f2-9714e84955d7')
-    @testtools.skipUnless(CONF.compute_feature_enabled.serial_console,
-                          'Serial console not supported.')
-    @testtools.skipUnless(
-        compute.is_scheduler_filter_enabled("DifferentHostFilter"),
-        'DifferentHostFilter is not available.')
     def test_live_migration_serial_console(self):
         """Test the live-migration of an instance which has a serial console
 
diff --git a/tempest/api/compute/admin/test_volume_swap.py b/tempest/api/compute/admin/test_volume_swap.py
index 36148c5..9576b74 100644
--- a/tempest/api/compute/admin/test_volume_swap.py
+++ b/tempest/api/compute/admin/test_volume_swap.py
@@ -13,7 +13,6 @@
 import time
 
 from tempest.api.compute import base
-from tempest.common import utils
 from tempest.common import waiters
 from tempest import config
 from tempest.lib import decorators
@@ -33,6 +32,8 @@
     @classmethod
     def skip_checks(cls):
         super(TestVolumeSwapBase, cls).skip_checks()
+        if not CONF.service_available.cinder:
+            raise cls.skipException("Cinder is not available")
         if not CONF.compute_feature_enabled.swap_volume:
             raise cls.skipException("Swapping volumes is not supported.")
 
@@ -81,7 +82,6 @@
     # so it's marked as such.
     @decorators.attr(type='slow')
     @decorators.idempotent_id('1769f00d-a693-4d67-a631-6a3496773813')
-    @utils.services('volume')
     def test_volume_swap(self):
         """Test swapping of volume attached to server with admin user
 
@@ -183,7 +183,6 @@
     # multiple computes but that would just side-step the underlying bug.
     @decorators.skip_because(bug='1807723',
                              condition=CONF.compute.min_compute_nodes > 1)
-    @utils.services('volume')
     def test_volume_swap_with_multiattach(self):
         """Test swapping volume attached to multiple servers
 
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index ce6cd60..9aa5d35 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -51,6 +51,9 @@
         super(BaseV2ComputeTest, cls).skip_checks()
         if not CONF.service_available.nova:
             raise cls.skipException("Nova is not available")
+        if cls.create_default_network and not CONF.service_available.neutron:
+            raise cls.skipException("Neutron is not available")
+
         api_version_utils.check_skip_with_microversion(
             cls.min_microversion, cls.max_microversion,
             CONF.compute.min_microversion, CONF.compute.max_microversion)
diff --git a/tempest/api/compute/images/test_image_metadata_negative.py b/tempest/api/compute/images/test_image_metadata_negative.py
index b9806c7..33a59ae 100644
--- a/tempest/api/compute/images/test_image_metadata_negative.py
+++ b/tempest/api/compute/images/test_image_metadata_negative.py
@@ -14,10 +14,13 @@
 #    under the License.
 
 from tempest.api.compute import base
+from tempest import config
 from tempest.lib.common.utils import data_utils
 from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 
+CONF = config.CONF
+
 
 class ImagesMetadataNegativeTestJSON(base.BaseV2ComputeTest):
     """Negative tests of image metadata
@@ -28,6 +31,13 @@
     max_microversion = '2.38'
 
     @classmethod
+    def skip_checks(cls):
+        super(ImagesMetadataNegativeTestJSON, cls).skip_checks()
+        if not CONF.service_available.glance:
+            skip_msg = ("%s skipped as glance is not available" % cls.__name__)
+            raise cls.skipException(skip_msg)
+
+    @classmethod
     def setup_clients(cls):
         super(ImagesMetadataNegativeTestJSON, cls).setup_clients()
         cls.client = cls.compute_images_client
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 3e54bf6..93c28af 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -810,9 +810,15 @@
 
     min_microversion = '2.47'
 
+    @classmethod
+    def skip_checks(cls):
+        if not CONF.service_available.glance:
+            skip_msg = ("%s skipped as glance is not available" % cls.__name__)
+            raise cls.skipException(skip_msg)
+        super(ServersAaction247Test, cls).skip_checks()
+
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting not available, backup not possible.')
-    @utils.services('image')
     @decorators.idempotent_id('252a4bdd-6366-4dae-9994-8c30aa660f23')
     def test_create_backup(self):
         server = self.create_test_server(wait_until='ACTIVE')
@@ -841,7 +847,6 @@
         cls.server_id = cls.recreate_server(None, volume_backed=True,
                                             validatable=True)
 
-    @utils.services('volume')
     @decorators.idempotent_id('6652dab9-ea24-4c93-ab5a-93d79c3041cf')
     def test_rebuild_volume_backed_server(self):
         """Test rebuilding a volume backed server"""
diff --git a/tempest/api/compute/servers/test_server_addresses.py b/tempest/api/compute/servers/test_server_addresses.py
index 5a3f5d0..978a9da 100644
--- a/tempest/api/compute/servers/test_server_addresses.py
+++ b/tempest/api/compute/servers/test_server_addresses.py
@@ -14,7 +14,6 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest.common import utils
 from tempest.lib import decorators
 
 
@@ -35,7 +34,6 @@
 
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('6eb718c0-02d9-4d5e-acd1-4e0c269cef39')
-    @utils.services('network')
     def test_list_server_addresses(self):
         """Test listing server address
 
@@ -52,7 +50,6 @@
 
     @decorators.attr(type='smoke')
     @decorators.idempotent_id('87bbc374-5538-4f64-b673-2b0e4443cc30')
-    @utils.services('network')
     def test_list_server_addresses_by_network(self):
         """Test listing server addresses filtered by network addresses
 
diff --git a/tempest/api/compute/servers/test_server_addresses_negative.py b/tempest/api/compute/servers/test_server_addresses_negative.py
index e7444d2..bb21594 100644
--- a/tempest/api/compute/servers/test_server_addresses_negative.py
+++ b/tempest/api/compute/servers/test_server_addresses_negative.py
@@ -14,7 +14,6 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest.common import utils
 from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 
@@ -35,7 +34,6 @@
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('02c3f645-2d2e-4417-8525-68c0407d001b')
-    @utils.services('network')
     def test_list_server_addresses_invalid_server_id(self):
         """List addresses request should fail if server id not in system"""
         self.assertRaises(lib_exc.NotFound, self.client.list_addresses,
@@ -43,7 +41,6 @@
 
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('a2ab5144-78c0-4942-a0ed-cc8edccfd9ba')
-    @utils.services('network')
     def test_list_server_addresses_by_network_neg(self):
         """List addresses by network should fail if network name not valid"""
         self.assertRaises(lib_exc.NotFound,
diff --git a/tempest/api/compute/test_tenant_networks.py b/tempest/api/compute/test_tenant_networks.py
index 17f4b80..da28b9b 100644
--- a/tempest/api/compute/test_tenant_networks.py
+++ b/tempest/api/compute/test_tenant_networks.py
@@ -14,8 +14,11 @@
 
 from tempest.api.compute import base
 from tempest.common import utils
+from tempest import config
 from tempest.lib import decorators
 
+CONF = config.CONF
+
 
 class ComputeTenantNetworksTest(base.BaseV2ComputeTest):
     """Test compute tenant networks API with microversion less than 2.36"""
@@ -23,6 +26,14 @@
     max_microversion = '2.35'
 
     @classmethod
+    def skip_checks(cls):
+        super(ComputeTenantNetworksTest, cls).skip_checks()
+        if not CONF.service_available.neutron:
+            skip_msg = (
+                "%s skipped as Neutron is not available" % cls.__name__)
+            raise cls.skipException(skip_msg)
+
+    @classmethod
     def resource_setup(cls):
         super(ComputeTenantNetworksTest, cls).resource_setup()
         cls.client = cls.os_primary.tenant_networks_client
diff --git a/tempest/api/identity/v3/test_users.py b/tempest/api/identity/v3/test_users.py
index dc6dd4a..b95bd75 100644
--- a/tempest/api/identity/v3/test_users.py
+++ b/tempest/api/identity/v3/test_users.py
@@ -31,6 +31,12 @@
     """Test identity user password"""
 
     @classmethod
+    def skip_checks(cls):
+        super(IdentityV3UsersTest, cls).skip_checks()
+        if not CONF.identity_feature_enabled.security_compliance:
+            raise cls.skipException("Security compliance not available.")
+
+    @classmethod
     def resource_setup(cls):
         super(IdentityV3UsersTest, cls).resource_setup()
         cls.creds = cls.os_primary.credentials
@@ -77,8 +83,6 @@
         time.sleep(1)
         self.non_admin_users_client.auth_provider.set_auth()
 
-    @testtools.skipUnless(CONF.identity_feature_enabled.security_compliance,
-                          'Security compliance not available.')
     @decorators.idempotent_id('ad71bd23-12ad-426b-bb8b-195d2b635f27')
     @testtools.skipIf(CONF.identity_feature_enabled.immutable_user_source,
                       'Skipped because environment has an '
@@ -107,8 +111,6 @@
                           user_id=self.user_id,
                           password=old_pass)
 
-    @testtools.skipUnless(CONF.identity_feature_enabled.security_compliance,
-                          'Security compliance not available.')
     @decorators.idempotent_id('941784ee-5342-4571-959b-b80dd2cea516')
     @testtools.skipIf(CONF.identity_feature_enabled.immutable_user_source,
                       'Skipped because environment has an '
@@ -142,8 +144,6 @@
         # A different password can be set
         self._update_password(original_password=new_pass1, password=new_pass2)
 
-    @testtools.skipUnless(CONF.identity_feature_enabled.security_compliance,
-                          'Security compliance not available.')
     @decorators.idempotent_id('a7ad8bbf-2cff-4520-8c1d-96332e151658')
     def test_user_account_lockout(self):
         """Test locking out user account after failure attempts"""
diff --git a/tempest/api/network/test_service_providers.py b/tempest/api/network/test_service_providers.py
index 5af5244..e203a2c 100644
--- a/tempest/api/network/test_service_providers.py
+++ b/tempest/api/network/test_service_providers.py
@@ -10,8 +10,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
-
 from tempest.api.network import base
 from tempest.common import utils
 from tempest.lib import decorators
@@ -20,10 +18,14 @@
 class ServiceProvidersTest(base.BaseNetworkTest):
     """Test network service providers"""
 
+    @classmethod
+    def skip_checks(cls):
+        super(ServiceProvidersTest, cls).skip_checks()
+        if not utils.is_extension_enabled('service-type', 'network'):
+            skip_msg = ("service-type extension not enabled.")
+            raise cls.skipException(skip_msg)
+
     @decorators.idempotent_id('2cbbeea9-f010-40f6-8df5-4eaa0c918ea6')
-    @testtools.skipUnless(
-        utils.is_extension_enabled('service-type', 'network'),
-        'service-type extension not enabled.')
     def test_service_providers_list(self):
         """Test listing network service providers"""
         body = self.service_providers_client.list_service_providers()
diff --git a/tempest/api/volume/admin/test_encrypted_volumes_extend.py b/tempest/api/volume/admin/test_encrypted_volumes_extend.py
index e85a00d..4506389 100644
--- a/tempest/api/volume/admin/test_encrypted_volumes_extend.py
+++ b/tempest/api/volume/admin/test_encrypted_volumes_extend.py
@@ -14,7 +14,6 @@
 
 from tempest.api.volume import base
 from tempest.api.volume import test_volumes_extend as extend
-from tempest.common import utils
 from tempest import config
 from tempest.lib import decorators
 
@@ -25,23 +24,25 @@
                                          base.BaseVolumeAdminTest):
     """Tests extending the size of an attached encrypted volume."""
 
+    @classmethod
+    def skip_checks(cls):
+        super(EncryptedVolumesExtendAttachedTest, cls).skip_checks()
+        if not CONF.service_available.nova:
+            skip_msg = ("%s skipped as Nova is not available" % cls.__name__)
+            raise cls.skipException(skip_msg)
+        if not CONF.volume_feature_enabled.extend_attached_encrypted_volume:
+            raise cls.skipException(
+                "Attached encrypted volume extend is disabled.")
+
     @decorators.idempotent_id('e93243ec-7c37-4b5b-a099-ebf052c13216')
-    @testtools.skipUnless(
-        CONF.volume_feature_enabled.extend_attached_encrypted_volume,
-        "Attached encrypted volume extend is disabled.")
-    @utils.services('compute')
     def test_extend_attached_encrypted_volume_luksv1(self):
         """LUKs v1 decrypts and extends through libvirt."""
         volume = self.create_encrypted_volume(encryption_provider="luks")
         self._test_extend_attached_volume(volume)
 
     @decorators.idempotent_id('381a2a3a-b2f4-4631-a910-720881f2cc2f')
-    @testtools.skipUnless(
-        CONF.volume_feature_enabled.extend_attached_encrypted_volume,
-        "Attached encrypted volume extend is disabled.")
     @testtools.skipIf(CONF.volume.storage_protocol == 'ceph',
                       'Ceph only supports LUKSv2 if doing host attach.')
-    @utils.services('compute')
     def test_extend_attached_encrypted_volume_luksv2(self):
         """LUKs v2 decrypts and extends through os-brick."""
         volume = self.create_encrypted_volume(encryption_provider="luks2")
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index a31390a..ad8f573 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -42,6 +42,10 @@
         if not CONF.service_available.cinder:
             skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
+        if cls.create_default_network and not CONF.service_available.neutron:
+            skip_msg = (
+                "%s skipped as Neutron is not available" % cls.__name__)
+            raise cls.skipException(skip_msg)
 
         api_version_utils.check_skip_with_microversion(
             cls.volume_min_microversion, cls.volume_max_microversion,
diff --git a/tempest/api/volume/test_volumes_extend.py b/tempest/api/volume/test_volumes_extend.py
index c5c94e1..c766db8 100644
--- a/tempest/api/volume/test_volumes_extend.py
+++ b/tempest/api/volume/test_volumes_extend.py
@@ -18,7 +18,6 @@
 import testtools
 
 from tempest.api.volume import base
-from tempest.common import utils
 from tempest.common import waiters
 from tempest import config
 from tempest.lib import decorators
@@ -181,10 +180,16 @@
 
 class VolumesExtendAttachedTest(BaseVolumesExtendAttachedTest):
 
+    @classmethod
+    def skip_checks(cls):
+        super(VolumesExtendAttachedTest, cls).skip_checks()
+        if not CONF.service_available.nova:
+            skip_msg = ("%s skipped as Nova is not available" % cls.__name__)
+            raise cls.skipException(skip_msg)
+        if not CONF.volume_feature_enabled.extend_attached_volume:
+            raise cls.skipException("Attached volume extend is disabled.")
+
     @decorators.idempotent_id('301f5a30-1c6f-4ea0-be1a-91fd28d44354')
-    @testtools.skipUnless(CONF.volume_feature_enabled.extend_attached_volume,
-                          "Attached volume extend is disabled.")
-    @utils.services('compute')
     def test_extend_attached_volume(self):
         volume = self.create_volume()
         self._test_extend_attached_volume(volume)
diff --git a/tempest/scenario/test_server_advanced_ops.py b/tempest/scenario/test_server_advanced_ops.py
index 990b325..1c2246d 100644
--- a/tempest/scenario/test_server_advanced_ops.py
+++ b/tempest/scenario/test_server_advanced_ops.py
@@ -14,7 +14,6 @@
 #    under the License.
 
 from oslo_log import log as logging
-import testtools
 
 from tempest.common import utils
 from tempest.common import waiters
@@ -36,14 +35,21 @@
     """
 
     @classmethod
+    def skip_checks(cls):
+        super(TestServerAdvancedOps, cls).skip_checks()
+        if not CONF.service_available.nova:
+            skip_msg = ("%s skipped as Nova is not available" % cls.__name__)
+            raise cls.skipException(skip_msg)
+        if not CONF.compute_feature_enabled.suspend:
+            raise cls.skipException("Suspend is not available.")
+
+    @classmethod
     def setup_credentials(cls):
         cls.set_network_resources(network=True, subnet=True)
         super(TestServerAdvancedOps, cls).setup_credentials()
 
     @decorators.attr(type='slow')
     @decorators.idempotent_id('949da7d5-72c8-4808-8802-e3d70df98e2c')
-    @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
-                          'Suspend is not available.')
     @utils.services('compute')
     def test_server_sequence_suspend_resume(self):
         # We create an instance for use in this test