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

nordisk/edda

crates/nornir-build-thing/tests/kernel_run_live.rs

//! **HEAVY, LIVE RUN — what a workload actually EXECUTED, `#[ignore]`d.**
//!
//! Design §4's loop. LTO and dead-code elimination are STATIC: they drop what
//! can never be called and know nothing about what ran. ftrace's function
//! profiler is the only instrument that does, and this drives it — boot a kernel
//! built with `profile_run = true` in QEMU inside the toolchain container, let
//! PID 1 profile a small appliance-shaped workload, and read the counters back
//! off the serial console.
//!
//! ```bash
//! export KERNEL_RUN_ROOT=/path/holding/.kernel-out
//! export KERNEL_RUN_NAME=e2e-slim-profiled
//! export KERNEL_RUN_TOOLCHAIN=localhost/nordisk-kernel-toolchain:latest
//! cargo test -p nornir-build-thing --features kernel-build \
//!     --test kernel_run_live -- --ignored --nocapture
//! ```
#![cfg(feature = "kernel-build")]

use nornir_build_thing::kernel::{run_kernel_with, DraupnirKernelRunner, KernelBuild};

#[test]
#[ignore = "HEAVY: boots a profiling kernel under QEMU inside a container. Needs \
            KERNEL_RUN_ROOT + KERNEL_RUN_NAME and a podman/Docker socket."]
fn a_profiled_kernel_reports_what_the_workload_executed() {
    let (Ok(root), Ok(name)) =
        (std::env::var("KERNEL_RUN_ROOT"), std::env::var("KERNEL_RUN_NAME"))
    else {
        eprintln!(
            "SKIP (not a pass): set KERNEL_RUN_ROOT to the repo_root a PROFILED kernel was \
             built under and KERNEL_RUN_NAME to its variant name."
        );
        return;
    };

    let mut k = KernelBuild {
        name,
        version: "0.0.0".into(),
        tarball_sha256: "0".repeat(64),
        profile_run: true,
        ..KernelBuild::default()
    };
    if let Ok(img) = std::env::var("KERNEL_RUN_TOOLCHAIN") {
        k.toolchain_image = img;
        k.toolchain_packages = Vec::new();
    }
    k.validate().expect("the run declaration");

    let run = run_kernel_with(&DraupnirKernelRunner::new(), &k, std::path::Path::new(&root))
        .expect("the profile run");

    eprintln!(
        "kernel_run_live: {} · tracing={} · {} executed of {} traceable · {} NEVER entered",
        k.name,
        run.tracing_path,
        run.executed(),
        run.traceable,
        run.never_executed()
            .map(|n| n.to_string())
            .unwrap_or_else(|| "<unknown: no available_filter_functions>".into()),
    );
    for (f, h) in run.hits.iter().filter(|(_, h)| *h > 0).take(15) {
        eprintln!("  {h:>8}  {f}");
    }

    assert!(run.complete, "the counters were not read to the end");
    assert!(!run.tracing_path.is_empty(), "the guest must say WHERE it read them");
    // A profiled boot touches thousands of functions. A handful would mean the
    // profiler was on but nothing was traced, which is a different failure from
    // a small workload and must not pass as one.
    // The drop candidates are the point of the loop: a run that could not say
    // how many functions COULD have been traced has measured a numerator with
    // no denominator.
    assert!(run.traceable > run.executed() as u64, "traceable={} executed={}", run.traceable, run.executed());
    // THE REPORT: which CONFIG symbols nothing under them executed.
    let (never, touched) = run.unused_configs();
    if run.mapping.is_empty() {
        eprintln!("  (no build tree in this workdir — no symbol report)");
    } else {
        eprintln!(
            "  mapping: {} function rows · {} CONFIG symbols touched · {} NEVER touched",
            run.mapping.len(),
            touched,
            never.len()
        );
        for c in never.iter().take(12) {
            eprintln!("    drop candidate: {c}");
        }
        assert!(touched > 0, "no symbol was touched at all — the join is broken, not the kernel");
        assert!(!never.is_empty(), "every claimed symbol ran, which is not credible");
    }
    assert!(
        run.executed() > 100,
        "only {} functions executed — the profiler reported almost nothing, which is not a \
         small workload, it is a broken measurement",
        run.executed()
    );
}