Files
sausage/userland/init/src/probe.rs
T

97 lines
3.4 KiB
Rust

//! Acceptance guest for unit lifecycle and process-interface readiness tests.
use std::{
fs,
io::{Read, Write},
};
fn main() {
let args: Vec<_> = std::env::args().collect();
match args.get(1).map(String::as_str).unwrap_or("") {
"kill-init" => {
let table = fs::read_to_string("/proc/processes").unwrap();
let row = table
.lines()
.find(|line| line.ends_with("/bin/init.wasm"))
.unwrap();
sausage_spawn::kill(row.split('\t').next().unwrap().parse().unwrap()).unwrap();
}
"watch" => {
use sausage_spawn::{ChangeKind, Watcher};
let watcher = Watcher::new(&["/run/watched".into()]);
let poll = watcher.subscribe();
assert!(!poll.ready());
fs::create_dir_all("/run/watched").unwrap();
poll.block();
assert!(
watcher
.changes()
.iter()
.any(|c| matches!(c.kind, ChangeKind::Created))
);
fs::write("/run/watched/a", "a").unwrap();
watcher.changes();
fs::write("/run/watched/a", "b").unwrap();
assert!(
watcher
.changes()
.iter()
.any(|c| c.path == "/run/watched/a" && matches!(c.kind, ChangeKind::Modified))
);
fs::remove_file("/run/watched/a").unwrap();
assert!(
watcher
.changes()
.iter()
.any(|c| matches!(c.kind, ChangeKind::Removed))
);
for i in 0..300 {
fs::write(format!("/run/watched/{i}"), "").unwrap();
}
assert!(
watcher
.changes()
.iter()
.any(|c| matches!(c.kind, ChangeKind::Overflow))
);
drop(poll);
let mut cmd = sausage_spawn::Command::new("/bin/probe.wasm");
cmd.arg("exit").arg("7");
let child = cmd.spawn().unwrap();
let exit = child.subscribe();
exit.block();
assert_eq!(child.try_wait(), Some(7));
}
"exit" => sausage_init::exit(args.get(2).and_then(|a| a.parse().ok()).unwrap_or(0)),
"oneshot" | "server" | "crash" | "after" | "linger" => {
if args[1] == "after" {
assert!(
!fs::read_to_string("/proc/processes")
.unwrap()
.contains("oneshot /order.log")
);
}
let mut log = fs::OpenOptions::new()
.create(true)
.append(true)
.open(&args[2])
.unwrap();
writeln!(log, "start").unwrap();
for n in 1..=10 {
println!("line {n}");
}
if args[1] == "linger" {
loop {
std::thread::sleep(std::time::Duration::from_secs(1));
}
}
if args[1] == "crash" {
std::process::exit(1);
}
if args[1] == "server" || args[1] == "after" {
let _ = std::io::stdin().read_to_end(&mut Vec::new());
writeln!(log, "stop").unwrap();
}
}
_ => panic!("unknown probe mode"),
}
}