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

nordisk/dwarves

crates/dwarves-slsa/tests/spec.rs

//! The release spec: pinned, by digest, inside the snapshot.

use std::collections::BTreeMap;

use dwarves_slsa::spec::{BinaryStep, ReleaseSpec};

pub const IMAGE: &str = "localhost/nordisk-cargo-toolchain@sha256:875a7a325dfe7f6b838535d085a2a502e8ad250076c947f6d023b1e224f03334";

fn good() -> String {
    format!(
        r#"
name = "holger-2.0.1"
image = "{IMAGE}"
lock = ["holger/Cargo.toml", "holger/estate/Cargo.toml"]

[[repo]]
name = "holger"
org = "nordisk"
commit = "87e5ada50ab5745464e4b46305bfd62d0460f52c"

[[repo]]
name = "tunnr"
org = "mikronova"
commit = "7b13bbec67c286cbdb98efde5ae68f56af78f68fb15913af686ac33ae67f3c86"

[[crate]]
name = "holger-errcode"
version = "2.0.1"
repo = "holger"
path = "errcode"

[[crate]]
name = "holger"
version = "2.0.1"
repo = "holger"
path = "server/cli"

[[binary]]
crate = "holger"
bin = "holger"
"#
    )
}

#[test]
fn a_good_spec_parses() {
    let s = ReleaseSpec::parse(&good()).unwrap();
    assert_eq!(s.repos.len(), 2);
    assert_eq!(s.crates[1].path, "server/cli");
    assert_eq!(s.binaries[0].bin, "holger");
    assert_eq!(s.forge, "ssh://git@git.gunnar.rs:2222");
    assert_eq!(
        s.image_digest(),
        "875a7a325dfe7f6b838535d085a2a502e8ad250076c947f6d023b1e224f03334"
    );
    assert_eq!(s.image_name(), "localhost/nordisk-cargo-toolchain");
    assert_eq!(
        s.clone_url(&s.repos[1]),
        "ssh://git@git.gunnar.rs:2222/mikronova/tunnr.git"
    );
    assert_eq!(
        s.web_url(&s.repos[0]),
        "https://git.gunnar.rs/nordisk/holger"
    );
}

fn refused(edit: impl Fn(String) -> String, why: &str) {
    let text = edit(good());
    let e = ReleaseSpec::parse(&text).expect_err(why);
    assert!(e.0.to_lowercase().contains(why), "expected {why:?} in: {e}");
}

#[test]
fn an_image_by_tag_is_refused() {
    refused(
        |t| t.replace(IMAGE, "localhost/nordisk-cargo-toolchain:ci4"),
        "digest",
    );
}

#[test]
fn a_short_commit_is_refused() {
    refused(
        |t| t.replace("87e5ada50ab5745464e4b46305bfd62d0460f52c", "87e5ada"),
        "commit",
    );
    refused(
        |t| t.replace("87e5ada50ab5745464e4b46305bfd62d0460f52c", "main"),
        "commit",
    );
}

#[test]
fn an_unsafe_or_doubled_repo_name_is_refused() {
    refused(
        |t| t.replacen("name = \"tunnr\"", "name = \"../tunnr\"", 1),
        "name",
    );
    refused(
        |t| t.replacen("name = \"tunnr\"", "name = \"holger\"", 1),
        "twice",
    );
}

#[test]
fn a_crate_of_an_unpinned_repo_is_refused() {
    refused(
        |t| {
            t.replacen(
                "repo = \"holger\"\npath = \"errcode\"",
                "repo = \"edda\"\npath = \"errcode\"",
                1,
            )
        },
        "pinned",
    );
}

#[test]
fn a_path_outside_the_snapshot_is_refused() {
    refused(
        |t| t.replace("path = \"errcode\"", "path = \"/etc\""),
        "path",
    );
    refused(
        |t| t.replace("path = \"errcode\"", "path = \"../../edda\""),
        "path",
    );
    refused(
        |t| {
            t.replace(
                "\"holger/estate/Cargo.toml\"",
                "\"holger/../../x/Cargo.toml\"",
            )
        },
        "path",
    );
}

#[test]
fn a_lock_of_an_unpinned_repo_or_no_lock_is_refused() {
    refused(
        |t| t.replace("\"holger/estate/Cargo.toml\"", "\"edda/Cargo.toml\""),
        "pinned",
    );
    refused(
        |t| {
            t.replace(
                "lock = [\"holger/Cargo.toml\", \"holger/estate/Cargo.toml\"]",
                "lock = []",
            )
        },
        "lock",
    );
}

