From f919d9892a4c075be0b5d15b14a599f43ef42b7d Mon Sep 17 00:00:00 2001 From: Allison Karlitskaya Date: Wed, 8 Nov 2023 10:26:03 +0100 Subject: [PATCH] test: fix more test_spawn_broken_pipe races On old Python versions, we can get the process-exited callback from the child watcher at the time of registration, without a return to the mainloop. That means that for very fast-exiting processes, we might never get a chance to write to them to observe a EPIPE error. Add a synchronization point so that we can prevent the process from exiting until after we've finished spawning it (and registering the watch). Closes #19586 --- test/pytest/test_peer.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/pytest/test_peer.py b/test/pytest/test_peer.py index 78e9a7028700..cba57540e5c7 100644 --- a/test/pytest/test_peer.py +++ b/test/pytest/test_peer.py @@ -187,8 +187,10 @@ def __init__(self, *, specific_error=False): self.specific_error = specific_error async def do_connect_transport(self) -> None: - transport = await self.spawn(['sh', '-c', 'exit 9'], ()) + transport = await self.spawn(['sh', '-c', 'read a; exit 9'], ()) assert isinstance(transport, SubprocessTransport) + # Make the process exit by writing a newline (causing `read` to finish) + transport.write(b'\n') # The process will exit soon — try writing to it until a write fails. while not transport.is_closing(): transport.write(b'x')