use super::*;
#[test]
#[serial_test::serial]
fn warmboot_index_timeout_parses_env_var() {
unsafe { std::env::set_var("TRUSTY_WARMBOOT_INDEX_TIMEOUT_SECS", "42") };
assert_eq!(
warmboot_index_timeout(),
Duration::from_secs(42),
"must parse 42 from env var"
);
unsafe { std::env::remove_var("TRUSTY_WARMBOOT_INDEX_TIMEOUT_SECS") };
assert_eq!(
warmboot_index_timeout(),
ROOT_SCAN_TIMEOUT,
"must fall back to ROOT_SCAN_TIMEOUT when env var is absent"
);
}
#[tokio::test]
#[serial_test::serial]
async fn colocated_scan_partial_failure_still_returns_accessible() {
let data_tmp = tempfile::tempdir().unwrap();
let real_root = tempfile::tempdir().unwrap();
let ts_dir = real_root.path().join(".trusty-search");
std::fs::create_dir_all(&ts_dir).unwrap();
unsafe {
std::env::set_var("TRUSTY_DATA_DIR", data_tmp.path());
}
let nonexistent = std::path::PathBuf::from("/tmp/trusty-718-no-root-xyz9999");
crate::service::roots_registry::upsert_root(real_root.path().to_path_buf()).unwrap();
crate::service::roots_registry::upsert_root(nonexistent).unwrap();
let known_ids: HashSet<String> = HashSet::new();
let known_root_paths: HashSet<PathBuf> = HashSet::new();
let inaccessible: HashSet<PathBuf> = HashSet::new();
let results = collect_colocated_entries(&known_ids, &known_root_paths, &inaccessible).await;
unsafe {
std::env::remove_var("TRUSTY_DATA_DIR");
}
assert_eq!(
results.len(),
1,
"accessible root must be discovered even when another root is inaccessible; \
got: {results:?}"
);
let canonical_root = real_root.path().canonicalize().unwrap();
assert_eq!(
results[0].root_path, canonical_root,
"discovered root_path must match the real tempdir"
);
}
#[tokio::test]
#[serial_test::serial]
async fn colocated_scan_deduplicates_against_known_ids() {
use crate::service::fs_discovery::id_from_path;
let data_tmp = tempfile::tempdir().unwrap();
let real_root = tempfile::tempdir().unwrap();
let ts_dir = real_root.path().join(".trusty-search");
std::fs::create_dir_all(&ts_dir).unwrap();
let canonical_root = real_root.path().canonicalize().unwrap();
let expected_id = id_from_path(&canonical_root);
unsafe {
std::env::set_var("TRUSTY_DATA_DIR", data_tmp.path());
}
crate::service::roots_registry::upsert_root(real_root.path().to_path_buf()).unwrap();
let mut known_ids: HashSet<String> = HashSet::new();
known_ids.insert(expected_id.clone());
let known_root_paths: HashSet<PathBuf> = HashSet::new();
let inaccessible: HashSet<PathBuf> = HashSet::new();
let results = collect_colocated_entries(&known_ids, &known_root_paths, &inaccessible).await;
unsafe {
std::env::remove_var("TRUSTY_DATA_DIR");
}
assert!(
results.is_empty(),
"index already in known_ids must not be returned again; got: {results:?}"
);
}
#[tokio::test]
#[serial_test::serial]
async fn colocated_scan_skips_inaccessible_volume_roots() {
use crate::service::fs_discovery::id_from_path;
let data_tmp = tempfile::tempdir().unwrap();
let real_root = tempfile::tempdir().unwrap();
let ts_dir = real_root.path().join(".trusty-search");
std::fs::create_dir_all(&ts_dir).unwrap();
let canonical_root = real_root.path().canonicalize().unwrap();
let real_id = id_from_path(&canonical_root);
let fake_blocked = PathBuf::from("/Volumes/BLOCKED/some-project");
unsafe {
std::env::set_var("TRUSTY_DATA_DIR", data_tmp.path());
}
crate::service::roots_registry::upsert_root(real_root.path().to_path_buf()).unwrap();
crate::service::roots_registry::upsert_root(fake_blocked.clone()).unwrap();
let known_ids: HashSet<String> = HashSet::new();
let known_root_paths: HashSet<PathBuf> = HashSet::new();
let mut inaccessible: HashSet<PathBuf> = HashSet::new();
inaccessible.insert(PathBuf::from("/Volumes/BLOCKED"));
let results = collect_colocated_entries(&known_ids, &known_root_paths, &inaccessible).await;
unsafe {
std::env::remove_var("TRUSTY_DATA_DIR");
}
assert_eq!(
results.len(),
1,
"only the accessible root must be returned; got: {results:?}"
);
assert_eq!(
results[0].id, real_id,
"the returned entry must be the real root, not the blocked one"
);
}
#[tokio::test]
#[serial_test::serial]
async fn colocated_scan_deduplicates_by_root_path_against_basename_legacy_id() {
let data_tmp = tempfile::tempdir().unwrap();
let real_root = tempfile::tempdir().unwrap();
let ts_dir = real_root.path().join(".trusty-search");
std::fs::create_dir_all(&ts_dir).unwrap();
let canonical_root = real_root.path().canonicalize().unwrap();
unsafe {
std::env::set_var("TRUSTY_DATA_DIR", data_tmp.path());
}
crate::service::roots_registry::upsert_root(real_root.path().to_path_buf()).unwrap();
let basename_id = canonical_root
.file_name()
.and_then(|n| n.to_str())
.unwrap_or("legacy-project")
.to_string();
let mut known_ids: HashSet<String> = HashSet::new();
known_ids.insert(basename_id.clone());
let mut known_root_paths: HashSet<PathBuf> = HashSet::new();
known_root_paths.insert(canonical_root.clone());
let inaccessible: HashSet<PathBuf> = HashSet::new();
let results = collect_colocated_entries(&known_ids, &known_root_paths, &inaccessible).await;
unsafe {
std::env::remove_var("TRUSTY_DATA_DIR");
}
assert!(
results.is_empty(),
"ghost entry must be suppressed when root_path is already owned by a \
legacy entry with a different id scheme (issue #860); got: {results:?}"
);
}
#[tokio::test]
#[serial_test::serial]
async fn colocated_scan_dedup_uses_consistent_canonicalization() {
let data_tmp = tempfile::tempdir().unwrap();
let real_root = tempfile::tempdir().unwrap();
let ts_dir = real_root.path().join(".trusty-search");
std::fs::create_dir_all(&ts_dir).unwrap();
let canonical_root = real_root.path().canonicalize().unwrap();
unsafe {
std::env::set_var("TRUSTY_DATA_DIR", data_tmp.path());
}
crate::service::roots_registry::upsert_root(real_root.path().to_path_buf()).unwrap();
let mut known_root_paths: HashSet<PathBuf> = HashSet::new();
known_root_paths.insert(canonical_root.clone());
let mut known_ids: HashSet<String> = HashSet::new();
known_ids.insert("__legacy-id-that-will-not-match-anything__".to_string());
let inaccessible: HashSet<PathBuf> = HashSet::new();
let results = collect_colocated_entries(&known_ids, &known_root_paths, &inaccessible).await;
unsafe {
std::env::remove_var("TRUSTY_DATA_DIR");
}
assert!(
results.is_empty(),
"canonicalization in Phase 2 must agree with Phase 1 so the root_path \
dedup fires consistently (canonicalization-symmetry fix, #864); got: {results:?}"
);
}