// This file is part of the uutils coreutils package. // // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. use rstest::rstest; use uutests::new_ucmd; use uutests::util::TestScenario; use uutests::util_name; // spell-checker:ignore checkfile, testf, ntestf macro_rules! get_hash( ($str:expr) => ( $str.split(' ').collect::>()[0] ); ); macro_rules! test_digest_with_len { ($id:ident, $size:expr) => { mod $id { use uutests::util::*; use uutests::util_name; static LENGTH_ARG: &'static str = concat!("--length=", stringify!($size)); static EXPECTED_FILE: &'static str = concat!(stringify!($id), ".expected"); static CHECK_FILE: &'static str = concat!(stringify!($id), ".checkfile"); static INPUT_FILE: &'static str = "input.txt"; #[test] fn test_single_file() { let ts = TestScenario::new(util_name!()); assert_eq!( ts.fixtures.read(EXPECTED_FILE), get_hash!( ts.ucmd() .arg(LENGTH_ARG) .arg(INPUT_FILE) .succeeds() .no_stderr() .stdout_str() ) ); } #[test] fn test_stdin() { let ts = TestScenario::new(util_name!()); assert_eq!( ts.fixtures.read(EXPECTED_FILE), get_hash!( ts.ucmd() .arg(LENGTH_ARG) .pipe_in_fixture(INPUT_FILE) .succeeds() .no_stderr() .stdout_str() ) ); } #[test] fn test_check() { let ts = TestScenario::new(util_name!()); println!("File content='{}'", ts.fixtures.read(INPUT_FILE)); println!("Check file='{}'", ts.fixtures.read(CHECK_FILE)); ts.ucmd() .args(&[LENGTH_ARG, "--check", CHECK_FILE]) .succeeds() .no_stderr() .stdout_is("input.txt: OK\n"); } #[test] fn test_zero() { let ts = TestScenario::new(util_name!()); assert_eq!( ts.fixtures.read(EXPECTED_FILE), get_hash!( ts.ucmd() .arg(LENGTH_ARG) .arg("--zero") .arg(INPUT_FILE) .succeeds() .no_stderr() .stdout_str() ) ); } #[test] fn test_missing_file() { let ts = TestScenario::new(util_name!()); let at = &ts.fixtures; at.write("a", "file1\n"); at.write("c", "file3\n"); ts.ucmd() .args(&[LENGTH_ARG, "a", "b", "c"]) .fails() .stdout_contains("a\n") .stdout_contains("c\n") .stderr_contains("b: No such file or directory"); } } }; } test_digest_with_len! {b2sum, 512} #[test] fn test_check_b2sum_length_option_0() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; at.write("testf", "foobar\n"); at.write("testf.b2sum", "9e2bf63e933e610efee4a8d6cd4a9387e80860edee97e27db3b37a828d226ab1eb92a9cdd8ca9ca67a753edaf8bd89a0558496f67a30af6f766943839acf0110 testf\n"); scene .ccmd("b2sum") .arg("--length=0") .arg("-c") .arg(at.subdir.join("testf.b2sum")) .succeeds() .stdout_only("testf: OK\n"); } #[test] fn test_check_b2sum_length_duplicate() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; at.write("testf", "foobar\n"); scene .ccmd("b2sum") .arg("--length=123") .arg("--length=128") .arg("testf") .succeeds() .stdout_contains("d6d45901dec53e65d2b55fb6e2ab67b0"); } #[test] fn test_check_b2sum_length_option_8() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; at.write("testf", "foobar\n"); at.write("testf.b2sum", "6a testf\n"); scene .ccmd("b2sum") .arg("--length=8") .arg("-c") .arg(at.subdir.join("testf.b2sum")) .succeeds() .stdout_only("testf: OK\n"); } #[test] fn test_invalid_b2sum_length_option_not_multiple_of_8() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; at.write("testf", "foobar\n"); scene .ccmd("b2sum") .arg("--length=9") .arg(at.subdir.join("testf")) .fails_with_code(1) .stderr_contains("b2sum: invalid length: '9'") .stderr_contains("b2sum: length is not a multiple of 8"); } #[rstest] #[case("513")] #[case("1024")] #[case("18446744073709552000")] fn test_invalid_b2sum_length_option_too_large(#[case] len: &str) { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; at.write("testf", "foobar\n"); scene .ccmd("b2sum") .arg("--length") .arg(len) .arg(at.subdir.join("testf")) .fails_with_code(1) .no_stdout() .stderr_contains(format!("b2sum: invalid length: '{len}'")) .stderr_contains("b2sum: maximum digest length for 'BLAKE2b' is 512 bits"); } #[test] fn test_check_b2sum_tag_output() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; at.touch("f"); scene .ccmd("b2sum") .arg("--length=0") .arg("--tag") .arg("f") .succeeds() .stdout_only("BLAKE2b (f) = 786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce\n"); scene .ccmd("b2sum") .arg("--length=128") .arg("--tag") .arg("f") .succeeds() .stdout_only("BLAKE2b-128 (f) = cae66941d9efbd404e4d88758ea67670\n"); } #[test] fn test_check_b2sum_verify() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; at.write("a", "a\n"); scene .ccmd("b2sum") .arg("--tag") .arg("a") .succeeds() .stdout_only("BLAKE2b (a) = bedfbb90d858c2d67b7ee8f7523be3d3b54004ef9e4f02f2ad79a1d05bfdfe49b81e3c92ebf99b504102b6bf003fa342587f5b3124c205f55204e8c4b4ce7d7c\n"); scene .ccmd("b2sum") .arg("--tag") .arg("-l") .arg("128") .arg("a") .succeeds() .stdout_only("BLAKE2b-128 (a) = b93e0fc7bb21633c08bba07c5e71dc00\n"); } #[test] fn test_invalid_arg() { new_ucmd!().arg("--definitely-invalid").fails_with_code(1); } #[test] fn test_check_b2sum_strict_check() { let scene = TestScenario::new(util_name!()); let at = &scene.fixtures; at.touch("f"); let checksums = [ "2e f\n", "e4a6a0577479b2b4 f\n", "cae66941d9efbd404e4d88758ea67670 f\n", "246c0442cd564aced8145b8b60f1370aa7 f\n", "0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8 f\n", "4ded8c5fc8b12f3273f877ca585a44ad6503249a2b345d6d9c0e67d85bcb700db4178c0303e93b8f4ad758b8e2c9fd8b3d0c28e585f1928334bb77d36782e8 f\n", "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce f\n", ]; at.write("ck", &checksums.join("")); let output = "f: OK\n".to_string().repeat(checksums.len()); scene .ccmd("b2sum") .arg("-c") .arg(at.subdir.join("ck")) .succeeds() .stdout_only(&output); scene .ccmd("b2sum") .arg("--strict") .arg("-c") .arg(at.subdir.join("ck")) .succeeds() .stdout_only(&output); }