Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/facett

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}");
}