use common::{cleanup_service, generate_unique_service_name, is_redis_available, setup_logging};
use oxcache::Cache;
use std::time::Duration;
use tokio::time::sleep;
use crate::common;
#[tokio::test]
async fn test_distributed_lock() {
if !is_redis_available().await {
println!("Skipping test_distributed_lock: Redis not available");
return;
}
setup_logging();
let service_name = generate_unique_service_name("lock_test");
let redis_url = "redis://127.0.0.1:6379";
let cache: Cache<String, String> = Cache::tiered(100, redis_url)
.await
.expect("Failed to create tiered cache");
let lock_key = "test_lock";
let _ttl = Duration::from_secs(5);
cache
.set(&"key1".to_string(), &"value1".to_string())
.await
.unwrap();
let val: Option<String> = cache.get(&"key1".to_string()).await.unwrap();
assert_eq!(val, Some("value1".to_string()));
let mut conn = redis::Client::open(redis_url)
.expect("Failed to create redis client")
.get_multiplexed_async_connection()
.await
.expect("Failed to get connection");
let lock_value: Option<String> = redis::cmd("SET")
.arg(&[lock_key, "lock_holder", "NX", "EX", "5"])
.query_async(&mut conn)
.await
.expect("Failed to acquire lock");
assert!(lock_value.is_some(), "Should acquire lock successfully");
let lock_again: Option<String> = redis::cmd("SET")
.arg(&[lock_key, "lock_holder", "NX", "EX", "5"])
.query_async(&mut conn)
.await
.expect("Failed to check lock");
assert!(lock_again.is_none(), "Should fail to acquire lock again");
let unlocked: i32 = redis::cmd("DEL")
.arg(lock_key)
.query_async(&mut conn)
.await
.expect("Failed to unlock");
assert_eq!(unlocked, 1, "Should unlock successfully");
sleep(Duration::from_secs(6)).await;
let lock_after_expire: Option<String> = redis::cmd("SET")
.arg(&[lock_key, "lock_holder", "NX", "EX", "5"])
.query_async(&mut conn)
.await
.expect("Failed to acquire lock after expiration");
assert!(
lock_after_expire.is_some(),
"Should acquire lock after expiration"
);
cache.shutdown().await.expect("Shutdown failed");
cleanup_service(&service_name).await;
}
#[tokio::test]
async fn test_cache_preheating() {
if !is_redis_available().await {
println!("Skipping test_cache_preheating: Redis not available");
return;
}
setup_logging();
let service_name = generate_unique_service_name("warmup_test");
let redis_url = "redis://127.0.0.1:6379";
let cache: Cache<String, String> = Cache::tiered(100, redis_url)
.await
.expect("Failed to create tiered cache");
let load_data = |keys: Vec<String>| async move {
let mut res = Vec::new();
for k in keys {
res.push((k.clone(), format!("value_of_{}", k)));
}
Ok::<Vec<(String, String)>, String>(res)
};
let keys = vec!["warm_1".to_string(), "warm_2".to_string()];
let data = load_data(keys.clone()).await.expect("Loader failed");
for (key, value) in &data {
cache.set(key, value).await.unwrap();
}
for key in keys {
let val: Option<String> = cache.get(&key).await.unwrap();
assert!(val.is_some(), "Key {} should be preheated", key);
}
cache.shutdown().await.expect("Shutdown failed");
cleanup_service(&service_name).await;
}