use std::error::Error;
use std::path::{Path, PathBuf};
use super::services::open_persistent_store;
fn config_files(root: &Path) -> Result<Vec<PathBuf>, Box<dyn Error>> {
let mut found = Vec::new();
for entry in std::fs::read_dir(root)? {
let path = entry?.path();
if path.is_dir() {
found.extend(config_files(&path)?);
} else if path.file_name().is_some_and(|name| name == "config.json") {
found.push(path);
}
}
Ok(found)
}
fn stored(config: &Path) -> Result<serde_json::Map<String, serde_json::Value>, Box<dyn Error>> {
let value: serde_json::Value = serde_json::from_slice(&std::fs::read(config)?)?;
Ok(value
.as_object()
.ok_or("config.json is not a JSON object")?
.clone())
}
#[test]
fn a_store_created_without_retention_opens_with_reclaim_written_in() -> Result<(), Box<dyn Error>> {
let dir = tempfile::tempdir()?;
drop(open_persistent_store(dir.path())?);
let configs = config_files(dir.path())?;
let [config] = configs.as_slice() else {
return Err(format!("expected one config.json, found {configs:?}").into());
};
let mut older = stored(config)?;
older.remove("retention");
std::fs::write(config, serde_json::to_vec_pretty(&older)?)?;
assert!(!stored(config)?.contains_key("retention"));
drop(open_persistent_store(dir.path())?);
let adopted = stored(config)?;
assert_eq!(
adopted.get("retention"),
Some(&serde_json::to_value(haematite::Retention::reclaim(0))?)
);
assert_eq!(
adopted.get("node_cache_budget"),
older.get("node_cache_budget")
);
Ok(())
}
#[test]
fn a_store_created_without_either_key_opens_with_both_written_in() -> Result<(), Box<dyn Error>> {
let dir = tempfile::tempdir()?;
drop(open_persistent_store(dir.path())?);
let configs = config_files(dir.path())?;
let [config] = configs.as_slice() else {
return Err(format!("expected one config.json, found {configs:?}").into());
};
let mut older = stored(config)?;
older.remove("retention");
older.remove("node_cache_budget");
std::fs::write(config, serde_json::to_vec_pretty(&older)?)?;
drop(open_persistent_store(dir.path())?);
let adopted = stored(config)?;
assert_eq!(
adopted.get("retention"),
Some(&serde_json::to_value(haematite::Retention::reclaim(0))?)
);
assert_eq!(
adopted.get("node_cache_budget"),
Some(&serde_json::Value::String("unlimited".to_owned()))
);
Ok(())
}