Skip to content

Commit 999c9f6

Browse files
committed
pytestadapter: Read pipe in non-blocking mode so tests don't hang if the subprocess fails to open the pipe for writing.
1 parent cd31afd commit 999c9f6

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

python_files/tests/pytestadapter/helpers.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import json
77
import os
88
import pathlib
9+
import select
910
import socket
1011
import subprocess
1112
import sys
@@ -182,18 +183,29 @@ def pipe_setup_an_listen(pipe_name: str, result: List[str]):
182183
completed = threading.Event()
183184

184185
def listen():
185-
# Open the FIFO for reading
186-
with pipe_path.open() as fifo:
187-
print("Waiting for data...")
186+
# When using blocking IO, open blocks forever if the subprocess compleates but never
187+
# opens the pipe for writing (which my happen if there is an error early in the
188+
# subprocess.) Hence we go to the effort of using non-blocking io so that we can
189+
# break out of this function if that happens.
190+
fd = os.open(pipe_path, os.O_RDONLY | os.O_NONBLOCK)
191+
try:
192+
all_data = bytearray()
188193
while True:
189194
if completed.is_set():
190-
break # Exit loop if completed event is set
191-
data = fifo.read() # This will block until data is available
192-
if len(data) == 0:
193-
# If data is empty, assume EOF
194195
break
195-
print(f"Received: {data}")
196-
result.append(data)
196+
197+
# Wait till the pipe has data to read, with a timeout.
198+
rlist, _, _ = select.select([fd], [], [], 0.1)
199+
if rlist:
200+
# Data is available, read it.
201+
data = os.read(fd, 1024)
202+
if not data:
203+
# Empty data indicates EOF.
204+
break
205+
all_data.extend(data)
206+
result.append(all_data.decode())
207+
finally:
208+
os.close(fd)
197209

198210
thread = threading.Thread(target=listen)
199211
thread.start()

0 commit comments

Comments
 (0)