From 6884e29f976583a9835a63228ff85d8f7757f41e Mon Sep 17 00:00:00 2001 From: Nicolas Boichat Date: Thu, 24 Jul 2025 09:24:41 +0800 Subject: [PATCH] test_df: Use lossy stdout string The tests fail when a non-UTF8 path is mounted, that's... not a common case, but using a lossy string works just as well for the tests, so let's use that. --- tests/by-util/test_df.rs | 78 +++++++++++++++++------------------ tests/uutests/src/lib/util.rs | 5 +++ 2 files changed, 44 insertions(+), 39 deletions(-) diff --git a/tests/by-util/test_df.rs b/tests/by-util/test_df.rs index 35738d837..ecb60bc5f 100644 --- a/tests/by-util/test_df.rs +++ b/tests/by-util/test_df.rs @@ -117,7 +117,7 @@ fn test_df_output() { .arg("-H") .arg("--total") .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let actual = output.lines().take(1).collect::>()[0]; let actual = actual.split_whitespace().collect::>(); assert_eq!(actual, expected); @@ -151,7 +151,7 @@ fn test_df_output_overridden() { .arg("-hH") .arg("--total") .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let actual = output.lines().take(1).collect::>()[0]; let actual = actual.split_whitespace().collect::>(); assert_eq!(actual, expected); @@ -181,7 +181,7 @@ fn test_default_headers() { "on", ] }; - let output = new_ucmd!().succeeds().stdout_move_str(); + let output = new_ucmd!().succeeds().stdout_str_lossy(); let actual = output.lines().take(1).collect::>()[0]; let actual = actual.split_whitespace().collect::>(); assert_eq!(actual, expected); @@ -195,7 +195,7 @@ fn test_precedence_of_human_readable_and_si_header_over_output_header() { let output = new_ucmd!() .args(&[arg, "--output=size"]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let header = output.lines().next().unwrap(); assert_eq!(header, " Size"); } @@ -207,7 +207,7 @@ fn test_used_header_starts_with_space() { // using -h here to ensure the width of the column's content is <= 4 .args(&["-h", "--output=used"]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let header = output.lines().next().unwrap(); assert_eq!(header, " Used"); } @@ -226,11 +226,11 @@ fn test_order_same() { let output1 = new_ucmd!() .arg("--output=source") .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let output2 = new_ucmd!() .arg("--output=source") .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); assert_eq!(output1, output2); } @@ -238,7 +238,7 @@ fn test_order_same() { #[cfg(all(unix, not(target_os = "freebsd")))] // FIXME: fix this test for FreeBSD #[test] fn test_output_mp_repeat() { - let output1 = new_ucmd!().arg("/").arg("/").succeeds().stdout_move_str(); + let output1 = new_ucmd!().arg("/").arg("/").succeeds().stdout_str_lossy(); let output1: Vec = output1 .lines() .map(|l| String::from(l.split_once(' ').unwrap().0)) @@ -272,7 +272,7 @@ fn test_type_option() { let fs_types = new_ucmd!() .arg("--output=fstype") .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let fs_type = fs_types.lines().nth(1).unwrap().trim(); new_ucmd!().args(&["-t", fs_type]).succeeds(); @@ -292,7 +292,7 @@ fn test_type_option_with_file() { let fs_type = new_ucmd!() .args(&["--output=fstype", "."]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let fs_type = fs_type.lines().nth(1).unwrap().trim(); new_ucmd!().args(&["-t", fs_type, "."]).succeeds(); @@ -310,7 +310,7 @@ fn test_type_option_with_file() { let fs_types = new_ucmd!() .arg("--output=fstype") .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let fs_types: Vec<_> = fs_types .lines() .skip(1) @@ -335,7 +335,7 @@ fn test_exclude_all_types() { let fs_types = new_ucmd!() .arg("--output=fstype") .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let fs_types: HashSet<_> = fs_types.lines().skip(1).collect(); let mut args = Vec::new(); @@ -379,7 +379,7 @@ fn test_total() { // ... // /dev/loop14 63488 63488 0 100% /snap/core20/1361 // total 258775268 98099712 148220200 40% - - let output = new_ucmd!().arg("--total").succeeds().stdout_move_str(); + let output = new_ucmd!().arg("--total").succeeds().stdout_str_lossy(); // Skip the header line. let lines: Vec<&str> = output.lines().skip(1).collect(); @@ -422,21 +422,21 @@ fn test_total_label_in_correct_column() { let output = new_ucmd!() .args(&["--output=source", "--total", "."]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let last_line = output.lines().last().unwrap(); assert_eq!(last_line.trim(), "total"); let output = new_ucmd!() .args(&["--output=target", "--total", "."]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let last_line = output.lines().last().unwrap(); assert_eq!(last_line.trim(), "total"); let output = new_ucmd!() .args(&["--output=source,target", "--total", "."]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let last_line = output.lines().last().unwrap(); assert_eq!( last_line.split_whitespace().collect::>(), @@ -446,7 +446,7 @@ fn test_total_label_in_correct_column() { let output = new_ucmd!() .args(&["--output=target,source", "--total", "."]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let last_line = output.lines().last().unwrap(); assert_eq!( last_line.split_whitespace().collect::>(), @@ -463,7 +463,7 @@ fn test_use_percentage() { // "percentage" values. .args(&["--total", "--output=used,avail,pcent", "--block-size=1"]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); // Skip the header line. let lines: Vec<&str> = output.lines().skip(1).collect(); @@ -488,7 +488,7 @@ fn test_iuse_percentage() { let output = new_ucmd!() .args(&["--total", "--output=itotal,iused,ipcent"]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); // Skip the header line. let lines: Vec<&str> = output.lines().skip(1).collect(); @@ -518,7 +518,7 @@ fn test_default_block_size() { let output = new_ucmd!() .arg("--output=size") .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let header = output.lines().next().unwrap().trim().to_string(); assert_eq!(header, "1K-blocks"); @@ -527,7 +527,7 @@ fn test_default_block_size() { .arg("--output=size") .env("POSIXLY_CORRECT", "1") .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let header = output.lines().next().unwrap().trim().to_string(); assert_eq!(header, "512B-blocks"); @@ -547,14 +547,14 @@ fn test_default_block_size_in_posix_portability_mode() { .to_string() } - let output = new_ucmd!().arg("-P").succeeds().stdout_move_str(); + let output = new_ucmd!().arg("-P").succeeds().stdout_str_lossy(); assert_eq!(get_header(&output), "1024-blocks"); let output = new_ucmd!() .arg("-P") .env("POSIXLY_CORRECT", "1") .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); assert_eq!(get_header(&output), "512-blocks"); } @@ -564,7 +564,7 @@ fn test_block_size_1024() { let output = new_ucmd!() .args(&["-B", &format!("{block_size}"), "--output=size"]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); output.lines().next().unwrap().trim().to_string() } @@ -588,7 +588,7 @@ fn test_block_size_with_suffix() { let output = new_ucmd!() .args(&["-B", block_size, "--output=size"]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); output.lines().next().unwrap().trim().to_string() } @@ -612,7 +612,7 @@ fn test_block_size_in_posix_portability_mode() { let output = new_ucmd!() .args(&["-P", "-B", block_size]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); output .lines() .next() @@ -639,7 +639,7 @@ fn test_block_size_from_env() { .arg("--output=size") .env(env_var, env_value) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); output.lines().next().unwrap().trim().to_string() } @@ -658,7 +658,7 @@ fn test_block_size_from_env_precedences() { .env(k1, v1) .env(k2, v2) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); output.lines().next().unwrap().trim().to_string() } @@ -677,7 +677,7 @@ fn test_precedence_of_block_size_arg_over_env() { .args(&["-B", "999", "--output=size"]) .env("DF_BLOCK_SIZE", "111") .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let header = output.lines().next().unwrap().trim().to_string(); assert_eq!(header, "999B-blocks"); @@ -691,7 +691,7 @@ fn test_invalid_block_size_from_env() { .arg("--output=size") .env("DF_BLOCK_SIZE", "invalid") .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let header = output.lines().next().unwrap().trim().to_string(); assert_eq!(header, default_block_size_header); @@ -701,7 +701,7 @@ fn test_invalid_block_size_from_env() { .env("DF_BLOCK_SIZE", "invalid") .env("BLOCK_SIZE", "222") .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let header = output.lines().next().unwrap().trim().to_string(); assert_eq!(header, default_block_size_header); @@ -717,7 +717,7 @@ fn test_ignore_block_size_from_env_in_posix_portability_mode() { .env("BLOCK_SIZE", "222") .env("BLOCKSIZE", "333") .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let header = output .lines() .next() @@ -784,13 +784,13 @@ fn test_output_selects_columns() { let output = new_ucmd!() .args(&["--output=source"]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); assert_eq!(output.lines().next().unwrap(), "Filesystem"); let output = new_ucmd!() .args(&["--output=source,target"]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); assert_eq!( output .lines() @@ -804,7 +804,7 @@ fn test_output_selects_columns() { let output = new_ucmd!() .args(&["--output=source,target,used"]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); assert_eq!( output .lines() @@ -821,7 +821,7 @@ fn test_output_multiple_occurrences() { let output = new_ucmd!() .args(&["--output=source", "--output=target"]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); assert_eq!( output .lines() @@ -840,7 +840,7 @@ fn test_output_file_all_filesystems() { let output = new_ucmd!() .arg("--output=file") .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let mut lines = output.lines(); assert_eq!(lines.next().unwrap(), "File"); for line in lines { @@ -862,7 +862,7 @@ fn test_output_file_specific_files() { let output = ucmd .args(&["--output=file", "a", "b", "c"]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let actual: Vec<&str> = output.lines().collect(); assert_eq!(actual, vec!["File", "a", "b", "c"]); } @@ -876,7 +876,7 @@ fn test_file_column_width_if_filename_contains_unicode_chars() { let output = ucmd .args(&["--output=file,target", "äöü.txt"]) .succeeds() - .stdout_move_str(); + .stdout_str_lossy(); let actual = output.lines().next().unwrap(); // expected width: 7 chars (length of äöü.txt) + 1 char (column separator) assert_eq!(actual, "File Mounted on"); diff --git a/tests/uutests/src/lib/util.rs b/tests/uutests/src/lib/util.rs index 154a7aa18..1e71a3cf1 100644 --- a/tests/uutests/src/lib/util.rs +++ b/tests/uutests/src/lib/util.rs @@ -357,6 +357,11 @@ impl CmdResult { std::str::from_utf8(&self.stdout).unwrap() } + /// Returns the program's standard output as a string, automatically handling invalid utf8 + pub fn stdout_str_lossy(self) -> String { + String::from_utf8_lossy(&self.stdout).to_string() + } + /// Returns the program's standard output as a string /// consumes self pub fn stdout_move_str(self) -> String {