use std::sync::Arc;
use std::time::Duration;
use oxcache::backend::{BackendKind, CacheConnector, CacheReader, CacheWriter, DragonflyBackend};
#[path = "../common/mod.rs"]
mod common;
use common::test_containers::DragonflyContainer;
fn set_allow_insecure() {
unsafe { std::env::set_var("OXCACHE_ALLOW_INSECURE_REDIS", "I_UNDERSTAND_THE_RISKS") };
}
async fn make_dragonfly_backend(url: &str) -> DragonflyBackend {
set_allow_insecure();
DragonflyBackend::new(url, 4)
.await
.expect("Failed to connect to Dragonfly")
}
#[tokio::test]
async fn test_dragonfly_backend_kind() {
let container = DragonflyContainer::start().await.expect("Failed to start Dragonfly");
container.wait_ready().await.expect("Dragonfly not ready");
let backend = make_dragonfly_backend(&container.url()).await;
assert_eq!(backend.backend_kind(), BackendKind::Dragonfly);
}
#[tokio::test]
async fn test_dragonfly_atomic_writer_is_none() {
let container = DragonflyContainer::start().await.expect("Failed to start Dragonfly");
container.wait_ready().await.expect("Dragonfly not ready");
let backend = make_dragonfly_backend(&container.url()).await;
assert!(backend.as_atomic_writer().is_none());
}
#[tokio::test]
async fn test_dragonfly_cache_writer_operations() {
let container = DragonflyContainer::start().await.expect("Failed to start Dragonfly");
container.wait_ready().await.expect("Dragonfly not ready");
let backend = make_dragonfly_backend(&container.url()).await;
backend
.set(Arc::from("df:key1"), Arc::new(b"value1".to_vec()), None)
.await
.expect("set failed");
backend
.set(
Arc::from("df:key2"),
Arc::new(b"value2".to_vec()),
Some(Duration::from_secs(60)),
)
.await
.expect("set with TTL failed");
let items = vec![
(Arc::from("df:batch1"), Arc::new(b"b1".to_vec()), None),
(Arc::from("df:batch2"), Arc::new(b"b2".to_vec()), None),
];
backend.set_many(&items).await.expect("set_many failed");
backend.delete("df:key1").await.expect("delete failed");
let keys = vec!["df:batch1".to_string(), "df:batch2".to_string()];
backend.delete_many(&keys).await.expect("delete_many failed");
}
#[tokio::test]
async fn test_dragonfly_cache_reader_operations() {
let container = DragonflyContainer::start().await.expect("Failed to start Dragonfly");
container.wait_ready().await.expect("Dragonfly not ready");
let backend = make_dragonfly_backend(&container.url()).await;
backend
.set(Arc::from("df:read1"), Arc::new(b"hello".to_vec()), None)
.await
.unwrap();
backend
.set(
Arc::from("df:read2"),
Arc::new(b"world".to_vec()),
Some(Duration::from_secs(120)),
)
.await
.unwrap();
let val = backend.get("df:read1").await.unwrap();
assert_eq!(val, Some(b"hello".to_vec()));
let val = backend.get("df:nonexistent").await.unwrap();
assert_eq!(val, None);
assert!(backend.exists("df:read1").await.unwrap());
assert!(!backend.exists("df:nonexistent").await.unwrap());
let ttl = backend.ttl("df:read2").await.unwrap();
assert!(ttl.is_some());
let ttl = ttl.unwrap();
assert!(ttl > Duration::from_secs(100));
let result = backend.expire("df:read1", Duration::from_secs(60)).await.unwrap();
assert!(result);
let result = backend.expire("df:nonexistent", Duration::from_secs(60)).await.unwrap();
assert!(!result);
}
#[tokio::test]
async fn test_dragonfly_cache_connector_operations() {
let container = DragonflyContainer::start().await.expect("Failed to start Dragonfly");
container.wait_ready().await.expect("Dragonfly not ready");
let backend = make_dragonfly_backend(&container.url()).await;
backend.health_check().await.expect("health_check failed");
assert_eq!(backend.backend_kind(), BackendKind::Dragonfly);
backend.shutdown().await;
}
#[tokio::test]
async fn test_dragonfly_chain_cache_basic() {
use oxcache::backend::MokaMemoryBackend;
use oxcache::cache::chain::{ChainCacheBuilder, ChainLink};
let container = DragonflyContainer::start().await.expect("Failed to start Dragonfly");
container.wait_ready().await.expect("Dragonfly not ready");
let dragonfly = make_dragonfly_backend(&container.url()).await;
let moka = MokaMemoryBackend::new();
let chain = ChainCacheBuilder::default()
.link(ChainLink::new(moka, 100, false, "moka"))
.link(ChainLink::new(dragonfly, 50, true, "dragonfly"))
.build();
chain
.set("chain:df_key1", b"chain_value".to_vec(), None)
.await
.expect("chain set failed");
let val = chain.get("chain:df_key1").await.unwrap();
assert_eq!(val, Some(b"chain_value".to_vec()));
chain.health_check().await.expect("chain health_check failed");
}