|
3 | 3 | // For the full copyright and license information, please view the LICENSE |
4 | 4 | // file that was distributed with this source code. |
5 | 5 | // spell-checker:ignore lmnop xlmnop |
| 6 | +use rstest::rstest; |
6 | 7 | use uutests::new_ucmd; |
| 8 | +#[cfg(unix)] |
| 9 | +use uutests::util::TestScenario; |
| 10 | +#[cfg(unix)] |
| 11 | +use uutests::util_name; |
7 | 12 |
|
8 | 13 | #[test] |
9 | 14 | fn test_invalid_arg() { |
10 | 15 | new_ucmd!().arg("--definitely-invalid").fails_with_code(1); |
11 | 16 | } |
12 | 17 |
|
13 | | -#[test] |
14 | | -#[cfg(unix)] |
15 | | -fn test_broken_pipe_still_exits_success() { |
16 | | - use std::process::Stdio; |
17 | | - |
18 | | - let mut child = new_ucmd!() |
19 | | - // Use an infinite sequence so a burst of output happens immediately after spawn. |
20 | | - // With small output the process can finish before stdout is closed and the Broken pipe never occurs. |
21 | | - .args(&["inf"]) |
22 | | - .set_stdout(Stdio::piped()) |
23 | | - .run_no_wait(); |
24 | | - |
25 | | - // Trigger a Broken pipe by writing to a pipe whose reader closed first. |
26 | | - child.close_stdout(); |
27 | | - let result = child.wait().unwrap(); |
28 | | - |
29 | | - result |
30 | | - .code_is(0) |
31 | | - .stderr_contains("write error: Broken pipe"); |
32 | | -} |
33 | | - |
34 | 18 | #[test] |
35 | 19 | fn test_no_args() { |
36 | 20 | new_ucmd!() |
@@ -203,6 +187,24 @@ fn test_width_invalid_float() { |
203 | 187 | .usage_error("invalid floating point argument: '1e2.3'"); |
204 | 188 | } |
205 | 189 |
|
| 190 | +#[test] |
| 191 | +#[cfg(unix)] |
| 192 | +fn test_sigpipe_ignored_reports_write_error() { |
| 193 | + let scene = TestScenario::new(util_name!()); |
| 194 | + let seq_bin = scene.bin_path.clone().into_os_string(); |
| 195 | + let script = "trap '' PIPE; { \"$SEQ_BIN\" seq inf 2>err; echo $? >code; } | head -n1"; |
| 196 | + let result = scene.cmd_shell(script).env("SEQ_BIN", &seq_bin).succeeds(); |
| 197 | + |
| 198 | + assert_eq!(result.stdout_str(), "1\n"); |
| 199 | + |
| 200 | + let err_contents = scene.fixtures.read("err"); |
| 201 | + assert!( |
| 202 | + err_contents.contains("seq: write error: Broken pipe"), |
| 203 | + "stderr missing write error message: {err_contents:?}" |
| 204 | + ); |
| 205 | + assert_eq!(scene.fixtures.read("code"), "1\n"); |
| 206 | +} |
| 207 | + |
206 | 208 | // ---- Tests for the big integer based path ---- |
207 | 209 |
|
208 | 210 | #[test] |
@@ -648,52 +650,49 @@ fn test_width_floats() { |
648 | 650 | .stdout_only("09.0\n10.0\n"); |
649 | 651 | } |
650 | 652 |
|
651 | | -#[test] |
652 | | -fn test_neg_inf() { |
653 | | - new_ucmd!() |
654 | | - .args(&["--", "-inf", "0"]) |
655 | | - .run_stdout_starts_with(b"-inf\n-inf\n-inf\n") |
656 | | - .success(); |
657 | | -} |
658 | | - |
659 | | -#[test] |
660 | | -fn test_neg_infinity() { |
661 | | - new_ucmd!() |
662 | | - .args(&["--", "-infinity", "0"]) |
663 | | - .run_stdout_starts_with(b"-inf\n-inf\n-inf\n") |
664 | | - .success(); |
665 | | -} |
666 | | - |
667 | | -#[test] |
668 | | -fn test_inf() { |
669 | | - new_ucmd!() |
670 | | - .args(&["inf"]) |
671 | | - .run_stdout_starts_with(b"1\n2\n3\n") |
672 | | - .success(); |
673 | | -} |
674 | | - |
675 | | -#[test] |
676 | | -fn test_infinity() { |
677 | | - new_ucmd!() |
678 | | - .args(&["infinity"]) |
679 | | - .run_stdout_starts_with(b"1\n2\n3\n") |
680 | | - .success(); |
681 | | -} |
682 | | - |
683 | | -#[test] |
684 | | -fn test_inf_width() { |
685 | | - new_ucmd!() |
686 | | - .args(&["-w", "1.000", "inf", "inf"]) |
687 | | - .run_stdout_starts_with(b"1.000\n inf\n inf\n inf\n") |
688 | | - .success(); |
689 | | -} |
690 | | - |
691 | | -#[test] |
692 | | -fn test_neg_inf_width() { |
693 | | - new_ucmd!() |
694 | | - .args(&["-w", "1.000", "-inf", "-inf"]) |
695 | | - .run_stdout_starts_with(b"1.000\n -inf\n -inf\n -inf\n") |
696 | | - .success(); |
| 653 | +/// Test infinite sequences - these produce endless output, so we check they start correctly |
| 654 | +/// and terminate with SIGPIPE on Unix (or succeed on non-Unix where pipe behavior differs). |
| 655 | +#[rstest] |
| 656 | +#[case::neg_inf( |
| 657 | + &["--", "-inf", "0"], |
| 658 | + b"-inf\n-inf\n-inf\n" |
| 659 | +)] |
| 660 | +#[case::neg_infinity( |
| 661 | + &["--", "-infinity", "0"], |
| 662 | + b"-inf\n-inf\n-inf\n" |
| 663 | +)] |
| 664 | +#[case::inf( |
| 665 | + &["inf"], |
| 666 | + b"1\n2\n3\n" |
| 667 | +)] |
| 668 | +#[case::infinity( |
| 669 | + &["infinity"], |
| 670 | + b"1\n2\n3\n" |
| 671 | +)] |
| 672 | +#[case::inf_width( |
| 673 | + &["-w", "1.000", "inf", "inf"], |
| 674 | + b"1.000\n inf\n inf\n inf\n" |
| 675 | +)] |
| 676 | +#[case::neg_inf_width( |
| 677 | + &["-w", "1.000", "-inf", "-inf"], |
| 678 | + b"1.000\n -inf\n -inf\n -inf\n" |
| 679 | +)] |
| 680 | +#[case::precision_inf( |
| 681 | + &["1", "1.2", "inf"], |
| 682 | + b"1.0\n2.2\n3.4\n" |
| 683 | +)] |
| 684 | +#[case::equalize_width_inf( |
| 685 | + &["-w", "1", "1.2", "inf"], |
| 686 | + b"1.0\n2.2\n3.4\n" |
| 687 | +)] |
| 688 | +fn test_infinite_sequence(#[case] args: &[&str], #[case] expected_start: &[u8]) { |
| 689 | + let result = new_ucmd!() |
| 690 | + .args(args) |
| 691 | + .run_stdout_starts_with(expected_start); |
| 692 | + #[cfg(unix)] |
| 693 | + result.signal_name_is("PIPE"); |
| 694 | + #[cfg(not(unix))] |
| 695 | + result.success(); |
697 | 696 | } |
698 | 697 |
|
699 | 698 | #[test] |
@@ -1073,12 +1072,6 @@ fn test_precision_corner_cases() { |
1073 | 1072 | .args(&["1", "1.20", "3.000000"]) |
1074 | 1073 | .succeeds() |
1075 | 1074 | .stdout_is("1.00\n2.20\n"); |
1076 | | - |
1077 | | - // Infinity is ignored |
1078 | | - new_ucmd!() |
1079 | | - .args(&["1", "1.2", "inf"]) |
1080 | | - .run_stdout_starts_with(b"1.0\n2.2\n3.4\n") |
1081 | | - .success(); |
1082 | 1075 | } |
1083 | 1076 |
|
1084 | 1077 | // GNU `seq` manual only makes guarantees about `-w` working if the |
@@ -1135,11 +1128,4 @@ fn test_equalize_widths_corner_cases() { |
1135 | 1128 | .args(&["-w", "0x1.1", "1.00002", "3"]) |
1136 | 1129 | .succeeds() |
1137 | 1130 | .stdout_is("1.0625\n2.06252\n"); |
1138 | | - |
1139 | | - // We can't really pad with infinite number of zeros, so `-w` is ignored. |
1140 | | - // (there is another test with infinity as an increment above) |
1141 | | - new_ucmd!() |
1142 | | - .args(&["-w", "1", "1.2", "inf"]) |
1143 | | - .run_stdout_starts_with(b"1.0\n2.2\n3.4\n") |
1144 | | - .success(); |
1145 | 1131 | } |
0 commit comments