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

nordisk/gunnar

crates/gunnar-recipe/tests/twin_is_the_same_medium.rs

//! **A twin is the SAME medium as the primary it twins — so it cannot be
//! another binary.**
//!
//! This test exists because of one line that was wrong for two days and could
//! only have been found at the worst possible moment.
//!
//! `gunnar-twin` was a `[[build.installer]]` row of its own, made by cloning
//! `gunnar-installer-open` and changing four things: the volume id, `--role
//! twin` welded into `korp.args`, two `ZNIPPY_*` env tokens and
//! `korp.data.disks=vdb`. Cloning the KEYLESS row also cloned its `variant`,
//! `gunnar-server`. gunnar.rs's appliance is `gunnar-installer-metered`, whose
//! variant is `gunnar-server-metered` — the build point that links
//! `monetize-embed` and the entitlement gate — and `tests/metered_symbols.rs`
//! GUARANTEES, off the artifact's own symbol table, that `gunnar-server`
//! contains no entitlement symbol at all.
//!
//! **The twin exists to BECOME the primary.** Promoted after a restore, it
//! would have served gunnar.rs from a binary with no plan enforcement in it:
//! every suspended tenant live again, silently, with nothing on the box able to
//! say why — because nothing on the box would have been wrong. The medium was,
//! and a medium is read once, at mastering, months before the takeover that
//! needs it.
//!
//! **Since 2026-09-22 there is nothing to realize at all** (owner: "gunnar twin
//! must be built EXACTLY like the main, it MUST use the SAME iso"; "the weakest
//! machine must become the twin … a bootstrap thing from xtask"). The medium
//! carries no `role` and no `data_disks` parameter: every box installs as a
//! fresh appliance, and the twin is made one over the wire
//! (`Bootstrap.BecomeTwin`, after `cargo xtask elect twin --apply` in
//! private-gunnar-ops). Where `/data` goes is korp-installer's own election.
//! So the twin's medium IS the primary's medium — the same row, the same
//! variant, the same cmdline — and this file stops that from being undone: by a
//! twin row, by a role or disk parameter coming back, or by a role token baked
//! on a cmdline.
//!
//! Every assertion here is about the DECLARATION and costs no build.

use gunnar_recipe::GunnarBuildThing;
use nornir_build_thing::installer::InstallerBuild;
use nornir_build_thing::plugin::BuildThing;

fn installers() -> Vec<InstallerBuild> {
    GunnarBuildThing.variants().installers
}

fn row(name: &str) -> InstallerBuild {
    installers()
        .into_iter()
        .find(|i| i.name == name)
        .unwrap_or_else(|| panic!("gunnar declares an installer row {name:?}"))
}

/// **The defect, pinned by name.** gunnar.rs's appliance is metered; its twin
/// installs that SAME row, so the twin lays the metered binary.
#[test]
fn the_twin_of_the_metered_appliance_is_metered() {
    let primary = row(gunnar_recipe::METERED_INSTALLER);
    assert_eq!(
        primary.variant,
        gunnar_recipe::METERED_VARIANT,
        "the row gunnar.rs installs stopped naming the metered build point, so there is \
         nothing for its twin to inherit"
    );
}

/// ★ **No medium can be told what it is.** No installer row declares a `role`
/// or a `data_disks` parameter — FAILS ON THE OLD RECIPE, which declared both
/// on every row (2026-09-17 → 2026-09-22).
#[test]
fn no_medium_takes_a_role_or_a_disk_declaration() {
    for i in installers() {
        for p in &i.params {
            assert!(
                p.name != "role" && p.name != "data_disks",
                "installer row {:?} declares the `{}` parameter (landing {:?}). The role is \
                 conferred over the wire (Bootstrap.BecomeTwin, from the election record) and \
                 the data disks are the installer's own election — a parameter for either is \
                 a second medium by another name",
                i.name,
                p.name,
                p.boot_param
            );
            assert!(
                p.boot_param != "korp.env.GUNNAR_ROLE" && p.boot_param != "korp.data.disks",
                "{}: `{}` lands on {:?}, which says what the box is or where its data goes",
                i.name,
                p.name,
                p.boot_param
            );
        }
    }
}

/// **No row may be a twin, and no cmdline may say what a box is.**
#[test]
fn no_medium_is_a_twin() {
    for i in installers() {
        assert!(
            !i.name.contains("twin") && !i.volume_id.contains("TWIN"),
            "installer row {:?} (volume {:?}) names itself a twin. A twin is a role conferred \
             over the wire, not a medium: the moment it is a row of its own, it is a row \
             someone has to remember to keep in step with the primary's lineage — and the \
             first time nobody did, the metered appliance's twin was unmetered",
            i.name,
            i.volume_id
        );
        for a in i.boot_params.iter().filter(|p| p.starts_with("korp.args=")) {
            assert!(
                !a.contains("--role"),
                "{}: the role is welded into `korp.args` ({a:?})",
                i.name
            );
        }
        for p in &i.boot_params {
            assert!(
                !p.starts_with("korp.env.ZNIPPY_GIT_EXPLODE")
                    && !p.starts_with("korp.env.ZNIPPY_GIT_GRAPH_CACHE")
                    && !p.starts_with("korp.data.disks=")
                    && !p.starts_with("korp.env.GUNNAR_ROLE="),
                "{}: {p:?} is baked on the medium. What a box is and where its data goes are \
                 not the medium's to say (BecomeTwin; korp-installer's own disk election)",
                i.name
            );
        }
    }
}