use super::*;
use serial_test::serial;
use std::collections::HashSet;
use std::thread;
fn reset_for_tests() {
GLOBAL_SEQNO.store(0, Ordering::SeqCst);
}
#[test]
#[serial]
fn allocate_increments() {
reset_for_tests();
let a = allocate();
let b = allocate();
let c = allocate();
assert_eq!(a + 1, b);
assert_eq!(b + 1, c);
assert_eq!(current(), c);
assert!(a >= 1);
}
#[test]
#[serial]
fn advance_to_sets_value_when_lower() {
reset_for_tests();
assert_eq!(current(), 0);
let after = advance_to(100);
assert_eq!(after, 100);
assert_eq!(current(), 100);
let next = allocate();
assert_eq!(next, 101);
}
#[test]
#[serial]
fn advance_to_noop_when_higher() {
reset_for_tests();
let _ = allocate(); let _ = allocate(); let cur = current();
let after = advance_to(cur - 1); assert_eq!(after, cur);
}
#[test]
#[serial]
fn concurrent_allocations_are_unique_and_monotonic() {
reset_for_tests();
let threads = 16;
let per_thread = 5_000; let mut handles = Vec::with_capacity(threads);
for _ in 0..threads {
handles.push(thread::spawn(move || {
let mut local = Vec::with_capacity(per_thread);
for _ in 0..per_thread {
local.push(crate::engine::seqno::allocate());
}
local
}));
}
let mut all = Vec::with_capacity(threads * per_thread);
for h in handles {
let v = h.join().expect("thread join");
all.extend(v);
}
assert_eq!(all.len(), threads * per_thread);
let set: HashSet<u64> = all.iter().copied().collect();
assert_eq!(set.len(), all.len(), "seqnos must be unique");
let mut all_sorted = all;
all_sorted.sort_unstable();
let n = threads * per_thread;
for (i, val) in all_sorted.iter().enumerate() {
let expected = (i as u64) + 1;
assert_eq!(*val, expected, "expected {}, got {}", expected, val);
}
assert_eq!(current(), n as u64);
}