| OLD | NEW |
| 1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. | 1 # copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
| 2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr | 2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
| 3 # | 3 # |
| 4 # This file is part of logilab-common. | 4 # This file is part of logilab-common. |
| 5 # | 5 # |
| 6 # logilab-common is free software: you can redistribute it and/or modify it unde
r | 6 # logilab-common is free software: you can redistribute it and/or modify it unde
r |
| 7 # the terms of the GNU Lesser General Public License as published by the Free | 7 # the terms of the GNU Lesser General Public License as published by the Free |
| 8 # Software Foundation, either version 2.1 of the License, or (at your option) an
y | 8 # Software Foundation, either version 2.1 of the License, or (at your option) an
y |
| 9 # later version. | 9 # later version. |
| 10 # | 10 # |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 | 112 |
| 113 ENABLE_DBC = False | 113 ENABLE_DBC = False |
| 114 FILE_RESTART = ".pytest.restart" | 114 FILE_RESTART = ".pytest.restart" |
| 115 | 115 |
| 116 import os, sys, re | 116 import os, sys, re |
| 117 import os.path as osp | 117 import os.path as osp |
| 118 from time import time, clock | 118 from time import time, clock |
| 119 import warnings | 119 import warnings |
| 120 import types | 120 import types |
| 121 from inspect import isgeneratorfunction, isclass | 121 from inspect import isgeneratorfunction, isclass |
| 122 from contextlib import contextmanager |
| 122 | 123 |
| 123 from logilab.common.fileutils import abspath_listdir | 124 from logilab.common.fileutils import abspath_listdir |
| 124 from logilab.common import textutils | 125 from logilab.common import textutils |
| 125 from logilab.common import testlib, STD_BLACKLIST | 126 from logilab.common import testlib, STD_BLACKLIST |
| 126 # use the same unittest module as testlib | 127 # use the same unittest module as testlib |
| 127 from logilab.common.testlib import unittest, start_interactive_mode | 128 from logilab.common.testlib import unittest, start_interactive_mode |
| 129 from logilab.common.deprecation import deprecated |
| 128 import doctest | 130 import doctest |
| 129 | 131 |
| 130 import unittest as unittest_legacy | 132 import unittest as unittest_legacy |
| 131 if not getattr(unittest_legacy, "__package__", None): | 133 if not getattr(unittest_legacy, "__package__", None): |
| 132 try: | 134 try: |
| 133 import unittest2.suite as unittest_suite | 135 import unittest2.suite as unittest_suite |
| 134 except ImportError: | 136 except ImportError: |
| 135 sys.exit("You have to install python-unittest2 to use this module") | 137 sys.exit("You have to install python-unittest2 to use this module") |
| 136 else: | 138 else: |
| 137 import unittest.suite as unittest_suite | 139 import unittest.suite as unittest_suite |
| 138 | 140 |
| 139 try: | 141 try: |
| 140 import django | 142 import django |
| 141 from logilab.common.modutils import modpath_from_file, load_module_from_modp
ath | 143 from logilab.common.modutils import modpath_from_file, load_module_from_modp
ath |
| 142 DJANGO_FOUND = True | 144 DJANGO_FOUND = True |
| 143 except ImportError: | 145 except ImportError: |
| 144 DJANGO_FOUND = False | 146 DJANGO_FOUND = False |
| 145 | 147 |
| 146 CONF_FILE = 'pytestconf.py' | 148 CONF_FILE = 'pytestconf.py' |
| 147 | 149 |
| 148 ## coverage hacks, do not read this, do not read this, do not read this | 150 ## coverage pausing tools |
| 149 | 151 |
| 150 # hey, but this is an aspect, right ?!!! | 152 @contextmanager |
| 153 def replace_trace(trace=None): |
| 154 """A context manager that temporary replaces the trace function""" |
| 155 oldtrace = sys.gettrace() |
| 156 sys.settrace(trace) |
| 157 try: |
| 158 yield |
| 159 finally: |
| 160 # specific hack to work around a bug in pycoverage, see |
| 161 # https://bitbucket.org/ned/coveragepy/issue/123 |
| 162 if (oldtrace is not None and not callable(oldtrace) and |
| 163 hasattr(oldtrace, 'pytrace')): |
| 164 oldtrace = oldtrace.pytrace |
| 165 sys.settrace(oldtrace) |
| 166 |
| 167 |
| 168 def pause_trace(): |
| 169 """A context manager that temporary pauses any tracing""" |
| 170 return replace_trace() |
| 171 |
| 151 class TraceController(object): | 172 class TraceController(object): |
| 152 nesting = 0 | 173 ctx_stack = [] |
| 153 | 174 |
| 175 @classmethod |
| 176 @deprecated('[lgc 0.63.1] Use the pause_trace() context manager') |
| 154 def pause_tracing(cls): | 177 def pause_tracing(cls): |
| 155 if not cls.nesting: | 178 cls.ctx_stack.append(pause_trace()) |
| 156 cls.tracefunc = staticmethod(getattr(sys, '__settrace__', sys.settra
ce)) | 179 cls.ctx_stack[-1].__enter__() |
| 157 cls.oldtracer = getattr(sys, '__tracer__', None) | |
| 158 sys.__notrace__ = True | |
| 159 cls.tracefunc(None) | |
| 160 cls.nesting += 1 | |
| 161 pause_tracing = classmethod(pause_tracing) | |
| 162 | 180 |
| 181 @classmethod |
| 182 @deprecated('[lgc 0.63.1] Use the pause_trace() context manager') |
| 163 def resume_tracing(cls): | 183 def resume_tracing(cls): |
| 164 cls.nesting -= 1 | 184 cls.ctx_stack.pop().__exit__(None, None, None) |
| 165 assert cls.nesting >= 0 | |
| 166 if not cls.nesting: | |
| 167 cls.tracefunc(cls.oldtracer) | |
| 168 delattr(sys, '__notrace__') | |
| 169 resume_tracing = classmethod(resume_tracing) | |
| 170 | 185 |
| 171 | 186 |
| 172 pause_tracing = TraceController.pause_tracing | 187 pause_tracing = TraceController.pause_tracing |
| 173 resume_tracing = TraceController.resume_tracing | 188 resume_tracing = TraceController.resume_tracing |
| 174 | 189 |
| 175 | 190 |
| 176 def nocoverage(func): | 191 def nocoverage(func): |
| 192 """Function decorator that pauses tracing functions""" |
| 177 if hasattr(func, 'uncovered'): | 193 if hasattr(func, 'uncovered'): |
| 178 return func | 194 return func |
| 179 func.uncovered = True | 195 func.uncovered = True |
| 196 |
| 180 def not_covered(*args, **kwargs): | 197 def not_covered(*args, **kwargs): |
| 181 pause_tracing() | 198 with pause_trace(): |
| 182 try: | |
| 183 return func(*args, **kwargs) | 199 return func(*args, **kwargs) |
| 184 finally: | |
| 185 resume_tracing() | |
| 186 not_covered.uncovered = True | 200 not_covered.uncovered = True |
| 187 return not_covered | 201 return not_covered |
| 188 | 202 |
| 189 | 203 ## end of coverage pausing tools |
| 190 ## end of coverage hacks | |
| 191 | 204 |
| 192 | 205 |
| 193 TESTFILE_RE = re.compile("^((unit)?test.*|smoketest)\.py$") | 206 TESTFILE_RE = re.compile("^((unit)?test.*|smoketest)\.py$") |
| 194 def this_is_a_testfile(filename): | 207 def this_is_a_testfile(filename): |
| 195 """returns True if `filename` seems to be a test file""" | 208 """returns True if `filename` seems to be a test file""" |
| 196 return TESTFILE_RE.match(osp.basename(filename)) | 209 return TESTFILE_RE.match(osp.basename(filename)) |
| 197 | 210 |
| 198 TESTDIR_RE = re.compile("^(unit)?tests?$") | 211 TESTDIR_RE = re.compile("^(unit)?tests?$") |
| 199 def this_is_a_testdir(dirpath): | 212 def this_is_a_testdir(dirpath): |
| 200 """returns True if `filename` seems to be a test directory""" | 213 """returns True if `filename` seems to be a test directory""" |
| (...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1075 """Return a sorted sequence of method names found within testCaseClass | 1088 """Return a sorted sequence of method names found within testCaseClass |
| 1076 """ | 1089 """ |
| 1077 is_skipped = self._this_is_skipped | 1090 is_skipped = self._this_is_skipped |
| 1078 classname = testCaseClass.__name__ | 1091 classname = testCaseClass.__name__ |
| 1079 if classname[0] == '_' or is_skipped(classname): | 1092 if classname[0] == '_' or is_skipped(classname): |
| 1080 return [] | 1093 return [] |
| 1081 testnames = super(NonStrictTestLoader, self).getTestCaseNames( | 1094 testnames = super(NonStrictTestLoader, self).getTestCaseNames( |
| 1082 testCaseClass) | 1095 testCaseClass) |
| 1083 return [testname for testname in testnames if not is_skipped(testname)] | 1096 return [testname for testname in testnames if not is_skipped(testname)] |
| 1084 | 1097 |
| 1098 |
| 1099 # The 2 functions below are modified versions of the TestSuite.run method |
| 1100 # that is provided with unittest2 for python 2.6, in unittest2/suite.py |
| 1101 # It is used to monkeypatch the original implementation to support |
| 1102 # extra runcondition and options arguments (see in testlib.py) |
| 1103 |
| 1085 def _ts_run(self, result, runcondition=None, options=None): | 1104 def _ts_run(self, result, runcondition=None, options=None): |
| 1086 self._wrapped_run(result,runcondition=runcondition, options=options) | 1105 self._wrapped_run(result, runcondition=runcondition, options=options) |
| 1087 self._tearDownPreviousClass(None, result) | 1106 self._tearDownPreviousClass(None, result) |
| 1088 self._handleModuleTearDown(result) | 1107 self._handleModuleTearDown(result) |
| 1089 return result | 1108 return result |
| 1090 | 1109 |
| 1091 def _ts_wrapped_run(self, result, debug=False, runcondition=None, options=None): | 1110 def _ts_wrapped_run(self, result, debug=False, runcondition=None, options=None): |
| 1092 for test in self: | 1111 for test in self: |
| 1093 if result.shouldStop: | 1112 if result.shouldStop: |
| 1094 break | 1113 break |
| 1095 if unittest_suite._isnotsuite(test): | 1114 if unittest_suite._isnotsuite(test): |
| 1096 self._tearDownPreviousClass(test, result) | 1115 self._tearDownPreviousClass(test, result) |
| 1097 self._handleModuleFixture(test, result) | 1116 self._handleModuleFixture(test, result) |
| 1098 self._handleClassSetUp(test, result) | 1117 self._handleClassSetUp(test, result) |
| 1099 result._previousTestClass = test.__class__ | 1118 result._previousTestClass = test.__class__ |
| 1100 if (getattr(test.__class__, '_classSetupFailed', False) or | 1119 if (getattr(test.__class__, '_classSetupFailed', False) or |
| 1101 getattr(result, '_moduleSetUpFailed', False)): | 1120 getattr(result, '_moduleSetUpFailed', False)): |
| 1102 continue | 1121 continue |
| 1103 | 1122 |
| 1123 # --- modifications to deal with _wrapped_run --- |
| 1124 # original code is: |
| 1125 # |
| 1126 # if not debug: |
| 1127 # test(result) |
| 1128 # else: |
| 1129 # test.debug() |
| 1104 if hasattr(test, '_wrapped_run'): | 1130 if hasattr(test, '_wrapped_run'): |
| 1105 try: | 1131 try: |
| 1106 test._wrapped_run(result, debug, runcondition=runcondition, opti
ons=options) | 1132 test._wrapped_run(result, debug, runcondition=runcondition, opti
ons=options) |
| 1107 except TypeError: | 1133 except TypeError: |
| 1108 test._wrapped_run(result, debug) | 1134 test._wrapped_run(result, debug) |
| 1109 elif not debug: | 1135 elif not debug: |
| 1110 try: | 1136 try: |
| 1111 test(result, runcondition, options) | 1137 test(result, runcondition, options) |
| 1112 except TypeError: | 1138 except TypeError: |
| 1113 test(result) | 1139 test(result) |
| 1114 else: | 1140 else: |
| 1115 test.debug() | 1141 test.debug() |
| 1142 # --- end of modifications to deal with _wrapped_run --- |
| 1143 return result |
| 1144 |
| 1145 if sys.version_info >= (2, 7): |
| 1146 # The function below implements a modified version of the |
| 1147 # TestSuite.run method that is provided with python 2.7, in |
| 1148 # unittest/suite.py |
| 1149 def _ts_run(self, result, debug=False, runcondition=None, options=None): |
| 1150 topLevel = False |
| 1151 if getattr(result, '_testRunEntered', False) is False: |
| 1152 result._testRunEntered = topLevel = True |
| 1153 |
| 1154 self._wrapped_run(result, debug, runcondition, options) |
| 1155 |
| 1156 if topLevel: |
| 1157 self._tearDownPreviousClass(None, result) |
| 1158 self._handleModuleTearDown(result) |
| 1159 result._testRunEntered = False |
| 1160 return result |
| 1116 | 1161 |
| 1117 | 1162 |
| 1118 def enable_dbc(*args): | 1163 def enable_dbc(*args): |
| 1119 """ | 1164 """ |
| 1120 Without arguments, return True if contracts can be enabled and should be | 1165 Without arguments, return True if contracts can be enabled and should be |
| 1121 enabled (see option -d), return False otherwise. | 1166 enabled (see option -d), return False otherwise. |
| 1122 | 1167 |
| 1123 With arguments, return False if contracts can't or shouldn't be enabled, | 1168 With arguments, return False if contracts can't or shouldn't be enabled, |
| 1124 otherwise weave ContractAspect with items passed as arguments. | 1169 otherwise weave ContractAspect with items passed as arguments. |
| 1125 """ | 1170 """ |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1145 | 1190 |
| 1146 if sys.version_info >= (2, 4): | 1191 if sys.version_info >= (2, 4): |
| 1147 doctest.DocTestCase.__bases__ = (testlib.TestCase,) | 1192 doctest.DocTestCase.__bases__ = (testlib.TestCase,) |
| 1148 # XXX check python2.6 compatibility | 1193 # XXX check python2.6 compatibility |
| 1149 #doctest.DocTestCase._cleanups = [] | 1194 #doctest.DocTestCase._cleanups = [] |
| 1150 #doctest.DocTestCase._out = [] | 1195 #doctest.DocTestCase._out = [] |
| 1151 else: | 1196 else: |
| 1152 unittest.FunctionTestCase.__bases__ = (testlib.TestCase,) | 1197 unittest.FunctionTestCase.__bases__ = (testlib.TestCase,) |
| 1153 unittest.TestSuite.run = _ts_run | 1198 unittest.TestSuite.run = _ts_run |
| 1154 unittest.TestSuite._wrapped_run = _ts_wrapped_run | 1199 unittest.TestSuite._wrapped_run = _ts_wrapped_run |
| OLD | NEW |