diff options
Diffstat (limited to 'odoo/tests/common.py')
| -rw-r--r-- | odoo/tests/common.py | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/odoo/tests/common.py b/odoo/tests/common.py index 6035cf21d10..fcf02041518 100644 --- a/odoo/tests/common.py +++ b/odoo/tests/common.py @@ -19,6 +19,7 @@ import requests import shutil import signal import subprocess +import sys import tempfile import threading import time @@ -128,9 +129,126 @@ def new_test_user(env, login='', groups='base.group_user', context=None, **kwarg # ------------------------------------------------------------ # Main classes # ------------------------------------------------------------ +class OdooSuite(unittest.suite.TestSuite): + + if sys.version_info < (3, 8): + # Partial backport of bpo-24412, merged in CPython 3.8 + + def _handleClassSetup(self, test, result): + previousClass = getattr(result, '_previousTestClass', None) + currentClass = test.__class__ + if currentClass == previousClass: + return + if result._moduleSetUpFailed: + return + if getattr(currentClass, "__unittest_skip__", False): + return + + try: + currentClass._classSetupFailed = False + except TypeError: + # test may actually be a function + # so its class will be a builtin-type + pass + + setUpClass = getattr(currentClass, 'setUpClass', None) + if setUpClass is not None: + unittest.suite._call_if_exists(result, '_setupStdout') + try: + setUpClass() + except Exception as e: + if isinstance(result, unittest.suite._DebugResult): + raise + currentClass._classSetupFailed = True + className = unittest.util.strclass(currentClass) + self._createClassOrModuleLevelException(result, e, + 'setUpClass', + className) + finally: + unittest.suite._call_if_exists(result, '_restoreStdout') + if currentClass._classSetupFailed is True: + currentClass.doClassCleanups() + if len(currentClass.tearDown_exceptions) > 0: + for exc in currentClass.tearDown_exceptions: + self._createClassOrModuleLevelException( + result, exc[1], 'setUpClass', className, + info=exc) + + def _createClassOrModuleLevelException(self, result, exc, method_name, parent, info=None): + errorName = f'{method_name} ({parent})' + self._addClassOrModuleLevelException(result, exc, errorName, info) + + def _addClassOrModuleLevelException(self, result, exception, errorName, info=None): + error = unittest.suite._ErrorHolder(errorName) + addSkip = getattr(result, 'addSkip', None) + if addSkip is not None and isinstance(exception, unittest.case.SkipTest): + addSkip(error, str(exception)) + else: + if not info: + result.addError(error, sys.exc_info()) + else: + result.addError(error, info) + + def _tearDownPreviousClass(self, test, result): + previousClass = getattr(result, '_previousTestClass', None) + currentClass = test.__class__ + if currentClass == previousClass: + return + if getattr(previousClass, '_classSetupFailed', False): + return + if getattr(result, '_moduleSetUpFailed', False): + return + if getattr(previousClass, "__unittest_skip__", False): + return + + tearDownClass = getattr(previousClass, 'tearDownClass', None) + if tearDownClass is not None: + unittest.suite._call_if_exists(result, '_setupStdout') + try: + tearDownClass() + except Exception as e: + if isinstance(result, unittest.suite._DebugResult): + raise + className = unittest.util.strclass(previousClass) + self._createClassOrModuleLevelException(result, e, + 'tearDownClass', + className) + finally: + unittest.suite._call_if_exists(result, '_restoreStdout') + previousClass.doClassCleanups() + if len(previousClass.tearDown_exceptions) > 0: + for exc in previousClass.tearDown_exceptions: + className = unittest.util.strclass(previousClass) + self._createClassOrModuleLevelException(result, exc[1], + 'tearDownClass', + className, + info=exc) class TreeCase(unittest.TestCase): + + if sys.version_info < (3, 8): + # Partial backport of bpo-24412, merged in CPython 3.8 + _class_cleanups = [] + + @classmethod + def addClassCleanup(cls, function, *args, **kwargs): + """Same as addCleanup, except the cleanup items are called even if + setUpClass fails (unlike tearDownClass). Backport of bpo-24412.""" + cls._class_cleanups.append((function, args, kwargs)) + + @classmethod + def doClassCleanups(cls): + """Execute all class cleanup functions. Normally called for you after tearDownClass. + Backport of bpo-24412.""" + cls.tearDown_exceptions = [] + while cls._class_cleanups: + function, args, kwargs = cls._class_cleanups.pop() + try: + function(*args, **kwargs) + except Exception as exc: + cls.tearDown_exceptions.append(sys.exc_info()) + def __init__(self, methodName='runTest'): super(TreeCase, self).__init__(methodName) self.addTypeEqualityFunc(etree._Element, self.assertTreesEqual) |
