use crate::common::{MockStorage, create_test_cache};
use limiteron::Storage;
use oxcache::Cache;
use std::sync::Arc;
use std::time::Duration;
async fn create_storage_with_cache() -> (Arc<MockStorage>, Cache<String, String>) {
let storage = Arc::new(MockStorage::new());
let cache = create_test_cache().await;
(storage, cache)
}
#[allow(dead_code)]
fn make_cache_key(prefix: &str, key: &str) -> String {
format!("{}:{}", prefix, key)
}
#[tokio::test]
async fn test_mock_storage_basic_operations() {
let storage = MockStorage::new();
storage.set("key1", "value1", None).await.unwrap();
let result = storage.get("key1").await.unwrap();
assert_eq!(result, Some("value1".to_string()));
storage.delete("key1").await.unwrap();
let result = storage.get("key1").await.unwrap();
assert!(result.is_none());
}
#[tokio::test]
async fn test_mock_storage_ttl() {
let storage = MockStorage::new();
storage
.set("key1", "value1", Some(1)) .await
.unwrap();
let result = storage.get("key1").await.unwrap();
assert!(result.is_some());
tokio::time::sleep(Duration::from_millis(1500)).await;
let result = storage.get("key1").await.unwrap();
assert!(result.is_none());
}
#[tokio::test]
async fn test_mock_storage_batch_operations() {
let storage = MockStorage::new();
for i in 0..100 {
storage
.set(&format!("key_{}", i), &format!("value_{}", i), None)
.await
.unwrap();
}
for i in 0..100 {
let result = storage.get(&format!("key_{}", i)).await.unwrap();
assert_eq!(result, Some(format!("value_{}", i)));
}
}
#[tokio::test]
async fn test_mock_storage_concurrent_access() {
let storage = Arc::new(MockStorage::new());
let mut handles = vec![];
for i in 0..50 {
let s = Arc::clone(&storage);
handles.push(tokio::spawn(async move {
s.set(&format!("key_{}", i), &format!("value_{}", i), None)
.await
.unwrap();
}));
}
futures::future::join_all(handles).await;
for i in 0..50 {
let result = storage.get(&format!("key_{}", i)).await.unwrap();
assert!(result.is_some());
}
}
#[tokio::test]
async fn test_cache_namespace_isolation() {
let (storage, _cache) = create_storage_with_cache().await;
let ns1_key = "namespace1:same_key";
let ns2_key = "namespace2:same_key";
storage.set(ns1_key, "value1", None).await.unwrap();
storage.set(ns2_key, "value2", None).await.unwrap();
let result1 = storage.get(ns1_key).await.unwrap();
let result2 = storage.get(ns2_key).await.unwrap();
assert_eq!(result1, Some("value1".to_string()));
assert_eq!(result2, Some("value2".to_string()));
}
#[tokio::test]
async fn test_mock_storage_error_injection() {
let storage = MockStorage::new();
storage
.inject_error(limiteron::error::StorageError::ConnectionError(
"模拟连接错误".to_string(),
))
.await;
let result = storage.get("any_key").await;
assert!(result.is_err());
storage.clear_error().await;
let result = storage.get("any_key").await;
assert!(result.is_ok());
}
#[tokio::test]
async fn test_mock_storage_high_concurrency() {
let storage = Arc::new(MockStorage::new());
let mut handles = vec![];
for i in 0..100 {
let s = Arc::clone(&storage);
handles.push(tokio::spawn(async move {
for j in 0..10 {
s.set(
&format!("key_{}_{}", i, j),
&format!("value_{}_{}", i, j),
None,
)
.await
.unwrap();
}
}));
}
futures::future::join_all(handles).await;
for i in 0..100 {
for j in 0..10 {
let result = storage.get(&format!("key_{}_{}", i, j)).await.unwrap();
assert_eq!(
result,
Some(format!("value_{}_{}", i, j)),
"数据完整性验证失败: key_{}_{}",
i,
j
);
}
}
}
#[tokio::test]
async fn test_mock_storage_data_isolation() {
let storage1 = MockStorage::new();
let storage2 = MockStorage::new();
storage1.set("key", "value1", None).await.unwrap();
storage2.set("key", "value2", None).await.unwrap();
let result1 = storage1.get("key").await.unwrap();
let result2 = storage2.get("key").await.unwrap();
assert_eq!(result1, Some("value1".to_string()));
assert_eq!(result2, Some("value2".to_string()));
}
#[tokio::test]
async fn test_cache_warmup() {
let (storage, _cache) = create_storage_with_cache().await;
let warmup_data = vec![
("warmup:1", "value1"),
("warmup:2", "value2"),
("warmup:3", "value3"),
];
for (key, value) in &warmup_data {
storage.set(key, value, None).await.unwrap();
}
for (key, value) in &warmup_data {
let result = storage.get(key).await.unwrap();
assert_eq!(result, Some(value.to_string()));
}
}
#[tokio::test]
async fn test_cache_hit_rate() {
let (storage, _cache) = create_storage_with_cache().await;
for i in 0..10 {
let key = format!("hit_rate_key_{}", i);
storage
.set(&key, &format!("value_{}", i), None)
.await
.unwrap();
}
for i in 0..10 {
let key = format!("hit_rate_key_{}", i);
let result = storage.get(&key).await.unwrap();
assert!(result.is_some());
}
}