//! 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"), } }