From 6c5da2804b00ae28b4837f56fa38671753ac64f8 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Thu, 3 Jan 2019 19:07:40 +0100 Subject: test: split SubprocessTestCase.run into setUp/tearDown The run method is not invoked when running in debug mode (for example, with `pytest --pdb`) and would result in spurious errors due to "log_fd" being None. Split the method to resolve this incompatibility. Note that with `pytest --pdb`, the tearDown method is not called when exceptions occur, see https://docs.pytest.org/en/latest/unittest.html Change-Id: I4b66c03d5b050b53311ec64021fe17dc91bb48dd Reviewed-on: https://code.wireshark.org/review/31339 Petri-Dish: Peter Wu Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman --- test/subprocesstest.py | 69 +++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 38 deletions(-) diff --git a/test/subprocesstest.py b/test/subprocesstest.py index 2510ce8992..fafd773144 100644 --- a/test/subprocesstest.py +++ b/test/subprocesstest.py @@ -130,25 +130,10 @@ class SubprocessTestCase(unittest.TestCase): except: pass - def _error_count(self, result): - if not result: - return 0 - if hasattr(result, 'failures'): - # Python standard unittest runner - return len(result.failures) + len(result.errors) - if hasattr(result, '_excinfo'): - # pytest test runner - return len(result._excinfo or []) - self.fail("Unexpected test result %r" % result) - - def run(self, result=None): - # Subclass run() so that we can do the following: - # - Open our log file and add it to the cleanup list. - # - Check our result before and after the run so that we can tell - # if the current test was successful. - - # Probably not needed, but shouldn't hurt. - self.kill_processes() + def setUp(self): + """ + Set up a single test. Opens a log file and add it to the cleanup list. + """ self.processes = [] self.log_fname = self.filename_from_id('log') # Our command line utilities generate UTF-8. The log file endcoding @@ -157,27 +142,35 @@ class SubprocessTestCase(unittest.TestCase): # to handle line endings in the future. self.log_fd = io.open(self.log_fname, 'w', encoding='UTF-8', newline='\n') self.cleanup_files.append(self.log_fname) - pre_run_problem_count = self._error_count(result) - try: - super().run(result=result) - except KeyboardInterrupt: - # XXX This doesn't seem to work on Windows, which is where we need it the most. - self.kill_processes() - - # Tear down our test. We don't do this in tearDown() because Python 3 - # updates "result" after calling tearDown(). + + def _last_test_failed(self): + """Check for non-skipped tests that resulted in errors.""" + # The test outcome is not available via the public unittest API, so + # check a private property, "_outcome", set by unittest.TestCase.run. + # It remains None when running in debug mode (`pytest --pdb`). + # The property is available since Python 3.4 until at least Python 3.7. + if self._outcome: + for test_case, exc_info in self._outcome.errors: + if exc_info: + return True + # No errors occurred or running in debug mode. + return False + + def tearDown(self): + """ + Tears down a single test. Kills stray processes and closes the log file. + On errors, display the log contents. On success, remove temporary files. + """ self.kill_processes() self.log_fd.close() - if result: - post_run_problem_count = self._error_count(result) - if pre_run_problem_count != post_run_problem_count: - self.dump_files.append(self.log_fname) - # Leave some evidence behind. - self.cleanup_files = [] - print('\nProcess output for {}:'.format(self.id())) - with io.open(self.log_fname, 'r', encoding='UTF-8', errors='backslashreplace') as log_fd: - for line in log_fd: - sys.stdout.write(line) + if self._last_test_failed(): + self.dump_files.append(self.log_fname) + # Leave some evidence behind. + self.cleanup_files = [] + print('\nProcess output for {}:'.format(self.id())) + with io.open(self.log_fname, 'r', encoding='UTF-8', errors='backslashreplace') as log_fd: + for line in log_fd: + sys.stdout.write(line) for filename in self.cleanup_files: try: os.unlink(filename) -- cgit v1.2.3