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
	 Wojtek Porczyk
						Wojtek Porczyk