Skip to content

Commit f8bb333

Browse files
committed
[GR-76253] Make pyc reparse rendezvous more robust
PullRequest: graalpython/4625
2 parents 5f0d76f + fa86ec7 commit f8bb333

1 file changed

Lines changed: 36 additions & 12 deletions

File tree

graalpython/com.oracle.graal.python.test/src/tests/test_reparse.py

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,32 @@
4949
import unittest
5050
from pathlib import Path
5151

52-
SYNC_PREAMBLE = '''
52+
SYNC_HOST = "127.0.0.1"
53+
SYNC_TIMEOUT = 180.0
54+
55+
SYNC_PREAMBLE = f'''
5356
import sys
5457
import socket
5558
56-
with socket.create_connection(('localhost', int(sys.argv[1]))) as sock:
59+
with socket.create_connection(({SYNC_HOST!r}, int(sys.argv[1])), timeout={SYNC_TIMEOUT!r}) as sock:
5760
sock.recv(1)
5861
'''
5962

6063

64+
def _terminate_and_collect(proc):
65+
if proc.poll() is not None:
66+
return proc.communicate()[0]
67+
try:
68+
proc.terminate()
69+
except ProcessLookupError:
70+
return proc.communicate()[0]
71+
try:
72+
return proc.communicate(timeout=10)[0]
73+
except subprocess.TimeoutExpired:
74+
proc.kill()
75+
return proc.communicate()[0]
76+
77+
6178
@contextlib.contextmanager
6279
def pyc_reparse(test_content, expect_success=True, python_options=()):
6380
if sys.implementation.name != "graalpy" or not __graalpython__.is_bytecode_dsl_interpreter:
@@ -73,7 +90,7 @@ def pyc_reparse(test_content, expect_success=True, python_options=()):
7390
compileall.compile_file(example_module_path, force=True, quiet=True)
7491
pyc_files = list((tempdir_path / '__pycache__').glob('*.pyc'))
7592
assert len(pyc_files) == 1, "Didn't find a .pyc file"
76-
with socket.create_server(('0.0.0.0', 0)) as server:
93+
with socket.create_server((SYNC_HOST, 0)) as server:
7794
port = server.getsockname()[1]
7895
env = os.environ.copy()
7996
env['PYTHONPATH'] = str(tempdir_path)
@@ -84,20 +101,27 @@ def pyc_reparse(test_content, expect_success=True, python_options=()):
84101
stderr=subprocess.STDOUT,
85102
text=True,
86103
)
87-
server.settimeout(3.0)
88-
retries = 20
89-
while retries:
104+
deadline = time.monotonic() + SYNC_TIMEOUT
105+
while True:
106+
remaining = deadline - time.monotonic()
107+
if remaining <= 0:
108+
out = _terminate_and_collect(proc)
109+
assert False, f"Timed out waiting for connection after {SYNC_TIMEOUT:.0f}s\n{out}"
110+
server.settimeout(min(3.0, remaining))
90111
try:
91112
with server.accept()[0] as sock:
92-
yield example_module_path, pyc_files[0]
93-
sock.sendall(b"x")
113+
try:
114+
yield example_module_path, pyc_files[0]
115+
finally:
116+
sock.sendall(b"x")
94117
break
95118
except socket.timeout:
96119
assert proc.poll() is None, proc.communicate()[0]
97-
retries -= 1
98-
else:
99-
assert False, "Timed out wating for connection"
100-
out = proc.communicate()[0]
120+
try:
121+
out = proc.communicate(timeout=SYNC_TIMEOUT)[0]
122+
except subprocess.TimeoutExpired:
123+
out = _terminate_and_collect(proc)
124+
assert False, f"Timed out waiting for child process after {SYNC_TIMEOUT:.0f}s\n{out}"
101125
if expect_success:
102126
assert proc.wait() == 0, out
103127
else:

0 commit comments

Comments
 (0)