...
This commit is contained in:
405
packages/system/kubernetes/tests/rhai_tests.rs
Normal file
405
packages/system/kubernetes/tests/rhai_tests.rs
Normal file
@@ -0,0 +1,405 @@
|
||||
//! Rhai integration tests for SAL Kubernetes
|
||||
//!
|
||||
//! These tests verify that the Rhai wrappers work correctly and can execute
|
||||
//! the Rhai test scripts in the tests/rhai/ directory.
|
||||
|
||||
#[cfg(feature = "rhai")]
|
||||
mod rhai_tests {
|
||||
use rhai::Engine;
|
||||
use sal_kubernetes::rhai::*;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
/// Check if Kubernetes integration tests should run
|
||||
fn should_run_k8s_tests() -> bool {
|
||||
std::env::var("KUBERNETES_TEST_ENABLED").unwrap_or_default() == "1"
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_register_kubernetes_module() {
|
||||
let mut engine = Engine::new();
|
||||
let result = register_kubernetes_module(&mut engine);
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"Failed to register Kubernetes module: {:?}",
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_kubernetes_functions_registered() {
|
||||
let mut engine = Engine::new();
|
||||
register_kubernetes_module(&mut engine).unwrap();
|
||||
|
||||
// Test that the constructor function is registered
|
||||
let script = r#"
|
||||
let result = "";
|
||||
try {
|
||||
let km = kubernetes_manager_new("test");
|
||||
result = "constructor_exists";
|
||||
} catch(e) {
|
||||
result = "constructor_exists_but_failed";
|
||||
}
|
||||
result
|
||||
"#;
|
||||
|
||||
let result = engine.eval::<String>(script);
|
||||
assert!(result.is_ok());
|
||||
let result_value = result.unwrap();
|
||||
assert!(
|
||||
result_value == "constructor_exists" || result_value == "constructor_exists_but_failed",
|
||||
"Expected constructor to be registered, got: {}",
|
||||
result_value
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_new_rhai_functions_registered() {
|
||||
let mut engine = Engine::new();
|
||||
register_kubernetes_module(&mut engine).unwrap();
|
||||
|
||||
// Test that the newly added functions are registered
|
||||
let new_functions_to_test = [
|
||||
"configmaps_list",
|
||||
"secrets_list",
|
||||
"configmap_delete",
|
||||
"secret_delete",
|
||||
"namespace_delete",
|
||||
];
|
||||
|
||||
for func_name in &new_functions_to_test {
|
||||
// Try to compile a script that references the function
|
||||
let script = format!("fn test() {{ {}; }}", func_name);
|
||||
let result = engine.compile(&script);
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"New function '{}' should be registered but compilation failed: {:?}",
|
||||
func_name,
|
||||
result
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rhai_function_signatures() {
|
||||
if !should_run_k8s_tests() {
|
||||
println!(
|
||||
"Skipping Rhai function signature tests. Set KUBERNETES_TEST_ENABLED=1 to enable."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let mut engine = Engine::new();
|
||||
register_kubernetes_module(&mut engine).unwrap();
|
||||
|
||||
// Test that the new object-oriented API methods work correctly
|
||||
// These will fail without a cluster, but should not fail due to missing methods
|
||||
let test_scripts = vec![
|
||||
// List methods (still function-based for listing)
|
||||
("pods_list", "let km = kubernetes_manager_new(\"test\"); km.pods_list();"),
|
||||
("services_list", "let km = kubernetes_manager_new(\"test\"); km.services_list();"),
|
||||
("deployments_list", "let km = kubernetes_manager_new(\"test\"); km.deployments_list();"),
|
||||
("namespaces_list", "let km = kubernetes_manager_new(\"test\"); km.namespaces_list();"),
|
||||
("resource_counts", "let km = kubernetes_manager_new(\"test\"); km.resource_counts();"),
|
||||
|
||||
// Create methods (object-oriented)
|
||||
("create_namespace", "let km = kubernetes_manager_new(\"test\"); km.create_namespace(\"test-ns\");"),
|
||||
("create_pod", "let km = kubernetes_manager_new(\"test\"); km.create_pod(\"test-pod\", \"nginx\", #{});"),
|
||||
("create_service", "let km = kubernetes_manager_new(\"test\"); km.create_service(\"test-svc\", #{}, 80, 80);"),
|
||||
|
||||
// Get methods (object-oriented)
|
||||
("get_pod", "let km = kubernetes_manager_new(\"test\"); km.get_pod(\"test-pod\");"),
|
||||
("get_service", "let km = kubernetes_manager_new(\"test\"); km.get_service(\"test-svc\");"),
|
||||
|
||||
// Delete methods (object-oriented)
|
||||
("delete_pod", "let km = kubernetes_manager_new(\"test\"); km.delete_pod(\"test-pod\");"),
|
||||
("delete_service", "let km = kubernetes_manager_new(\"test\"); km.delete_service(\"test-service\");"),
|
||||
("delete_deployment", "let km = kubernetes_manager_new(\"test\"); km.delete_deployment(\"test-deployment\");"),
|
||||
("delete_namespace", "let km = kubernetes_manager_new(\"test\"); km.delete_namespace(\"test-ns\");"),
|
||||
|
||||
// Utility methods
|
||||
("namespace_exists", "let km = kubernetes_manager_new(\"test\"); km.namespace_exists(\"test-ns\");"),
|
||||
("namespace", "let km = kubernetes_manager_new(\"test\"); namespace(km);"),
|
||||
("delete_pattern", "let km = kubernetes_manager_new(\"test\"); km.delete(\"test-.*\");"),
|
||||
];
|
||||
|
||||
for (function_name, script) in test_scripts {
|
||||
println!("Testing function: {}", function_name);
|
||||
let result = engine.eval::<rhai::Dynamic>(script);
|
||||
|
||||
// The function should be registered (not get a "function not found" error)
|
||||
// It may fail due to no Kubernetes cluster, but that's expected
|
||||
match result {
|
||||
Ok(_) => {
|
||||
println!("Function {} executed successfully", function_name);
|
||||
}
|
||||
Err(e) => {
|
||||
let error_msg = e.to_string();
|
||||
// Should not be a "function not found" error
|
||||
assert!(
|
||||
!error_msg.contains("Function not found")
|
||||
&& !error_msg.contains("Unknown function"),
|
||||
"Function {} not registered: {}",
|
||||
function_name,
|
||||
error_msg
|
||||
);
|
||||
println!(
|
||||
"Function {} failed as expected (no cluster): {}",
|
||||
function_name, error_msg
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rhai_with_real_cluster() {
|
||||
if !should_run_k8s_tests() {
|
||||
println!("Skipping Rhai Kubernetes integration tests. Set KUBERNETES_TEST_ENABLED=1 to enable.");
|
||||
return;
|
||||
}
|
||||
|
||||
let mut engine = Engine::new();
|
||||
register_kubernetes_module(&mut engine).unwrap();
|
||||
|
||||
// Test basic functionality with a real cluster
|
||||
let script = r#"
|
||||
let km = kubernetes_manager_new("default");
|
||||
let ns = namespace(km);
|
||||
ns
|
||||
"#;
|
||||
|
||||
let result = engine.eval::<String>(script);
|
||||
match result {
|
||||
Ok(namespace) => {
|
||||
assert_eq!(namespace, "default");
|
||||
println!("Successfully got namespace from Rhai: {}", namespace);
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to execute Rhai script with real cluster: {}", e);
|
||||
// Don't fail the test if we can't connect to cluster
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rhai_pods_list() {
|
||||
if !should_run_k8s_tests() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut engine = Engine::new();
|
||||
register_kubernetes_module(&mut engine).unwrap();
|
||||
|
||||
let script = r#"
|
||||
let km = kubernetes_manager_new("default");
|
||||
let pods = pods_list(km);
|
||||
pods.len()
|
||||
"#;
|
||||
|
||||
let result = engine.eval::<i64>(script);
|
||||
match result {
|
||||
Ok(count) => {
|
||||
assert!(count >= 0);
|
||||
println!("Successfully listed {} pods from Rhai", count);
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to list pods from Rhai: {}", e);
|
||||
// Don't fail the test if we can't connect to cluster
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rhai_resource_counts() {
|
||||
if !should_run_k8s_tests() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut engine = Engine::new();
|
||||
register_kubernetes_module(&mut engine).unwrap();
|
||||
|
||||
let script = r#"
|
||||
let km = kubernetes_manager_new("default");
|
||||
let counts = resource_counts(km);
|
||||
counts
|
||||
"#;
|
||||
|
||||
let result = engine.eval::<rhai::Map>(script);
|
||||
match result {
|
||||
Ok(counts) => {
|
||||
println!("Successfully got resource counts from Rhai: {:?}", counts);
|
||||
|
||||
// Verify expected keys are present
|
||||
assert!(counts.contains_key("pods"));
|
||||
assert!(counts.contains_key("services"));
|
||||
assert!(counts.contains_key("deployments"));
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to get resource counts from Rhai: {}", e);
|
||||
// Don't fail the test if we can't connect to cluster
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rhai_namespace_operations() {
|
||||
if !should_run_k8s_tests() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut engine = Engine::new();
|
||||
register_kubernetes_module(&mut engine).unwrap();
|
||||
|
||||
// Test namespace existence check
|
||||
let script = r#"
|
||||
let km = kubernetes_manager_new("default");
|
||||
let exists = namespace_exists(km, "default");
|
||||
exists
|
||||
"#;
|
||||
|
||||
let result = engine.eval::<bool>(script);
|
||||
match result {
|
||||
Ok(exists) => {
|
||||
assert!(exists, "Default namespace should exist");
|
||||
println!(
|
||||
"Successfully checked namespace existence from Rhai: {}",
|
||||
exists
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
println!("Failed to check namespace existence from Rhai: {}", e);
|
||||
// Don't fail the test if we can't connect to cluster
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rhai_error_handling() {
|
||||
if !should_run_k8s_tests() {
|
||||
println!(
|
||||
"Skipping Rhai error handling tests. Set KUBERNETES_TEST_ENABLED=1 to enable."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let mut engine = Engine::new();
|
||||
register_kubernetes_module(&mut engine).unwrap();
|
||||
|
||||
// Test that errors are properly converted to Rhai errors
|
||||
// Use a namespace that will definitely cause an error when trying to list pods
|
||||
let script = r#"
|
||||
let km = kubernetes_manager_new("nonexistent-namespace-12345");
|
||||
pods_list(km)
|
||||
"#;
|
||||
|
||||
let result = engine.eval::<rhai::Array>(script);
|
||||
|
||||
// The test might succeed if no cluster is available, which is fine
|
||||
match result {
|
||||
Ok(_) => {
|
||||
println!("No error occurred - possibly no cluster available, which is acceptable");
|
||||
}
|
||||
Err(e) => {
|
||||
let error_msg = e.to_string();
|
||||
println!("Got expected error: {}", error_msg);
|
||||
assert!(
|
||||
error_msg.contains("Kubernetes error")
|
||||
|| error_msg.contains("error")
|
||||
|| error_msg.contains("not found")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rhai_script_files_exist() {
|
||||
// Test that our Rhai test files exist and are readable
|
||||
let test_files = [
|
||||
"tests/rhai/basic_kubernetes.rhai",
|
||||
"tests/rhai/namespace_operations.rhai",
|
||||
"tests/rhai/resource_management.rhai",
|
||||
"tests/rhai/run_all_tests.rhai",
|
||||
];
|
||||
|
||||
for test_file in test_files {
|
||||
let path = Path::new(test_file);
|
||||
assert!(path.exists(), "Rhai test file should exist: {}", test_file);
|
||||
|
||||
// Try to read the file to ensure it's valid
|
||||
let content = fs::read_to_string(path)
|
||||
.unwrap_or_else(|e| panic!("Failed to read {}: {}", test_file, e));
|
||||
|
||||
assert!(
|
||||
!content.is_empty(),
|
||||
"Rhai test file should not be empty: {}",
|
||||
test_file
|
||||
);
|
||||
assert!(
|
||||
content.contains("print("),
|
||||
"Rhai test file should contain print statements: {}",
|
||||
test_file
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_basic_rhai_script_syntax() {
|
||||
// Test that we can at least parse our basic Rhai script
|
||||
let mut engine = Engine::new();
|
||||
register_kubernetes_module(&mut engine).unwrap();
|
||||
|
||||
// Simple script that should parse without errors
|
||||
let script = r#"
|
||||
print("Testing Kubernetes Rhai integration");
|
||||
let functions = ["kubernetes_manager_new", "pods_list", "namespace"];
|
||||
for func in functions {
|
||||
print("Function: " + func);
|
||||
}
|
||||
print("Basic syntax test completed");
|
||||
"#;
|
||||
|
||||
let result = engine.eval::<()>(script);
|
||||
assert!(
|
||||
result.is_ok(),
|
||||
"Basic Rhai script should parse and execute: {:?}",
|
||||
result
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rhai_script_execution_with_cluster() {
|
||||
if !should_run_k8s_tests() {
|
||||
println!(
|
||||
"Skipping Rhai script execution test. Set KUBERNETES_TEST_ENABLED=1 to enable."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
let mut engine = Engine::new();
|
||||
register_kubernetes_module(&mut engine).unwrap();
|
||||
|
||||
// Try to execute a simple script that creates a manager
|
||||
let script = r#"
|
||||
let km = kubernetes_manager_new("default");
|
||||
let ns = namespace(km);
|
||||
print("Created manager for namespace: " + ns);
|
||||
ns
|
||||
"#;
|
||||
|
||||
let result = engine.eval::<String>(script);
|
||||
match result {
|
||||
Ok(namespace) => {
|
||||
assert_eq!(namespace, "default");
|
||||
println!("Successfully executed Rhai script with cluster");
|
||||
}
|
||||
Err(e) => {
|
||||
println!(
|
||||
"Rhai script execution failed (expected if no cluster): {}",
|
||||
e
|
||||
);
|
||||
// Don't fail the test if we can't connect to cluster
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user