From a557bc55ef3c136b1fca3f27cd55fdb0014dc6e7 Mon Sep 17 00:00:00 2001 From: Ming-Hung Tsai Date: Fri, 23 Feb 2024 20:20:01 +0800 Subject: [PATCH 10/10] [thin_dump] Do not print error messages on BrokenPipe (EPIPE) Handle the case that doesn't write through quick_xml, e.g., thin_dump --format human_readable (cherry picked from commit b3e05f2eb9b704af897f14215536dadde5c13b2d) --- src/commands/utils.rs | 7 +++++-- tests/thin_dump.rs | 34 +++++++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/commands/utils.rs b/src/commands/utils.rs index 38751603..82b2529e 100644 --- a/src/commands/utils.rs +++ b/src/commands/utils.rs @@ -165,8 +165,11 @@ pub fn to_exit_code(report: &Report, result: anyhow::Result) -> exitcode:: let root_cause = e.root_cause(); let is_broken_pipe = root_cause .downcast_ref::>() // quick_xml::Error::Io wraps io::Error in Arc - .map(|err| err.kind() == std::io::ErrorKind::BrokenPipe) - .unwrap_or(false); + .map_or_else( + || root_cause.downcast_ref::(), + |err| Some(err.as_ref()), + ) + .map_or(false, |err| err.kind() == std::io::ErrorKind::BrokenPipe); if !is_broken_pipe { if e.chain().len() > 1 { diff --git a/tests/thin_dump.rs b/tests/thin_dump.rs index 6e2cd3db..81982188 100644 --- a/tests/thin_dump.rs +++ b/tests/thin_dump.rs @@ -142,8 +142,7 @@ fn no_stderr_on_success() -> Result<()> { //------------------------------------------ // test no stderr on broken pipe errors -#[test] -fn no_stderr_on_broken_pipe() -> Result<()> { +fn test_no_stderr_on_broken_pipe(extra_args: &[&std::ffi::OsStr]) -> Result<()> { use anyhow::ensure; let mut td = TestDir::new()?; @@ -157,7 +156,9 @@ fn no_stderr_on_broken_pipe() -> Result<()> { ensure!(libc::pipe2(pipefd.as_mut_slice().as_mut_ptr(), libc::O_CLOEXEC) == 0); } - let cmd = thin_dump_cmd(args![&md]) + let mut args = args![&md].to_vec(); + args.extend_from_slice(extra_args); + let cmd = thin_dump_cmd(args) .to_expr() .stdout_file(pipefd[1]) .stderr_capture(); @@ -179,7 +180,16 @@ fn no_stderr_on_broken_pipe() -> Result<()> { } #[test] -fn no_stderr_on_broken_fifo() -> Result<()> { +fn no_stderr_on_broken_pipe_xml() -> Result<()> { + test_no_stderr_on_broken_pipe(&[]) +} + +#[test] +fn no_stderr_on_broken_pipe_humanreadable() -> Result<()> { + test_no_stderr_on_broken_pipe(&args!["--format", "human_readable"]) +} + +fn test_no_stderr_on_broken_fifo(extra_args: &[&std::ffi::OsStr]) -> Result<()> { use anyhow::ensure; let mut td = TestDir::new()?; @@ -194,9 +204,9 @@ fn no_stderr_on_broken_fifo() -> Result<()> { ensure!(libc::mkfifo(c_str.as_ptr(), 0o666) == 0); }; - let cmd = thin_dump_cmd(args![&md, "-o", &out_fifo]) - .to_expr() - .stderr_capture(); + let mut args = args![&md, "-o", &out_fifo].to_vec(); + args.extend_from_slice(extra_args); + let cmd = thin_dump_cmd(args).to_expr().stderr_capture(); let handle = cmd.unchecked().start()?; let fifo = std::fs::File::open(out_fifo)?; @@ -209,6 +219,16 @@ fn no_stderr_on_broken_fifo() -> Result<()> { Ok(()) } +#[test] +fn no_stderr_on_broken_fifo_xml() -> Result<()> { + test_no_stderr_on_broken_fifo(&[]) +} + +#[test] +fn no_stderr_on_broken_fifo_humanreadable() -> Result<()> { + test_no_stderr_on_broken_fifo(&args!["--format", "human_readable"]) +} + //------------------------------------------ // test dump metadata snapshot from a live metadata // here we use a corrupted metadata to ensure that "thin_dump -m" reads the -- 2.43.0