use fibre_cache::{builder::CacheBuilder, policy::lru::LruPolicy, Cache};
use std::{sync::Arc, thread, time::Duration};
fn new_test_cache(capacity: u64) -> Cache<i32, String> {
CacheBuilder::new()
.capacity(capacity)
.shards(4) .cache_policy_factory(|| Box::new(LruPolicy::new()))
.janitor_tick_interval(Duration::from_millis(50))
.maintenance_chance(1)
.build()
.unwrap()
}
#[test]
#[cfg(feature = "bulk")]
fn test_sync_multi_insert_and_multiget() {
let cache = new_test_cache(100);
let items: Vec<_> = (0..20).map(|i| (i, i.to_string(), 1)).collect();
cache.multi_insert(items);
let metrics = cache.metrics();
assert_eq!(metrics.current_cost, 20);
let keys_to_get: Vec<_> = (0..20).collect();
let found = cache.multiget(keys_to_get.clone());
assert_eq!(found.len(), 20, "Should find all inserted items");
for i in 0..20 {
assert_eq!(*found.get(&i).unwrap(), Arc::new(i.to_string()));
}
assert_eq!(cache.metrics().hits, 20);
assert_eq!(cache.metrics().misses, 0);
let mixed_keys: Vec<_> = (10..30).collect();
let found_mixed = cache.multiget(mixed_keys);
assert_eq!(
found_mixed.len(),
10,
"Should only find the 10 existing keys"
);
assert_eq!(cache.metrics().hits, 30); assert_eq!(cache.metrics().misses, 10); }
#[test]
#[cfg(feature = "bulk")]
fn test_sync_multi_invalidate() {
let cache = new_test_cache(100);
let items: Vec<_> = (0..20).map(|i| (i, i.to_string(), 1)).collect();
cache.multi_insert(items);
assert_eq!(cache.metrics().current_cost, 20);
let keys_to_invalidate: Vec<_> = (5..15).collect();
cache.multi_invalidate(keys_to_invalidate);
let metrics = cache.metrics();
assert_eq!(metrics.current_cost, 10, "Cost should be reduced by 10");
assert_eq!(metrics.invalidations, 10);
for i in 5..15 {
assert!(cache.fetch(&i).is_none());
}
for i in (0..5).chain(15..20) {
assert!(cache.fetch(&i).is_some());
}
}
#[test]
#[cfg(feature = "bulk")]
fn test_sync_multi_insert_triggers_eviction() {
let cache = new_test_cache(10);
let items: Vec<_> = (0..15).map(|i| (i, i.to_string(), 1)).collect();
cache.multi_insert(items);
assert_eq!(cache.metrics().current_cost, 15);
thread::sleep(Duration::from_millis(150));
assert_eq!(
cache.metrics().current_cost,
10,
"Janitor should bring cost back to capacity"
);
assert_eq!(
cache.metrics().evicted_by_capacity,
5,
"Janitor should evict 5 items"
);
let mut total_keys = 0;
for i in 0..15 {
if cache.fetch(&i).is_some() {
total_keys += 1;
}
}
assert_eq!(
total_keys, 10,
"Cache should contain exactly 10 items after eviction"
);
}