use oxcache::backend::{BackendScore, CacheConnector, CacheReader, CacheWriter, MokaMemoryBackend, Scores};
use oxcache::cache::{ChainCache, ChainLink};
use std::time::Duration;
#[tokio::test]
async fn test_chain_cache_basic_operations() {
let moka1 = MokaMemoryBackend::builder().capacity(100).build();
let moka2 = MokaMemoryBackend::builder().capacity(100).build();
let chain = ChainCache::builder()
.link(ChainLink::from_backend(moka1))
.link(ChainLink::from_backend(moka2))
.build();
chain.set("key1", b"value1".to_vec(), None).await.unwrap();
let value = chain.get("key1").await.unwrap();
assert_eq!(value, Some(b"value1".to_vec()));
let exists = chain.exists("key1").await.unwrap();
assert!(exists);
chain.delete("key1").await.unwrap();
let exists = chain.exists("key1").await.unwrap();
assert!(!exists);
}
#[tokio::test]
async fn test_chain_cache_auto_sort() {
let high = MokaMemoryBackend::builder().capacity(100).build();
let low = MokaMemoryBackend::builder().capacity(100).build();
assert_eq!(high.score(), Scores::MOKA);
let chain = ChainCache::builder()
.link(ChainLink::from_backend(low))
.link(ChainLink::from_backend(high))
.build();
assert_eq!(chain.links().len(), 2);
}
#[tokio::test]
async fn test_chain_cache_backfill() {
let high = MokaMemoryBackend::builder().capacity(100).build();
let low = MokaMemoryBackend::builder().capacity(100).build();
low.set("key1", b"value1".to_vec(), None).await.unwrap();
let chain = ChainCache::builder()
.link(ChainLink::from_backend(high))
.link(ChainLink::from_backend(low))
.enable_backfill()
.build();
let value = chain.get("key1").await.unwrap();
assert_eq!(value, Some(b"value1".to_vec()));
}
#[tokio::test]
async fn test_single_backend_chain() {
let moka = MokaMemoryBackend::new();
let chain = ChainCache::builder().link(ChainLink::from_backend(moka)).build();
assert_eq!(chain.links().len(), 1);
chain.set("key", b"value".to_vec(), None).await.unwrap();
let value = chain.get("key").await.unwrap();
assert_eq!(value, Some(b"value".to_vec()));
}
#[tokio::test]
async fn test_chain_cache_ttl() {
let moka = MokaMemoryBackend::builder()
.capacity(100)
.ttl(Duration::from_secs(3600))
.build();
let chain = ChainCache::builder().link(ChainLink::from_backend(moka)).build();
chain.set("key", b"value".to_vec(), None).await.unwrap();
let value = chain.get("key").await.unwrap();
assert_eq!(value, Some(b"value".to_vec()));
}
#[tokio::test]
async fn test_chain_cache_health_check() {
let moka = MokaMemoryBackend::new();
let chain = ChainCache::builder().link(ChainLink::from_backend(moka)).build();
chain.health_check().await.unwrap();
}
#[tokio::test]
async fn test_chain_cache_stats() {
let moka = MokaMemoryBackend::new();
let chain = ChainCache::builder().link(ChainLink::from_backend(moka)).build();
let stats = chain.stats().await.unwrap();
assert_eq!(stats.get("type"), Some(&"chain".to_string()));
assert_eq!(stats.get("backend_count"), Some(&"1".to_string()));
}
#[tokio::test]
async fn test_chain_cache_clear() {
let moka = MokaMemoryBackend::new();
let chain = ChainCache::builder().link(ChainLink::from_backend(moka)).build();
for i in 0..10 {
chain.set(&format!("key{}", i), b"value".to_vec(), None).await.unwrap();
}
chain.clear().await.unwrap();
for i in 0..10 {
let exists = chain.exists(&format!("key{}", i)).await.unwrap();
assert!(!exists, "key{} should not exist after clear", i);
}
}
#[tokio::test]
async fn test_chain_cache_builder_direct() {
let moka = MokaMemoryBackend::new();
let chain = ChainCache::builder()
.link(ChainLink::from_backend(moka))
.enable_backfill()
.build();
assert_eq!(chain.links().len(), 1);
}
#[tokio::test]
async fn test_chain_link_creation() {
let moka = MokaMemoryBackend::new();
let link = ChainLink::from_backend(moka);
assert_eq!(link.score(), Scores::MOKA);
assert!(!link.is_persistent());
assert_eq!(link.name(), "moka");
}