use super::*;
use std::sync::Mutex;
static GUARD_TURN: Mutex<()> = Mutex::new(());
struct Releases {
count: usize,
fails: bool,
}
impl ReleaseSteps for Releases {
fn release(&mut self) -> Result<(), String> {
self.count += 1;
if self.fails {
return Err(String::from("lock refused"));
}
return Ok(());
}
}
#[cfg(unix)]
#[test]
fn the_guarded_child_exit_code_is_returned_after_one_release() {
let _turn = GUARD_TURN.lock().unwrap_or_else(std::sync::PoisonError::into_inner);
let mut releases: Releases = Releases { count: 0, fails: false };
let mut command: Command = Command::new("/bin/sh");
command.args(["-c", "exit 3"]);
assert_eq!(run_guarded_child(&mut command, &mut releases), Ok(3));
assert_eq!(releases.count, 1);
}
#[cfg(unix)]
#[test]
fn a_failed_release_is_reported_after_the_child_ends() {
let _turn = GUARD_TURN.lock().unwrap_or_else(std::sync::PoisonError::into_inner);
let mut releases: Releases = Releases { count: 0, fails: true };
let mut command: Command = Command::new("/bin/sh");
command.args(["-c", "exit 0"]);
let outcome: Result<i32, String> = run_guarded_child(&mut command, &mut releases);
assert!(matches!(&outcome, Err(message) if message.contains("releasing after the child failed")), "{outcome:?}");
assert_eq!(releases.count, 1);
}