Remove `test_runner`'s dependence on `async-std` and `tokio`. `test_runner` used both `async-std` and `tokio` to implement a timeout on test execution. This brought in a *large* dependency tree. Some of the crates in that dependency tree (e.g. `value-bag`) assume that if you're on nightly Rust, you have an up to date compiler. At the moment, this is breaking `libtock-rs`' CI: `value-bag` does not build with the toolchain `libtock-rs` uses. I tried to update the compiler, but newer compilers SIGSEGV somewhere in `libtock-rs`. Rather than investigating that (which will likely be very time-consuming), I decided to remove `libtock-rs`' dependency on `value-bag`. This required removing `test_runner`'s dependency on both `tokio` and `async-std`. I replaced the timeout functionality by spawning a second thread that waits for 10 seconds then kills QEMU.
diff --git a/test_runner/Cargo.toml b/test_runner/Cargo.toml index 66a407a..9471138 100644 --- a/test_runner/Cargo.toml +++ b/test_runner/Cargo.toml
@@ -3,20 +3,3 @@ version = "0.1.0" authors = ["torfmaster <briefe@kebes.de>"] edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -structopt = { version = "0.3", default-features = false } -futures = "0.3.4" - -[dependencies.async-std] -# async-std 1.7 pulls in crossbeam_utils 1.8, which does not work with the -# nightly Rust toolchain we use. Temporarily block async-std 1.7 until we can -# update our Rust toolchain. -version = "1.5.0, <1.7" -features = ["attributes"] - -[dependencies.tokio] -version = "0.2.12" -features = ["process", "rt-threaded", "macros", "io-util", "time"]
diff --git a/test_runner/src/main.rs b/test_runner/src/main.rs index 0bea1cf..b21b945 100644 --- a/test_runner/src/main.rs +++ b/test_runner/src/main.rs
@@ -1,20 +1,10 @@ use std::fmt; -use std::process::Stdio; +use std::io::{BufRead, BufReader}; +use std::process::{ChildStdout, Command, Stdio}; use std::time::Duration; -use tokio::io::AsyncBufReadExt; -use tokio::io::BufReader; -use tokio::process::Command; -use tokio::time::timeout; -#[tokio::main] -async fn main() -> Result<(), Box<dyn std::error::Error>> { - timeout(Duration::from_secs(10), perform_tests()).await? -} - -async fn perform_tests() -> Result<(), Box<dyn std::error::Error>> { - let mut failed_tests = Vec::new(); - - let tests = Command::new("tock/tools/qemu-build/riscv32-softmmu/qemu-system-riscv32") +fn main() -> Result<(), Box<dyn std::error::Error>> { + let mut tests = Command::new("tock/tools/qemu-build/riscv32-softmmu/qemu-system-riscv32") .arg("-M") .arg("sifive_e,revb=true") .arg("-kernel") @@ -24,15 +14,32 @@ .arg("-nographic") .stdin(Stdio::null()) .stdout(Stdio::piped()) - .kill_on_drop(true) .spawn()?; + let stdout = tests.stdout.take().unwrap(); + let child_handle = std::sync::Arc::new(std::sync::Mutex::new(tests)); + let timeout_handle = child_handle.clone(); + std::thread::spawn(move || { + std::thread::sleep(Duration::from_secs(10)); + let _ = timeout_handle + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .kill(); + }); + let result = process_output(stdout); + let _ = child_handle + .lock() + .unwrap_or_else(std::sync::PoisonError::into_inner) + .kill(); + result +} - let stdout = tests.stdout.unwrap(); - +fn process_output(stdout: ChildStdout) -> Result<(), Box<dyn std::error::Error>> { + let mut failed_tests = Vec::new(); let stdout_reader = BufReader::new(stdout); - let mut stdout_lines = stdout_reader.lines(); + let stdout_lines = stdout_reader.lines(); - while let Some(line) = stdout_lines.next_line().await? { + for line in stdout_lines { + let line = line?; println!("UART: {}", line); let test_result = test_succeeded(line, &mut failed_tests); if let Some(true) = test_result {