Skip to content

Commit 60d8d5c

Browse files
karthiknadigCopilot
andcommitted
test: isolate broken-pipe fixture from concurrent forks (Refs #529)
Concurrent Unix fork/exec can retain another fixture pipe reader until exec, allowing the sole response write to succeed before the final reader disappears. Run the same real-pipe scenario in an isolated test subprocess; keep the one-second measured deadline and bounded cleanup unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 4276b38 commit 60d8d5c

1 file changed

Lines changed: 23 additions & 0 deletions

File tree

‎crates/pet/tests/jsonrpc_server_test.rs‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,29 @@ fn truncated_input_exits_unsuccessfully_without_an_error_flood() {
584584

585585
#[test]
586586
fn closed_output_exits_without_waiting_for_stdin_eof() {
587+
// Concurrent fork/exec can temporarily inherit a pipe reader despite CLOEXEC.
588+
// Isolate this scenario so its dropped handle really is the final reader.
589+
if std::env::var_os("PET_TEST_CLOSED_OUTPUT_CHILD").is_none() {
590+
let mut child = Command::new(std::env::current_exe().unwrap())
591+
.args([
592+
"--exact",
593+
"closed_output_exits_without_waiting_for_stdin_eof",
594+
"--nocapture",
595+
])
596+
.env("PET_TEST_CLOSED_OUTPUT_CHILD", "1")
597+
.stdin(Stdio::null())
598+
.stdout(Stdio::null())
599+
.stderr(Stdio::inherit())
600+
.spawn()
601+
.expect("isolated closed-output fixture must spawn");
602+
let status = jsonrpc_client::shutdown_fixture(&mut child, Duration::from_secs(20)).unwrap();
603+
assert!(
604+
status.success(),
605+
"isolated closed-output fixture failed: {status}"
606+
);
607+
return;
608+
}
609+
587610
let mut fixture = ShutdownFixture::spawn();
588611
let mut stdout = BufReader::new(fixture.child.stdout.take().unwrap());
589612
let (sender, receiver) = mpsc::sync_channel(1);

0 commit comments

Comments
 (0)