#[test]
fn a_binary_of_a_crate_not_in_the_release_is_refused() {
    refused(
        |t| t.replace("crate = \"holger\"\nbin", "crate = \"gunnar\"\nbin"),
        "binary",
    );
}

#[test]
fn nothing_to_build_is_refused() {
    let s = format!("name = \"x\"\nimage = \"{IMAGE}\"\nlock = [\"holger/Cargo.toml\"]\n[[repo]]\nname = \"holger\"\norg = \"nordisk\"\ncommit = \"87e5ada50ab5745464e4b46305bfd62d0460f52c\"\n");
    let e = ReleaseSpec::parse(&s).unwrap_err();
    assert!(e.0.contains("nothing"), "{e}");
}

#[test]
fn an_unknown_field_is_refused() {
    let e = ReleaseSpec::parse(&format!(
        "{}\nsccache = true\n",
        good().replacen(
            "name = \"holger-2.0.1\"",
            "name = \"holger-2.0.1\"\nsccache = true",
            1
        )
    ));
    assert!(e.is_err());
}

#[test]
fn the_toml_round_trips() {
    let s = ReleaseSpec::parse(&good()).unwrap();
    assert_eq!(ReleaseSpec::parse(&s.to_toml().unwrap()).unwrap(), s);
}

#[test]
fn the_external_parameters_name_the_release_its_commits_and_crates() {
    let s = ReleaseSpec::parse(&good()).unwrap();
    let x = s.external_parameters();
    assert_eq!(x["release"], "holger-2.0.1");
    assert_eq!(
        x["repositories"][0]["repository"],
        "https://git.gunnar.rs/nordisk/holger"
    );
    assert_eq!(
        x["repositories"][0]["commit"],
        "87e5ada50ab5745464e4b46305bfd62d0460f52c"
    );
    assert_eq!(x["repositories"][1]["name"], "tunnr");
    assert_eq!(x["crates"][0]["name"], "holger-errcode");
    assert_eq!(x["crates"][1]["path"], "server/cli");
    assert_eq!(x["binaries"][0]["bin"], "holger");
    assert_eq!(x["locks"][1], "holger/estate/Cargo.toml");
    // The image is the platform's choice, so it is internal, not external.
    assert!(x.get("image").is_none());
}

const STEPS: &str = "
1  holger-errcode                        2.0.1  holger  errcode                                all
# a comment
43 holger                                2.0.1  holger  server/cli                             default
";

const PINS: &str = "# the tree
holger 87e5ada50ab5745464e4b46305bfd62d0460f52c
tunnr 7b13bbec67c286cbdb98efde5ae68f56af78f68fb15913af686ac33ae67f3c86
";

#[test]
fn a_spec_is_made_from_the_publish_scripts_tables() {
    let mut orgs = BTreeMap::new();
    orgs.insert("tunnr".to_string(), "mikronova".to_string());
    let bins = vec![BinaryStep {
        crate_name: "holger".into(),
        bin: "holger".into(),
        features: vec![],
        no_default_features: false,
    }];
    let s = ReleaseSpec::from_tables(
        "holger-2.0.1",
        IMAGE,
        STEPS,
        PINS,
        &orgs,
        "nordisk",
        vec!["holger/Cargo.toml".into()],
        bins,
    )
    .unwrap();
    assert_eq!(
        s.repos
            .iter()
            .map(|r| (r.name.as_str(), r.org.as_str()))
            .collect::<Vec<_>>(),
        vec![("holger", "nordisk"), ("tunnr", "mikronova")]
    );
    assert_eq!(
        s.crates.iter().map(|c| c.name.as_str()).collect::<Vec<_>>(),
        vec!["holger-errcode", "holger"]
    );
    assert_eq!(s.crates[1].version, "2.0.1");
    assert_eq!(s, ReleaseSpec::parse(&s.to_toml().unwrap()).unwrap());
}

#[test]
fn a_step_of_an_unpinned_repo_is_refused_from_the_tables() {
    let steps = "1 edda-x 0.1.0 edda crates/x all\n";
    let e = ReleaseSpec::from_tables(
        "x",
        IMAGE,
        steps,
        PINS,
        &BTreeMap::new(),
        "nordisk",
        vec!["holger/Cargo.toml".into()],
        vec![],
    )
    .unwrap_err();
    assert!(e.0.contains("pinned"), "{e}");
}