use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::Duration;
use super::{pump, run};
use crate::state::Link;
use crate::test_support::Scratch;
use crate::test_support::wire::{flat, wired};
use crate::ui::{Channel, Chunk, Model};
use serde_json::json;
mod window;
const HUNG: Duration = Duration::from_mins(4);
#[test]
fn a_worker_passes_until_the_link_says_stop() {
let link = Link::new(Duration::from_millis(1));
let passes = AtomicUsize::new(0);
pump(&link, || {
if passes.fetch_add(1, Ordering::Relaxed) >= 2 {
link.stop();
}
});
assert_eq!(
passes.load(Ordering::Relaxed),
3,
"three passes, then the check"
);
}
#[test]
fn a_worker_started_after_a_stop_does_nothing() {
let link = Link::new(Duration::from_millis(1));
link.stop();
let passes = AtomicUsize::new(0);
pump(&link, || {
passes.fetch_add(1, Ordering::Relaxed);
});
assert_eq!(passes.load(Ordering::Relaxed), 0);
}
#[test]
fn the_threads_carry_a_real_answer_to_a_real_frame() {
let scratch = Scratch::new();
let roster = json!({"ok": true, "kind": "workspaces",
"rows": [{"workspace": "home", "kind": "named", "attention": 0,
"agents": 3, "running": true}]});
wired(&scratch, &flat(), vec![vec![roster.clone()]; 8]);
let mut model = Model {
roster: vec![Chunk::of(Channel {
name: crate::seat::OWN.to_owned(),
named_there: None,
dials: None,
})],
..Model::default()
};
let link = Link::new(Duration::from_millis(1));
link.settle(&mut model);
let workers = run(&link, scratch.path());
let deadline = std::time::Instant::now() + HUNG;
while model.roster[0].walls.is_empty() && std::time::Instant::now() < deadline {
std::thread::sleep(Duration::from_millis(5));
link.settle(&mut model);
}
link.stop();
for worker in workers {
worker.join().expect("a worker");
}
assert_eq!(
model.roster[0]
.walls
.first()
.map(|row| row.workspace.clone()),
Some("home".to_owned()),
"the asker's answer reached the frame"
);
}