Skip to content

Commit 73c4e1a

Browse files
committed
Use temp directory instead of individual files
1 parent 0abf36c commit 73c4e1a

File tree

1 file changed

+87
-85
lines changed
  • graalpython/com.oracle.graal.python.test/src

1 file changed

+87
-85
lines changed

graalpython/com.oracle.graal.python.test/src/runner.py

Lines changed: 87 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
import json
4343
import math
4444
import multiprocessing
45-
import multiprocessing.connection
4645
import os
4746
import pickle
4847
import re
@@ -515,22 +514,19 @@ def run_partitions_in_subprocesses(self, executor, partitions: list[list[TestId]
515514

516515
def run_in_subprocess_and_watch(self, tests: list[TestId]):
517516
# noinspection PyUnresolvedReferences
518-
use_pipe = not IS_GRAALPY or __graalpython__.posix_module_backend() == 'native'
519-
use_pipe = False
517+
use_pipe = sys.platform != 'win32' and (not IS_GRAALPY or __graalpython__.posix_module_backend() == 'native')
520518
remaining_tests = tests
521519
last_started_test: TestId | None = None
522520
last_started_time: float | None = None
523-
with (
524-
tempfile.NamedTemporaryFile(prefix='graalpytest-in-', mode='w+') as tests_file,
525-
tempfile.NamedTemporaryFile(prefix='graalpytest-out-', mode='w+') as out_file,
526-
):
521+
with tempfile.TemporaryDirectory(prefix='graalpytest-') as tmp_dir:
522+
tmp_dir = Path(tmp_dir)
527523
env = os.environ.copy()
528524
env['IN_PROCESS'] = '1'
529525

530526
if use_pipe:
531527
pipe, child_pipe = multiprocessing.Pipe()
532528
else:
533-
result_file = out_file.name + '.result'
529+
result_file = tmp_dir / 'result'
534530

535531
def process_event(event):
536532
nonlocal remaining_tests, last_started_test, last_started_time, last_out_pos
@@ -560,86 +556,91 @@ def process_event(event):
560556
last_out_pos = event['out_pos']
561557

562558
while remaining_tests and not self.stop_event.is_set():
563-
last_out_pos = out_file.tell()
564-
cmd = [
565-
sys.executable,
566-
'-u',
567-
*self.subprocess_args,
568-
__file__,
569-
'--tests-file', tests_file.name,
570-
]
571-
if use_pipe:
572-
cmd += ['--pipe-fd', str(child_pipe.fileno())]
573-
else:
574-
cmd += ['--result-file', result_file]
575-
if self.failfast:
576-
cmd.append('--failfast')
577-
# We communicate the tests through a temp file to avoid running into too long commandlines on windows
578-
tests_file.seek(0)
579-
tests_file.truncate()
580-
tests_file.write('\n'.join(map(str, remaining_tests)))
581-
tests_file.flush()
582-
process = subprocess.Popen(
583-
cmd,
584-
stdout=out_file,
585-
stderr=out_file,
586-
env=env,
587-
pass_fds=[child_pipe.fileno()] if use_pipe else [],
588-
)
589-
590-
timed_out = False
591-
592-
if use_pipe:
593-
while process.poll() is None:
559+
with (
560+
open(tmp_dir / 'out', 'w+') as out_file,
561+
open(tmp_dir / 'tests', 'w+') as tests_file,
562+
):
563+
last_out_pos = 0
564+
cmd = [
565+
sys.executable,
566+
'-u',
567+
*self.subprocess_args,
568+
__file__,
569+
'--tests-file', str(tests_file.name),
570+
]
571+
if use_pipe:
572+
cmd += ['--pipe-fd', str(child_pipe.fileno())]
573+
else:
574+
cmd += ['--result-file', str(result_file)]
575+
if self.failfast:
576+
cmd.append('--failfast')
577+
# We communicate the tests through a temp file to avoid running into too long commandlines on windows
578+
tests_file.seek(0)
579+
tests_file.truncate()
580+
tests_file.write('\n'.join(map(str, remaining_tests)))
581+
tests_file.flush()
582+
popen_kwargs: dict = dict(
583+
stdout=out_file,
584+
stderr=out_file,
585+
env=env,
586+
)
587+
if use_pipe:
588+
popen_kwargs.update(pass_fds=[child_pipe.fileno()])
589+
process = subprocess.Popen(cmd, **popen_kwargs)
590+
591+
timed_out = False
592+
593+
if use_pipe:
594+
while process.poll() is None:
595+
while pipe.poll(0.1):
596+
process_event(pipe.recv())
597+
if self.stop_event.is_set():
598+
interrupt_process(process)
599+
break
600+
if last_started_time is not None and time.time() - last_started_time >= self.default_test_timeout:
601+
interrupt_process(process)
602+
timed_out = True
603+
# Drain the pipe
604+
while pipe.poll(0.1):
605+
pipe.recv()
606+
break
607+
608+
returncode = process.wait()
609+
if self.stop_event.is_set():
610+
return
611+
if use_pipe:
594612
while pipe.poll(0.1):
595613
process_event(pipe.recv())
596-
if self.stop_event.is_set():
597-
interrupt_process(process)
598-
break
599-
if last_started_time is not None and time.time() - last_started_time >= self.default_test_timeout:
600-
interrupt_process(process)
601-
timed_out = True
602-
# Drain the pipe
603-
while pipe.poll(0.1):
604-
pipe.recv()
605-
break
606-
607-
returncode = process.wait()
608-
if self.stop_event.is_set():
609-
return
610-
if use_pipe:
611-
while pipe.poll(0.1):
612-
process_event(pipe.recv())
613-
else:
614-
with open(result_file, 'rb') as f:
615-
for file_event in pickle.load(f):
616-
process_event(file_event)
617-
618-
if returncode != 0 or timed_out:
619-
out_file.seek(last_out_pos)
620-
output = out_file.read()
621-
if last_started_test:
622-
if timed_out:
623-
message = "Timed out"
624-
elif returncode >= 0:
625-
message = f"Test process exitted with code {returncode}"
626-
else:
627-
try:
628-
signal_name = signal.Signals(-returncode).name
629-
except ValueError:
630-
signal_name = str(-returncode)
631-
message = f"Test process killed by signal {signal_name}"
632-
self.report_result(TestResult(
633-
test_id=last_started_test,
634-
status=TestStatus.ERROR,
635-
param=message,
636-
output=output,
637-
))
638-
continue
639614
else:
640-
# Crashed outside of tests, don't retry
641-
self.crashes.append(output or 'Runner subprocess crashed')
642-
return
615+
with open(result_file, 'rb') as f:
616+
for file_event in pickle.load(f):
617+
process_event(file_event)
618+
619+
if returncode != 0 or timed_out:
620+
out_file.seek(last_out_pos)
621+
output = out_file.read()
622+
if last_started_test:
623+
if timed_out:
624+
message = "Timed out"
625+
elif returncode >= 0:
626+
message = f"Test process exitted with code {returncode}"
627+
else:
628+
try:
629+
signal_name = signal.Signals(-returncode).name
630+
except ValueError:
631+
signal_name = str(-returncode)
632+
message = f"Test process killed by signal {signal_name}"
633+
self.report_result(TestResult(
634+
test_id=last_started_test,
635+
status=TestStatus.ERROR,
636+
param=message,
637+
output=output,
638+
))
639+
continue
640+
else:
641+
# Crashed outside of tests, don't retry
642+
self.crashes.append(output or 'Runner subprocess crashed')
643+
return
643644

644645

645646
def filter_tree(test_file: Path, test_suite: unittest.TestSuite, specifiers: list[TestSpecifier],
@@ -900,6 +901,7 @@ def in_process():
900901

901902
data = []
902903
if args.pipe_fd:
904+
import multiprocessing.connection
903905
conn = multiprocessing.connection.Connection(args.pipe_fd)
904906

905907
def result_factory(suite):

0 commit comments

Comments
 (0)