use std::env; use std::process::{Command, Stdio}; use std::sync::mpsc; use std::thread; use std::time::Duration; use std::io::{BufRead, BufReader, Read}; fn main() { assert_eq!(env::args().len(), 2); let status = Command::new("rumprun-bake") .arg("hw_virtio") .arg("/tmp/ifstructs-test.img") .arg(env::args().nth(1).unwrap()) .status() .expect("failed to run rumprun-bake"); assert!(status.success()); let mut child = Command::new("qemu-system-x86_64") .arg("-nographic") .arg("-vga").arg("none") .arg("-m").arg("64") .arg("-kernel").arg("/tmp/ifstructs-test.img") .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn() .expect("failed to spawn qemu"); let mut stdout = child.stdout.take().unwrap(); let mut stderr = child.stderr.take().unwrap(); let (tx, rx) = mpsc::channel(); let tx2 = tx.clone(); let t1 = thread::spawn(move || find_ok(&mut stdout, tx)); let t2 = thread::spawn(move || find_ok(&mut stderr, tx2)); let res = rx.recv_timeout(Duration::new(5, 0)); child.kill().unwrap(); t1.join().unwrap(); t2.join().unwrap(); if res.is_err() { panic!("didn't find success"); } } fn find_ok(input: &mut Read, tx: mpsc::Sender<()>) { for line in BufReader::new(input).lines() { let line = line.unwrap(); println!("{}", line); if line.starts_with("PASSED ") && line.contains(" tests") { tx.send(()).unwrap(); } } }