use crate::common::{is_redis_available, wait_for_sentinel};
use oxcache::backend::memory::RedisBackend;
use oxcache::backend::CacheBackend;
use std::time::Duration;
#[path = "../common/mod.rs"]
mod common;
fn get_sentinel_urls() -> Vec<String> {
vec![
"redis://127.0.0.1:26379".to_string(),
"redis://127.0.0.1:26380".to_string(),
"redis://127.0.0.1:26381".to_string(),
]
}
fn get_master_url() -> String {
std::env::var("REDIS_SENTINEL_MASTER_URL").unwrap_or_else(|_| "redis://127.0.0.1:16379".to_string())
}
fn is_sentinel_available() -> bool {
std::env::var("REDIS_SENTINEL_AVAILABLE").is_ok()
}
#[tokio::test]
async fn test_sentinel_connection() {
println!("测试 Redis Sentinel 连接...");
if !is_sentinel_available() {
println!("跳过测试: Redis Sentinel 不可用 (设置 REDIS_SENTINEL_AVAILABLE=1 启用)");
return;
}
if !wait_for_sentinel().await {
println!("跳过测试: Redis Sentinel 未就绪");
return;
}
let urls = get_sentinel_urls();
for url in &urls {
let backend = RedisBackend::new(url).await;
if backend.is_ok() {
println!("✓ 成功连接到 Sentinel 节点: {}", url);
return;
}
}
panic!("无法连接到任何 Sentinel 节点");
}
#[tokio::test]
async fn test_sentinel_master_operations() {
println!("测试 Redis Sentinel 主节点操作...");
if !is_sentinel_available() {
println!("跳过测试: Redis Sentinel 不可用");
return;
}
if !wait_for_sentinel().await {
println!("跳过测试: Redis Sentinel 未就绪");
return;
}
let master_url = get_master_url();
let backend = match RedisBackend::new(&master_url).await {
Ok(b) => b,
Err(e) => {
println!("跳过测试: 无法连接到主节点 - {}", e);
return;
}
};
backend
.set(
"sentinel_key_1",
b"sentinel_value_1".to_vec(),
Some(Duration::from_secs(60)),
)
.await
.unwrap();
let value = backend.get("sentinel_key_1").await.unwrap();
assert_eq!(value, Some(b"sentinel_value_1".to_vec()));
backend.delete("sentinel_key_1").await.unwrap();
println!("✓ Redis Sentinel 主节点操作测试成功");
}
#[tokio::test]
async fn test_sentinel_ttl() {
println!("测试 Redis Sentinel TTL...");
if !is_sentinel_available() {
println!("跳过测试: Redis Sentinel 不可用");
return;
}
if !wait_for_sentinel().await {
println!("跳过测试: Redis Sentinel 未就绪");
return;
}
let master_url = get_master_url();
let backend = match RedisBackend::new(&master_url).await {
Ok(b) => b,
Err(e) => {
println!("跳过测试: 无法连接到主节点 - {}", e);
return;
}
};
backend
.set("sentinel_ttl_key", b"ttl_value".to_vec(), Some(Duration::from_secs(2)))
.await
.unwrap();
assert!(backend.exists("sentinel_ttl_key").await.unwrap());
let ttl = backend.ttl("sentinel_ttl_key").await.unwrap();
assert!(ttl.is_some());
tokio::time::sleep(Duration::from_secs(3)).await;
assert!(!backend.exists("sentinel_ttl_key").await.unwrap());
println!("✓ Redis Sentinel TTL 测试成功");
}
#[tokio::test]
async fn test_sentinel_expire() {
println!("测试 Redis Sentinel EXPIRE...");
if !is_sentinel_available() {
println!("跳过测试: Redis Sentinel 不可用");
return;
}
if !wait_for_sentinel().await {
println!("跳过测试: Redis Sentinel 未就绪");
return;
}
let master_url = get_master_url();
let backend = match RedisBackend::new(&master_url).await {
Ok(b) => b,
Err(e) => {
println!("跳过测试: 无法连接到主节点 - {}", e);
return;
}
};
backend
.set("sentinel_expire_key", b"expire_value".to_vec(), None)
.await
.unwrap();
let result = backend
.expire("sentinel_expire_key", Duration::from_secs(60))
.await
.unwrap();
assert!(result);
let ttl = backend.ttl("sentinel_expire_key").await.unwrap();
assert!(ttl.is_some());
backend.delete("sentinel_expire_key").await.unwrap();
println!("✓ Redis Sentinel EXPIRE 测试成功");
}
#[tokio::test]
async fn test_sentinel_health_check() {
println!("测试 Redis Sentinel 健康检查...");
if !is_sentinel_available() {
println!("跳过测试: Redis Sentinel 不可用");
return;
}
if !wait_for_sentinel().await {
println!("跳过测试: Redis Sentinel 未就绪");
return;
}
let master_url = get_master_url();
let backend = match RedisBackend::new(&master_url).await {
Ok(b) => b,
Err(e) => {
println!("跳过测试: 无法连接到主节点 - {}", e);
return;
}
};
backend.health_check().await.unwrap();
println!("✓ Redis Sentinel 健康检查测试成功");
}
#[tokio::test]
async fn test_sentinel_stats() {
println!("测试 Redis Sentinel 统计信息...");
if !is_sentinel_available() {
println!("跳过测试: Redis Sentinel 不可用");
return;
}
if !wait_for_sentinel().await {
println!("跳过测试: Redis Sentinel 未就绪");
return;
}
let master_url = get_master_url();
let backend = match RedisBackend::new(&master_url).await {
Ok(b) => b,
Err(e) => {
println!("跳过测试: 无法连接到主节点 - {}", e);
return;
}
};
backend
.set("sentinel_stats_key", b"stats_value".to_vec(), None)
.await
.unwrap();
let stats = backend.stats().await.unwrap();
assert_eq!(stats.get("type"), Some(&"redis".to_string()));
backend.delete("sentinel_stats_key").await.unwrap();
println!("✓ Redis Sentinel 统计信息测试成功");
}
#[tokio::test]
async fn test_sentinel_many_keys() {
println!("测试 Redis Sentinel 多键操作...");
if !is_sentinel_available() {
println!("跳过测试: Redis Sentinel 不可用");
return;
}
if !wait_for_sentinel().await {
println!("跳过测试: Redis Sentinel 未就绪");
return;
}
let master_url = get_master_url();
let backend = match RedisBackend::new(&master_url).await {
Ok(b) => b,
Err(e) => {
println!("跳过测试: 无法连接到主节点 - {}", e);
return;
}
};
for i in 0..50 {
let key = format!("sentinel_many_{}", i);
let value = format!("value_{}", i);
backend.set(&key, value.as_bytes().to_vec(), None).await.unwrap();
}
for i in 0..50 {
let key = format!("sentinel_many_{}", i);
let expected = format!("value_{}", i);
let value = backend.get(&key).await.unwrap();
assert_eq!(value, Some(expected.as_bytes().to_vec()));
}
for i in 0..50 {
let key = format!("sentinel_many_{}", i);
backend.delete(&key).await.unwrap();
}
println!("✓ Redis Sentinel 多键操作测试成功");
}
#[tokio::test]
async fn test_sentinel_large_value() {
println!("测试 Redis Sentinel 大值...");
if !is_sentinel_available() {
println!("跳过测试: Redis Sentinel 不可用");
return;
}
if !wait_for_sentinel().await {
println!("跳过测试: Redis Sentinel 未就绪");
return;
}
let master_url = get_master_url();
let backend = match RedisBackend::new(&master_url).await {
Ok(b) => b,
Err(e) => {
println!("跳过测试: 无法连接到主节点 - {}", e);
return;
}
};
let large_value = vec![0u8; 1024 * 1024];
backend
.set("sentinel_large_key", large_value.clone(), None)
.await
.unwrap();
let retrieved = backend.get("sentinel_large_key").await.unwrap();
assert_eq!(retrieved, Some(large_value));
backend.delete("sentinel_large_key").await.unwrap();
println!("✓ Redis Sentinel 大值测试成功");
}