facett-ops/tests/install_judgement.rs
//! **RED FIRST for the install verdict.**
//!
//! `verify_install` runs a container and `judge_install` decides whether what came
//! back is acceptable. Splitting them is the point: if the verdict were the
//! container's exit code, it would be a python script asserting on itself and
//! exiting 0 — the container saying it is fine. `judge_install` is a pure function
//! over the container's report and the wheel we actually built, so it can be driven
//! red here without podman, holger, or a network.
//!
//! Every rejection below is a way a `pip install` can "succeed" and still be wrong.
use facett_ops::holger::{InstallProof, judge_install};
fn built() -> Vec<(String, u64)> {
vec![
("facet_wrapped_bg.wasm".into(), 9_920_451),
("facet_wrapped.js".into(), 100_963),
("manifest.json".into(), 4_682),
("index.html".into(), 9_277),
]
}
/// A report shaped like the real one measured on oden 2026-09-05.
fn good() -> InstallProof {
InstallProof {
image_ref: "nordisk-pip-consumer".into(),
image_id: Some("sha256:c6da9892".into()),
version: "0.1.19".into(),
assets_dir: "/tmp/v/lib/python3.13/site-packages/facet_wrapped_web/assets".into(),
assets: built(),
wasm_magic: "0061736d".into(),
components: 27,
streamlit_installed: false,
glue_refusal: "facett.streamlit needs Streamlit, which is an optional extra of facett: pip install 'facett[streamlit]'".into(),
}
}
#[test]
fn the_real_install_passes() {
judge_install(&good(), "0.1.19", &built()).expect("the measured install must pass");
}
#[test]
fn a_different_version_is_refused() {
// pip resolving an older wheel still on the index, or stale metadata. Both look
// like a clean install from the outside.
let mut p = good();
p.version = "0.1.15".into();
let err = judge_install(&p, "0.1.19", &built()).unwrap_err();
assert!(err.contains("0.1.15") && err.contains("0.1.19"), "must name both: {err}");
}
#[test]
fn reading_the_source_tree_instead_of_the_install_is_refused() {
// THE hollow-check case. If the container somehow imported a source checkout,
// every other assertion below would pass while proving nothing about the wheel.
let mut p = good();
p.assets_dir = "/home/rickard/git/facett/pkg-facet-wrapped/src/facett/assets".into();
let err = judge_install(&p, "0.1.19", &built()).unwrap_err();
assert!(err.contains("site-packages"), "{err}");
assert!(err.contains("source tree"), "the refusal must say what happened: {err}");
}
#[test]
fn a_wasm_that_did_not_survive_the_trip_is_refused() {
// Present, right size, wrong bytes at the front. This is what a wheel that was
// re-encoded or partially written looks like on the consumer's disk.
let mut p = good();
p.wasm_magic = "3c21646f".into(); // "<!do"
let err = judge_install(&p, "0.1.19", &built()).unwrap_err();
assert!(err.contains("0061736d"), "must name the magic it wanted: {err}");
}
#[test]
fn a_size_that_changed_between_build_and_install_is_refused_by_name() {
// The claim the whole chain exists to make: the bytes on the consumer's disk are
// the bytes wrap-wasm produced, after a wheel, a znippy archive, an HTTP index
// and a pip resolve. Each asset is checked individually, not as a total.
for i in 0..4 {
let mut p = good();
p.assets[i].1 -= 1;
let name = p.assets[i].0.clone();
let err = judge_install(&p, "0.1.19", &built()).unwrap_err();
assert!(err.contains(&name), "a changed `{name}` must be caught by name: {err}");
assert!(err.contains("wrap-wasm"), "{err}");
}
}
#[test]
fn a_missing_asset_is_refused() {
let mut p = good();
p.assets.retain(|(n, _)| n != "index.html");
let err = judge_install(&p, "0.1.19", &built()).unwrap_err();
assert!(err.contains("index.html"), "{err}");
}
#[test]
fn an_empty_manifest_is_refused() {
// A wheel whose manifest.json parsed to zero components installs fine, imports
// fine, and can mount nothing. Every other check above passes on it.
let mut p = good();
p.components = 0;
assert!(judge_install(&p, "0.1.19", &built()).is_err());
}
#[test]
fn a_plain_install_that_drags_in_streamlit_is_refused() {
// 0.2.0: Streamlit is the `[streamlit]` extra. `pip install facett` putting it in
// the environment would be a hard dependency wearing an extra's name.
let mut p = good();
p.streamlit_installed = true;
let err = judge_install(&p, "0.1.19", &built()).unwrap_err();
assert!(err.contains("[streamlit]"), "{err}");
}
#[test]
fn a_glue_module_that_does_not_name_its_extra_is_refused() {
let mut p = good();
p.glue_refusal = "No module named 'streamlit'".into();
let err = judge_install(&p, "0.1.19", &built()).unwrap_err();
assert!(err.contains("No module named"), "the refusal must quote what it said: {err}");
}