...
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));
|
||||
}
|
||||
}
|
@@ -0,0 +1,68 @@
|
||||
// 01_redis_connection.rhai
|
||||
// Tests for Redis client connection and basic operations
|
||||
|
||||
// Custom assert function
|
||||
fn assert_true(condition, message) {
|
||||
if !condition {
|
||||
print(`ASSERTION FAILED: ${message}`);
|
||||
throw message;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to check if Redis is available
|
||||
fn is_redis_available() {
|
||||
try {
|
||||
// Try to execute a simple PING command
|
||||
let ping_result = redis_ping();
|
||||
return ping_result == "PONG";
|
||||
} catch(err) {
|
||||
print(`Redis connection error: ${err}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
print("=== Testing Redis Client Connection ===");
|
||||
|
||||
// Check if Redis is available
|
||||
let redis_available = is_redis_available();
|
||||
if !redis_available {
|
||||
print("Redis server is not available. Skipping Redis tests.");
|
||||
// Exit gracefully without error
|
||||
return;
|
||||
}
|
||||
|
||||
print("✓ Redis server is available");
|
||||
|
||||
// Test redis_ping function
|
||||
print("Testing redis_ping()...");
|
||||
let ping_result = redis_ping();
|
||||
assert_true(ping_result == "PONG", "PING should return PONG");
|
||||
print(`✓ redis_ping(): Returned ${ping_result}`);
|
||||
|
||||
// Test redis_set and redis_get functions
|
||||
print("Testing redis_set() and redis_get()...");
|
||||
let test_key = "rhai_test_key";
|
||||
let test_value = "Hello from Rhai test";
|
||||
|
||||
// Set a value
|
||||
let set_result = redis_set(test_key, test_value);
|
||||
assert_true(set_result, "SET operation should succeed");
|
||||
print(`✓ redis_set(): Successfully set key ${test_key}`);
|
||||
|
||||
// Get the value back
|
||||
let get_result = redis_get(test_key);
|
||||
assert_true(get_result == test_value, "GET should return the value we set");
|
||||
print(`✓ redis_get(): Successfully retrieved value for key ${test_key}`);
|
||||
|
||||
// Test redis_del function
|
||||
print("Testing redis_del()...");
|
||||
let del_result = redis_del(test_key);
|
||||
assert_true(del_result, "DEL operation should succeed");
|
||||
print(`✓ redis_del(): Successfully deleted key ${test_key}`);
|
||||
|
||||
// Verify the key was deleted
|
||||
let get_after_del = redis_get(test_key);
|
||||
assert_true(get_after_del == "", "Key should not exist after deletion");
|
||||
print("✓ Key was successfully deleted");
|
||||
|
||||
print("All Redis connection tests completed successfully!");
|
109
packages/clients/redisclient/tests/rhai/02_redis_operations.rhai
Normal file
109
packages/clients/redisclient/tests/rhai/02_redis_operations.rhai
Normal file
@@ -0,0 +1,109 @@
|
||||
// 02_redis_operations.rhai
|
||||
// Tests for advanced Redis operations
|
||||
|
||||
// Custom assert function
|
||||
fn assert_true(condition, message) {
|
||||
if !condition {
|
||||
print(`ASSERTION FAILED: ${message}`);
|
||||
throw message;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to check if Redis is available
|
||||
fn is_redis_available() {
|
||||
try {
|
||||
// Try to execute a simple PING command
|
||||
let ping_result = redis_ping();
|
||||
return ping_result == "PONG";
|
||||
} catch(err) {
|
||||
print(`Redis connection error: ${err}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
print("=== Testing Advanced Redis Operations ===");
|
||||
|
||||
// Check if Redis is available
|
||||
let redis_available = is_redis_available();
|
||||
if !redis_available {
|
||||
print("Redis server is not available. Skipping Redis tests.");
|
||||
// Exit gracefully without error
|
||||
return;
|
||||
}
|
||||
|
||||
print("✓ Redis server is available");
|
||||
|
||||
// Test prefix for all keys to avoid conflicts
|
||||
let prefix = "rhai_test_";
|
||||
|
||||
// Test redis_hset and redis_hget functions
|
||||
print("Testing redis_hset() and redis_hget()...");
|
||||
let hash_key = prefix + "hash";
|
||||
let field1 = "field1";
|
||||
let value1 = "value1";
|
||||
let field2 = "field2";
|
||||
let value2 = "value2";
|
||||
|
||||
// Set hash fields
|
||||
let hset_result1 = redis_hset(hash_key, field1, value1);
|
||||
assert_true(hset_result1, "HSET operation should succeed for field1");
|
||||
let hset_result2 = redis_hset(hash_key, field2, value2);
|
||||
assert_true(hset_result2, "HSET operation should succeed for field2");
|
||||
print(`✓ redis_hset(): Successfully set fields in hash ${hash_key}`);
|
||||
|
||||
// Get hash fields
|
||||
let hget_result1 = redis_hget(hash_key, field1);
|
||||
assert_true(hget_result1 == value1, "HGET should return the value we set for field1");
|
||||
let hget_result2 = redis_hget(hash_key, field2);
|
||||
assert_true(hget_result2 == value2, "HGET should return the value we set for field2");
|
||||
print(`✓ redis_hget(): Successfully retrieved values from hash ${hash_key}`);
|
||||
|
||||
// Test redis_hgetall function
|
||||
print("Testing redis_hgetall()...");
|
||||
let hgetall_result = redis_hgetall(hash_key);
|
||||
assert_true(hgetall_result.len() == 2, "HGETALL should return 2 fields");
|
||||
assert_true(hgetall_result[field1] == value1, "HGETALL should include field1 with correct value");
|
||||
assert_true(hgetall_result[field2] == value2, "HGETALL should include field2 with correct value");
|
||||
print(`✓ redis_hgetall(): Successfully retrieved all fields from hash ${hash_key}`);
|
||||
|
||||
// Test redis_hdel function
|
||||
print("Testing redis_hdel()...");
|
||||
let hdel_result = redis_hdel(hash_key, field1);
|
||||
assert_true(hdel_result, "HDEL operation should succeed");
|
||||
print(`✓ redis_hdel(): Successfully deleted field from hash ${hash_key}`);
|
||||
|
||||
// Verify the field was deleted
|
||||
let hget_after_del = redis_hget(hash_key, field1);
|
||||
assert_true(hget_after_del == "", "Field should not exist after deletion");
|
||||
print("✓ Field was successfully deleted from hash");
|
||||
|
||||
// Test redis_list operations
|
||||
print("Testing redis list operations...");
|
||||
let list_key = prefix + "list";
|
||||
|
||||
// Push items to list
|
||||
let rpush_result = redis_rpush(list_key, "item1");
|
||||
assert_true(rpush_result > 0, "RPUSH operation should succeed");
|
||||
redis_rpush(list_key, "item2");
|
||||
redis_rpush(list_key, "item3");
|
||||
print(`✓ redis_rpush(): Successfully pushed items to list ${list_key}`);
|
||||
|
||||
// Get list length
|
||||
let llen_result = redis_llen(list_key);
|
||||
assert_true(llen_result == 3, "List should have 3 items");
|
||||
print(`✓ redis_llen(): List has ${llen_result} items`);
|
||||
|
||||
// Get list range
|
||||
let lrange_result = redis_lrange(list_key, 0, -1);
|
||||
assert_true(lrange_result.len() == 3, "LRANGE should return 3 items");
|
||||
assert_true(lrange_result[0] == "item1", "First item should be 'item1'");
|
||||
assert_true(lrange_result[2] == "item3", "Last item should be 'item3'");
|
||||
print(`✓ redis_lrange(): Successfully retrieved all items from list ${list_key}`);
|
||||
|
||||
// Clean up
|
||||
print("Cleaning up...");
|
||||
redis_del(hash_key);
|
||||
redis_del(list_key);
|
||||
print("✓ Cleanup: All test keys removed");
|
||||
|
||||
print("All Redis operations tests completed successfully!");
|
@@ -0,0 +1,59 @@
|
||||
// 03_redis_authentication.rhai
|
||||
// Tests for Redis client authentication (placeholder for future implementation)
|
||||
|
||||
// Custom assert function
|
||||
fn assert_true(condition, message) {
|
||||
if !condition {
|
||||
print(`ASSERTION FAILED: ${message}`);
|
||||
throw message;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to check if Redis is available
|
||||
fn is_redis_available() {
|
||||
try {
|
||||
// Try to execute a simple ping
|
||||
let ping_result = redis_ping();
|
||||
return ping_result == "PONG";
|
||||
} catch(err) {
|
||||
print(`Redis connection error: ${err}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
print("=== Testing Redis Client Authentication ===");
|
||||
|
||||
// Check if Redis is available
|
||||
let redis_available = is_redis_available();
|
||||
if !redis_available {
|
||||
print("Redis server is not available. Skipping Redis authentication tests.");
|
||||
// Exit gracefully without error
|
||||
return;
|
||||
}
|
||||
|
||||
print("✓ Redis server is available");
|
||||
|
||||
print("Authentication support will be implemented in a future update.");
|
||||
print("The backend implementation is ready, but the Rhai bindings are still in development.");
|
||||
|
||||
// For now, just test basic Redis functionality
|
||||
print("\nTesting basic Redis functionality...");
|
||||
|
||||
// Test a simple operation
|
||||
let test_key = "auth_test_key";
|
||||
let test_value = "auth_test_value";
|
||||
|
||||
let set_result = redis_set(test_key, test_value);
|
||||
assert_true(set_result, "Should be able to set a key");
|
||||
print("✓ Set key");
|
||||
|
||||
let get_result = redis_get(test_key);
|
||||
assert_true(get_result == test_value, "Should be able to get the key");
|
||||
print("✓ Got key");
|
||||
|
||||
// Clean up
|
||||
let del_result = redis_del(test_key);
|
||||
assert_true(del_result, "Should be able to delete the key");
|
||||
print("✓ Deleted test key");
|
||||
|
||||
print("All Redis tests completed successfully!");
|
154
packages/clients/redisclient/tests/rhai/run_all_tests.rhai
Normal file
154
packages/clients/redisclient/tests/rhai/run_all_tests.rhai
Normal file
@@ -0,0 +1,154 @@
|
||||
// run_all_tests.rhai
|
||||
// Runs all Redis client module tests
|
||||
|
||||
print("=== Running Redis Client Module Tests ===");
|
||||
|
||||
// Custom assert function
|
||||
fn assert_true(condition, message) {
|
||||
if !condition {
|
||||
print(`ASSERTION FAILED: ${message}`);
|
||||
throw message;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to check if Redis is available
|
||||
fn is_redis_available() {
|
||||
try {
|
||||
// Try to execute a simple PING command
|
||||
let ping_result = redis_ping();
|
||||
return ping_result == "PONG";
|
||||
} catch(err) {
|
||||
print(`Redis connection error: ${err}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Run each test directly
|
||||
let passed = 0;
|
||||
let failed = 0;
|
||||
let skipped = 0;
|
||||
|
||||
// Check if Redis is available
|
||||
let redis_available = is_redis_available();
|
||||
if !redis_available {
|
||||
print("Redis server is not available. Skipping all Redis tests.");
|
||||
skipped = 3; // Skip all three tests
|
||||
} else {
|
||||
// Test 1: Redis Connection
|
||||
print("\n--- Running Redis Connection Tests ---");
|
||||
try {
|
||||
// Test redis_ping function
|
||||
print("Testing redis_ping()...");
|
||||
let ping_result = redis_ping();
|
||||
assert_true(ping_result == "PONG", "PING should return PONG");
|
||||
print(`✓ redis_ping(): Returned ${ping_result}`);
|
||||
|
||||
// Test redis_set and redis_get functions
|
||||
print("Testing redis_set() and redis_get()...");
|
||||
let test_key = "rhai_test_key";
|
||||
let test_value = "Hello from Rhai test";
|
||||
|
||||
// Set a value
|
||||
let set_result = redis_set(test_key, test_value);
|
||||
assert_true(set_result, "SET operation should succeed");
|
||||
print(`✓ redis_set(): Successfully set key ${test_key}`);
|
||||
|
||||
// Get the value back
|
||||
let get_result = redis_get(test_key);
|
||||
assert_true(get_result == test_value, "GET should return the value we set");
|
||||
print(`✓ redis_get(): Successfully retrieved value for key ${test_key}`);
|
||||
|
||||
// Clean up
|
||||
redis_del(test_key);
|
||||
|
||||
print("--- Redis Connection Tests completed successfully ---");
|
||||
passed += 1;
|
||||
} catch(err) {
|
||||
print(`!!! Error in Redis Connection Tests: ${err}`);
|
||||
failed += 1;
|
||||
}
|
||||
|
||||
// Test 2: Redis Operations
|
||||
print("\n--- Running Redis Operations Tests ---");
|
||||
try {
|
||||
// Test prefix for all keys to avoid conflicts
|
||||
let prefix = "rhai_test_";
|
||||
|
||||
// Test redis_hset and redis_hget functions
|
||||
print("Testing redis_hset() and redis_hget()...");
|
||||
let hash_key = prefix + "hash";
|
||||
let field = "field1";
|
||||
let value = "value1";
|
||||
|
||||
// Set hash field
|
||||
let hset_result = redis_hset(hash_key, field, value);
|
||||
assert_true(hset_result, "HSET operation should succeed");
|
||||
print(`✓ redis_hset(): Successfully set field in hash ${hash_key}`);
|
||||
|
||||
// Get hash field
|
||||
let hget_result = redis_hget(hash_key, field);
|
||||
assert_true(hget_result == value, "HGET should return the value we set");
|
||||
print(`✓ redis_hget(): Successfully retrieved value from hash ${hash_key}`);
|
||||
|
||||
// Clean up
|
||||
redis_del(hash_key);
|
||||
|
||||
print("--- Redis Operations Tests completed successfully ---");
|
||||
passed += 1;
|
||||
} catch(err) {
|
||||
print(`!!! Error in Redis Operations Tests: ${err}`);
|
||||
failed += 1;
|
||||
}
|
||||
|
||||
// Test 3: Redis Authentication
|
||||
print("\n--- Running Redis Authentication Tests ---");
|
||||
try {
|
||||
print("Authentication support will be implemented in a future update.");
|
||||
print("The backend implementation is ready, but the Rhai bindings are still in development.");
|
||||
|
||||
// For now, just test basic Redis functionality
|
||||
print("\nTesting basic Redis functionality...");
|
||||
|
||||
// Test a simple operation
|
||||
let test_key = "auth_test_key";
|
||||
let test_value = "auth_test_value";
|
||||
|
||||
let set_result = redis_set(test_key, test_value);
|
||||
assert_true(set_result, "Should be able to set a key");
|
||||
print("✓ Set key");
|
||||
|
||||
let get_result = redis_get(test_key);
|
||||
assert_true(get_result == test_value, "Should be able to get the key");
|
||||
print("✓ Got key");
|
||||
|
||||
// Clean up
|
||||
let del_result = redis_del(test_key);
|
||||
assert_true(del_result, "Should be able to delete the key");
|
||||
print("✓ Deleted test key");
|
||||
|
||||
print("--- Redis Authentication Tests completed successfully ---");
|
||||
passed += 1;
|
||||
} catch(err) {
|
||||
print(`!!! Error in Redis Authentication Tests: ${err}`);
|
||||
failed += 1;
|
||||
}
|
||||
}
|
||||
|
||||
print("\n=== Test Summary ===");
|
||||
print(`Passed: ${passed}`);
|
||||
print(`Failed: ${failed}`);
|
||||
print(`Skipped: ${skipped}`);
|
||||
print(`Total: ${passed + failed + skipped}`);
|
||||
|
||||
if failed == 0 {
|
||||
if skipped > 0 {
|
||||
print("\n⚠️ All tests skipped or passed!");
|
||||
} else {
|
||||
print("\n✅ All tests passed!");
|
||||
}
|
||||
} else {
|
||||
print("\n❌ Some tests failed!");
|
||||
}
|
||||
|
||||
// Return the number of failed tests (0 means success)
|
||||
failed;
|
200
packages/clients/redisclient/tests/rhai_integration_tests.rs
Normal file
200
packages/clients/redisclient/tests/rhai_integration_tests.rs
Normal file
@@ -0,0 +1,200 @@
|
||||
use rhai::{Engine, EvalAltResult};
|
||||
use sal_redisclient::rhai::*;
|
||||
|
||||
#[cfg(test)]
|
||||
mod rhai_integration_tests {
|
||||
use super::*;
|
||||
|
||||
fn create_test_engine() -> Engine {
|
||||
let mut engine = Engine::new();
|
||||
register_redisclient_module(&mut engine).expect("Failed to register redisclient module");
|
||||
engine
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rhai_module_registration() {
|
||||
let engine = create_test_engine();
|
||||
|
||||
// Test that the functions are registered
|
||||
let script = r#"
|
||||
// Just test that the functions exist and can be called
|
||||
// We don't test actual Redis operations here since they require a server
|
||||
true
|
||||
"#;
|
||||
|
||||
let result: Result<bool, Box<EvalAltResult>> = engine.eval(script);
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(result.unwrap(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rhai_redis_functions_exist() {
|
||||
let engine = create_test_engine();
|
||||
|
||||
// Test that all expected functions are registered by attempting to call them
|
||||
// We expect them to either succeed or fail with Redis connection errors,
|
||||
// but NOT with "function not found" errors
|
||||
let function_tests = [
|
||||
("redis_ping()", "redis_ping"),
|
||||
("redis_set(\"test\", \"value\")", "redis_set"),
|
||||
("redis_get(\"test\")", "redis_get"),
|
||||
("redis_del(\"test\")", "redis_del"),
|
||||
("redis_hset(\"hash\", \"field\", \"value\")", "redis_hset"),
|
||||
("redis_hget(\"hash\", \"field\")", "redis_hget"),
|
||||
("redis_hgetall(\"hash\")", "redis_hgetall"),
|
||||
("redis_hdel(\"hash\", \"field\")", "redis_hdel"),
|
||||
("redis_rpush(\"list\", \"value\")", "redis_rpush"),
|
||||
("redis_llen(\"list\")", "redis_llen"),
|
||||
("redis_lrange(\"list\", 0, -1)", "redis_lrange"),
|
||||
("redis_reset()", "redis_reset"),
|
||||
];
|
||||
|
||||
for (script, func_name) in &function_tests {
|
||||
let result = engine.eval::<rhai::Dynamic>(script);
|
||||
|
||||
// The function should be registered - if not, we'd get "Function not found"
|
||||
// If Redis is not available, we might get connection errors, which is fine
|
||||
if let Err(err) = result {
|
||||
let error_msg = err.to_string();
|
||||
assert!(
|
||||
!error_msg.contains("Function not found")
|
||||
&& !error_msg.contains("Variable not found"),
|
||||
"Function {} should be registered but got: {}",
|
||||
func_name,
|
||||
error_msg
|
||||
);
|
||||
}
|
||||
// If it succeeds, that's even better - the function is registered and working
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rhai_function_signatures() {
|
||||
let engine = create_test_engine();
|
||||
|
||||
// Test function signatures by calling them with mock/invalid data
|
||||
// This verifies they're properly registered and have correct parameter counts
|
||||
|
||||
// Test functions that should fail gracefully with invalid Redis connection
|
||||
let test_cases = vec![
|
||||
(
|
||||
"redis_set(\"test\", \"value\")",
|
||||
"redis_set should accept 2 string parameters",
|
||||
),
|
||||
(
|
||||
"redis_get(\"test\")",
|
||||
"redis_get should accept 1 string parameter",
|
||||
),
|
||||
(
|
||||
"redis_del(\"test\")",
|
||||
"redis_del should accept 1 string parameter",
|
||||
),
|
||||
(
|
||||
"redis_hset(\"hash\", \"field\", \"value\")",
|
||||
"redis_hset should accept 3 string parameters",
|
||||
),
|
||||
(
|
||||
"redis_hget(\"hash\", \"field\")",
|
||||
"redis_hget should accept 2 string parameters",
|
||||
),
|
||||
(
|
||||
"redis_hgetall(\"hash\")",
|
||||
"redis_hgetall should accept 1 string parameter",
|
||||
),
|
||||
(
|
||||
"redis_hdel(\"hash\", \"field\")",
|
||||
"redis_hdel should accept 2 string parameters",
|
||||
),
|
||||
(
|
||||
"redis_rpush(\"list\", \"value\")",
|
||||
"redis_rpush should accept 2 string parameters",
|
||||
),
|
||||
(
|
||||
"redis_llen(\"list\")",
|
||||
"redis_llen should accept 1 string parameter",
|
||||
),
|
||||
(
|
||||
"redis_lrange(\"list\", 0, -1)",
|
||||
"redis_lrange should accept string and 2 integers",
|
||||
),
|
||||
];
|
||||
|
||||
for (script, description) in test_cases {
|
||||
let result = engine.eval::<rhai::Dynamic>(script);
|
||||
// We expect these to either succeed (if Redis is available) or fail with Redis connection error
|
||||
// But they should NOT fail with "function not found" or "wrong number of parameters"
|
||||
if let Err(err) = result {
|
||||
let error_msg = err.to_string();
|
||||
assert!(
|
||||
!error_msg.contains("Function not found")
|
||||
&& !error_msg.contains("wrong number of arguments")
|
||||
&& !error_msg.contains("expects")
|
||||
&& !error_msg.contains("parameters"),
|
||||
"{}: Got parameter error: {}",
|
||||
description,
|
||||
error_msg
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to check if Redis is available for integration tests
|
||||
fn is_redis_available() -> bool {
|
||||
match sal_redisclient::get_redis_client() {
|
||||
Ok(_) => true,
|
||||
Err(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rhai_redis_ping_integration() {
|
||||
if !is_redis_available() {
|
||||
println!("Skipping Redis integration test - Redis server not available");
|
||||
return;
|
||||
}
|
||||
|
||||
let engine = create_test_engine();
|
||||
|
||||
let script = r#"
|
||||
let result = redis_ping();
|
||||
result == "PONG"
|
||||
"#;
|
||||
|
||||
let result: Result<bool, Box<EvalAltResult>> = engine.eval(script);
|
||||
if result.is_ok() {
|
||||
assert_eq!(result.unwrap(), true);
|
||||
} else {
|
||||
println!("Redis ping test failed: {:?}", result.err());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rhai_redis_set_get_integration() {
|
||||
if !is_redis_available() {
|
||||
println!("Skipping Redis integration test - Redis server not available");
|
||||
return;
|
||||
}
|
||||
|
||||
let engine = create_test_engine();
|
||||
|
||||
let script = r#"
|
||||
// Set a test value
|
||||
redis_set("rhai_test_key", "rhai_test_value");
|
||||
|
||||
// Get the value back
|
||||
let value = redis_get("rhai_test_key");
|
||||
|
||||
// Clean up
|
||||
redis_del("rhai_test_key");
|
||||
|
||||
value == "rhai_test_value"
|
||||
"#;
|
||||
|
||||
let result: Result<bool, Box<EvalAltResult>> = engine.eval(script);
|
||||
if result.is_ok() {
|
||||
assert_eq!(result.unwrap(), true);
|
||||
} else {
|
||||
println!("Redis set/get test failed: {:?}", result.err());
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user