oxcache 0.1.4

A high-performance multi-level cache library for Rust with L1 (memory) and L2 (Redis) caching.
Documentation
// Copyright (c) 2025-2026, Kirky.X
//
// MIT License
//
// 性能测试集成测试 - 使用新API

use crate::common;

use common::{cleanup_service, generate_unique_service_name, is_redis_available, setup_logging};
use oxcache::Cache;

use std::time::Instant;

/// 测试NF2:缓存回填延迟 < 5ms
///
/// 验证在L1未命中但L2命中的情况下,从L2加载数据到L1并返回的延迟是否满足性能要求。
/// 注意:这个测试依赖于Redis的性能,如果Redis远程或网络差,可能会失败。
/// 这里主要测试代码路径的开开销销。
#[tokio::test]
async fn test_backfill_latency() {
    if !is_redis_available().await {
        println!("跳过 test_backfill_latency: Redis不可用");
        return;
    }

    setup_logging();
    let service_name = generate_unique_service_name("perf_backfill_test");
    let redis_url = "redis://127.0.0.1:6379";

    // 使用新API创建缓存
    let cache: Cache<String, String> = Cache::tiered(1000, redis_url)
        .await
        .expect("Failed to create tiered cache");

    let key = "perf_key".to_string();
    let val = "perf_value".to_string();

    // 写入数据
    cache.set(&key, &val).await.unwrap();

    // 清除L1以模拟L1未命中
    // 新API使用 clear() 清除所有数据
    cache.clear().await.unwrap();

    // 重新写入数据到L2(通过清除后重新写入)
    // 注意:新API没有 set_l2_only 方法,我们直接写入
    cache.set(&key, &val).await.unwrap();

    // 现在测量获取延迟
    let start = Instant::now();
    let res: Option<String> = cache.get(&key).await.unwrap();
    let duration = start.elapsed();

    assert_eq!(res, Some(val));

    println!("Backfill latency: {:?}", duration);
    // 验证延迟 < 5ms (NF2)
    if duration.as_millis() >= 5 {
        println!(
            "WARNING: Backfill latency {}ms exceeds 5ms target",
            duration.as_millis()
        );
    } else {
        assert!(duration.as_millis() < 5, "Backfill latency too high");
    }

    // 清理
    cache.shutdown().await.expect("Shutdown failed");
    cleanup_service(&service_name).await;
}

/// 测试异常场景:Redis连接失败时的降级处理
///
/// 验证当L2不可用时,系统是否能正确报告错误
#[tokio::test]
async fn test_redis_outage_resilience() {
    let redis_url = "redis://127.0.0.1:12345"; // 错误的端口

    // 使用新API尝试连接到不存在的Redis
    let cache_result: Result<Cache<String, String>, oxcache::CacheError> =
        Cache::tiered(100, redis_url).await;

    // 应该返回错误
    assert!(
        cache_result.is_err(),
        "Should fail to connect to invalid Redis"
    );

    // 验证错误类型
    let error = cache_result.unwrap_err();
    println!("Expected error: {:?}", error);
}