From 1b911ef1fdd78922dbc20467295c9055c719ddbe Mon Sep 17 00:00:00 2001 From: Ryan Fowler Date: Sat, 8 Aug 2026 06:17:00 -0400 Subject: [PATCH 1/2] test: drain PTY output before assertions Wait for the PTY capture thread to finish before collecting the large binary-response fixture output. This prevents the final warning from racing the test assertion on Linux. --- tests/support/pty.rs | 9 +++++++++ tests/support/terminal.rs | 3 +-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/tests/support/pty.rs b/tests/support/pty.rs index 47c091b4..4472f3dc 100644 --- a/tests/support/pty.rs +++ b/tests/support/pty.rs @@ -117,6 +117,15 @@ impl PtyCapture { drop(self.file); let _ = self.done.recv_timeout(Duration::from_secs(1)); } + + /// Closes the PTY and returns all output after the capture thread drains it. + pub(crate) fn finish(self) -> String { + drop(self.file); + self.done + .recv_timeout(Duration::from_secs(3)) + .expect("PTY capture thread did not finish"); + String::from_utf8_lossy(&self.buffer.lock().unwrap()).into_owned() + } } pub(crate) fn configure_pty_child(cmd: &mut Command, slave: &fs::File) { diff --git a/tests/support/terminal.rs b/tests/support/terminal.rs index 7082c581..be096029 100644 --- a/tests/support/terminal.rs +++ b/tests/support/terminal.rs @@ -301,9 +301,8 @@ pub(crate) fn run_binary_pty_with_custom_body( "fetch exited with {status}; PTY output:\n{}", capture.output() ); - let output = capture.output(); drop(pty.master); - capture.close(); + let output = capture.finish(); ( output, fs::read_to_string(less_args).ok(), From 6834f12b75c8af79b24b3954a7e8afc99790de48 Mon Sep 17 00:00:00 2001 From: Ryan Fowler Date: Sat, 8 Aug 2026 06:39:32 -0400 Subject: [PATCH 2/2] test: close parent PTY slave after spawn --- tests/support/terminal.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/support/terminal.rs b/tests/support/terminal.rs index be096029..74ee4b4e 100644 --- a/tests/support/terminal.rs +++ b/tests/support/terminal.rs @@ -285,6 +285,9 @@ pub(crate) fn run_binary_pty_with_custom_body( cmd.env("NO_PROXY", "*"); configure_pty_child(&mut cmd, &pty.slave); let mut child = cmd.spawn().expect("spawn fetch under PTY"); + // Command keeps its configured stdio handles after spawning. Drop it so + // the parent does not keep the PTY slave open after the child exits. + drop(cmd); drop(pty.slave); let capture = start_pty_capture(&pty.master); let status = wait_child(&mut child, Duration::from_secs(5))