use super::{MonotonicTimeSource, SystemTimeSource};
use crate::kairos::{Clock, TimeSource};
use std::time::{SystemTime, UNIX_EPOCH};
use std::vec::Vec;
#[test]
fn monotonic_source_is_nondecreasing() {
let src = MonotonicTimeSource::new();
let mut prev = src.now();
for _ in 0..1000 {
let next = src.now();
assert!(
next >= prev,
"monotonic source stepped backward: {next} < {prev}"
);
prev = next;
}
}
#[test]
fn system_source_reads_wall_clock() {
let slack = 1_000_000_000u128;
let before = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("system clock is after the Unix epoch")
.as_nanos();
let reading = u128::from(SystemTimeSource::new().now());
let after = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("system clock is after the Unix epoch")
.as_nanos();
assert!(
reading >= before.saturating_sub(slack),
"reading {reading} precedes {before}"
);
assert!(
reading <= after + slack,
"reading {reading} follows {after}"
);
}
#[test]
fn clock_driven_by_system_source_is_strictly_monotonic() {
let clock =
Clock::with_default_config(SystemTimeSource::new(), 1).expect("non-zero station_id");
let mut stamps = Vec::with_capacity(1000);
let mut prev = clock.now(0u16);
stamps.push(prev);
for _ in 1..1000 {
let next = clock.now(0u16);
assert!(
next > prev,
"HLC output must be strictly monotonic: {next:?} !> {prev:?}"
);
prev = next;
stamps.push(next);
}
let len = stamps.len();
stamps.sort_unstable();
stamps.dedup();
assert_eq!(len, stamps.len(), "stamps must be unique");
}
#[test]
fn clock_driven_by_monotonic_source_is_strictly_monotonic() {
let clock =
Clock::with_default_config(MonotonicTimeSource::new(), 9).expect("non-zero station_id");
let mut prev = clock.now(0u16);
for _ in 1..1000 {
let next = clock.now(0u16);
assert!(
next > prev,
"HLC output must be strictly monotonic: {next:?} !> {prev:?}"
);
prev = next;
}
}