facett-ops/tests/archive_round_trip.rs
//! **RED FIRST for the publish's own verification.**
//!
//! `pack_index` returning `Ok` means the compressor did not error and wrote a
//! non-zero file. That is a state round-trip. The failure it cannot see is the one
//! that matters: an archive with a correct index and a short payload still has a
//! size, holger still serves it, and `pip` downloads a truncated wheel and fails its
//! own hash check with a message about the network — pointing at the client for a
//! defect in the publish.
//!
//! So `verify_archive_round_trip` extracts the finished archive and compares bytes.
//! These tests prove it actually catches the two ways that can go wrong, using REAL
//! znippy archives rather than a mock, because a mock of the compressor would be
//! testing the mock.
use std::path::PathBuf;
use facett_ops::holger::{pack_index, stage_index, verify_archive_round_trip};
fn scratch(tag: &str) -> PathBuf {
let base = std::env::var("CARGO_TARGET_TMPDIR")
.map(PathBuf::from)
.unwrap_or_else(|_| std::env::temp_dir());
let d = base.join(format!("roundtrip-{tag}"));
let _ = std::fs::remove_dir_all(&d);
std::fs::create_dir_all(&d).unwrap();
d
}
/// A wheel-shaped payload big enough that the packer takes a real path through
/// chunking rather than a degenerate one.
fn payload(seed: u8) -> Vec<u8> {
let mut v = b"PK\x03\x04".to_vec();
v.extend((0..200_000u32).map(|i| (i as u8).wrapping_add(seed)));
v
}
/// Stage + pack one artifact, returning `(archive, original)`.
fn packed(tag: &str, bytes: &[u8]) -> (PathBuf, PathBuf, PathBuf) {
let dir = scratch(tag);
let src = dir.join("in");
std::fs::create_dir_all(&src).unwrap();
let whl = src.join("facet_wrapped_web-0.1.19-py3-none-any.whl");
std::fs::write(&whl, bytes).unwrap();
let stage = dir.join("stage");
stage_index(std::slice::from_ref(&whl), &stage).unwrap();
let archive = dir.join("out").join("facett-pip.znippy");
pack_index(&stage, &archive).unwrap();
(archive, whl, dir)
}
// ── GREEN: a real archive round-trips byte for byte ────────────────────────
#[test]
fn a_healthy_archive_returns_the_exact_bytes_that_went_in() {
let bytes = payload(0);
let (archive, whl, dir) = packed("healthy", &bytes);
let checked =
verify_archive_round_trip(&archive, &[whl], &dir.join("extract")).expect("must verify");
assert_eq!(checked.len(), 1);
assert_eq!(checked[0].0, "packages/facet-wrapped-web/facet_wrapped_web-0.1.19-py3-none-any.whl");
// The LENGTH is asserted against the input, not against itself.
assert_eq!(checked[0].1, bytes.len() as u64);
}
// ── RED: the bytes came out different ──────────────────────────────────────
#[test]
fn a_single_flipped_byte_is_caught() {
// Same length, one byte different — a size check alone passes this, and that is
// precisely the corruption a "the file is there and non-empty" check cannot see.
let bytes = payload(0);
let (archive, _whl, dir) = packed("flipped", &bytes);
let mut evil = bytes.clone();
evil[123_456] ^= 0xff;
let decoy = dir.join("decoy");
std::fs::create_dir_all(&decoy).unwrap();
let decoy_whl = decoy.join("facet_wrapped_web-0.1.19-py3-none-any.whl");
std::fs::write(&decoy_whl, &evil).unwrap();
let err = verify_archive_round_trip(&archive, &[decoy_whl], &dir.join("extract2"))
.expect_err("differing bytes must be refused");
assert!(err.contains("DIFFERENT bytes"), "{err}");
}
#[test]
fn a_length_mismatch_names_both_lengths() {
let bytes = payload(0);
let (archive, _whl, dir) = packed("short", &bytes);
let short = dir.join("short-copy");
std::fs::create_dir_all(&short).unwrap();
let short_whl = short.join("facet_wrapped_web-0.1.19-py3-none-any.whl");
std::fs::write(&short_whl, &bytes[..bytes.len() - 1000]).unwrap();
let err = verify_archive_round_trip(&archive, &[short_whl], &dir.join("extract3"))
.expect_err("a length mismatch must be refused");
// Both numbers, or the reader cannot tell which side is short.
assert!(err.contains(&bytes.len().to_string()), "must name the length that went in: {err}");
assert!(err.contains(&(bytes.len() - 1000).to_string()), "must name what came out: {err}");
assert!(err.contains("truncated"), "must say what this looks like downstream: {err}");
}
// ── RED: the artifact is not in the archive at all ─────────────────────────
#[test]
fn an_artifact_missing_from_the_archive_is_caught_by_name() {
let (archive, _whl, dir) = packed("missing", &payload(0));
// An artifact that was never packed. The check must not shrug and return the
// one it did find — the count would still look plausible to a careless caller.
let other = dir.join("other");
std::fs::create_dir_all(&other).unwrap();
let ghost = other.join("facet_wrapped_web-0.1.20-py3-none-any.whl");
std::fs::write(&ghost, payload(1)).unwrap();
let err = verify_archive_round_trip(&archive, &[ghost], &dir.join("extract4"))
.expect_err("an absent artifact must be refused");
assert!(err.contains("0.1.20"), "must name the artifact it could not find: {err}");
assert!(err.contains("not in the extracted archive"), "{err}");
}
// ── RED: the archive itself is damaged ─────────────────────────────────────
#[test]
fn a_truncated_archive_does_not_verify() {
let bytes = payload(0);
let (archive, whl, dir) = packed("truncated", &bytes);
// Chop the tail. This is the shape of an interrupted publish: a file with a
// size, an index, and a payload that stops early.
let full = std::fs::read(&archive).unwrap();
let damaged = dir.join("out").join("damaged.znippy");
std::fs::write(&damaged, &full[..full.len() / 2]).unwrap();
let r = verify_archive_round_trip(&damaged, &[whl], &dir.join("extract5"));
assert!(r.is_err(), "a half-written archive must not verify, got {r:?}");
}
#[test]
fn an_empty_pack_is_refused_rather_than_producing_an_empty_archive() {
let dir = scratch("emptypack");
let stage = dir.join("stage");
std::fs::create_dir_all(&stage).unwrap();
// Nothing staged. Whatever the compressor does with an empty tree, the publish
// must not hand holger an index of no packages and call it done.
let archive = dir.join("out").join("empty.znippy");
let r = pack_index(&stage, &archive);
if let Ok(n) = r {
// If the compressor happily seals an empty tree, the round-trip check is the
// backstop: verifying it against a real artifact must fail.
let fake = dir.join("f.whl");
std::fs::write(&fake, payload(0)).unwrap();
let src = dir.join("named");
std::fs::create_dir_all(&src).unwrap();
let named = src.join("facet_wrapped_web-0.1.19-py3-none-any.whl");
std::fs::rename(&fake, &named).unwrap();
assert!(
verify_archive_round_trip(&archive, &[named], &dir.join("ex")).is_err(),
"an empty {n}-byte archive must not verify against a real artifact"
);
}
}