use super::super::*;
#[tokio::test]
async fn bind_does_not_load_artifact_index_from_disk() {
let tmp = tempfile::tempdir().unwrap();
let cache_dir = crate::core::NormalizedPath::new(tmp.path());
let index_path = crate::core::config::index_path_from_cache_dir(&cache_dir);
let pre = crate::artifact::ArtifactStore::open(index_path.as_path()).unwrap();
pre.insert("key-a", &synthetic_index_entry(7));
pre.insert("key-b", &synthetic_index_entry(11));
pre.flush().unwrap();
assert!(index_path.as_path().exists());
let endpoint = crate::ipc::unique_test_endpoint();
let server = DaemonServer::bind_with_cache_dir(&endpoint, &cache_dir).unwrap();
let state = server.test_state();
assert!(
state.artifact_store.get("key-a").is_none(),
"bind must start with an empty artifact store (no key-a)",
);
assert!(
state.artifact_store.get("key-b").is_none(),
"bind must start with an empty artifact store (no key-b)",
);
assert!(
!state.artifact_store_loaded.load(Ordering::Acquire),
"the loaded flag must start false until the background loader runs",
);
}
#[tokio::test]
async fn artifact_store_loader_merges_index_into_live_store() {
let tmp = tempfile::tempdir().unwrap();
let cache_dir = crate::core::NormalizedPath::new(tmp.path());
let index_path = crate::core::config::index_path_from_cache_dir(&cache_dir);
let pre = crate::artifact::ArtifactStore::open(index_path.as_path()).unwrap();
pre.insert("hot-key", &synthetic_index_entry(0x42));
pre.flush().unwrap();
let endpoint = crate::ipc::unique_test_endpoint();
let server = DaemonServer::bind_with_cache_dir(&endpoint, &cache_dir).unwrap();
server.artifact_store_loader().load_and_install();
let state = server.test_state();
let entry = state
.artifact_store
.get("hot-key")
.expect("loader must merge the persisted entry into the live store");
assert_eq!(entry.total_size, 0x42);
assert!(
state.artifact_store_loaded.load(Ordering::Acquire),
"loader must set artifact_store_loaded=true",
);
}
#[tokio::test]
async fn artifact_store_loader_tolerates_missing_index_file() {
let tmp = tempfile::tempdir().unwrap();
let cache_dir = crate::core::NormalizedPath::new(tmp.path());
let endpoint = crate::ipc::unique_test_endpoint();
let server = DaemonServer::bind_with_cache_dir(&endpoint, &cache_dir).unwrap();
server.artifact_store_loader().load_and_install();
let state = server.test_state();
assert!(state.artifact_store.get("any").is_none());
assert!(
state.artifact_store_loaded.load(Ordering::Acquire),
"loaded flag flips even when the blob was absent",
);
}
#[test]
fn artifact_store_open_empty_does_not_touch_disk() {
let tmp = tempfile::tempdir().unwrap();
let missing_path = tmp.path().join("does-not-exist").join("index.bin");
let store = crate::artifact::ArtifactStore::open_empty(&missing_path);
assert!(store.get("anything").is_none());
assert!(
!missing_path.exists(),
"open_empty must not create the index file",
);
}
#[tokio::test]
async fn lookup_triggers_synchronous_load_when_background_load_pending() {
let tmp = tempfile::tempdir().unwrap();
let cache_dir = crate::core::NormalizedPath::new(tmp.path());
let index_path = crate::core::config::index_path_from_cache_dir(&cache_dir);
let artifact_dir = crate::core::config::artifacts_dir_from_cache_dir(&cache_dir);
std::fs::create_dir_all(artifact_dir.as_path()).unwrap();
let key_hex = "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff";
let payload: &[u8] = b"abcd";
let payload_path = artifact_dir.join(format!("{key_hex}_0"));
std::fs::write(payload_path.as_path(), payload).unwrap();
let pre = crate::artifact::ArtifactStore::open(index_path.as_path()).unwrap();
pre.insert(
key_hex,
&crate::artifact::ArtifactIndex::new(
vec!["foo.o".to_string()],
vec![payload.len() as u64],
b"".to_vec(),
b"".to_vec(),
0,
),
);
pre.flush().unwrap();
drop(pre);
let endpoint = crate::ipc::unique_test_endpoint();
let server = DaemonServer::bind_with_cache_dir(&endpoint, &cache_dir).unwrap();
let state = server.test_state();
assert!(state.artifact_store.get(key_hex).is_none());
assert!(!state.artifact_store_loaded.load(Ordering::Acquire));
let found = server.test_lookup_artifact(key_hex);
assert!(
found,
"lookup must hit even when background loader hasn't run yet \
— the helper itself triggers load_from_disk on the spot",
);
assert!(
state.artifact_store_loaded.load(Ordering::Acquire),
"synchronous fallback load must flip the loaded flag",
);
}
fn synthetic_index_entry(total_size: u64) -> crate::artifact::ArtifactIndex {
use std::sync::Arc;
crate::artifact::ArtifactIndex {
output_names: Arc::from(vec!["foo.o".to_string()]),
output_sizes: vec![total_size],
stdout: Arc::new(Vec::new()),
stderr: Arc::new(Vec::new()),
exit_code: 0,
total_size,
stored_at_secs: 0,
}
}