From: Rob van der Linde Date: Tue, 26 Sep 2023 08:10:33 +0000 (+1300) Subject: python: tests: implement setUpTestData overridable class method X-Git-Tag: tevent-0.16.0~324 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=71c191ca9fc8c836609f579de78678711e1ed034;p=thirdparty%2Fsamba.git python: tests: implement setUpTestData overridable class method On Python 3.6 and 3.7 the addClassCleanup method needs to be implemented, and tearDownClass must be called by setupClass if any exception is raised. On Python 3.8 and higher, unittest already calls tearDownClass, even if it raises an exception in setUpClass. Signed-off-by: Rob van der Linde Reviewed-by: Douglas Bagnall Reviewed-by: Andrew Bartlett --- diff --git a/python/samba/tests/__init__.py b/python/samba/tests/__init__.py index 8cb3d13df54..e7811566539 100644 --- a/python/samba/tests/__init__.py +++ b/python/samba/tests/__init__.py @@ -19,6 +19,7 @@ """Samba Python tests.""" import os import tempfile +import traceback import collections import ldb import samba @@ -81,6 +82,59 @@ def DynamicTestCase(cls): class TestCase(unittest.TestCase): """A Samba test case.""" + # Re-implement addClassCleanup to support Python versions older than 3.8. + # Can be removed once these older Python versions are no longer needed. + if sys.version_info.major == 3 and sys.version_info.minor < 8: + _class_cleanups = [] + + @classmethod + def addClassCleanup(cls, function, *args, **kwargs): + cls._class_cleanups.append((function, args, kwargs)) + + @classmethod + def tearDownClass(cls): + teardown_exceptions = [] + + while cls._class_cleanups: + function, args, kwargs = cls._class_cleanups.pop() + try: + function(*args, **kwargs) + except Exception: + teardown_exceptions.append(traceback.format_exc()) + + # ExceptionGroup would be better but requires Python 3.11 + if teardown_exceptions: + raise ValueError("tearDownClass failed:\n\n" + + "\n".join(teardown_exceptions)) + + @classmethod + def setUpClass(cls): + """ + Call setUpTestData, ensure tearDownClass is called on exceptions. + + This is only required on Python versions older than 3.8. + """ + try: + cls.setUpTestData() + except Exception: + cls.tearDownClass() + raise + else: + @classmethod + def setUpClass(cls): + """ + setUpClass only needs to call setUpTestData. + + On Python 3.8 and above unittest will always call tearDownClass, + even if an exception was raised in setUpClass. + """ + cls.setUpTestData() + + @classmethod + def setUpTestData(cls): + """Create class level test fixtures here.""" + pass + @classmethod def generate_dynamic_test(cls, fnname, suffix, *args, doc=None): """