use std::sync::Arc;
use liminal::durability::bridge::block_on;
use liminal::durability::{CountingStore, DurableStore, open_ephemeral};
use super::super::{IncarnationStartup, IncarnationStream};
use super::EPOCH_ANCHOR_KEY;
type TestResult<T = ()> = Result<T, Box<dyn std::error::Error>>;
fn start(store: &Arc<dyn DurableStore>) -> TestResult<u64> {
let startup = block_on(IncarnationStream::new(Arc::clone(store), 4).startup())??;
let IncarnationStartup::Started(started) = startup else {
return Err("the start did not complete".into());
};
Ok(started.header().server_incarnation)
}
#[test]
fn a_restart_rotation_flushes_once_and_the_anchor_names_its_epoch() -> TestResult {
let counting = Arc::new(CountingStore::new(open_ephemeral(1)?));
let store: Arc<dyn DurableStore> = counting.clone();
assert_eq!(start(&store)?, 1);
for restart in [2_u64, 3] {
let before = counting.snapshot().flushes;
assert_eq!(start(&store)?, restart);
assert_eq!(
counting.snapshot().flushes - before,
1,
"restart {restart}: the epoch's Startup is flushed once and the anchor rides it"
);
assert_eq!(
block_on(store.read_value(EPOCH_ANCHOR_KEY))??,
Some(restart),
"the anchor names the epoch of record"
);
}
Ok(())
}