use std::path::{Path, PathBuf};
use crate::BenchError;
pub struct BenchIsolation {
pub qdrant_collection: String,
pub sqlite_db_path: PathBuf,
}
impl BenchIsolation {
#[must_use]
pub fn new(dataset: &str, run_id: &str, data_dir: &Path) -> Self {
Self {
qdrant_collection: format!("bench_{dataset}_{run_id}"),
sqlite_db_path: data_dir.join(format!("bench-{run_id}.db")),
}
}
#[allow(clippy::unused_async)]
pub async fn reset(&self) -> Result<(), BenchError> {
if self.sqlite_db_path.exists() {
std::fs::remove_file(&self.sqlite_db_path)?;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use std::path::Path;
use super::*;
#[test]
fn collection_name_follows_bench_prefix() {
let iso = BenchIsolation::new("locomo", "run42", Path::new("/tmp"));
assert!(iso.qdrant_collection.starts_with("bench_"));
assert!(!iso.qdrant_collection.contains("zeph_memory"));
assert!(!iso.qdrant_collection.contains("zeph_skills"));
assert_eq!(iso.qdrant_collection, "bench_locomo_run42");
}
#[test]
fn sqlite_path_inside_data_dir() {
let iso = BenchIsolation::new("locomo", "run42", Path::new("/data"));
assert_eq!(iso.sqlite_db_path, Path::new("/data/bench-run42.db"));
}
#[tokio::test]
async fn reset_deletes_sqlite_file() {
let dir = tempfile::tempdir().unwrap();
let iso = BenchIsolation::new("test", "r1", dir.path());
std::fs::write(&iso.sqlite_db_path, b"data").unwrap();
iso.reset().await.unwrap();
assert!(!iso.sqlite_db_path.exists());
}
#[tokio::test]
async fn reset_succeeds_when_db_absent() {
let dir = tempfile::tempdir().unwrap();
let iso = BenchIsolation::new("test", "r1", dir.path());
iso.reset().await.unwrap();
}
#[tokio::test]
#[ignore]
async fn reset_completes_under_2_seconds() {
let dir = tempfile::tempdir().unwrap();
let iso = BenchIsolation::new("test", "timing", dir.path());
std::fs::write(&iso.sqlite_db_path, b"data").unwrap();
let start = std::time::Instant::now();
iso.reset().await.unwrap();
assert!(start.elapsed().as_secs() < 2, "reset exceeded 2s NFR-007");
}
}