...
This commit is contained in:
384
packages/clients/redisclient/tests/redis_tests.rs
Normal file
384
packages/clients/redisclient/tests/redis_tests.rs
Normal file
@@ -0,0 +1,384 @@
|
||||
use redis::RedisResult;
|
||||
use sal_redisclient::*;
|
||||
use std::env;
|
||||
|
||||
#[cfg(test)]
|
||||
mod redis_client_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_env_vars() {
|
||||
// Save original REDISDB value to restore later
|
||||
let original_redisdb = env::var("REDISDB").ok();
|
||||
|
||||
// Set test environment variables
|
||||
env::set_var("REDISDB", "5");
|
||||
|
||||
// Test with invalid value
|
||||
env::set_var("REDISDB", "invalid");
|
||||
|
||||
// Test with unset value
|
||||
env::remove_var("REDISDB");
|
||||
|
||||
// Restore original REDISDB value
|
||||
if let Some(redisdb) = original_redisdb {
|
||||
env::set_var("REDISDB", redisdb);
|
||||
} else {
|
||||
env::remove_var("REDISDB");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_redis_config_environment_variables() {
|
||||
// Test that environment variables are properly handled
|
||||
let original_home = env::var("HOME").ok();
|
||||
let original_redis_host = env::var("REDIS_HOST").ok();
|
||||
let original_redis_port = env::var("REDIS_PORT").ok();
|
||||
|
||||
// Set test environment variables
|
||||
env::set_var("HOME", "/tmp/test");
|
||||
env::set_var("REDIS_HOST", "test.redis.com");
|
||||
env::set_var("REDIS_PORT", "6380");
|
||||
|
||||
// Test that the configuration builder respects environment variables
|
||||
let config = RedisConfigBuilder::new()
|
||||
.host(&env::var("REDIS_HOST").unwrap_or_else(|_| "127.0.0.1".to_string()))
|
||||
.port(
|
||||
env::var("REDIS_PORT")
|
||||
.ok()
|
||||
.and_then(|p| p.parse().ok())
|
||||
.unwrap_or(6379),
|
||||
);
|
||||
|
||||
assert_eq!(config.host, "test.redis.com");
|
||||
assert_eq!(config.port, 6380);
|
||||
|
||||
// Restore original environment variables
|
||||
if let Some(home) = original_home {
|
||||
env::set_var("HOME", home);
|
||||
} else {
|
||||
env::remove_var("HOME");
|
||||
}
|
||||
if let Some(host) = original_redis_host {
|
||||
env::set_var("REDIS_HOST", host);
|
||||
} else {
|
||||
env::remove_var("REDIS_HOST");
|
||||
}
|
||||
if let Some(port) = original_redis_port {
|
||||
env::set_var("REDIS_PORT", port);
|
||||
} else {
|
||||
env::remove_var("REDIS_PORT");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_redis_config_validation() {
|
||||
// Test configuration validation and edge cases
|
||||
|
||||
// Test invalid port handling
|
||||
let config = RedisConfigBuilder::new().port(0);
|
||||
assert_eq!(config.port, 0); // Should accept any port value
|
||||
|
||||
// Test empty strings
|
||||
let config = RedisConfigBuilder::new().host("").username("").password("");
|
||||
assert_eq!(config.host, "");
|
||||
assert_eq!(config.username, Some("".to_string()));
|
||||
assert_eq!(config.password, Some("".to_string()));
|
||||
|
||||
// Test chaining methods
|
||||
let config = RedisConfigBuilder::new()
|
||||
.host("localhost")
|
||||
.port(6379)
|
||||
.db(1)
|
||||
.use_tls(true)
|
||||
.connection_timeout(30);
|
||||
|
||||
assert_eq!(config.host, "localhost");
|
||||
assert_eq!(config.port, 6379);
|
||||
assert_eq!(config.db, 1);
|
||||
assert_eq!(config.use_tls, true);
|
||||
assert_eq!(config.connection_timeout, Some(30));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_redis_config_builder() {
|
||||
// Test the Redis configuration builder
|
||||
|
||||
// Test default values
|
||||
let config = RedisConfigBuilder::new();
|
||||
assert_eq!(config.host, "127.0.0.1");
|
||||
assert_eq!(config.port, 6379);
|
||||
assert_eq!(config.db, 0);
|
||||
assert_eq!(config.username, None);
|
||||
assert_eq!(config.password, None);
|
||||
assert_eq!(config.use_tls, false);
|
||||
assert_eq!(config.use_unix_socket, false);
|
||||
assert_eq!(config.socket_path, None);
|
||||
assert_eq!(config.connection_timeout, None);
|
||||
|
||||
// Test setting values
|
||||
let config = RedisConfigBuilder::new()
|
||||
.host("redis.example.com")
|
||||
.port(6380)
|
||||
.db(1)
|
||||
.username("user")
|
||||
.password("pass")
|
||||
.use_tls(true)
|
||||
.connection_timeout(30);
|
||||
|
||||
assert_eq!(config.host, "redis.example.com");
|
||||
assert_eq!(config.port, 6380);
|
||||
assert_eq!(config.db, 1);
|
||||
assert_eq!(config.username, Some("user".to_string()));
|
||||
assert_eq!(config.password, Some("pass".to_string()));
|
||||
assert_eq!(config.use_tls, true);
|
||||
assert_eq!(config.connection_timeout, Some(30));
|
||||
|
||||
// Test socket path setting
|
||||
let config = RedisConfigBuilder::new().socket_path("/tmp/redis.sock");
|
||||
|
||||
assert_eq!(config.use_unix_socket, true);
|
||||
assert_eq!(config.socket_path, Some("/tmp/redis.sock".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_connection_url_building() {
|
||||
// Test building connection URLs
|
||||
|
||||
// Test default URL
|
||||
let config = RedisConfigBuilder::new();
|
||||
let url = config.build_connection_url();
|
||||
assert_eq!(url, "redis://127.0.0.1:6379/0");
|
||||
|
||||
// Test with authentication
|
||||
let config = RedisConfigBuilder::new().username("user").password("pass");
|
||||
let url = config.build_connection_url();
|
||||
assert_eq!(url, "redis://user:pass@127.0.0.1:6379/0");
|
||||
|
||||
// Test with password only
|
||||
let config = RedisConfigBuilder::new().password("pass");
|
||||
let url = config.build_connection_url();
|
||||
assert_eq!(url, "redis://:pass@127.0.0.1:6379/0");
|
||||
|
||||
// Test with TLS
|
||||
let config = RedisConfigBuilder::new().use_tls(true);
|
||||
let url = config.build_connection_url();
|
||||
assert_eq!(url, "rediss://127.0.0.1:6379/0");
|
||||
|
||||
// Test with Unix socket
|
||||
let config = RedisConfigBuilder::new().socket_path("/tmp/redis.sock");
|
||||
let url = config.build_connection_url();
|
||||
assert_eq!(url, "unix:///tmp/redis.sock");
|
||||
}
|
||||
}
|
||||
|
||||
// Integration tests that require a real Redis server
|
||||
// These tests will be skipped if Redis is not available
|
||||
#[cfg(test)]
|
||||
mod redis_integration_tests {
|
||||
use super::*;
|
||||
|
||||
// Helper function to check if Redis is available
|
||||
fn is_redis_available() -> bool {
|
||||
match get_redis_client() {
|
||||
Ok(_) => true,
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_redis_client_integration() {
|
||||
if !is_redis_available() {
|
||||
println!("Skipping Redis integration tests - Redis server not available");
|
||||
return;
|
||||
}
|
||||
|
||||
println!("Running Redis integration tests...");
|
||||
|
||||
// Test basic operations
|
||||
test_basic_redis_operations();
|
||||
|
||||
// Test more complex operations
|
||||
test_hash_operations();
|
||||
test_list_operations();
|
||||
|
||||
// Test error handling
|
||||
test_error_handling();
|
||||
}
|
||||
|
||||
fn test_basic_redis_operations() {
|
||||
if !is_redis_available() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Test setting and getting values
|
||||
let client_result = get_redis_client();
|
||||
|
||||
if client_result.is_err() {
|
||||
// Skip the test if we can't connect to Redis
|
||||
return;
|
||||
}
|
||||
|
||||
// Create SET command
|
||||
let mut set_cmd = redis::cmd("SET");
|
||||
set_cmd.arg("test_key").arg("test_value");
|
||||
|
||||
// Execute SET command
|
||||
let set_result: RedisResult<()> = execute(&mut set_cmd);
|
||||
assert!(set_result.is_ok());
|
||||
|
||||
// Create GET command
|
||||
let mut get_cmd = redis::cmd("GET");
|
||||
get_cmd.arg("test_key");
|
||||
|
||||
// Execute GET command and check the result
|
||||
if let Ok(value) = execute::<String>(&mut get_cmd) {
|
||||
assert_eq!(value, "test_value");
|
||||
}
|
||||
|
||||
// Test expiration
|
||||
let mut expire_cmd = redis::cmd("EXPIRE");
|
||||
expire_cmd.arg("test_key").arg(1); // Expire in 1 second
|
||||
let expire_result: RedisResult<i32> = execute(&mut expire_cmd);
|
||||
assert!(expire_result.is_ok());
|
||||
assert_eq!(expire_result.unwrap(), 1);
|
||||
|
||||
// Sleep for 2 seconds to let the key expire
|
||||
std::thread::sleep(std::time::Duration::from_secs(2));
|
||||
|
||||
// Check that the key has expired
|
||||
let mut exists_cmd = redis::cmd("EXISTS");
|
||||
exists_cmd.arg("test_key");
|
||||
let exists_result: RedisResult<i32> = execute(&mut exists_cmd);
|
||||
assert!(exists_result.is_ok());
|
||||
assert_eq!(exists_result.unwrap(), 0);
|
||||
|
||||
// Clean up
|
||||
let _: RedisResult<()> = execute(&mut redis::cmd("DEL").arg("test_key"));
|
||||
}
|
||||
|
||||
fn test_hash_operations() {
|
||||
if !is_redis_available() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Test hash operations
|
||||
let hash_key = "test_hash";
|
||||
|
||||
// Set hash fields
|
||||
let mut hset_cmd = redis::cmd("HSET");
|
||||
hset_cmd
|
||||
.arg(hash_key)
|
||||
.arg("field1")
|
||||
.arg("value1")
|
||||
.arg("field2")
|
||||
.arg("value2");
|
||||
let hset_result: RedisResult<i32> = execute(&mut hset_cmd);
|
||||
assert!(hset_result.is_ok());
|
||||
assert_eq!(hset_result.unwrap(), 2);
|
||||
|
||||
// Get hash field
|
||||
let mut hget_cmd = redis::cmd("HGET");
|
||||
hget_cmd.arg(hash_key).arg("field1");
|
||||
let hget_result: RedisResult<String> = execute(&mut hget_cmd);
|
||||
assert!(hget_result.is_ok());
|
||||
assert_eq!(hget_result.unwrap(), "value1");
|
||||
|
||||
// Get all hash fields
|
||||
let mut hgetall_cmd = redis::cmd("HGETALL");
|
||||
hgetall_cmd.arg(hash_key);
|
||||
let hgetall_result: RedisResult<Vec<String>> = execute(&mut hgetall_cmd);
|
||||
assert!(hgetall_result.is_ok());
|
||||
let hgetall_values = hgetall_result.unwrap();
|
||||
assert_eq!(hgetall_values.len(), 4); // field1, value1, field2, value2
|
||||
|
||||
// Delete hash field
|
||||
let mut hdel_cmd = redis::cmd("HDEL");
|
||||
hdel_cmd.arg(hash_key).arg("field1");
|
||||
let hdel_result: RedisResult<i32> = execute(&mut hdel_cmd);
|
||||
assert!(hdel_result.is_ok());
|
||||
assert_eq!(hdel_result.unwrap(), 1);
|
||||
|
||||
// Clean up
|
||||
let _: RedisResult<()> = execute(&mut redis::cmd("DEL").arg(hash_key));
|
||||
}
|
||||
|
||||
fn test_list_operations() {
|
||||
if !is_redis_available() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Test list operations
|
||||
let list_key = "test_list";
|
||||
|
||||
// Push items to list
|
||||
let mut rpush_cmd = redis::cmd("RPUSH");
|
||||
rpush_cmd
|
||||
.arg(list_key)
|
||||
.arg("item1")
|
||||
.arg("item2")
|
||||
.arg("item3");
|
||||
let rpush_result: RedisResult<i32> = execute(&mut rpush_cmd);
|
||||
assert!(rpush_result.is_ok());
|
||||
assert_eq!(rpush_result.unwrap(), 3);
|
||||
|
||||
// Get list length
|
||||
let mut llen_cmd = redis::cmd("LLEN");
|
||||
llen_cmd.arg(list_key);
|
||||
let llen_result: RedisResult<i32> = execute(&mut llen_cmd);
|
||||
assert!(llen_result.is_ok());
|
||||
assert_eq!(llen_result.unwrap(), 3);
|
||||
|
||||
// Get list range
|
||||
let mut lrange_cmd = redis::cmd("LRANGE");
|
||||
lrange_cmd.arg(list_key).arg(0).arg(-1);
|
||||
let lrange_result: RedisResult<Vec<String>> = execute(&mut lrange_cmd);
|
||||
assert!(lrange_result.is_ok());
|
||||
let lrange_values = lrange_result.unwrap();
|
||||
assert_eq!(lrange_values.len(), 3);
|
||||
assert_eq!(lrange_values[0], "item1");
|
||||
assert_eq!(lrange_values[1], "item2");
|
||||
assert_eq!(lrange_values[2], "item3");
|
||||
|
||||
// Pop item from list
|
||||
let mut lpop_cmd = redis::cmd("LPOP");
|
||||
lpop_cmd.arg(list_key);
|
||||
let lpop_result: RedisResult<String> = execute(&mut lpop_cmd);
|
||||
assert!(lpop_result.is_ok());
|
||||
assert_eq!(lpop_result.unwrap(), "item1");
|
||||
|
||||
// Clean up
|
||||
let _: RedisResult<()> = execute(&mut redis::cmd("DEL").arg(list_key));
|
||||
}
|
||||
|
||||
fn test_error_handling() {
|
||||
if !is_redis_available() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Test error handling
|
||||
|
||||
// Test invalid command
|
||||
let mut invalid_cmd = redis::cmd("INVALID_COMMAND");
|
||||
let invalid_result: RedisResult<()> = execute(&mut invalid_cmd);
|
||||
assert!(invalid_result.is_err());
|
||||
|
||||
// Test wrong data type
|
||||
let key = "test_wrong_type";
|
||||
|
||||
// Set a string value
|
||||
let mut set_cmd = redis::cmd("SET");
|
||||
set_cmd.arg(key).arg("string_value");
|
||||
let set_result: RedisResult<()> = execute(&mut set_cmd);
|
||||
assert!(set_result.is_ok());
|
||||
|
||||
// Try to use a hash command on a string
|
||||
let mut hget_cmd = redis::cmd("HGET");
|
||||
hget_cmd.arg(key).arg("field");
|
||||
let hget_result: RedisResult<String> = execute(&mut hget_cmd);
|
||||
assert!(hget_result.is_err());
|
||||
|
||||
// Clean up
|
||||
let _: RedisResult<()> = execute(&mut redis::cmd("DEL").arg(key));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user