crates/nornir-build-thing/src/selftest.rs
//! # Functional-status emit bridge — `nornir-build-thing` → test matrix
//!
//! The single internal call site this crate uses to push a *functional* row
//! into the [`nornir_testmatrix`] matrix, so `nornir test --features testmatrix`
//! records whether `nornir-build-thing`'s real surfaces (variant validation /
//! cargo-argv materialization / surface projection / variant lookup) ACTUALLY
//! work.
//!
//! ## Release strips everything
//! The `testmatrix` cargo feature gates the whole bridge: with it OFF (the
//! release default) [`emit`] is an `#[inline]` no-op and `nornir-testmatrix` is
//! not even linked. Lit ONLY under `cargo … --features testmatrix`.
/// The aspect tag every self-emitted row carries (matches `functional_row`).
pub const ASPECT_FUNCTIONAL: &str = "functional";
/// Push ONE functional-status row for a single real check (feature ON).
#[cfg(feature = "testmatrix")]
#[inline]
pub fn emit(component: &str, check: &str, ok: bool, detail: &str) {
nornir_testmatrix::functional_status(component, check, ok, detail);
}
/// No-op stub when the `testmatrix` feature is OFF (release builds).
#[cfg(not(feature = "testmatrix"))]
#[inline]
pub fn emit(_component: &str, _check: &str, _ok: bool, _detail: &str) {}
/// `assert!`-with-emit: assert on the real return value AND record the verdict
/// as a matrix row.
#[macro_export]
macro_rules! bt_assert_emit {
($component:expr, $check:expr, $ok:expr, $($detail:tt)+) => {{
let __ok: bool = $ok;
let __detail = ::std::format!($($detail)+);
$crate::selftest::emit($component, $check, __ok, &__detail);
::std::assert!(__ok, "{}::{} — {}", $component, $check, __detail);
}};
}
// ─── inject-and-assert wiring test (feature ON only) ─────────────────────────
#[cfg(all(test, feature = "testmatrix"))]
mod wiring {
use crate::surface::BuildSurface;
use crate::variant::{BuildVariant, BuildVariantSet, Profile};
const HOLGER: &str = r#"
[build]
offers = ["embedded", "minimal", "full", "served", "gui"]
exclusive = [["embedded", "minimal", "full"]]
[build.required]
"holger-full" = ["full"]
[[build.variant]]
name = "full"
package = "holger-full"
bin = "holger-full"
features = ["full", "served", "gui"]
profile = "release"
"#;
/// Drive `nornir-build-thing`'s real surfaces, emit an honest row per surface,
/// then drain the process-global functional buffer and assert the rows landed —
/// proving the emit bridge is wired end to end.
#[test]
fn emits_honest_rows_for_build_surfaces() {
// Surface: parse the declarative `[build]` set.
let parsed = BuildVariantSet::from_toml_str(HOLGER);
let set = parsed.expect("holger set parses");
crate::selftest::emit(
"nornir-build-thing",
"variant_set_parses_from_toml",
set.names() == vec!["full"],
&format!("names={:?}", set.names()),
);
// Surface: a declared variant validates against its owning set.
let full = set.get("full").expect("full variant");
let valid = set.validate(full).is_ok();
bt_assert_emit!(
"nornir-build-thing",
"declared_variant_validates",
valid,
"variant=full valid={valid}"
);
// Surface: cargo-argv materialization is exact + deterministic.
let args = full.cargo_args();
let args_ok = args.first().map(|a| a == "build").unwrap_or(false)
&& args.windows(2).any(|w| w == ["-p", "holger-full"])
&& args.windows(2).any(|w| w == ["--profile", "release"]);
bt_assert_emit!(
"nornir-build-thing",
"cargo_args_materialize",
args_ok,
"args={args:?}"
);
// Surface: an unoffered feature is REJECTED with a reason (negative path).
let bogus = BuildVariant {
name: "bad".to_string(),
package: Some("holger-full".to_string()),
bin: Some("holger-full".to_string()),
features: vec!["quantum".to_string()],
profile: Profile::Release,
..Default::default()
};
let rejected = set.validate(&bogus).is_err();
bt_assert_emit!(
"nornir-build-thing",
"unoffered_feature_rejected",
rejected,
"rejected={rejected}"
);
// Surface: the data-driven UI surface projects + flags validity.
let surface = BuildSurface::from_set("holger", &set);
let full_view = surface.variants.iter().find(|v| v.name == "full");
let surface_ok = surface.variant_names() == vec!["full"]
&& full_view.map(|v| v.valid).unwrap_or(false);
bt_assert_emit!(
"nornir-build-thing",
"build_surface_projects_variants",
surface_ok,
"names={:?}",
surface.variant_names()
);
// Surface: `require` on an unknown variant errors, naming known variants.
let unknown = set.require("nope");
let unknown_ok = unknown
.as_ref()
.err()
.map(|e| e.to_string().contains("no build variant 'nope'"))
.unwrap_or(false);
bt_assert_emit!(
"nornir-build-thing",
"require_unknown_variant_errors",
unknown_ok,
"err={:?}",
unknown.as_ref().err().map(|e| e.to_string())
);
// Surface: the container/image target kind materializes a Containerfile
// and validates its chained cargo variant.
use crate::container::{ContainerBuild, ImageLayer};
let image = ContainerBuild {
name: "holger-appliance".to_string(),
base: "debian:bookworm-slim".to_string(),
layers: vec![ImageLayer::from_variant("full", "/usr/local/bin/holger")],
entrypoint: vec!["/usr/local/bin/holger".to_string()],
tags: vec!["holger-appliance:0.1".to_string()],
..Default::default()
};
let image_ok = set.validate_container(&image).is_ok()
&& image.containerfile().contains("FROM debian:bookworm-slim")
&& image.content_id().len() == 64;
bt_assert_emit!(
"nornir-build-thing",
"container_build_materializes",
image_ok,
"image=holger-appliance deps={:?}",
image.variant_deps()
);
let rows = nornir_testmatrix::drain_functional_rows();
for want in [
"variant_set_parses_from_toml",
"declared_variant_validates",
"cargo_args_materialize",
"unoffered_feature_rejected",
"build_surface_projects_variants",
"require_unknown_variant_errors",
"container_build_materializes",
] {
assert!(
rows.iter().any(|r| r.suite == "nornir-build-thing"
&& r.test_name == want
&& r.status == "pass"),
"missing green row {want}: {rows:?}"
);
}
assert!(rows.iter().all(|r| r.aspect == "functional"), "rows={rows:?}");
}
}