Make skip_checks and setup_creds safe

The skip_checks and setup_credentials "fixtures" are implemented
in the base class. The implementation can be extended by test
classes but it should not be overwritten.

Enforcing this by checking that the base class version has been
invoked. Added unit tests for it as well.

Change-Id: Ie5d994519f9d56de423d1a0bede7ee8d703b9390
diff --git a/tempest/test.py b/tempest/test.py
index ce977fa..434c58b 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -132,6 +132,7 @@
     def _reset_class(cls):
         cls.__setup_credentials_called = False
         cls.__resource_cleaup_called = False
+        cls.__skip_checks_called = False
         cls._class_cleanups = []
 
     @classmethod
@@ -146,10 +147,16 @@
         cls.teardowns = []
         # All the configuration checks that may generate a skip
         cls.skip_checks()
+        if not cls.__skip_checks_called:
+            raise RuntimeError("skip_checks for %s did not call the super's "
+                               "skip_checks" % cls.__name__)
         try:
             # Allocation of all required credentials and client managers
             cls.teardowns.append(('credentials', cls.clear_credentials))
             cls.setup_credentials()
+            if not cls.__setup_credentials_called:
+                raise RuntimeError("setup_credentials for %s did not call the "
+                                   "super's setup_credentials" % cls.__name__)
             # Shortcuts to clients
             cls.setup_clients()
             # Additional class-wide test resources
@@ -245,6 +252,7 @@
         If one is really needed it may be implemented either in the
         resource_setup or at test level.
         """
+        cls.__skip_checks_called = True
         identity_version = cls.get_identity_version()
         # setting force_tenant_isolation to True also needs admin credentials.
         if ('admin' in cls.credentials or
diff --git a/tempest/tests/test_test.py b/tempest/tests/test_test.py
index f2c28a6..42e213e 100644
--- a/tempest/tests/test_test.py
+++ b/tempest/tests/test_test.py
@@ -332,3 +332,48 @@
         found_exc = log[0][1][1]
         self.assertTrue(isinstance(found_exc, RuntimeError))
         self.assertIn(BadResourceCleanup.__name__, str(found_exc))
+
+    def test_super_skip_checks_not_invoked(self):
+
+        class BadSkipChecks(self.parent_test):
+
+            @classmethod
+            def skip_checks(cls):
+                pass
+
+        bad_class = BadSkipChecks()
+        with testtools.ExpectedException(
+                RuntimeError,
+                value_re='^.* ' + BadSkipChecks.__name__):
+            bad_class.setUpClass()
+
+    def test_super_setup_credentials_not_invoked(self):
+
+        class BadSetupCredentials(self.parent_test):
+
+            @classmethod
+            def skip_checks(cls):
+                pass
+
+        bad_class = BadSetupCredentials()
+        with testtools.ExpectedException(
+                RuntimeError,
+                value_re='^.* ' + BadSetupCredentials.__name__):
+            bad_class.setUpClass()
+
+    def test_grandparent_skip_checks_not_invoked(self):
+
+        class BadSkipChecks(self.parent_test):
+
+            @classmethod
+            def skip_checks(cls):
+                pass
+
+        class SonOfBadSkipChecks(BadSkipChecks):
+            pass
+
+        bad_class = SonOfBadSkipChecks()
+        with testtools.ExpectedException(
+                RuntimeError,
+                value_re='^.* ' + SonOfBadSkipChecks.__name__):
+            bad_class.setUpClass()