Files
MercuryToolbox/crates/runtimekit/tests/loom_capture.rs
T

58 lines
1.7 KiB
Rust

//! Loom model for the runtime command capture join pattern.
use loom::sync::{Arc, Mutex};
use loom::thread;
fn join_capture(
handle: loom::thread::JoinHandle<Result<Vec<u8>, &'static str>>,
stream: &'static str,
) -> Result<Vec<u8>, String> {
handle
.join()
.map_err(|_| format!("{stream} capture thread panicked"))?
.map_err(|error| format!("failed to read child {stream}: {error}"))
}
#[test]
fn capture_threads_publish_before_join_returns() {
loom::model(|| {
let events = Arc::new(Mutex::new(Vec::new()));
let stdout_events = Arc::clone(&events);
let stderr_events = Arc::clone(&events);
let stdout = thread::spawn(move || {
let mut guard = stdout_events.lock().expect("stdout lock");
guard.push("stdout");
});
let stderr = thread::spawn(move || {
let mut guard = stderr_events.lock().expect("stderr lock");
guard.push("stderr");
});
stdout.join().expect("stdout join");
stderr.join().expect("stderr join");
{
let guard = events.lock().expect("events lock");
assert_eq!(guard.len(), 2);
assert!(guard.contains(&"stdout"));
assert!(guard.contains(&"stderr"));
drop(guard);
}
});
}
#[test]
fn capture_join_models_success_and_read_error_paths() {
loom::model(|| {
let stdout = thread::spawn(|| Ok(vec![b'o', b'k']));
let stderr = thread::spawn(|| Err("broken pipe"));
assert_eq!(join_capture(stdout, "stdout").expect("stdout"), b"ok");
assert_eq!(
join_capture(stderr, "stderr").expect_err("stderr"),
"failed to read child stderr: broken pipe"
);
});
}