use tempfile::TempDir;
use super::*;
#[test]
fn test_get_fk_column_cache_hit() {
let result1 = get_fk_column("nonexistent::path::Schema", "SomeRelation");
let result2 = get_fk_column("nonexistent::path::Schema", "SomeRelation");
assert_eq!(result1, result2);
}
#[serial_test::serial]
#[test]
fn path_lookup_caches_survive_epoch_bumps() {
bump_epoch();
let _ = get_fk_column("ra::stale::Schema", "Rel");
assert!(
fk_lookup_contains("ra::stale::Schema", "Rel"),
"result must be cached within the same epoch"
);
let _ = get_fk_column("ra::stale::Schema", "Rel");
assert!(fk_lookup_contains("ra::stale::Schema", "Rel"));
bump_epoch();
let _ = get_fk_column("ra::trigger::Schema", "Rel");
assert!(
fk_lookup_contains("ra::stale::Schema", "Rel"),
"lookup entry must remain cached when the epoch advances"
);
}
#[serial_test::serial]
#[test]
fn path_lookup_revalidates_when_resolved_file_mtime_changes() {
struct Restore(Option<String>);
impl Drop for Restore {
fn drop(&mut self) {
match self.0.take() {
Some(v) => unsafe { std::env::set_var("CARGO_MANIFEST_DIR", v) },
None => unsafe { std::env::remove_var("CARGO_MANIFEST_DIR") },
}
}
}
let temp_dir = TempDir::new().unwrap();
let models_dir = temp_dir.path().join("src").join("models");
std::fs::create_dir_all(&models_dir).unwrap();
let model_path = models_dir.join("user.rs");
std::fs::write(&model_path, "pub struct Model { pub id: i32 }").unwrap();
let _restore = Restore(std::env::var("CARGO_MANIFEST_DIR").ok());
unsafe { std::env::set_var("CARGO_MANIFEST_DIR", temp_dir.path()) };
bump_epoch();
let first = get_struct_from_schema_path("crate::models::user::Model")
.expect("initial model should resolve");
assert!(first.definition.contains("id : i32"));
std::thread::sleep(std::time::Duration::from_millis(30));
std::fs::write(&model_path, "pub struct Model { pub name: String }").unwrap();
bump_epoch();
let second = get_struct_from_schema_path("crate::models::user::Model")
.expect("edited model should resolve");
assert!(
second.definition.contains("name : String"),
"path lookup must invalidate stale resolved-file entries after mtime changes: {}",
second.definition
);
}
#[serial_test::serial]
#[test]
fn test_print_profile_summary_with_profile_env() {
unsafe { std::env::set_var("VESPERA_PROFILE", "1") };
print_profile_summary();
unsafe { std::env::remove_var("VESPERA_PROFILE") };
}
#[serial_test::serial]
#[test]
fn test_print_profile_summary_without_profile_env() {
unsafe { std::env::remove_var("VESPERA_PROFILE") };
print_profile_summary();
}
#[serial_test::serial]
#[test]
fn test_epoch_skips_metadata_syscall() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("target.rs");
std::fs::write(&file_path, "pub struct Foo { pub x: i32 }").unwrap();
reset_metadata_call_count();
bump_epoch();
let before = metadata_call_count();
let c1 = get_struct_definition(&file_path, "Foo");
assert!(c1.is_some(), "struct should be found");
assert_eq!(
metadata_call_count() - before,
1,
"first read should trigger exactly 1 metadata call"
);
let c2 = get_struct_definition(&file_path, "Foo");
assert_eq!(c1, c2);
assert_eq!(
metadata_call_count() - before,
1,
"second read in same epoch must NOT call metadata again"
);
bump_epoch();
let c3 = get_struct_definition(&file_path, "Foo");
assert_eq!(c1, c3);
assert_eq!(
metadata_call_count() - before,
2,
"read after epoch bump must call metadata exactly once more"
);
}
#[serial_test::serial]
#[test]
fn test_missing_file_content_is_negative_cached_within_epoch() {
let temp_dir = TempDir::new().unwrap();
let missing_path = temp_dir.path().join("missing.rs");
reset_metadata_call_count();
bump_epoch();
let before = metadata_call_count();
assert!(get_struct_definition(&missing_path, "Missing").is_none());
assert!(get_struct_definition(&missing_path, "Missing").is_none());
assert_eq!(
metadata_call_count() - before,
1,
"missing file should be stat'd once in one epoch"
);
}
#[serial_test::serial]
#[test]
fn test_epoch_cross_entry_invalidation() {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("cross.rs");
std::fs::write(&file_path, "pub struct Bar { pub y: u64 }").unwrap();
reset_metadata_call_count();
bump_epoch(); let before_a = metadata_call_count();
let r1 = get_struct_definition(&file_path, "Bar");
assert!(r1.is_some());
assert_eq!(
metadata_call_count() - before_a,
1,
"invocation A: first access must call metadata once"
);
let r2 = get_struct_definition(&file_path, "Bar");
assert_eq!(r1, r2);
assert_eq!(
metadata_call_count() - before_a,
1,
"invocation A: second access must NOT call metadata again"
);
bump_epoch(); let before_b = metadata_call_count();
let r3 = get_struct_definition(&file_path, "Bar");
assert_eq!(r1, r3);
assert_eq!(
metadata_call_count() - before_b,
1,
"invocation B: first access must re-check metadata (cross-entry invalidation)"
);
let r4 = get_struct_definition(&file_path, "Bar");
assert_eq!(r1, r4);
assert_eq!(
metadata_call_count() - before_b,
1,
"invocation B: second access must NOT call metadata again"
);
}
#[serial_test::serial]
#[test]
fn test_file_list_skips_walk_within_same_epoch() {
struct Restore(Option<String>);
impl Drop for Restore {
fn drop(&mut self) {
match self.0.take() {
Some(v) => unsafe { std::env::set_var("CARGO_MANIFEST_DIR", v) },
None => unsafe { std::env::remove_var("CARGO_MANIFEST_DIR") },
}
}
}
let temp_dir = TempDir::new().unwrap();
let src_dir = temp_dir.path().join("src");
std::fs::create_dir_all(&src_dir).unwrap();
std::fs::write(src_dir.join("a.rs"), "pub struct Alpha { pub id: i32 }").unwrap();
std::fs::write(src_dir.join("b.rs"), "pub struct Beta { pub name: String }").unwrap();
let _restore = Restore(std::env::var("CARGO_MANIFEST_DIR").ok());
unsafe { std::env::set_var("CARGO_MANIFEST_DIR", temp_dir.path()) };
reset_metadata_call_count();
bump_epoch();
let before = metadata_call_count();
let _ = get_struct_from_schema_path("Alpha");
let after_first = metadata_call_count();
assert!(
after_first > before,
"first lookup must walk the directory (mtime syscalls expected)",
);
let _ = get_struct_from_schema_path("Beta");
let _ = get_struct_from_schema_path("Alpha");
assert_eq!(
metadata_call_count(),
after_first,
"same-epoch lookups must not rewalk the directory",
);
}
#[serial_test::serial]
#[test]
fn manifest_dir_revalidates_across_epochs() {
struct Restore(Option<String>);
impl Drop for Restore {
fn drop(&mut self) {
match self.0.take() {
Some(v) => unsafe { std::env::set_var("CARGO_MANIFEST_DIR", v) },
None => unsafe { std::env::remove_var("CARGO_MANIFEST_DIR") },
}
}
}
let _restore = Restore(std::env::var("CARGO_MANIFEST_DIR").ok());
unsafe { std::env::set_var("CARGO_MANIFEST_DIR", "/vespera_test/crate_a") };
bump_epoch();
assert_eq!(get_manifest_dir().as_deref(), Some("/vespera_test/crate_a"));
unsafe { std::env::set_var("CARGO_MANIFEST_DIR", "/vespera_test/crate_b") };
assert_eq!(
get_manifest_dir().as_deref(),
Some("/vespera_test/crate_a"),
"manifest dir must be cached within an epoch"
);
bump_epoch();
assert_eq!(
get_manifest_dir().as_deref(),
Some("/vespera_test/crate_b"),
"manifest dir must revalidate when the epoch advances"
);
}
#[test]
fn raw_cache_helpers_reuse_directory_struct_and_content_entries() {
let temp_dir = TempDir::new().unwrap();
let src_dir = temp_dir.path().join("src");
std::fs::create_dir_all(&src_dir).unwrap();
let file = src_dir.join("model.rs");
std::fs::write(&file, "pub struct Model { pub id: i32 }").unwrap();
FILE_CACHE.with(|cell| {
let mut cache = cell.borrow_mut();
cache.epoch = cache.epoch.wrapping_add(1);
let first_files = ensure_file_list(&mut cache, &src_dir);
assert_eq!(first_files.as_ref(), std::slice::from_ref(&file));
cache.epoch = cache.epoch.wrapping_add(1);
let second_files = ensure_file_list(&mut cache, &src_dir);
assert!(Arc::ptr_eq(&first_files, &second_files));
assert!(ensure_struct_definitions(&mut cache, &file));
let first_content = get_file_content_inner(&mut cache, &file).expect("content exists");
let second_content =
get_file_content_inner(&mut cache, &file).expect("cached content exists");
assert!(Arc::ptr_eq(&first_content, &second_content));
assert_eq!(cache.struct_definitions[&file].1.len(), 1);
assert_eq!(
cache.file_contents[&file].1.as_str(),
"pub struct Model { pub id: i32 }"
);
});
}