use crate::time::Instant;
use crate::*;
use std::cell::RefCell;
use std::collections::HashSet;
use std::rc::Rc;
use std::time::Duration;
test_fn!(
#[cfg_attr(miri, ignore)]
fn run() {
let data = std::include_bytes!("timers_corpus.bin");
let mut p = &data[..];
while !p.is_empty() {
let len = ((p[0] as usize) << 8) + (p[1] as usize);
fuzz_timers(&p[2..2 + len]);
p = &p[2 + len..];
}
}
);
pub fn fuzz_timers(data: &[u8]) {
if data.is_empty() {
return;
}
let mut now = Instant::now();
let mut stakker = Stakker::new(now);
let s = &mut stakker;
let mut seq = 1;
let expecting = Rc::new(RefCell::new(HashSet::new()));
let pull_inc = data[0] as u32;
let mut pull_val = 128;
for b in &data[1..] {
seq += 1;
let dur = ((*b & 15) as u64) << ((*b >> 4) as u32);
let dur = Duration::from_micros(dur * 853439);
let expiry = now + dur;
expecting.borrow_mut().insert(seq);
let exp = expecting.clone();
let seq2 = seq;
at!(expiry, [s], |s| {
let now = s.now();
assert!(now >= expiry);
assert!(now < expiry + Duration::from_micros(17));
assert!(exp.borrow_mut().remove(&seq2));
});
pull_val += pull_inc;
if pull_val >= 255 {
pull_val -= 255;
now = s.next_expiry().unwrap();
s.run(now, false);
}
}
while let Some(next) = s.next_expiry() {
now = next;
s.run(now, false);
}
assert!(expecting.borrow_mut().is_empty());
}