4949import unittest
5050from pathlib import Path
5151
52- SYNC_PREAMBLE = '''
52+ SYNC_HOST = "127.0.0.1"
53+ SYNC_TIMEOUT = 180.0
54+
55+ SYNC_PREAMBLE = f'''
5356import sys
5457import 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
6279def 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