aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorakbash <akbash@herdr.dev>2026-08-19 20:39:24 +0300
committerGitHub <noreply@github.com>2026-08-19 20:39:24 +0300
commite3c3d443584b629803a73ad66e0e298943c7f201 (patch)
tree639abd8b3d8f03d07d05eef47ca025cafaeda02b /tests
parent5203a5dc0f39a082938ea0f9836d6257ea7e155f (diff)
fix(cli): exit quietly when output pipes close (#2996)
refs #2994 Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/broken_pipe.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/tests/broken_pipe.rs b/tests/broken_pipe.rs
new file mode 100644
index 00000000..66aa029e
--- /dev/null
+++ b/tests/broken_pipe.rs
@@ -0,0 +1,49 @@
+#![cfg(unix)]
+
+use std::os::fd::{FromRawFd, OwnedFd};
+use std::os::unix::process::ExitStatusExt;
+use std::process::{Command, Output, Stdio};
+
+fn closed_pipe_writer() -> Stdio {
+ let mut fds = [-1; 2];
+ assert_eq!(unsafe { libc::pipe(fds.as_mut_ptr()) }, 0);
+ // SAFETY: pipe initialized both descriptors, and each is assigned to one
+ // OwnedFd so it is closed exactly once.
+ let read_fd = unsafe { OwnedFd::from_raw_fd(fds[0]) };
+ let write_fd = unsafe { OwnedFd::from_raw_fd(fds[1]) };
+ drop(read_fd);
+ Stdio::from(write_fd)
+}
+
+fn run_with_closed_stdout(args: &[&str]) -> Output {
+ Command::new(env!("CARGO_BIN_EXE_herdr"))
+ .args(args)
+ .stdout(closed_pipe_writer())
+ .stderr(Stdio::piped())
+ .output()
+ .expect("run herdr CLI")
+}
+
+fn assert_quiet_sigpipe(output: Output) {
+ assert_eq!(output.status.signal(), Some(libc::SIGPIPE));
+ assert!(
+ output.stderr.is_empty(),
+ "closed stdout should not emit an error or panic: {}",
+ String::from_utf8_lossy(&output.stderr)
+ );
+}
+
+#[test]
+fn cli_exits_via_sigpipe_without_panicking_when_stdout_closes() {
+ assert_quiet_sigpipe(run_with_closed_stdout(&["api", "schema", "--json"]));
+}
+
+#[test]
+fn terminal_help_uses_cli_sigpipe_behavior_before_attach_starts() {
+ assert_quiet_sigpipe(run_with_closed_stdout(&["terminal", "attach", "--help"]));
+}
+
+#[test]
+fn completion_direct_writer_uses_cli_sigpipe_behavior() {
+ assert_quiet_sigpipe(run_with_closed_stdout(&["completion", "bash"]));
+}