src/mimir_lens/room_feed/built_tests.rs
//! The binary lenses over REAL Build Thing builds: a small crate is built by
//! `nornir_build_thing::build_variant_with_info` (the one cargo-driving loop
//! every Build Thing door runs), filed through builder 2's job
//! (`code_room::products::land_build`: artifact node, BUILT_FROM,
//! provenance, the binary half), and the lenses answer from what it filed.
use std::path::Path;
use std::process::Command;
use nornir_build_thing::build_info::{BuildInfoKind, BuildInfoRow};
use nornir_build_thing::{BuildProvenance, BuildVariantSet, InMemBuildInfoSink, build_variant_with_info};
use serde_json::{Value, json};
use super::fixture::{self, SHOP, Without};
use crate::code_room::products::{self, COMMIT_PREFIX, DEP_CRATE, REPO_ROOT};
use crate::code_room::{CodeRoom, Reach};
use crate::warehouse::iceberg::IcebergWarehouse;
const RECIPE: &str = r#"
[[build.variant]]
name = "probe"
package = "PKG"
profile = "release"
"#;
/// The probe's `checksum` before and after the change between two builds.
const CHECKSUM_V1: &str = "data.iter().map(|b| *b as u64).sum()";
const CHECKSUM_V2: &str = "let mut h: u64 = 0xcbf2_9ce4_8422_2325;
for (i, b) in data.iter().enumerate() {
h ^= *b as u64;
h = h.wrapping_mul(0x0100_0000_01b3);
if i % 3 == 0 {
h = h.rotate_left(7) ^ (i as u64).wrapping_mul(0x9e37_79b9_7f4a_7c15);
}
}
h ^ (h >> 33)";
/// A small real crate: a generic instantiated six times, a `checksum` the
/// second build changes, and `pay::dead` (the fixture shop's gated item).
fn write_crate(root: &Path, pkg: &str, checksum: &str) {
std::fs::create_dir_all(root.join("src")).unwrap();
std::fs::write(
root.join("Cargo.toml"),
format!("[package]\nname = \"{pkg}\"\nversion = \"0.1.0\"\nedition = \"2021\"\npublish = false\n\n[workspace]\n\n[profile.release]\ndebug = false\nstrip = false\n"),
)
.unwrap();
let main = r#"use std::hint::black_box;
#[inline(never)]
pub fn widen<T: Copy + Into<u64>>(xs: &[T]) -> u64 {
let mut acc = 0u64;
for (i, x) in xs.iter().enumerate() {
let v: u64 = (*x).into();
acc = acc.rotate_left((i % 63) as u32) ^ v.wrapping_mul(0x9e37_79b9_7f4a_7c15);
if v % 7 == 3 {
acc = acc.wrapping_add(v.wrapping_pow(3));
}
if v % 5 == 1 {
acc ^= acc >> 17;
}
acc = acc.wrapping_mul(0xff51_afd7_ed55_8ccd) ^ (acc >> 29);
}
acc
}
#[inline(never)]
pub fn checksum(data: &[u8]) -> u64 {
CHECKSUM
}
pub mod pay {
#[inline(never)]
pub fn dead(n: u64) -> u64 {
(0..n).map(|i| (i * i) ^ 0x5a).sum()
}
}
fn main() {
let a = black_box([1u8, 2, 3]);
let b = black_box([1u16, 2]);
let c = black_box([7u32, 8]);
let d = black_box([9u64]);
let e = black_box([true, false]);
let f = black_box(['p', 'q']);
println!(
"{} {} {} {} {} {} {} {}",
widen(&a), widen(&b), widen(&c), widen(&d), widen(&e), widen(&f), checksum(black_box(b"probe")), pay::dead(black_box(5))
);
}
"#;
std::fs::write(root.join("src/main.rs"), main.replace("CHECKSUM", checksum)).unwrap();
}
fn git(root: &Path, args: &[&str]) -> String {
let out = Command::new("git")
.args(["-c", "user.name=probe", "-c", "user.email=probe@example.invalid", "-c", "commit.gpgsign=false"])
.args(args)
.current_dir(root)
.output()
.expect("git");
assert!(out.status.success(), "git {args:?}: {}", String::from_utf8_lossy(&out.stderr));
String::from_utf8_lossy(&out.stdout).trim().to_string()
}
/// Commit the crate as it is now; the sha.
fn commit(root: &Path, msg: &str) -> String {
if !root.join(".git").exists() {
git(root, &["init", "-q"]);
}
git(root, &["add", "-A"]);
git(root, &["commit", "-qm", msg]);
git(root, &["rev-parse", "HEAD"])
}
/// A real Build Thing build of the crate at `root` (its dir name is the repo),
/// filed the way the server files one: the build's own `build_info` rows +
/// the forge's lineage rows (dwarves' `build_lineage`), landed by builder 2.
fn build_and_file(room: &CodeRoom, wh: &IcebergWarehouse, root: &Path, pkg: &str, sha: &str) -> (BuildProvenance, Value) {
let set = BuildVariantSet::from_toml_str(&RECIPE.replace("PKG", pkg)).expect("the recipe");
let sink = InMemBuildInfoSink::new();
let out = build_variant_with_info(&set, "probe", root, &sink).expect("a real Build Thing build");
assert!(out.success, "cargo built the probe");
let record = out.attestation.record.clone();
let mut rows = sink.rows();
assert_eq!(products::landed_builds(&rows), vec![record.id.clone()], "the manifest says success");
let repo = root.file_name().unwrap().to_string_lossy().into_owned();
let row = |k: BuildInfoKind, n: &str, v: &str| BuildInfoRow::new(&record.id, 2, k).kv(n, v.to_string());
rows.push(row(BuildInfoKind::Provenance, REPO_ROOT, &root.display().to_string()));
rows.push(row(BuildInfoKind::Provenance, &format!("{COMMIT_PREFIX}{repo}"), sha));
rows.push(row(BuildInfoKind::Dep, DEP_CRATE, &format!("{pkg}@0.1.0")));
let landed = products::land_build(room, wh, &record, &rows).expect("builder 2 lands the build");
(record, landed)
}
fn ask(room: &CodeRoom, wh: &IcebergWarehouse, lens: &str, p: Value) -> Value {
crate::mimir_lens::answer(lens, &Reach::new(room, wh), &p)
}
fn note(v: &Value) -> &str {
v["evidence_note"].as_str().unwrap_or("")
}
/// A real build files an artifact (Coderoom.Artifacts lists it, its bytes are
/// analysed under its sha256), and `generic_cost` answers from it: the
/// probe's `widen`, instantiated six times, is its named tax. Before any
/// build both binary lenses say so plainly; after ONE build `binary_drift`
/// says there is nothing to compare yet.
#[test]
fn a_real_build_thing_build_files_an_artifact_and_generic_cost_answers_from_it() {
let _g = fixture::serial();
let tmp = tempfile::tempdir().unwrap();
let builds = tmp.path().join("builds");
std::fs::create_dir_all(&builds).unwrap();
let wh = IcebergWarehouse::open(&builds).unwrap();
let room = CodeRoom::new("ws", &builds);
let root = tmp.path().join("binlens-probe");
write_crate(&root, "binlens-probe", CHECKSUM_V1);
let sha = commit(&root, "v1");
// nothing filed yet: said, never an empty list on its own
for lens in ["generic_cost", "binary_drift"] {
let v = ask(&room, &wh, lens, json!({}));
assert_eq!(v["lens_meta"]["state"], "empty_gap", "{v}");
assert!(note(&v).contains("no Build Thing run has filed an artifact for this workspace yet: ⚒ Build it"), "{}", note(&v));
}
let (record, landed) = build_and_file(&room, &wh, &root, "binlens-probe", &sha);
assert_eq!(landed["artifacts"].as_array().map(Vec::len), Some(1), "{landed}");
assert!(landed["binary_half"][0].get("error").is_none(), "analysed on this box: {landed}");
let arts = products::answer(&room, &json!({ "crate": "binlens-probe" })).unwrap();
assert_eq!(arts["count"], 1, "{arts}");
let sha256 = &record.artifacts[0].sha256;
assert!(crate::binscan::load_report(&wh, sha256).unwrap().is_some_and(|r| !r.symbols.is_empty()), "its symbols are filed under its sha256");
let v = ask(&room, &wh, "generic_cost", json!({ "repo": "binlens-probe" }));
assert_eq!(v["lens_meta"]["state"], "complete", "{v}");
assert_eq!(v["source"], "build");
let a = &v["worst_artifacts"][0];
assert_eq!(a["repo"], "binlens-probe", "{v}");
assert!(a["artifact"].as_str().unwrap().ends_with(&sha256[..16]), "the filed artifact, by its bytes: {v}");
assert!(a["total_bytes"].as_u64().unwrap() > 0);
let widen = a["top_named"].as_array().unwrap().iter().find(|g| g["symbol"].as_str().is_some_and(|s| s.ends_with("widen"))).unwrap_or_else(|| panic!("widen is a named generic: {v}"));
assert_eq!(widen["instantiations"], 6, "{widen}");
assert!(note(&v).contains("latest Build Thing artifact of each variant"), "{}", note(&v));
// a repo nothing was built for is said by name
let other = ask(&room, &wh, "generic_cost", json!({ "repo": "nobody" }));
assert!(note(&other).contains("no Build Thing run has filed an artifact for `nobody` yet: ⚒ Build it"), "{}", note(&other));
let d = ask(&room, &wh, "binary_drift", json!({}));
assert_eq!(d["lens_meta"]["state"], "empty_gap", "{d}");
assert!(note(&d).contains("filed once") && note(&d).contains("⚒ Build it again after a change"), "{}", note(&d));
assert!(d["attestation"].as_str().unwrap().contains("UNKNOWN"), "{d}");
}
/// Two real builds of the same variant, the second after a commit that
/// changed `checksum`: `binary_drift` reports the change between the two
/// filings — first party, explained by the commit — and `generic_cost`
/// reads the newer artifact.
#[test]
fn a_second_build_with_a_changed_function_is_the_drift_binary_drift_reports() {
let _g = fixture::serial();
let tmp = tempfile::tempdir().unwrap();
let builds = tmp.path().join("builds");
std::fs::create_dir_all(&builds).unwrap();
let wh = IcebergWarehouse::open(&builds).unwrap();
let room = CodeRoom::new("ws", &builds);
let root = tmp.path().join("binlens-probe");
write_crate(&root, "binlens-probe", CHECKSUM_V1);
let sha1 = commit(&root, "v1");
let (first, _) = build_and_file(&room, &wh, &root, "binlens-probe", &sha1);
write_crate(&root, "binlens-probe", CHECKSUM_V2);
let sha2 = commit(&root, "checksum: fnv");
let (second, _) = build_and_file(&room, &wh, &root, "binlens-probe", &sha2);
assert_ne!(first.artifacts[0].sha256, second.artifacts[0].sha256, "other bytes");
let d = ask(&room, &wh, "binary_drift", json!({ "repo": "binlens-probe" }));
// the edge half (P4) is the one named gap
assert_eq!(d["lens_meta"]["state"], "partial", "{d}");
let step = &d["steps"][0];
assert_eq!((step["from"]["sha256"].as_str(), step["to"]["sha256"].as_str()), (Some(first.artifacts[0].sha256.as_str()), Some(second.artifacts[0].sha256.as_str())), "{step}");
assert!(step["provenance_changed"][0].as_str().unwrap().starts_with("commit binlens-probe"), "{step}");
let checksum = d["findings"]
.as_array()
.unwrap()
.iter()
.find(|f| f["symbol"].as_str().is_some_and(|s| s.contains("checksum")))
.unwrap_or_else(|| panic!("the changed function is reported: {d}"));
assert!(["symbol-grew", "symbol-shrunk", "symbol-added", "symbol-removed"].contains(&checksum["kind"].as_str().unwrap()), "{checksum}");
assert_eq!((checksum["first_party"].as_bool(), checksum["explained_by"].as_str(), checksum["severity"].as_str()), (Some(true), Some("source"), Some("medium")), "{checksum}");
assert_eq!((checksum["from_commit"].as_str(), checksum["to_commit"].as_str()), (Some(&sha1[..10]), Some(&sha2[..10])));
assert_eq!(d["attested"], true, "a source change explains it: {d}");
// the first-party change ranks above the dependency churn
assert_eq!(d["findings"][0]["first_party"], true, "{d}");
let g = ask(&room, &wh, "generic_cost", json!({ "repo": "binlens-probe" }));
assert!(g["worst_artifacts"][0]["artifact"].as_str().unwrap().ends_with(&second.artifacts[0].sha256[..16]), "the latest filed artifact: {g}");
}
/// `zombie_features`' bytes are the gated item's symbols in the latest Build
/// Thing artifact built from its repo: the fixture shop's `pay::dead` (gated
/// by `unused`), built for real and filed from shop's commit.
#[test]
fn zombie_bytes_are_the_gated_items_symbols_in_the_latest_filed_artifact() {
let _g = fixture::serial();
let ws = fixture::graph_only(Without::default());
let tmp = tempfile::tempdir().unwrap();
let root = tmp.path().join(SHOP);
write_crate(&root, SHOP, CHECKSUM_V1);
let sha = commit(&root, "shop");
let before = ws.ask("zombie_features", json!({ "repo": SHOP }));
let unused = |v: &Value| v["worst"].as_array().unwrap().iter().find(|f| f["feature"] == "shop/unused").cloned().unwrap_or_else(|| panic!("{v}"));
assert_eq!(unused(&before)["bytes_in_binary"], Value::Null, "nothing filed yet: {before}");
build_and_file(&ws.room, &ws.warehouse, &root, SHOP, &sha);
let after = ws.ask("zombie_features", json!({ "repo": SHOP }));
assert_eq!(after["lens_meta"]["state"], "complete", "{after}");
assert!(unused(&after)["bytes_in_binary"].as_u64().unwrap() > 0, "pay::dead's bytes: {after}");
assert!(note(&after).contains("latest Build Thing artifact built from its repo"), "{}", note(&after));
}