crates/edda-build-thing/tests/rows.rs
//! **The rows ARE the matrix** — so the matrix is asserted here, not described.
//!
//! Five properties, one per way this declaration has already been wrong once:
//!
//! 1. the row set is EXACTLY what edda ships — two executables, named;
//! 2. every row carries a suite tag and the set names a `base_suite` — the debt
//! the 2026-09-17 census counted (27 untagged rows across the constellation,
//! three of them edda's) is closed here and cannot silently come back;
//! 3. the pinned image is a real pin, any row `target` is a triple it carries,
//! and the appliance PID-1 rows are GONE — they moved to tunnr on 2026-09-26
//! (`tunnr/korp-installer`, `tunnr/korp-start`) and must not come back here;
//! 4. the typed consequence cannot drift from the declaration: the argv
//! materialized from a row is a function of the row, so `features`, `bin`,
//! `profile` and `target` all appear in it;
//! 5. the feature axis does not rot — offered ∖ built must be exactly the
//! excused set, and a stale excuse fails too.
use edda_build_thing::EddaBuildThing;
use nornir_build_thing::feature_axis::FeatureAxis;
use nornir_build_thing::plugin::{BuildThing, Role};
use nornir_build_thing::variant::{ArtifactKind, Profile, ServiceShape};
/// **What edda ships, as an assertion.** The hand-written file declared two rows
/// and excused the other two in prose; prose is not a declaration. If edda grows
/// or drops a shipped binary this test is the thing that fails.
#[test]
fn the_row_set_is_exactly_the_two_executables_edda_ships() {
let set = EddaBuildThing.variants();
let names: Vec<&str> = set.variants.iter().map(|v| v.name.as_str()).collect();
assert_eq!(
names,
["autonom", "robotui"],
"edda ships two executables: the autonom CLI and the robotui UI (the two \
static-musl appliance PID-1s moved to tunnr on 2026-09-26). A third row is \
a new artifact and a missing one is an artifact that stopped being described."
);
for v in &set.variants {
assert_eq!(v.kind, ArtifactKind::Exe, "'{}' is an executable", v.name);
assert_eq!(v.profile, Profile::Release, "'{}' ships release", v.name);
assert_eq!(
v.shape,
ServiceShape::NotApplicable,
"'{}': the fat/thin linkage axis does not apply to a plain exe, and \
an OMITTED linkage reads as FAT — which is what the hand-written file \
said in prose and declared as its opposite",
v.name
);
assert!(
v.embeds.is_empty() && v.reaches.is_empty(),
"'{}': edda is a library samling and no product — no row embeds or \
reaches a suite sibling",
v.name
);
assert!(
v.member.is_none(),
"'{}': `member` names a node in the SUITE dep graph, and edda has no \
product in the suite",
v.name
);
}
assert!(set.check_bins().is_empty(), "{:?}", set.check_bins());
assert!(set.check_defaults().is_empty(), "{:?}", set.check_defaults());
set.validate_all().expect("and the whole set validates");
}
/// **Untagged is not a third flavour — it is a row delivery cannot select.**
#[test]
fn every_row_is_tagged_original_and_the_set_names_its_base_suite() {
let set = EddaBuildThing.variants();
assert_eq!(
set.base_suite.as_deref(),
Some("ORIGINAL"),
"`--suite ORIGINAL` must resolve here rather than fall through to UNSUITED"
);
for v in &set.variants {
assert_eq!(
v.suites,
vec!["ORIGINAL".to_string()],
"'{}' must carry the delivery tag: holger's MVP is the only other \
flavour anywhere, and every other product tags ORIGINAL so the build \
verb has ONE shape everywhere",
v.name
);
}
assert!(set.declares_suites());
assert!(set.check_suites().is_empty(), "{:?}", set.check_suites());
}
/// **The pin, and any row triple it has to carry.** The appliance PID-1 rows
/// (`korp-installer`, `korp-start`) moved to tunnr on 2026-09-26 with their crate,
/// so this also holds that they did not come back: two declarations of one
/// artifact in two repos is two coordinates that can disagree.
#[test]
fn the_pinned_image_carries_every_row_target_and_the_pid1_rows_live_in_tunnr() {
let set = EddaBuildThing.variants();
let tc = set.toolchain.as_ref().expect(
"an absent [build.toolchain] does not mean a host build — it means \
CargoToolchain::validate refuses by name and the code road closes",
);
assert_eq!(tc.image_sha256.len(), 64, "a MANIFEST digest, not a tag");
assert!(!tc.image_sha256.is_empty());
assert!(!tc.network, "an attested build is hermetic");
for v in &set.variants {
let Some(target) = v.target.as_deref() else { continue };
assert!(
tc.targets.iter().any(|t| t == target),
"'{}' targets {target}, which the pinned image does not declare std \
for — refusable now, or E0463 an hour into the build",
v.name
);
}
for v in &set.variants {
assert!(
v.package.as_deref() != Some("korp-installer")
&& !["korp-installer", "korp-start"].contains(&v.name.as_str()),
"'{}': the appliance PID-1s are declared in tunnr (tunnr/korp-installer, \
tunnr/korp-start) since 2026-09-26, not here",
v.name
);
}
let autonom = set.get("autonom").expect("autonom is declared");
assert_eq!(autonom.role, Some(Role::Tool));
assert!(autonom.is_default, "the default tool is the autonom CLI");
}
/// **The typed consequence cannot drift from the declaration.** For typ `cargo`
/// the consequence is the dep/feature closure, and the argv is how the
/// declaration reaches cargo at all: a row's features, bin, profile and target
/// are materialized by the ONE writer, never spelled a second time by an xtask.
#[test]
fn the_cargo_consequence_is_a_function_of_the_row() {
let set = EddaBuildThing.variants();
for v in &set.variants {
assert!(v.kind.is_cargo(), "'{}' is a cargo typ", v.name);
let argv = v.cargo_args();
let line = argv.join(" ");
assert!(line.starts_with("build"), "{line}");
if let Some(bin) = &v.bin {
assert!(line.contains(&format!("--bin {bin}")), "{line}");
}
if let Some(pkg) = &v.package {
assert!(line.contains(&format!("-p {pkg}")), "{line}");
}
if !v.features.is_empty() {
assert!(line.contains(&v.features.join(",")), "{line}");
}
if let Some(target) = &v.target {
assert!(line.contains(&format!("--target {target}")), "{line}");
}
assert!(line.contains("--profile release"), "{line}");
// A feature the repo does not offer is refused, so the row cannot name a
// build point outside the declared space.
assert!(
v.features.iter().all(|f| set.offers.contains(f)),
"'{}' names a feature outside `offers`",
v.name
);
}
}
/// **The feature axis does not rot**: five offered, two built, three excused
/// by name — and an excuse for a feature a row now DOES build fails too.
#[test]
fn the_feature_axis_gate_is_clean() {
let set = EddaBuildThing.variants();
if let Err(rot) = FeatureAxis::of("edda", &set).gate() {
panic!("the feature axis is rotting: {rot:#?}");
}
for (feature, reason) in &set.allow_unbuilt {
assert!(
!reason.trim().is_empty(),
"'{feature}' is excused with no words — an excuse with no words is not \
an excuse"
);
}
}