use std::time::{Duration, Instant};
use crate::budget::{deterministic_deadline, expired, remaining};
use crate::config::ConstructionBudget;
use crate::decompose::meter;
#[test]
fn a_unit_budget_names_a_deadline_that_much_work_ahead() {
let epoch = Instant::now();
for ms in [1_u64, 90_000, 900_000] {
let units = ConstructionBudget::units_for_wall_ms(ms);
assert_eq!(
deterministic_deadline(units, epoch),
Some(epoch + Duration::from_millis(ms)),
);
}
if let Some(absurd) = deterministic_deadline(u64::MAX, epoch) {
assert!(absurd > epoch);
}
}
#[test]
fn the_deadline_predicates_answer_on_charged_work() {
let epoch = Instant::now();
let units = ConstructionBudget::units_for_wall_ms(50);
let deadline = deterministic_deadline(units, epoch).expect("a 50 ms budget is representable");
let _armed = meter::arm(epoch);
assert!(!expired(Some(deadline)), "nothing charged, nothing spent");
assert_eq!(remaining(deadline), Duration::from_millis(50));
meter::charge(units / 2);
assert!(!expired(Some(deadline)));
assert_eq!(remaining(deadline), Duration::from_millis(25));
meter::charge(units);
assert!(expired(Some(deadline)), "the budget was spent twice over");
assert_eq!(remaining(deadline), Duration::ZERO);
}
#[test]
fn an_absent_deadline_never_expires_under_the_meter() {
let _armed = meter::arm(Instant::now());
meter::charge(u64::MAX / 2);
assert!(!expired(None));
}