crates/mimir-room/tests/room/boundary.rs
//! The system boundary in the room: a consumed repo whose code reaches std,
//! std reaching libc's `ffi` items, the boundary written once
//! (`mimir_ingest::boundary::ensure`: table, maps, a generated kernel BTF) —
//! and the ring-on room answers who reaches which system call, by class,
//! with the path, down to the kernel function the call enters.
//!
//! ```text
//! own k files → std fsread → std open_c → libc open64 (ffi) ⇒ openat (file)
//! k net → std connect ──────────────→ libc connect (ffi) ⇒ connect (network)
//! k pure → std add ⇒ nothing
//! std statx (named like the call) → libc syscall (the raw door)
//! ```
use mimir_ingest::boundary::{self, KernelSource, Target};
use mimir_room::{MaskSpec, Room, Scope};
use mimir_schema::{EdgeKind, Origin, kind as nk, moniker};
use super::common::*;
const REPO: &str = "bound";
fn libc_ffi(name: &str) -> mimir_schema::NodeRow {
let mut n = node(&format!("libc {name}"), nk::FFI, "libc", Origin::Library, true);
n.link_name = Some(name.to_string());
n
}
fn libc_syscall_id() -> String {
// the raw door is recognised by its moniker (`libc … syscall().`)
"rust-analyzer cargo libc 0.2.0 unix/linux_like/linux/syscall().".to_string()
}
fn steps() -> Vec<Step> {
use EdgeKind::*;
let own = vec![
node("k", "crate", "k", Origin::Local, true),
k("files", "fn"),
k("net", "fn"),
k("pure", "fn"),
node("std", "crate", "std", Origin::Lang, false),
node("std fsread", "fn", "std", Origin::Lang, false),
node("std connect", "fn", "std", Origin::Lang, false),
node("std add", "fn", "std", Origin::Lang, false),
];
let own_edges = vec![
edge("k", "std", DependsOn),
edge("k files", "std fsread", Calls),
edge("k net", "std connect", Calls),
edge("k pure", "std add", Calls),
];
let mut raw = node(&libc_syscall_id(), nk::FFI, "libc", Origin::Library, true);
raw.link_name = Some("syscall".into());
let std_ring = (
"std@lang:lib",
vec![
node("std", "crate", "std", Origin::Lang, true),
node("std fsread", "fn", "std", Origin::Lang, true),
node("std open_c", "fn", "std", Origin::Lang, true),
node("std connect", "fn", "std", Origin::Lang, true),
node("std add", "fn", "std", Origin::Lang, true),
node("std statx", "fn", "std", Origin::Lang, true),
node("libc", "crate", "libc", Origin::Library, false),
],
vec![
edge("std", "libc", DependsOn),
edge("std fsread", "std open_c", Calls),
edge("std open_c", "libc open64", Calls),
edge("std connect", "libc connect", Calls),
edge("std statx", &libc_syscall_id(), Calls),
],
);
let libc_ring = ("libc@0.2.0:lib", vec![node("libc", "crate", "libc", Origin::Library, true), libc_ffi("open64"), libc_ffi("connect"), libc_ffi("strlen"), raw], vec![]);
vec![Step { owner: "k@0.1.0:lib", nodes: own, edges: own_edges, binary: None, ring: vec![std_ring, libc_ring] }]
}
fn sc(n: &str) -> String {
moniker::syscall("x86_64", n)
}
#[tokio::test(flavor = "current_thread")]
async fn the_room_walks_own_code_down_to_the_system_call_and_the_kernel() {
let _g = serial().await;
let tmp = tempfile::tempdir().unwrap();
let log = consume(open_log(tmp.path()).await, tmp.path(), REPO, steps()).await;
let btf = tmp.path().join("vmlinux.btf");
std::fs::write(&btf, mimir_ingest::boundary::btf::sample_kernel()).unwrap();
let kernel = KernelSource { path: btf, release: "6.99.0-test".into(), chosen: "configured" };
let target = Target::parse("x86_64-unknown-linux-gnu").unwrap();
let w = log.writer().unwrap();
let first = boundary::ensure(&w, &target, "nightly-fixture", Some(&kernel)).await.unwrap();
eprintln!("{}", first.line());
assert!(first.table_written.is_some());
assert!(first.kernel.as_ref().is_some_and(|k| k.written && k.entries_linked == 3), "{:?}", first.kernel);
assert_eq!(first.map.owners_with_edges, 2, "std (statx → the raw door) and libc: {:?}", first.map);
// ONCE: a second ensure writes nothing
let again = boundary::ensure(&w, &target, "nightly-fixture", Some(&kernel)).await.unwrap();
assert!(again.table_written.is_none() && again.maps_written == 0 && !again.kernel.as_ref().unwrap().written, "{}", again.line());
drop(w);
let room = Room::at(&log, &Scope::current().with_universe(true)).await.unwrap();
let o = |id: &str| room.ordinal(id).unwrap_or_else(|| panic!("{id} not in the room"));
let walk = [EdgeKind::Calls, EdgeKind::Syscalls];
// file: k files → … → libc open64 ⇒ openat
let p = room.path(&[o("k files")][..], &[o(&sc("openat"))][..], &walk, None, None).unwrap().value.expect("a path to openat");
assert_eq!(room.monikers(&p.nodes), vec!["k files", "std fsread", "std open_c", "libc open64", sc("openat").as_str()]);
assert_eq!(p.kinds.last(), Some(&EdgeKind::Syscalls));
assert_eq!(room.node(o(&sc("openat"))).ty, Some("file"));
// network: k net ⇒ connect, and connect enters the kernel at __x64_sys_connect
let reached = room.reach(&[o("k net")][..], &walk, None, None).unwrap().value.reached;
let calls: Vec<&str> = reached.iter().filter(|r| room.node(**r).kind == Some(nk::SYSCALL)).map(|r| room.node(*r).name.unwrap()).collect();
assert_eq!(calls, vec!["connect"]);
assert_eq!(room.node(o(&sc("connect"))).ty, Some("network"));
let entry = moniker::kernel_item("6.99.0-test", "func", "__x64_sys_connect", None);
let into_kernel = room.path(&[o("k net")][..], &[o(&entry)][..], &walk, None, None).unwrap().value.expect("into the kernel");
assert_eq!(room.moniker(*into_kernel.nodes.last().unwrap()), entry);
// the kernel's types came with it
assert!(room.ordinal(&moniker::kernel_item("6.99.0-test", "struct", "task_struct", None)).is_some());
// pure: reaches no system call
let pure = room.reach(&[o("k pure")][..], &walk, None, None).unwrap().value.reached;
assert!(pure.iter().all(|r| room.node(*r).kind != Some(nk::SYSCALL)), "{:?}", room.monikers(&pure));
// the raw door: std's statx-named fn → statx (uncertain), libc syscall → <indirect>
assert!(room.path(&[o("std statx")][..], &[o(&sc("statx"))][..], &[EdgeKind::Syscalls], Some(1), None).unwrap().value.is_some());
assert!(room.path(&[o(&libc_syscall_id())][..], &[o(&sc(boundary::INDIRECT))][..], &[EdgeKind::Syscalls], Some(1), None).unwrap().value.is_some());
// who reaches the network, walked BACK from every network call
let net = room.mask(&MaskSpec { node_kinds: vec![nk::SYSCALL.into()], ..Default::default() }).unwrap().value;
let net: Vec<u64> = net.ordinals().iter().copied().filter(|x| room.node(*x).ty == Some("network")).collect();
let back = room.dependents_by(&net[..], &walk, None, None).unwrap().value.reached;
let own: Vec<&str> = back.iter().filter(|r| room.node(**r).origin == Some(Origin::Local)).map(|r| room.moniker(*r)).collect();
assert_eq!(own, vec!["k net"]);
// ring off: the boundary is not in the room of the own code
let off = Room::at(&log, &Scope::current()).await.unwrap();
assert!(off.ordinal(&sc("openat")).is_none());
}
/// What a reader of the ring room needs to carry an answer across a room
/// advance: the universe's identity (`universe_key`, equal while the ring
/// rows are), the nodes local edge rows leave (`local_out`: the only out-edges
/// a consume moves), and the out-edges of a FEW nodes without listing the
/// whole kind (`edges` with a sparse `from` = the row filter of the full list).
#[tokio::test(flavor = "current_thread")]
async fn the_ring_room_names_its_universe_and_its_local_edge_sources() {
let _g = serial().await;
let tmp = tempfile::tempdir().unwrap();
let log = consume(open_log(tmp.path()).await, tmp.path(), REPO, steps()).await;
let target = Target::parse("x86_64-unknown-linux-gnu").unwrap();
let w = log.writer().unwrap();
boundary::ensure(&w, &target, "nightly-fixture", None).await.unwrap();
drop(w);
let room = Room::at(&log, &Scope::current().with_universe(true)).await.unwrap();
let o = |id: &str| room.ordinal(id).unwrap_or_else(|| panic!("{id} not in the room"));
let key = room.universe_key().expect("ring on: the universe has a key");
let off = Room::at(&log, &Scope::current()).await.unwrap();
assert_eq!(off.universe_key(), None, "ring off: no universe");
let local: Vec<&str> = room.local_out().iter().map(|x| room.moniker(*x)).collect();
for m in ["k", "k files", "k net", "k pure"] {
assert!(local.contains(&m), "{m} leaves a local edge row: {local:?}");
}
for m in ["std fsread", "std open_c", "std connect"] {
assert!(!local.contains(&m), "{m}'s edges are the ring's: {local:?}");
}
// a sparse `from` takes the rows only — the same edges as the filter
let all = room.edges(&mimir_room::EdgeSel::kinds(&[EdgeKind::Calls])).unwrap().value.edges;
for seeds in [vec![o("k files")], vec![o("k net"), o("std open_c")], vec![]] {
let m = room.mask_of(&seeds);
let some = room.edges(&mimir_room::EdgeSel { from: Some(&m), ..mimir_room::EdgeSel::kinds(&[EdgeKind::Calls]) }).unwrap().value.edges;
let want: Vec<_> = all.iter().copied().filter(|e| seeds.contains(&e.from)).collect();
assert_eq!(some, want, "{seeds:?}");
let pairs = room.out_pairs(EdgeKind::Calls, &m.ordinals().to_vec()).unwrap();
assert_eq!(pairs, want.iter().map(|e| (e.from, e.to)).collect::<Vec<_>>());
}
assert!(all.len() * 8 > 0 && room.len() > 8 * 2, "the room is large enough for the row path");
// the same lake state, opened again: the same universe
let again = Room::at(&log, &Scope::current().with_universe(true)).await.unwrap();
assert_eq!(again.universe_key(), Some(key));
// a ring write (the kernel's rows) moves the manifest: another universe
let btf = tmp.path().join("vmlinux.btf");
std::fs::write(&btf, mimir_ingest::boundary::btf::sample_kernel()).unwrap();
let kernel = KernelSource { path: btf, release: "6.99.0-test".into(), chosen: "configured" };
let w = log.writer().unwrap();
boundary::ensure(&w, &target, "nightly-fixture", Some(&kernel)).await.unwrap();
drop(w);
Room::clear_cache();
let moved = Room::at(&log, &Scope::current().with_universe(true)).await.unwrap();
assert_ne!(moved.universe_key(), Some(key), "the ring rows moved: the universe key moves with them");
}