use std::env;
use std::fs;
use std::io::Write;
use std::path::PathBuf;
use std::process::{Command, Stdio};
const MKTOOL: &str = env!("CARGO_BIN_EXE_mktool");
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
#[test]
fn test_checksum_invalid_args() -> Result<()> {
let cmd = Command::new(MKTOOL).arg("checksum").output()?;
assert_eq!(cmd.status.code(), Some(2));
Ok(())
}
#[test]
fn test_checksum_no_input() -> Result<()> {
let mut distinfo = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
distinfo.push("tests/data/distinfo");
let cmd = Command::new(MKTOOL).arg("checksum").arg(distinfo).output()?;
assert_eq!(cmd.status.code(), Some(0));
assert_eq!(cmd.stdout, "".as_bytes());
assert_eq!(cmd.stderr, "".as_bytes());
Ok(())
}
#[test]
fn test_checksum_bad_distinfo() -> Result<()> {
let distinfo = PathBuf::from("/nonexistent");
let cmd = Command::new(MKTOOL).arg("checksum").arg(&distinfo).output()?;
let stderr = String::from_utf8_lossy(&cmd.stderr);
assert_eq!(cmd.status.code(), Some(3));
assert_eq!(cmd.stdout, "".as_bytes());
assert!(
stderr.contains("/nonexistent"),
"expected filename in error: {stderr}"
);
assert!(
stderr.contains("No such file") || stderr.contains("not found"),
"expected error reason: {stderr}"
);
Ok(())
}
#[test]
fn test_checksum_bad_distfile() -> Result<()> {
let mut distinfo = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
distinfo.push("tests/data/distinfo");
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg(&distinfo)
.arg("foo")
.output()?;
assert_eq!(cmd.status.code(), Some(2));
assert_eq!(cmd.stdout, "".as_bytes());
assert_eq!(
cmd.stderr,
"checksum: No checksum recorded for foo\n".as_bytes()
);
Ok(())
}
#[test]
fn test_checksum_valid_distfile() -> Result<()> {
let mut distinfo = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
distinfo.push("tests/data/distinfo");
let output = format!(
"{}\n{}\n",
"=> Checksum BLAKE2s OK for digest1.txt",
"=> Checksum SHA512 OK for digest1.txt"
);
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg(&distinfo)
.arg("digest1.txt")
.current_dir("tests/data")
.output()?;
assert_eq!(cmd.status.code(), Some(0));
assert_eq!(cmd.stdout, output.as_bytes());
assert_eq!(cmd.stderr, "".as_bytes());
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg(&distinfo)
.arg("../data/digest1.txt")
.current_dir("tests/data")
.output()?;
assert_eq!(cmd.status.code(), Some(0));
assert_eq!(cmd.stdout, output.as_bytes());
assert_eq!(cmd.stderr, "".as_bytes());
let output = "=> Checksum BLAKE2s OK for digest1.txt\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-a")
.arg("BLAKE2s")
.arg(&distinfo)
.arg("digest1.txt")
.current_dir("tests/data")
.output()?;
assert_eq!(cmd.status.code(), Some(0));
assert_eq!(cmd.stdout, output.as_bytes());
assert_eq!(cmd.stderr, "".as_bytes());
let output = "=> Checksum SHA512 OK for digest2.txt\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-a")
.arg("SHA512")
.arg(&distinfo)
.arg("digest2.txt")
.current_dir("tests/data")
.output()?;
assert_eq!(cmd.status.code(), Some(0));
assert_eq!(cmd.stdout, output.as_bytes());
assert_eq!(cmd.stderr, "".as_bytes());
let output = format!(
"{}\n{}\n{}\n{}\n",
"=> Checksum BLAKE2s OK for digest1.txt",
"=> Checksum SHA512 OK for digest1.txt",
"=> Checksum BLAKE2s OK for digest2.txt",
"=> Checksum SHA512 OK for digest2.txt"
);
let outerr = "checksum: No checksum recorded for digest11.txt\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg(&distinfo)
.arg("digest2.txt")
.arg("digest11.txt")
.arg("digest1.txt")
.current_dir("tests/data")
.output()?;
assert_eq!(cmd.status.code(), Some(2));
assert_eq!(cmd.stdout, output.as_bytes());
assert_eq!(cmd.stderr, outerr.as_bytes());
Ok(())
}
#[test]
fn test_checksum_input_file() -> Result<()> {
let mut distinfo = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
distinfo.push("tests/data/distinfo");
let tmpdir = PathBuf::from(env!("CARGO_TARGET_TMPDIR"));
let tmpfile = tmpdir.join("test_checksum_input_file.txt");
fs::write(&tmpfile, "digest2.txt\n")?;
let output = format!(
"{}\n{}\n{}\n{}\n",
"=> Checksum BLAKE2s OK for digest1.txt",
"=> Checksum SHA512 OK for digest1.txt",
"=> Checksum BLAKE2s OK for digest2.txt",
"=> Checksum SHA512 OK for digest2.txt"
);
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg(&distinfo)
.arg("-I")
.arg(&tmpfile)
.arg("digest1.txt")
.current_dir("tests/data")
.output()?;
fs::remove_file(&tmpfile)?;
assert_eq!(cmd.status.code(), Some(0));
assert_eq!(cmd.stdout, output.as_bytes());
assert_eq!(cmd.stderr, "".as_bytes());
Ok(())
}
#[test]
fn test_checksum_input_stdin() -> Result<()> {
let mut distinfo = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
distinfo.push("tests/data/distinfo");
let output = format!(
"{}\n{}\n{}\n{}\n",
"=> Checksum BLAKE2s OK for digest1.txt",
"=> Checksum SHA512 OK for digest1.txt",
"=> Checksum BLAKE2s OK for digest2.txt",
"=> Checksum SHA512 OK for digest2.txt"
);
let mut cmd = Command::new(MKTOOL)
.arg("checksum")
.arg(&distinfo)
.arg("-I")
.arg("-")
.arg("digest2.txt")
.current_dir("tests/data")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()?;
let mut stdin = cmd.stdin.take().ok_or("failed to open stdin")?;
std::thread::spawn(move || {
let _ = stdin.write_all("digest1.txt".as_bytes());
});
let out = cmd.wait_with_output()?;
assert_eq!(out.status.code(), Some(0));
assert_eq!(out.stdout, output.as_bytes());
assert_eq!(out.stderr, "".as_bytes());
Ok(())
}
#[test]
fn test_checksum_strip_mode() -> Result<()> {
let mut distinfo = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
distinfo.push("tests/data/distinfo");
let output = "=> Checksum SHA512 OK for digest1.txt\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-a")
.arg("SHA512")
.arg("-s")
.arg(".suffix")
.arg(&distinfo)
.arg("digest1.txt.suffix")
.current_dir("tests/data")
.output()?;
assert_eq!(cmd.status.code(), Some(0));
assert_eq!(cmd.stdout, output.as_bytes());
assert_eq!(cmd.stderr, "".as_bytes());
let output = "checksum: No checksum recorded for digest1.txt.suffix\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-s")
.arg(".badsuffix")
.arg(&distinfo)
.arg("digest1.txt.suffix")
.current_dir("tests/data")
.output()?;
assert_eq!(cmd.status.code(), Some(2));
assert_eq!(cmd.stdout, "".as_bytes());
assert_eq!(cmd.stderr, output.as_bytes());
Ok(())
}
#[test]
fn test_checksum_strip_opens_original() -> Result<()> {
let mut distinfo = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
distinfo.push("tests/data/distinfo");
let mut src = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
src.push("tests/data/digest1.txt");
let tmpdir = PathBuf::from(env!("CARGO_TARGET_TMPDIR"))
.join("test_checksum_strip_opens_original");
fs::create_dir_all(&tmpdir)?;
let tmpfile = tmpdir.join("digest1.txt.fetchtmp");
fs::copy(&src, &tmpfile)?;
assert!(!tmpdir.join("digest1.txt").exists());
let output = "=> Checksum SHA512 OK for digest1.txt\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-a")
.arg("SHA512")
.arg("-s")
.arg(".fetchtmp")
.arg(&distinfo)
.arg("digest1.txt.fetchtmp")
.current_dir(&tmpdir)
.output()?;
assert_eq!(cmd.status.code(), Some(0));
assert_eq!(cmd.stdout, output.as_bytes());
assert_eq!(cmd.stderr, "".as_bytes());
let output = "checksum: No SHA1 checksum recorded for digest1.txt\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-a")
.arg("SHA1")
.arg("-s")
.arg(".fetchtmp")
.arg(&distinfo)
.arg("digest1.txt.fetchtmp")
.current_dir(&tmpdir)
.output()?;
fs::remove_dir_all(&tmpdir)?;
assert_eq!(cmd.status.code(), Some(2));
assert_eq!(cmd.stdout, "".as_bytes());
assert_eq!(cmd.stderr, output.as_bytes());
Ok(())
}
#[test]
fn test_checksum_strip_input() -> Result<()> {
let mut distinfo = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
distinfo.push("tests/data/distinfo");
let tmpdir = PathBuf::from(env!("CARGO_TARGET_TMPDIR"));
let tmpfile = tmpdir.join("test_checksum_strip_input.txt");
fs::write(&tmpfile, "digest1.txt.suffix\n")?;
let output = "=> Checksum SHA512 OK for digest1.txt\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-a")
.arg("SHA512")
.arg("-s")
.arg(".suffix")
.arg("-I")
.arg(&tmpfile)
.arg(&distinfo)
.current_dir("tests/data")
.output()?;
fs::remove_file(&tmpfile)?;
assert_eq!(cmd.status.code(), Some(0));
assert_eq!(cmd.stdout, output.as_bytes());
assert_eq!(cmd.stderr, "".as_bytes());
let tmpfile = tmpdir.join("test_checksum_strip_input_nomatch.txt");
fs::write(&tmpfile, "digest1.txt\n")?;
let output = "=> Checksum SHA512 OK for digest1.txt\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-a")
.arg("SHA512")
.arg("-s")
.arg(".badsuffix")
.arg("-I")
.arg(&tmpfile)
.arg(&distinfo)
.current_dir("tests/data")
.output()?;
fs::remove_file(&tmpfile)?;
assert_eq!(cmd.status.code(), Some(0));
assert_eq!(cmd.stdout, output.as_bytes());
assert_eq!(cmd.stderr, "".as_bytes());
Ok(())
}
#[test]
fn test_checksum_bad_input_file() -> Result<()> {
let mut distinfo = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
distinfo.push("tests/data/distinfo");
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-I")
.arg("/nonexistent/inputfile")
.arg(&distinfo)
.output()?;
let stderr = String::from_utf8_lossy(&cmd.stderr);
assert_eq!(cmd.status.code(), Some(1));
assert!(
stderr.contains("/nonexistent/inputfile"),
"expected filename in error: {stderr}"
);
assert!(
stderr.contains("No such file") || stderr.contains("not found"),
"expected error reason: {stderr}"
);
Ok(())
}
#[test]
fn test_checksum_bad_distfile_algorithm() -> Result<()> {
let mut distinfo = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
distinfo.push("tests/data/distinfo");
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-a")
.arg("SHA512")
.arg(&distinfo)
.arg("foo")
.output()?;
assert_eq!(cmd.status.code(), Some(2));
assert_eq!(cmd.stdout, "".as_bytes());
assert_eq!(
cmd.stderr,
"checksum: No SHA512 checksum recorded for foo\n".as_bytes()
);
Ok(())
}
#[test]
fn test_checksum_bad_algorithm() -> Result<()> {
let mut distinfo = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
distinfo.push("tests/data/distinfo");
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-a")
.arg("BOGUS")
.arg(&distinfo)
.arg("digest1.txt")
.current_dir("tests/data")
.output()?;
let stderr = String::from_utf8_lossy(&cmd.stderr);
assert_ne!(cmd.status.code(), Some(0));
assert!(
stderr.contains("BOGUS"),
"expected algorithm name in error: {stderr}"
);
Ok(())
}
#[test]
fn test_checksum_jobs_flag() -> Result<()> {
let mut distinfo = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
distinfo.push("tests/data/distinfo");
let output = "=> Checksum SHA512 OK for digest1.txt\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-a")
.arg("SHA512")
.arg("-j")
.arg("1")
.arg(&distinfo)
.arg("digest1.txt")
.current_dir("tests/data")
.output()?;
assert_eq!(cmd.status.code(), Some(0));
assert_eq!(cmd.stdout, output.as_bytes());
assert_eq!(cmd.stderr, "".as_bytes());
Ok(())
}
#[test]
fn test_checksum_jobs_env() -> Result<()> {
let mut distinfo = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
distinfo.push("tests/data/distinfo");
let output = "=> Checksum SHA512 OK for digest1.txt\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-a")
.arg("SHA512")
.arg(&distinfo)
.arg("digest1.txt")
.env("MKTOOL_JOBS", "1")
.current_dir("tests/data")
.output()?;
assert_eq!(cmd.status.code(), Some(0));
assert_eq!(cmd.stdout, output.as_bytes());
assert_eq!(cmd.stderr, "".as_bytes());
Ok(())
}
#[test]
fn test_checksum_no_checksum() -> Result<()> {
let mut distinfo = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
distinfo.push("tests/data/distinfo");
let output = format!(
"{}\n{}\n",
"checksum: No SHA1 checksum recorded for digest1.txt",
"checksum: No SHA1 checksum recorded for nonexistent.txt",
);
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-a")
.arg("SHA1")
.arg(&distinfo)
.arg("digest1.txt")
.arg("nonexistent.txt")
.current_dir("tests/data")
.output()?;
assert_eq!(cmd.status.code(), Some(2));
assert_eq!(cmd.stdout, "".as_bytes());
assert_eq!(cmd.stderr, output.as_bytes());
Ok(())
}
#[test]
fn test_checksum_patch() -> Result<()> {
let mut distinfo = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
distinfo.push("tests/data/distinfo");
let output = "=> Checksum SHA1 OK for patch-Makefile\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-p")
.arg(&distinfo)
.arg("patch-Makefile")
.current_dir("tests/data")
.output()?;
assert_eq!(cmd.status.code(), Some(0));
assert_eq!(cmd.stdout, output.as_bytes());
assert_eq!(cmd.stderr, "".as_bytes());
Ok(())
}
#[test]
fn test_checksum_patch_path() -> Result<()> {
let mut distinfo = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
distinfo.push("tests/data/distinfo");
let output = "=> Checksum SHA1 OK for patch-Makefile\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-p")
.arg(&distinfo)
.arg("../data/patch-Makefile")
.current_dir("tests/data")
.output()?;
assert_eq!(cmd.status.code(), Some(0));
assert_eq!(cmd.stdout, output.as_bytes());
assert_eq!(cmd.stderr, "".as_bytes());
Ok(())
}
#[test]
fn test_checksum_mismatch() -> Result<()> {
let mut distinfo = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
distinfo.push("tests/data/distinfo.bad");
let output = "checksum: Checksum BLAKE2s mismatch for digest1.txt\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg(&distinfo)
.arg("digest1.txt")
.current_dir("tests/data")
.output()?;
assert_eq!(cmd.status.code(), Some(1));
assert_eq!(cmd.stdout, "".as_bytes());
assert_eq!(cmd.stderr, output.as_bytes());
let output = "checksum: Checksum SHA512 mismatch for digest1.txt\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-a")
.arg("SHA512")
.arg(&distinfo)
.arg("digest1.txt")
.current_dir("tests/data")
.output()?;
assert_eq!(cmd.status.code(), Some(1));
assert_eq!(cmd.stdout, "".as_bytes());
assert_eq!(cmd.stderr, output.as_bytes());
let output = "checksum: Checksum SHA1 mismatch for patch-Makefile\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-p")
.arg(&distinfo)
.arg("patch-Makefile")
.current_dir("tests/data")
.output()?;
assert_eq!(cmd.status.code(), Some(1));
assert_eq!(cmd.stdout, "".as_bytes());
assert_eq!(cmd.stderr, output.as_bytes());
let output = "checksum: Checksum BLAKE2s mismatch for digest1.txt\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg(&distinfo)
.arg("data/digest1.txt")
.current_dir("tests")
.output()?;
assert_eq!(cmd.status.code(), Some(1));
assert_eq!(cmd.stdout, "".as_bytes());
assert_eq!(cmd.stderr, output.as_bytes());
let output = "checksum: Checksum SHA1 mismatch for patch-Makefile\n";
let cmd = Command::new(MKTOOL)
.arg("checksum")
.arg("-p")
.arg(&distinfo)
.arg("data/patch-Makefile")
.current_dir("tests")
.output()?;
assert_eq!(cmd.status.code(), Some(1));
assert_eq!(cmd.stdout, "".as_bytes());
assert_eq!(cmd.stderr, output.as_bytes());
Ok(())
}