diff --git a/tests/by-util/test_cksum.rs b/tests/by-util/test_cksum.rs index b73ee1425d..64c61cda29 100644 --- a/tests/by-util/test_cksum.rs +++ b/tests/by-util/test_cksum.rs @@ -1284,6 +1284,18 @@ fn test_several_files_error_mgmt() { .stderr_contains("incorrect: no properly "); } +#[test] +fn test_check_unknown_checksum_file() { + let scene = TestScenario::new(util_name!()); + + scene + .ucmd() + .arg("--check") + .arg("missing") + .fails() + .stderr_only("cksum: missing: No such file or directory\n"); +} + #[test] fn test_check_comment_line() { // A comment in a checksum file shall be discarded unnoticed. @@ -1811,6 +1823,374 @@ mod gnu_cksum_base64 { } } +/// This module reimplements the cksum-c.sh GNU test. +mod gnu_cksum_c { + use super::*; + + const INVALID_SUM: &str = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaafdb57c725157cb40b5aee8d937b8351477e"; + + fn make_scene() -> TestScenario { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + at.write("input", "9\n7\n1\n4\n2\n6\n3\n5\n8\n10\n"); + + let algos: &[&[&str]] = &[ + &["-a", "sha384"], + &["-a", "blake2b"], + &["-a", "blake2b", "-l", "384"], + &["-a", "sm3"], + ]; + + for args in algos { + let result = scene.ucmd().args(args).succeeds(); + let stdout = result.stdout(); + at.append_bytes("CHECKSUMS", stdout); + } + + scene + } + + #[test] + #[ignore] + fn test_signed_checksums() { + todo!() + } + + #[test] + fn test_check_individual_digests_in_mixed_file() { + let scene = make_scene(); + + scene + .ucmd() + .arg("--check") + .arg("-a") + .arg("sm3") + .arg("CHECKSUMS") + .succeeds(); + } + + #[test] + fn test_check_against_older_non_hex_formats() { + let scene = make_scene(); + + scene + .ucmd() + .arg("-c") + .arg("-a") + .arg("crc") + .arg("CHECKSUMS") + .fails(); + + let crc_cmd = scene.ucmd().arg("-a").arg("crc").arg("input").succeeds(); + let crc_cmd_out = crc_cmd.stdout(); + scene.fixtures.write_bytes("CHECKSUMS.crc", crc_cmd_out); + + scene.ucmd().arg("-c").arg("CHECKSUMS.crc").fails(); + } + + #[test] + fn test_status() { + let scene = make_scene(); + + scene + .ucmd() + .arg("--status") + .arg("--check") + .arg("CHECKSUMS") + .succeeds() + .no_output(); + } + + fn make_scene_with_comment() -> TestScenario { + let scene = make_scene(); + + scene + .fixtures + .append("CHECKSUMS", "# Very important comment\n"); + + scene + } + + #[test] + fn test_status_with_comment() { + let scene = make_scene_with_comment(); + + scene + .ucmd() + .arg("--status") + .arg("--check") + .arg("CHECKSUMS") + .succeeds() + .no_output(); + } + + fn make_scene_with_invalid_line() -> TestScenario { + let scene = make_scene_with_comment(); + + scene.fixtures.append("CHECKSUMS", "invalid_line\n"); + + scene + } + + #[test] + fn test_check_strict() { + let scene = make_scene_with_invalid_line(); + + // without strict, succeeds + scene + .ucmd() + .arg("--check") + .arg("CHECKSUMS") + .succeeds() + .stderr_contains("1 line is improperly formatted"); + + // with strict, fails + scene + .ucmd() + .arg("--strict") + .arg("--check") + .arg("CHECKSUMS") + .fails() + .stderr_contains("1 line is improperly formatted"); + } + + fn make_scene_with_two_invalid_lines() -> TestScenario { + let scene = make_scene_with_comment(); + + scene + .fixtures + .append("CHECKSUMS", "invalid_line\ninvalid_line\n"); + + scene + } + + #[test] + fn test_check_strict_plural_checks() { + let scene = make_scene_with_two_invalid_lines(); + + scene + .ucmd() + .arg("--strict") + .arg("--check") + .arg("CHECKSUMS") + .fails() + .stderr_contains("2 lines are improperly formatted"); + } + + fn make_scene_with_incorrect_checksum() -> TestScenario { + let scene = make_scene_with_two_invalid_lines(); + + scene + .fixtures + .append("CHECKSUMS", &format!("SM3 (input) = {INVALID_SUM}\n")); + + scene + } + + #[test] + fn test_check_with_incorrect_checksum() { + let scene = make_scene_with_incorrect_checksum(); + + scene + .ucmd() + .arg("--check") + .arg("CHECKSUMS") + .fails() + .stdout_contains("input: FAILED") + .stderr_contains("1 computed checksum did NOT match"); + + // also fails with strict + scene + .ucmd() + .arg("--strict") + .arg("--check") + .arg("CHECKSUMS") + .fails() + .stdout_contains("input: FAILED") + .stderr_contains("1 computed checksum did NOT match"); + } + + #[test] + fn test_status_with_errors() { + let scene = make_scene_with_incorrect_checksum(); + + scene + .ucmd() + .arg("--status") + .arg("--check") + .arg("CHECKSUMS") + .fails() + .no_output(); + } + + #[test] + fn test_check_with_non_existing_file() { + let scene = make_scene(); + scene + .fixtures + .write("CHECKSUMS2", &format!("SM3 (input2) = {INVALID_SUM}\n")); + + scene + .ucmd() + .arg("--check") + .arg("CHECKSUMS2") + .fails() + .stdout_contains("input2: FAILED open or read") + .stderr_contains("1 listed file could not be read"); + + // also fails with strict + scene + .ucmd() + .arg("--strict") + .arg("--check") + .arg("CHECKSUMS2") + .fails() + .stdout_contains("input2: FAILED open or read") + .stderr_contains("1 listed file could not be read"); + } + + fn make_scene_with_another_improperly_formatted() -> TestScenario { + let scene = make_scene_with_incorrect_checksum(); + + scene.fixtures.append( + "CHECKSUMS", + &format!("BLAKE2b (missing-file) = {INVALID_SUM}\n"), + ); + + scene + } + + #[test] + fn test_warn() { + let scene = make_scene_with_another_improperly_formatted(); + + scene + .ucmd() + .arg("--warn") + .arg("--check") + .arg("CHECKSUMS") + .run() + .stderr_contains("CHECKSUMS: 6: improperly formatted SM3 checksum line") + .stderr_contains("CHECKSUMS: 9: improperly formatted BLAKE2b checksum line"); + } + + fn make_scene_with_checksum_missing() -> TestScenario { + let scene = make_scene_with_another_improperly_formatted(); + + scene.fixtures.write( + "CHECKSUMS-missing", + &format!("SM3 (nonexistent) = {INVALID_SUM}\n"), + ); + + scene + } + + #[test] + fn test_ignore_missing() { + let scene = make_scene_with_checksum_missing(); + + scene + .ucmd() + .arg("--ignore-missing") + .arg("--check") + .arg("CHECKSUMS-missing") + .fails() + .stdout_does_not_contain("nonexistent: No such file or directory") + .stdout_does_not_contain("nonexistent: FAILED open or read") + .stderr_contains("CHECKSUMS-missing: no file was verified"); + } + + #[test] + fn test_status_and_warn() { + let scene = make_scene_with_checksum_missing(); + + // --status before --warn + scene + .ucmd() + .arg("--status") + .arg("--warn") + .arg("--check") + .arg("CHECKSUMS") + .fails() + .stderr_contains("CHECKSUMS: 9: improperly formatted BLAKE2b checksum line") + .stderr_contains("WARNING: 3 lines are improperly formatted") + .stderr_contains("WARNING: 1 computed checksum did NOT match"); + + // --warn before --status (status hides the results) + scene + .ucmd() + .arg("--warn") + .arg("--status") + .arg("--check") + .arg("CHECKSUMS") + .fails() + .stderr_does_not_contain("CHECKSUMS: 9: improperly formatted BLAKE2b checksum line") + .stderr_does_not_contain("WARNING: 3 lines are improperly formatted") + .stderr_does_not_contain("WARNING: 1 computed checksum did NOT match"); + } + + #[test] + fn test_status_and_ignore_missing() { + let scene = make_scene_with_checksum_missing(); + + scene + .ucmd() + .arg("--status") + .arg("--ignore-missing") + .arg("--check") + .arg("CHECKSUMS") + .run() + .no_output() + .code_is(1); + } + + #[test] + fn test_status_warn_and_ignore_missing() { + let scene = make_scene_with_checksum_missing(); + + scene + .ucmd() + .arg("--status") + .arg("--warn") + .arg("--ignore-missing") + .arg("--check") + .arg("CHECKSUMS-missing") + .fails() + .stderr_contains("CHECKSUMS-missing: no file was verified") + .stdout_does_not_contain("nonexistent: No such file or directory"); + } + + #[test] + fn test_check_several_files_dont_exist() { + let scene = make_scene(); + + scene + .ucmd() + .arg("--check") + .arg("non-existing-1") + .arg("non-existing-2") + .fails() + .stderr_contains("non-existing-1: No such file or directory") + .stderr_contains("non-existing-2: No such file or directory"); + } + + #[test] + fn test_check_several_files_empty() { + let scene = make_scene(); + scene.fixtures.touch("empty-1"); + scene.fixtures.touch("empty-2"); + + scene + .ucmd() + .arg("--check") + .arg("empty-1") + .arg("empty-2") + .fails() + .stderr_contains("empty-1: no properly formatted checksum lines found") + .stderr_contains("empty-2: no properly formatted checksum lines found"); + } +} + /// The tests in this module check the behavior of cksum when given different /// checksum formats and algorithms in the same file, while specifying an /// algorithm on CLI or not.