qubes/tests: convert some tearDown into addCleanup
This is because .tearDown() is not executed if the exception occurs in setUp() [for example self.skipTest() raises an exception]. The lower levels of .tearDown() being executed are critical to not leaking file descriptors.
This commit is contained in:
parent
d0f2fdba55
commit
6ff1bfdc16
@ -345,12 +345,6 @@ class substitute_entry_points(object):
|
||||
self._orig_iter_entry_points = None
|
||||
|
||||
|
||||
class BeforeCleanExit(BaseException):
|
||||
'''Raised from :py:meth:`QubesTestCase.tearDown` when
|
||||
:py:attr:`qubes.tests.run.QubesDNCTestResult.do_not_clean` is set.'''
|
||||
pass
|
||||
|
||||
|
||||
class QubesTestCase(unittest.TestCase):
|
||||
'''Base class for Qubes unit tests.
|
||||
'''
|
||||
@ -379,27 +373,15 @@ class QubesTestCase(unittest.TestCase):
|
||||
super().setUp()
|
||||
self.loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(self.loop)
|
||||
self.addCleanup(self.cleanup_loop)
|
||||
|
||||
def tearDown(self):
|
||||
def cleanup_loop(self):
|
||||
# The loop, when closing, throws a warning if there is
|
||||
# some unfinished bussiness. Let's catch that.
|
||||
with warnings.catch_warnings():
|
||||
warnings.simplefilter('error')
|
||||
self.loop.close()
|
||||
|
||||
# TODO: find better way in py3
|
||||
try:
|
||||
result = self._outcome.result
|
||||
except:
|
||||
result = self._resultForDoCleanups
|
||||
failed_test_cases = result.failures \
|
||||
+ result.errors \
|
||||
+ [(tc, None) for tc in result.unexpectedSuccesses]
|
||||
|
||||
if getattr(result, 'do_not_clean', False) \
|
||||
and any(tc is self for tc, exc in failed_test_cases):
|
||||
raise BeforeCleanExit()
|
||||
|
||||
del self.loop
|
||||
|
||||
def assertNotRaises(self, excClass, callableObj=None, *args, **kwargs):
|
||||
"""Fail if an exception of class excClass is raised
|
||||
@ -628,10 +610,12 @@ class SystemTestCase(QubesTestCase):
|
||||
qubes.api.internal.QubesInternalAPI,
|
||||
app=self.app, debug=True))
|
||||
|
||||
def tearDown(self):
|
||||
self.addCleanup(self.cleanup_app)
|
||||
|
||||
|
||||
def cleanup_app(self):
|
||||
self.remove_test_vms()
|
||||
|
||||
# close the servers before super(), because that might close the loop
|
||||
server = None
|
||||
for server in self.qubesd:
|
||||
for sock in server.sockets:
|
||||
@ -674,7 +658,6 @@ class SystemTestCase(QubesTestCase):
|
||||
'libvirt event impl not clean: callbacks %r descriptors %r',
|
||||
self.libvirt_event_impl.callbacks,
|
||||
self.libvirt_event_impl.descriptors)
|
||||
super(SystemTestCase, self).tearDown()
|
||||
|
||||
def init_default_template(self, template=None):
|
||||
if template is None:
|
||||
|
@ -231,10 +231,6 @@ class QubesTestResult(unittest.TestResult):
|
||||
self.stream.writeln('%s' % err)
|
||||
|
||||
|
||||
class QubesDNCTestResult(QubesTestResult):
|
||||
do_not_clean = True
|
||||
|
||||
|
||||
def demo(verbosity=2):
|
||||
class TC_00_Demo(qubes.tests.QubesTestCase):
|
||||
'''Demo class'''
|
||||
@ -293,13 +289,6 @@ parser.add_argument('--no-failfast',
|
||||
action='store_false', dest='failfast',
|
||||
help='disable --failfast')
|
||||
|
||||
parser.add_argument('--do-not-clean', '--dnc', '-D',
|
||||
action='store_true', dest='do_not_clean',
|
||||
help='do not execute tearDown on failed tests. Implies --failfast.')
|
||||
parser.add_argument('--do-clean', '-C',
|
||||
action='store_false', dest='do_not_clean',
|
||||
help='do execute tearDown even on failed tests.')
|
||||
|
||||
# pylint: disable=protected-access
|
||||
try:
|
||||
name_to_level = logging._nameToLevel
|
||||
@ -387,9 +376,6 @@ def main(args=None):
|
||||
print(str(test)) # pylint: disable=superfluous-parens
|
||||
return True
|
||||
|
||||
if args.do_not_clean:
|
||||
args.failfast = True
|
||||
|
||||
logging.root.setLevel(args.loglevel)
|
||||
|
||||
if args.logfile is not None:
|
||||
@ -425,10 +411,7 @@ def main(args=None):
|
||||
verbosity=(args.verbose-args.quiet),
|
||||
failfast=args.failfast)
|
||||
unittest.signals.installHandler()
|
||||
|
||||
runner.resultclass = QubesDNCTestResult \
|
||||
if args.do_not_clean else QubesTestResult
|
||||
|
||||
runner.resultclass = QubesTestResult
|
||||
result = runner.run(suite)
|
||||
|
||||
if args.break_to_repl:
|
||||
|
Loading…
Reference in New Issue
Block a user