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 <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
da4aea6b55
commit
6c5da2804b
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue