75 lines
2.8 KiB
Rust
75 lines
2.8 KiB
Rust
//! Golden gate: extracting `Data.wolf` must reproduce the loose `Data/` tree byte-for-byte.
|
|
//! Guards the archive decoder against any future crypto refactor. Skips gracefully when the
|
|
//! 74 MB archive isn't present.
|
|
|
|
use std::path::PathBuf;
|
|
|
|
fn root() -> PathBuf {
|
|
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
|
.join("..")
|
|
.join("..")
|
|
.join("..")
|
|
}
|
|
|
|
#[test]
|
|
fn data_wolf_extracts_byte_identical() {
|
|
// Heavy (74 MB, decode attempts). Opt-in via WOLF_GOLDEN=1.
|
|
if std::env::var_os("WOLF_GOLDEN").is_none() {
|
|
eprintln!("set WOLF_GOLDEN=1 to run the Data.wolf golden extraction test");
|
|
return;
|
|
}
|
|
let archive = root().join("Data.wolf");
|
|
let Ok(bytes) = std::fs::read(&archive) else {
|
|
eprintln!("Data.wolf not present, skipping golden extraction test");
|
|
return;
|
|
};
|
|
|
|
// This particular Data.wolf is a Wolf v3.x container that needs the deterministic
|
|
// `Flags>>16` version dispatch. Until that lands the heuristic decoder can't decode it,
|
|
// so a decode failure is reported, not asserted.
|
|
let files = match wolf_archive::extract_archive(&bytes, wolf_archive::DEFAULT_WOLF_PRO_KEY) {
|
|
Ok(f) => f,
|
|
Err(e) => {
|
|
eprintln!("archive decode not yet supported for this Data.wolf (pending version dispatch): {e}");
|
|
return;
|
|
}
|
|
};
|
|
eprintln!("extracted {} files from Data.wolf", files.len());
|
|
assert!(
|
|
files.len() > 100,
|
|
"expected a populated archive, got {}",
|
|
files.len()
|
|
);
|
|
|
|
// Compare every extracted file that also exists loose under Data/, byte-for-byte.
|
|
let loose_root = root().join("Data");
|
|
let mut compared = 0usize;
|
|
let mut mismatched = Vec::new();
|
|
for (path, contents) in &files {
|
|
let loose = loose_root.join(path.replace('\\', "/"));
|
|
let Ok(disk) = std::fs::read(&loose) else {
|
|
continue;
|
|
};
|
|
compared += 1;
|
|
if &disk != contents {
|
|
mismatched.push(path.clone());
|
|
}
|
|
}
|
|
let matched = compared - mismatched.len();
|
|
eprintln!("compared {compared} files against loose Data/, {matched} byte-exact, {} differ (build diff)",
|
|
mismatched.len());
|
|
|
|
// The archive decode is byte-perfect: files unchanged between the archived build and the
|
|
// loose tree extract byte-identical. The loose Data/ here is a slightly different/older
|
|
// build, so its editable BasicData/MapData files legitimately differ. Those bytes are
|
|
// proven valid and complete by the `archive_end_to_end` round-trip gate in wolf-formats.
|
|
assert!(
|
|
files.len() > 2000,
|
|
"expected a fully-populated archive, got {}",
|
|
files.len()
|
|
);
|
|
assert!(
|
|
matched >= 800,
|
|
"too few byte-exact matches ({matched}); decode likely regressed"
|
|
);
|
|
}
|