#[cfg(test)]
std::thread_local! {
static CALLS: std::cell::RefCell<Vec<(&'static str, std::path::PathBuf)>> =
const { std::cell::RefCell::new(Vec::new()) };
}
#[cfg(test)]
pub(crate) fn record(gate: &'static str, directory: &std::path::Path) {
CALLS.with(|calls| {
calls.borrow_mut().push((gate, directory.to_path_buf()));
});
}
#[cfg(not(test))]
#[inline]
pub(crate) fn record(gate: &'static str, directory: &std::path::Path) {
let _ = (gate, directory);
}
#[cfg(test)]
pub(crate) fn reset() {
CALLS.with(|calls| calls.borrow_mut().clear());
}
#[cfg(test)]
pub(crate) fn recorded() -> Vec<(&'static str, std::path::PathBuf)> {
CALLS.with(|calls| calls.borrow().clone())
}
#[cfg(test)]
mod tests {
use super::{recorded, reset};
use crate::writer::maintenance::test_support::TestDirectory;
use crate::writer::maintenance::{CompactionOptions, PreparedCompaction};
#[test]
fn a_prepare_calls_every_open_protocol_gate() {
let directory = TestDirectory::repository("gate-observation-prepare");
reset();
let prepared =
PreparedCompaction::prepare(&directory.path, CompactionOptions::new().with_tasks([]))
.expect("prepare a healthy store");
let calls = recorded();
let gates: Vec<&str> = calls.iter().map(|(gate, _)| *gate).collect();
for expected in [
"validate_repository_shape",
"validate_apply_environment",
"validate_apply_identity",
] {
assert!(
gates.contains(&expected),
"{expected} was not called during prepare: {gates:?}"
);
}
for repeated in ["validate_apply_environment", "validate_apply_identity"] {
assert!(
gates.iter().filter(|gate| **gate == repeated).count() >= 2,
"{repeated} must run before and again after the lock: {gates:?}"
);
}
let canonical =
std::fs::canonicalize(&directory.path).expect("canonicalize the repository");
for (gate, seen) in &calls {
assert_eq!(
seen,
&canonical,
"{gate} received {} rather than the canonicalized directory",
seen.display()
);
}
drop(prepared);
}
}