#![cfg(target_os = "linux")]
use super::*;
use crate::test_support::{fixture, remove};
use std::path::PathBuf;
use std::sync::mpsc::channel;
const WINDOW: Duration = Duration::from_millis(1200);
const QUIET_FIXTURE: Duration = Duration::from_secs(4);
const PATIENCE: Duration = Duration::from_secs(20);
#[test]
fn the_calling_thread_has_a_number() {
let tid: i32 = current_thread_id().expect("Linux names threads");
assert!(std::path::Path::new(format!("/proc/self/task/{tid}").as_str()).exists());
}
#[test]
fn a_sleeping_thread_is_judged_quiet_after_the_window() {
let (sender, receiver) = channel::<i32>();
let sleeper = std::thread::spawn(move || {
sender.send(current_thread_id().expect("a thread number")).expect("tell the control");
std::thread::sleep(QUIET_FIXTURE);
});
let tid: i32 = receiver.recv().expect("the sleeper's number");
let mut clock: ThreadClock = ThreadClock::start(tid, WINDOW, false);
let began: Instant = Instant::now();
while !clock.quiet() {
assert!(began.elapsed() < PATIENCE, "a sleeping thread was never judged quiet");
std::thread::sleep(Duration::from_millis(20));
}
assert!(clock.longest_quiet() >= WINDOW, "{:?}", clock.longest_quiet());
sleeper.join().expect("the sleeper ends");
}
#[test]
fn a_writing_thread_is_never_judged_quiet() {
let root: PathBuf = fixture("thread-quiet-writer");
let target: PathBuf = root.join("progress");
let (sender, receiver) = channel::<i32>();
let rounds: u32 = 15;
let writer = std::thread::spawn(move || {
sender.send(current_thread_id().expect("a thread number")).expect("tell the control");
for round in 0..rounds {
std::fs::write(&target, round.to_string()).expect("write");
std::thread::sleep(Duration::from_millis(200));
}
});
let tid: i32 = receiver.recv().expect("the writer's number");
let mut clock: ThreadClock = ThreadClock::start(tid, WINDOW, false);
let mut judged_quiet: bool = false;
while !writer.is_finished() {
judged_quiet |= clock.quiet();
std::thread::sleep(Duration::from_millis(20));
}
let longest: Duration = clock.longest_quiet();
writer.join().expect("the writer ends");
assert!(!judged_quiet, "a thread that kept writing was judged quiet");
assert!(longest < WINDOW, "{longest:?}");
remove(root.as_path());
}
#[test]
fn an_unreadable_thread_is_never_judged_quiet() {
let mut clock: ThreadClock = ThreadClock::start(i32::MAX, Duration::ZERO, false);
std::thread::sleep(Duration::from_millis(5));
assert!(!clock.quiet());
}
#[test]
fn a_measured_job_leaves_its_gap_in_the_ledger() {
crate::quiet_ledger::drain();
let pause: Duration = Duration::from_millis(900);
let value: u8 = measured_quiet("measured fixture", || {
std::thread::sleep(pause);
return 3;
});
assert_eq!(value, 3);
let figures = crate::quiet_ledger::drain();
let kept = figures.iter().find(|(step, _)| { return step == "measured fixture"; }).expect("the step is in the ledger");
assert!(kept.1 >= pause / 2 && kept.1 <= pause * 4, "{kept:?}");
}