Add workaround to handle the testtool skip exception issue
stestr which is used by Tempest internally to run the test switch
the customize test runner(which use stdlib unittest) for >=py3.5
else testtools.run.- https://github.com/mtreinish/stestr/pull/265
These two test runner are not compatible due to skip exception
handling(due to unittest2). testtools.run treat unittestt.SkipTest
as error and stdlib unittest treat unittest2.case.SkipTest raised
by testtools.TestCase.skipException.
testtool issue: https://github.com/testing-cabal/testtools/issues/272
testtool is not so active now a days and fix is also not decided,
let's add a workaround in Tempest to make it work for both test runner
based on python version same as used by stestr
Tempest should work perfectly with stestr<2.5.0 also which is
also handled in this workaround.
Change-Id: Ie9c013d4d6851d4deef57c1e4c254a9a34374e5a
diff --git a/tempest/test.py b/tempest/test.py
index 85000b6..438f4d9 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -20,6 +20,7 @@
import debtcollector.moves
import fixtures
from oslo_log import log as logging
+import pkg_resources
import six
import testtools
@@ -77,6 +78,10 @@
atexit.register(validate_tearDownClass)
+class DummyException(Exception):
+ pass
+
+
class BaseTestCase(testtools.testcase.WithAttributes,
testtools.TestCase):
"""The test base class defines Tempest framework for class level fixtures.
@@ -140,6 +145,26 @@
cls._teardowns = []
@classmethod
+ def handle_skip_exception(cls):
+ try:
+ stestr_version = pkg_resources.parse_version(
+ pkg_resources.get_distribution("stestr").version)
+ stestr_min = pkg_resources.parse_version('2.5.0')
+ new_stestr = (stestr_version >= stestr_min)
+ import unittest
+ import unittest2
+ if sys.version_info >= (3, 5) and new_stestr:
+ exc = unittest2.case.SkipTest
+ exc_to_raise = unittest.case.SkipTest
+ else:
+ exc = unittest.case.SkipTest
+ exc_to_raise = unittest2.case.SkipTest
+ except Exception:
+ exc = DummyException
+ exc_to_raise = DummyException
+ return exc, exc_to_raise
+
+ @classmethod
def setUpClass(cls):
cls.__setupclass_called = True
# Reset state
@@ -148,11 +173,24 @@
if hasattr(super(BaseTestCase, cls), 'setUpClass'):
super(BaseTestCase, cls).setUpClass()
# 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__)
+ # TODO(gmann): cls.handle_skip_exception is really workaround for
+ # testtools bug- https://github.com/testing-cabal/testtools/issues/272
+ # stestr which is used by Tempest internally to run the test switch
+ # the customize test runner(which use stdlib unittest) for >=py3.5
+ # else testtools.run.- https://github.com/mtreinish/stestr/pull/265
+ # These two test runner are not compatible due to skip exception
+ # handling(due to unittest2). testtools.run treat unittestt.SkipTest
+ # as error and stdlib unittest treat unittest2.case.SkipTest raised
+ # by testtools.TestCase.skipException.
+ # The below workaround can be removed once testtools fix issue# 272.
try:
+ exc, exc_to_raise = cls.handle_skip_exception()
+ 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__)
# Allocation of all required credentials and client managers
cls._teardowns.append(('credentials', cls.clear_credentials))
cls.setup_credentials()
@@ -164,6 +202,8 @@
# Additional class-wide test resources
cls._teardowns.append(('resources', cls.resource_cleanup))
cls.resource_setup()
+ except exc as e:
+ raise exc_to_raise(e.args)
except Exception:
etype, value, trace = sys.exc_info()
LOG.info("%s raised in %s.setUpClass. Invoking tearDownClass.",
diff --git a/tempest/tests/test_test.py b/tempest/tests/test_test.py
index fc50736..ad0793c 100644
--- a/tempest/tests/test_test.py
+++ b/tempest/tests/test_test.py
@@ -531,8 +531,8 @@
def test_skip_only(self):
# If a skip condition is hit in the test, no credentials or resource
# is provisioned / cleaned-up
- self.mocks['skip_checks'].side_effect = (
- testtools.testcase.TestSkipped())
+ exc, _ = test.BaseTestCase.handle_skip_exception()
+ self.mocks['skip_checks'].side_effect = (exc)
suite = unittest.TestSuite((self.test,))
log = []
result = LoggingTestResult(log)