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
153 lines
5.4 KiB
Rust
153 lines
5.4 KiB
Rust
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);
|
|
}
|