Merge "Add workaround to handle the testtool skip exception in CLI test"
diff --git a/releasenotes/notes/fix-1847749-2670b1d4f6097a1a.yaml b/releasenotes/notes/fix-1847749-2670b1d4f6097a1a.yaml
new file mode 100644
index 0000000..d9ef626
--- /dev/null
+++ b/releasenotes/notes/fix-1847749-2670b1d4f6097a1a.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+ - |
+ Bug#1847749. This privides the workaround of Skip Exception raised instead of skipping
+ the CLI tests. If you are running Tempest with stestr > 2.5.0 then use this fix.
+ Ref- https://github.com/testing-cabal/testtools/issues/272
diff --git a/tempest/lib/base.py b/tempest/lib/base.py
index 3be55c0..74ae77c 100644
--- a/tempest/lib/base.py
+++ b/tempest/lib/base.py
@@ -14,11 +14,29 @@
# under the License.
import os
+import sys
import fixtures
+import pkg_resources
import testtools
+def _handle_skip_exception():
+ 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:
+ testtools.TestCase.skipException = unittest.case.SkipTest
+ else:
+ testtools.TestCase.skipException = unittest2.case.SkipTest
+ except Exception:
+ pass
+
+
class BaseTestCase(testtools.testcase.WithAttributes, testtools.TestCase):
setUpClassCalled = False
@@ -33,6 +51,18 @@
if hasattr(super(BaseTestCase, cls), 'setUpClass'):
super(BaseTestCase, cls).setUpClass()
cls.setUpClassCalled = True
+ # 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.
+ cls.orig_skip_exception = testtools.TestCase.skipException
+ _handle_skip_exception()
@classmethod
def tearDownClass(cls):
@@ -40,6 +70,7 @@
super(BaseTestCase, cls).tearDownClass()
def setUp(self):
+ testtools.TestCase.skipException = self.orig_skip_exception
super(BaseTestCase, self).setUp()
if not self.setUpClassCalled:
raise RuntimeError("setUpClass does not calls the super's "
diff --git a/tempest/test.py b/tempest/test.py
index 1e5cd19..f383bc1 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -20,7 +20,6 @@
import debtcollector.moves
import fixtures
from oslo_log import log as logging
-import pkg_resources
import six
import testtools
@@ -28,6 +27,7 @@
from tempest.common import credentials_factory as credentials
from tempest.common import utils
from tempest import config
+from tempest.lib import base as lib_base
from tempest.lib.common import fixed_network
from tempest.lib.common import profiler
from tempest.lib.common import validation_resources as vr
@@ -78,10 +78,6 @@
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.
@@ -145,26 +141,6 @@
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
@@ -183,8 +159,9 @@
# 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.
+ orig_skip_exception = testtools.TestCase.skipException
+ lib_base._handle_skip_exception()
try:
- exc, exc_to_raise = cls.handle_skip_exception()
cls.skip_checks()
if not cls.__skip_checks_called:
@@ -202,12 +179,6 @@
# Additional class-wide test resources
cls._teardowns.append(('resources', cls.resource_cleanup))
cls.resource_setup()
- except exc as e:
- # NOTE(dviroel): the exception may be raised after setting up the
- # user credentials, so we must call tearDownClass to release all
- # allocated resources.
- cls.tearDownClass()
- raise exc_to_raise(e.args)
except Exception:
etype, value, trace = sys.exc_info()
LOG.info("%s raised in %s.setUpClass. Invoking tearDownClass.",
@@ -217,6 +188,8 @@
six.reraise(etype, value, trace)
finally:
del trace # to avoid circular refs
+ finally:
+ testtools.TestCase.skipException = orig_skip_exception
@classmethod
def tearDownClass(cls):
diff --git a/tempest/tests/lib/test_base.py b/tempest/tests/lib/test_base.py
index 27cda1a..2c16e1c 100644
--- a/tempest/tests/lib/test_base.py
+++ b/tempest/tests/lib/test_base.py
@@ -48,6 +48,7 @@
@classmethod
def setUpClass(cls): # noqa
"""Simulate absence of super() call."""
+ cls.orig_skip_exception = cls.skipException
def setUp(self):
try:
diff --git a/tempest/tests/test_test.py b/tempest/tests/test_test.py
index a2e0efd..49fd010 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
- exc, _ = test.BaseTestCase.handle_skip_exception()
- self.mocks['skip_checks'].side_effect = (exc)
+ self.mocks['skip_checks'].side_effect = (
+ testtools.TestCase.skipException())
suite = unittest.TestSuite((self.test,))
log = []
result = LoggingTestResult(log)