Add comprehensive documentation and unit tests
Documentation: - Add detailed README files for all services (auth, character, database, launcher, packet, utils, world) - Create API documentation for the database service with detailed endpoint specifications - Document database schema and relationships - Add service architecture overviews and configuration instructions Unit Tests: - Implement comprehensive test suite for database repositories (user, character, session) - Add gRPC service tests for database interactions - Create tests for packet service components (bufferpool, connection, packets) - Add utility service tests (health check, logging, load balancer, redis cache, service discovery) - Implement auth service user tests - Add character service tests Code Structure: - Reorganize test files into a more consistent structure - Create a dedicated tests crate for integration testing - Add test helpers and mock implementations for easier testing
This commit is contained in:
152
tests/utils/redis_cache_tests.rs
Normal file
152
tests/utils/redis_cache_tests.rs
Normal file
@@ -0,0 +1,152 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::env;
|
||||
use tokio::sync::Mutex;
|
||||
use utils::redis_cache::{Cache, RedisCache};
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, PartialEq)]
|
||||
struct TestData {
|
||||
id: i32,
|
||||
name: String,
|
||||
value: f64,
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_redis_cache_set_get() {
|
||||
// Skip test if REDIS_TEST_ENABLED is not set to true
|
||||
if env::var("REDIS_TEST_ENABLED").unwrap_or_else(|_| "false".to_string()) != "true" {
|
||||
println!("Skipping Redis test. Set REDIS_TEST_ENABLED=true to run.");
|
||||
return;
|
||||
}
|
||||
|
||||
let redis_url = env::var("TEST_REDIS_URL").unwrap_or_else(|_| "redis://127.0.0.1:6379".to_string());
|
||||
let cache = RedisCache::new(&redis_url);
|
||||
|
||||
let key = "test_key_set_get".to_string();
|
||||
let test_data = TestData {
|
||||
id: 1,
|
||||
name: "test".to_string(),
|
||||
value: 3.14,
|
||||
};
|
||||
|
||||
// Test setting a value
|
||||
let set_result = cache.set(&key, &test_data, 10).await;
|
||||
assert!(set_result.is_ok(), "Failed to set value: {:?}", set_result.err());
|
||||
|
||||
// Test getting the value
|
||||
let get_result: Result<Option<TestData>, _> = cache.get(&key).await;
|
||||
assert!(get_result.is_ok(), "Failed to get value: {:?}", get_result.err());
|
||||
|
||||
let retrieved_data = get_result.unwrap();
|
||||
assert!(retrieved_data.is_some(), "Retrieved data is None");
|
||||
assert_eq!(retrieved_data.unwrap(), test_data);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_redis_cache_update() {
|
||||
// Skip test if REDIS_TEST_ENABLED is not set to true
|
||||
if env::var("REDIS_TEST_ENABLED").unwrap_or_else(|_| "false".to_string()) != "true" {
|
||||
println!("Skipping Redis test. Set REDIS_TEST_ENABLED=true to run.");
|
||||
return;
|
||||
}
|
||||
|
||||
let redis_url = env::var("TEST_REDIS_URL").unwrap_or_else(|_| "redis://127.0.0.1:6379".to_string());
|
||||
let cache = RedisCache::new(&redis_url);
|
||||
|
||||
let key = "test_key_update".to_string();
|
||||
let initial_data = TestData {
|
||||
id: 2,
|
||||
name: "initial".to_string(),
|
||||
value: 2.71,
|
||||
};
|
||||
let updated_data = TestData {
|
||||
id: 2,
|
||||
name: "updated".to_string(),
|
||||
value: 2.71,
|
||||
};
|
||||
|
||||
// Set initial value
|
||||
let set_result = cache.set(&key, &initial_data, 10).await;
|
||||
assert!(set_result.is_ok(), "Failed to set initial value: {:?}", set_result.err());
|
||||
|
||||
// Update the value
|
||||
let update_result = cache.update(&key, Some(&updated_data), Some(10)).await;
|
||||
assert!(update_result.is_ok(), "Failed to update value: {:?}", update_result.err());
|
||||
|
||||
// Get the updated value
|
||||
let get_result: Result<Option<TestData>, _> = cache.get(&key).await;
|
||||
assert!(get_result.is_ok(), "Failed to get updated value: {:?}", get_result.err());
|
||||
|
||||
let retrieved_data = get_result.unwrap();
|
||||
assert!(retrieved_data.is_some(), "Retrieved data is None");
|
||||
assert_eq!(retrieved_data.unwrap(), updated_data);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_redis_cache_delete() {
|
||||
// Skip test if REDIS_TEST_ENABLED is not set to true
|
||||
if env::var("REDIS_TEST_ENABLED").unwrap_or_else(|_| "false".to_string()) != "true" {
|
||||
println!("Skipping Redis test. Set REDIS_TEST_ENABLED=true to run.");
|
||||
return;
|
||||
}
|
||||
|
||||
let redis_url = env::var("TEST_REDIS_URL").unwrap_or_else(|_| "redis://127.0.0.1:6379".to_string());
|
||||
let mut cache = RedisCache::new(&redis_url);
|
||||
|
||||
let key = "test_key_delete".to_string();
|
||||
let test_data = TestData {
|
||||
id: 3,
|
||||
name: "delete_test".to_string(),
|
||||
value: 1.618,
|
||||
};
|
||||
|
||||
// Set a value
|
||||
let set_result = cache.set(&key, &test_data, 10).await;
|
||||
assert!(set_result.is_ok(), "Failed to set value: {:?}", set_result.err());
|
||||
|
||||
// Delete the value
|
||||
let delete_result = cache.delete(&key).await;
|
||||
assert!(delete_result.is_ok(), "Failed to delete value: {:?}", delete_result.err());
|
||||
|
||||
// Verify the value is gone
|
||||
let get_result: Result<Option<TestData>, _> = cache.get(&key).await;
|
||||
assert!(get_result.is_ok(), "Failed to get value after deletion: {:?}", get_result.err());
|
||||
assert!(get_result.unwrap().is_none(), "Value still exists after deletion");
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_redis_cache_refresh() {
|
||||
// Skip test if REDIS_TEST_ENABLED is not set to true
|
||||
if env::var("REDIS_TEST_ENABLED").unwrap_or_else(|_| "false".to_string()) != "true" {
|
||||
println!("Skipping Redis test. Set REDIS_TEST_ENABLED=true to run.");
|
||||
return;
|
||||
}
|
||||
|
||||
let redis_url = env::var("TEST_REDIS_URL").unwrap_or_else(|_| "redis://127.0.0.1:6379".to_string());
|
||||
let cache = RedisCache::new(&redis_url);
|
||||
|
||||
let key = "test_key_refresh".to_string();
|
||||
let test_data = TestData {
|
||||
id: 4,
|
||||
name: "refresh_test".to_string(),
|
||||
value: 0.577,
|
||||
};
|
||||
|
||||
// Set a value with a short TTL
|
||||
let set_result = cache.set(&key, &test_data, 5).await;
|
||||
assert!(set_result.is_ok(), "Failed to set value: {:?}", set_result.err());
|
||||
|
||||
// Refresh the TTL
|
||||
let refresh_result = cache.refresh(&key, 30).await;
|
||||
assert!(refresh_result.is_ok(), "Failed to refresh TTL: {:?}", refresh_result.err());
|
||||
|
||||
// Wait for the original TTL to expire
|
||||
tokio::time::sleep(tokio::time::Duration::from_secs(6)).await;
|
||||
|
||||
// Verify the value still exists due to the refresh
|
||||
let get_result: Result<Option<TestData>, _> = cache.get(&key).await;
|
||||
assert!(get_result.is_ok(), "Failed to get value after refresh: {:?}", get_result.err());
|
||||
|
||||
let retrieved_data = get_result.unwrap();
|
||||
assert!(retrieved_data.is_some(), "Value expired despite TTL refresh");
|
||||
assert_eq!(retrieved_data.unwrap(), test_data);
|
||||
}
|
||||
Reference in New Issue
Block a user