Commit 3cde440f authored by Victor Stinner's avatar Victor Stinner Committed by GitHub

bpo-36725: Refactor regrtest multiprocessing code (GH-12961)

Rewrite run_tests_multiprocess() function as a new MultiprocessRunner
class with multiple methods to better report errors and stop
immediately when needed.

Changes:

* Worker processes are now killed immediately if tests are
  interrupted or if a test does crash (CHILD_ERROR): worker
  processes are killed.
* Rewrite how errors in a worker thread are reported to
  the main thread. No longer ignore BaseException or parsing errors
  silently.
* Remove 'finished' variable: use worker.is_alive() instead
* Always compute omitted tests. Add Regrtest.get_executed() method.
parent 87d23a04
......@@ -79,8 +79,8 @@ class Regrtest:
self.skipped = []
self.resource_denieds = []
self.environment_changed = []
self.rerun = []
self.run_no_tests = []
self.rerun = []
self.first_result = None
self.interrupted = False
......@@ -105,6 +105,11 @@ class Regrtest:
# used by --junit-xml
self.testsuite_xml = None
def get_executed(self):
return (set(self.good) | set(self.bad) | set(self.skipped)
| set(self.resource_denieds) | set(self.environment_changed)
| set(self.run_no_tests))
def accumulate_result(self, result):
test_name = result.test_name
ok = result.result
......@@ -311,8 +316,6 @@ class Regrtest:
self.bad.remove(test_name)
if ok.result == INTERRUPTED:
# print a newline separate from the ^C
print()
self.interrupted = True
break
else:
......@@ -331,11 +334,11 @@ class Regrtest:
print("== Tests result: %s ==" % self.get_tests_result())
if self.interrupted:
print()
# print a newline after ^C
print("Test suite interrupted by signal SIGINT.")
executed = set(self.good) | set(self.bad) | set(self.skipped)
omitted = set(self.selected) - executed
omitted = set(self.selected) - self.get_executed()
if omitted:
print()
print(count(len(omitted), "test"), "omitted:")
printlist(omitted)
......
......@@ -275,6 +275,7 @@ def _runtest_inner(ns, test_name, display_failure=True):
except support.TestDidNotRun:
return TEST_DID_NOT_RUN
except KeyboardInterrupt:
print()
return INTERRUPTED
except:
if not ns.pgo:
......
This diff is collapsed.
......@@ -916,13 +916,13 @@ class ArgsTestCase(BaseTestCase):
testname)
self.assertEqual(output.splitlines(), all_methods)
@support.cpython_only
def test_crashed(self):
# Any code which causes a crash
code = 'import faulthandler; faulthandler._sigsegv()'
crash_test = self.create_test(name="crash", code=code)
ok_test = self.create_test(name="ok")
tests = [crash_test, ok_test]
tests = [crash_test]
output = self.run_tests("-j2", *tests, exitcode=2)
self.check_executed_tests(output, tests, failed=crash_test,
randomize=True)
......
When using mulitprocessing mode (-jN), regrtest now better reports errors if
a worker process fails, and it exits immediately on a worker thread failure
or when interrupted.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment