//! Tests for DiskCache and PackCache. use std::path::PathBuf; use std::time::Duration; use gitks::disk_cache::DiskCache; fn temp_dir() -> PathBuf { tempfile::tempdir().unwrap().path().to_path_buf() } #[test] fn test_disk_cache_basic_operations() { let dir = temp_dir(); let cache = DiskCache::new(dir.clone(), "test-version".to_string(), 300, true); // Ensure state creates latest file let state = cache.ensure_state("test_repo.git").unwrap(); assert!(!state.is_empty()); // Same state on second call let state2 = cache.ensure_state("test_repo.git").unwrap(); assert_eq!(state, state2); } #[test] fn test_disk_cache_insert_and_lookup() { let dir = temp_dir(); let cache = DiskCache::new(dir.clone(), "test-version".to_string(), 300, true); let digest = "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"; let data = b"test cache data"; // Insert cache.insert("+gitks-cache/cache", digest, data).unwrap(); // Lookup let result = cache.lookup("+gitks-cache/cache", digest).unwrap(); assert!(result.is_some()); assert_eq!(result.unwrap(), data.to_vec()); // Non-existent key let result = cache.lookup("+gitks-cache/cache", "nonexistent").unwrap(); assert!(result.is_none()); } #[test] fn test_disk_cache_invalidation() { let dir = temp_dir(); let cache = DiskCache::new(dir.clone(), "test-version".to_string(), 300, true); let state1 = cache.ensure_state("test_repo.git").unwrap(); // Invalidate cache.invalidate_repo("test_repo.git"); // State should change let state2 = cache.ensure_state("test_repo.git").unwrap(); assert_ne!(state1, state2); } #[test] fn test_disk_cache_disabled() { let dir = temp_dir(); let cache = DiskCache::new(dir.clone(), "test-version".to_string(), 300, false); // All operations should succeed but do nothing let state = cache.ensure_state("test_repo.git").unwrap(); assert!(!state.is_empty()); // Returns random value let result = cache.lookup("+gitks-cache/cache", "anykey").unwrap(); assert!(result.is_none()); // Disabled → always None } #[test] fn test_disk_cache_lease_guard() { let dir = temp_dir(); let cache = DiskCache::new(dir.clone(), "test-version".to_string(), 300, true); let state1 = cache.ensure_state("test_repo.git").unwrap(); let mut lease = cache.create_lease("test_repo.git").unwrap(); // Lease exists let pending_dir = dir.join("+gitks-cache/state/test_repo.git/pending"); assert!(pending_dir.exists()); // Commit lease (updates latest) lease.commit(); // Pending should be cleaned up // (may still have dir but no files) let state2 = cache.ensure_state("test_repo.git").unwrap(); assert_ne!(state1, state2); } #[test] fn test_sha256_digest_determinism() { let dir = temp_dir(); let cache = DiskCache::new(dir, "v1".to_string(), 300, true); cache.ensure_state("repo.git").unwrap(); let key1 = cache .compute_info_refs_key("repo.git", "upload-pack") .unwrap(); let key2 = cache .compute_info_refs_key("repo.git", "upload-pack") .unwrap(); assert_eq!(key1, key2); // Different protocol should produce different key let key3 = cache .compute_info_refs_key("repo.git", "receive-pack") .unwrap(); assert_ne!(key1, key3); } #[test] fn test_cleanup_expired() { let dir = temp_dir(); // Very short max age for testing let cache = DiskCache::new(dir.clone(), "test-version".to_string(), 1, true); let digest = "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789"; cache.insert("+gitks-cache/cache", digest, b"data").unwrap(); // Should be available immediately let result = cache.lookup("+gitks-cache/cache", digest).unwrap(); assert!(result.is_some()); // Wait for expiration std::thread::sleep(Duration::from_secs(2)); // Should be expired now let result = cache.lookup("+gitks-cache/cache", digest).unwrap(); assert!(result.is_none()); } #[test] fn test_startup_cleanup() { let dir = temp_dir(); let cache = DiskCache::new(dir.clone(), "test-version".to_string(), 300, true); // Write some cache data cache .insert("+gitks-cache/cache", "abc123", b"test") .unwrap(); assert!( dir.join("+gitks-cache/cache") .join("ab") .join("c123") .exists() ); // Startup cleanup removes all cache dirs cache.cleanup_on_startup().unwrap(); assert!(!dir.join("+gitks-cache/cache").exists()); }