bpo-30258: regrtest handles child process crash (#1431) · python/cpython@c991eb2 (original) (raw)

`@@ -220,6 +220,7 @@

`

220

220

`SKIPPED = -2

`

221

221

`RESOURCE_DENIED = -3

`

222

222

`INTERRUPTED = -4

`

``

223

`+

CHILD_ERROR = -5 # error in a child process

`

223

224

``

224

225

`from test import test_support

`

225

226

``

`@@ -466,7 +467,8 @@ def main(tests=None, testdir=None, verbose=0, quiet=False,

`

466

467

``

467

468

`def accumulate_result(test, result):

`

468

469

`ok, test_time = result

`

469

``

`-

test_times.append((test_time, test))

`

``

470

`+

if ok not in (CHILD_ERROR, INTERRUPTED):

`

``

471

`+

test_times.append((test_time, test))

`

470

472

`if ok == PASSED:

`

471

473

`good.append(test)

`

472

474

`elif ok == FAILED:

`

`@@ -478,6 +480,9 @@ def accumulate_result(test, result):

`

478

480

`elif ok == RESOURCE_DENIED:

`

479

481

`skipped.append(test)

`

480

482

`resource_denieds.append(test)

`

``

483

`+

else:

`

``

484

`+

CHILD_ERROR

`

``

485

`+

bad.append(test)

`

481

486

``

482

487

`if forever:

`

483

488

`def test_forever(tests=list(selected)):

`

`@@ -533,9 +538,17 @@ def work():

`

533

538

`universal_newlines=True,

`

534

539

`close_fds=(os.name != 'nt'))

`

535

540

`stdout, stderr = popen.communicate()

`

``

541

`+

retcode = popen.wait()

`

``

542

+

536

543

`# Strip last refcount output line if it exists, since it

`

537

544

`# comes from the shutdown of the interpreter in the subcommand.

`

538

545

`stderr = debug_output_pat.sub("", stderr)

`

``

546

+

``

547

`+

if retcode != 0:

`

``

548

`+

result = (CHILD_ERROR, "Exit code %s" % retcode)

`

``

549

`+

output.put((test, stdout.rstrip(), stderr.rstrip(),

`

``

550

`+

result))

`

``

551

+

539

552

`stdout, _, result = stdout.strip().rpartition("\n")

`

540

553

`if not result:

`

541

554

`output.put((None, None, None, None))

`

`@@ -545,9 +558,11 @@ def work():

`

545

558

`except BaseException:

`

546

559

`output.put((None, None, None, None))

`

547

560

`raise

`

``

561

+

548

562

`workers = [Thread(target=work) for i in range(use_mp)]

`

549

563

`for worker in workers:

`

550

564

`worker.start()

`

``

565

+

551

566

`finished = 0

`

552

567

`test_index = 1

`

553

568

`try:

`

`@@ -556,21 +571,24 @@ def work():

`

556

571

`if test is None:

`

557

572

`finished += 1

`

558

573

`continue

`

``

574

`+

accumulate_result(test, result)

`

``

575

`+

if not quiet:

`

``

576

`+

fmt = "[{1:{0}}{2}/{3}] {4}" if bad else "[{1:{0}}{2}] {4}"

`

``

577

`+

print(fmt.format(

`

``

578

`+

test_count_width, test_index, test_count,

`

``

579

`+

len(bad), test))

`

``

580

+

559

581

`if stdout:

`

560

582

`print stdout

`

``

583

`+

sys.stdout.flush()

`

561

584

`if stderr and not pgo:

`

562

585

`print >>sys.stderr, stderr

`

563

``

`-

sys.stdout.flush()

`

564

586

`sys.stderr.flush()

`

``

587

+

565

588

`if result[0] == INTERRUPTED:

`

566

589

`assert result[1] == 'KeyboardInterrupt'

`

567

590

`raise KeyboardInterrupt # What else?

`

568

``

`-

accumulate_result(test, result)

`

569

``

`-

if not quiet:

`

570

``

`-

fmt = "[{1:{0}}{2}/{3}] {4}" if bad else "[{1:{0}}{2}] {4}"

`

571

``

`-

print(fmt.format(

`

572

``

`-

test_count_width, test_index, test_count,

`

573

``

`-

len(bad), test))

`

``

591

+

574

592

`test_index += 1

`

575

593

`except KeyboardInterrupt:

`

576

594

`interrupted = True

`

`@@ -738,6 +756,7 @@ def runtest(test, verbose, quiet,

`

738

756

` for Profile Guided Optimization build

`

739

757

``

740

758

` Returns one of the test result constants:

`

``

759

`+

CHILD_ERROR Child process crashed

`

741

760

` INTERRUPTED KeyboardInterrupt when run under -j

`

742

761

` RESOURCE_DENIED test skipped because resource denied

`

743

762

` SKIPPED test skipped for some other reason

`