Use nose skip exception conditionally
testtools and nose disagree on the exception raised for skipping
tests with python < 2.7 (see inline comments for exact details).
This monkey-patches testtools to recognise the nose skip exception.
However, due to nose being deprecated we hide this behind an
environment variable to make it an opt-in fix.
While we're there, modify tempest.test.api.utils @skip_unless_attr
decorator to raise from tempest's BaseTestCase rather than
testtools.TestCase directly.
Change-Id: I13a8f374e879799870bc9193a1ddbdc8d6abb73c
diff --git a/tempest/api/utils.py b/tempest/api/utils.py
index 0738201..69ab7fb 100644
--- a/tempest/api/utils.py
+++ b/tempest/api/utils.py
@@ -17,7 +17,7 @@
"""Common utilities used in testing."""
-from testtools import TestCase
+from tempest.test import BaseTestCase
class skip_unless_attr(object):
@@ -32,7 +32,7 @@
"""Wrapped skipper function."""
testobj = args[0]
if not getattr(testobj, self.attr, False):
- raise TestCase.skipException(self.message)
+ raise BaseTestCase.skipException(self.message)
func(*args, **kw)
_skipper.__name__ = func.__name__
_skipper.__doc__ = func.__doc__
diff --git a/tempest/test.py b/tempest/test.py
index d7008a7..2e93056 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -15,6 +15,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import os
import time
import nose.plugins.attrib
@@ -54,6 +55,42 @@
return decorator
+# there is a mis-match between nose and testtools for older pythons.
+# testtools will set skipException to be either
+# unittest.case.SkipTest, unittest2.case.SkipTest or an internal skip
+# exception, depending on what it can find. Python <2.7 doesn't have
+# unittest.case.SkipTest; so if unittest2 is not installed it falls
+# back to the internal class.
+#
+# The current nose skip plugin will decide to raise either
+# unittest.case.SkipTest or its own internal exception; it does not
+# look for unittest2 or the internal unittest exception. Thus we must
+# monkey-patch testtools.TestCase.skipException to be the exception
+# the nose skip plugin expects.
+#
+# However, with the switch to testr nose may not be available, so we
+# require you to opt-in to this fix with an environment variable.
+#
+# This is temporary until upstream nose starts looking for unittest2
+# as testtools does; we can then remove this and ensure unittest2 is
+# available for older pythons; then nose and testtools will agree
+# unittest2.case.SkipTest is the one-true skip test exception.
+#
+# https://review.openstack.org/#/c/33056
+# https://github.com/nose-devs/nose/pull/699
+if 'TEMPEST_PY26_NOSE_COMPAT' in os.environ:
+ try:
+ import unittest.case.SkipTest
+ # convince pep8 we're using the import...
+ if unittest.case.SkipTest:
+ pass
+ raise RuntimeError("You have unittest.case.SkipTest; "
+ "no need to override")
+ except ImportError:
+ LOG.info("Overriding skipException to nose SkipTest")
+ testtools.TestCase.skipException = nose.plugins.skip.SkipTest
+
+
class BaseTestCase(testtools.TestCase,
testtools.testcase.WithAttributes,
testresources.ResourcedTestCase):