feat: Add CI/CD workflows for testing and publishing SAL crates
Some checks failed
Test Publishing Setup / Test Publishing Setup (pull_request) Has been cancelled
Some checks failed
Test Publishing Setup / Test Publishing Setup (pull_request) Has been cancelled
- Add a workflow for testing the publishing setup - Add a workflow for publishing SAL crates to crates.io - Improve crate metadata and version management - Add optional dependencies for modularity - Improve documentation for publishing and usage
This commit is contained in:
307
rhai_tests/kubernetes/04_error_handling.rhai
Normal file
307
rhai_tests/kubernetes/04_error_handling.rhai
Normal file
@@ -0,0 +1,307 @@
|
||||
#!/usr/bin/env rhai
|
||||
|
||||
// Test 4: Error Handling and Edge Cases
|
||||
// This test covers error scenarios and edge cases
|
||||
|
||||
// Helper function to generate timestamp for unique names
|
||||
fn timestamp() {
|
||||
let now = 1640995200; // Base timestamp
|
||||
let random = (now % 1000000).to_string();
|
||||
random
|
||||
}
|
||||
|
||||
print("=== Kubernetes Error Handling Test ===");
|
||||
print("");
|
||||
|
||||
// Test connection validation
|
||||
print("Test 1: Connection Validation");
|
||||
print("-----------------------------");
|
||||
|
||||
try {
|
||||
// This should work if cluster is available
|
||||
let km = kubernetes_manager_new("default");
|
||||
print("✅ Successfully connected to Kubernetes cluster");
|
||||
|
||||
// Test basic operation to verify connection
|
||||
let namespaces = km.namespaces_list();
|
||||
print("✅ Successfully retrieved " + namespaces.len() + " namespaces");
|
||||
|
||||
} catch (error) {
|
||||
print("❌ Kubernetes connection failed: " + error);
|
||||
print("");
|
||||
print("This test requires a running Kubernetes cluster.");
|
||||
print("Please ensure:");
|
||||
print(" - kubectl is configured");
|
||||
print(" - Cluster is accessible");
|
||||
print(" - Proper RBAC permissions are set");
|
||||
print("");
|
||||
throw "Kubernetes cluster not available";
|
||||
}
|
||||
|
||||
print("");
|
||||
|
||||
// Test invalid namespace handling
|
||||
print("Test 2: Invalid Namespace Handling");
|
||||
print("----------------------------------");
|
||||
|
||||
try {
|
||||
// Try to create manager for invalid namespace name
|
||||
let invalid_names = [
|
||||
"INVALID-UPPERCASE",
|
||||
"invalid_underscore",
|
||||
"invalid.dot",
|
||||
"invalid space",
|
||||
"invalid@symbol",
|
||||
"123-starts-with-number",
|
||||
"ends-with-dash-",
|
||||
"-starts-with-dash"
|
||||
];
|
||||
|
||||
for invalid_name in invalid_names {
|
||||
try {
|
||||
print("Testing invalid namespace: '" + invalid_name + "'");
|
||||
let km = kubernetes_manager_new(invalid_name);
|
||||
|
||||
// If we get here, the name was accepted (might be valid after all)
|
||||
print(" ⚠️ Name was accepted: " + invalid_name);
|
||||
|
||||
} catch (name_error) {
|
||||
print(" ✅ Properly rejected invalid name: " + invalid_name);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
print("❌ Invalid namespace test failed: " + error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
print("");
|
||||
|
||||
// Test resource not found errors
|
||||
print("Test 3: Resource Not Found Errors");
|
||||
print("---------------------------------");
|
||||
|
||||
try {
|
||||
let km = kubernetes_manager_new("default");
|
||||
|
||||
// Try to get a pod that doesn't exist
|
||||
let nonexistent_pod = "nonexistent-pod-" + timestamp();
|
||||
|
||||
try {
|
||||
let pod = km.get_pod(nonexistent_pod);
|
||||
print("❌ Expected error for nonexistent pod, but got result: " + pod.name);
|
||||
throw "Should have failed to get nonexistent pod";
|
||||
} catch (not_found_error) {
|
||||
print("✅ Properly handled nonexistent pod error: " + not_found_error);
|
||||
}
|
||||
|
||||
// Try to delete a pod that doesn't exist
|
||||
try {
|
||||
km.delete_pod(nonexistent_pod);
|
||||
print("✅ Delete nonexistent pod handled gracefully");
|
||||
} catch (delete_error) {
|
||||
print("✅ Delete nonexistent pod error handled: " + delete_error);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
print("❌ Resource not found test failed: " + error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
print("");
|
||||
|
||||
// Test invalid resource names
|
||||
print("Test 4: Invalid Resource Names");
|
||||
print("------------------------------");
|
||||
|
||||
try {
|
||||
let km = kubernetes_manager_new("default");
|
||||
|
||||
let invalid_resource_names = [
|
||||
"INVALID-UPPERCASE",
|
||||
"invalid_underscore",
|
||||
"invalid.multiple.dots",
|
||||
"invalid space",
|
||||
"invalid@symbol",
|
||||
"toolong" + "a".repeat(100), // Too long name
|
||||
"", // Empty name
|
||||
"-starts-with-dash",
|
||||
"ends-with-dash-"
|
||||
];
|
||||
|
||||
for invalid_name in invalid_resource_names {
|
||||
try {
|
||||
print("Testing invalid resource name: '" + invalid_name + "'");
|
||||
|
||||
let labels = #{ "test": "invalid-name" };
|
||||
km.create_pod(invalid_name, "nginx:alpine", labels);
|
||||
|
||||
print(" ⚠️ Invalid name was accepted: " + invalid_name);
|
||||
|
||||
// Clean up if it was created
|
||||
try {
|
||||
km.delete_pod(invalid_name);
|
||||
} catch (cleanup_error) {
|
||||
// Ignore cleanup errors
|
||||
}
|
||||
|
||||
} catch (name_error) {
|
||||
print(" ✅ Properly rejected invalid resource name: " + invalid_name);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
print("❌ Invalid resource names test failed: " + error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
print("");
|
||||
|
||||
// Test invalid patterns
|
||||
print("Test 5: Invalid PCRE Patterns");
|
||||
print("------------------------------");
|
||||
|
||||
try {
|
||||
let km = kubernetes_manager_new("default");
|
||||
|
||||
let invalid_patterns = [
|
||||
"[unclosed-bracket",
|
||||
"(?invalid-group",
|
||||
"*invalid-quantifier",
|
||||
"(?P<invalid-named-group>)",
|
||||
"\\invalid-escape"
|
||||
];
|
||||
|
||||
for invalid_pattern in invalid_patterns {
|
||||
try {
|
||||
print("Testing invalid pattern: '" + invalid_pattern + "'");
|
||||
km.delete(invalid_pattern);
|
||||
print(" ⚠️ Invalid pattern was accepted: " + invalid_pattern);
|
||||
|
||||
} catch (pattern_error) {
|
||||
print(" ✅ Properly rejected invalid pattern: " + invalid_pattern);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
print("❌ Invalid patterns test failed: " + error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
print("");
|
||||
|
||||
// Test permission errors (if applicable)
|
||||
print("Test 6: Permission Handling");
|
||||
print("---------------------------");
|
||||
|
||||
try {
|
||||
let km = kubernetes_manager_new("default");
|
||||
|
||||
// Try to create a namespace (might require cluster-admin)
|
||||
let test_ns = "sal-permission-test-" + timestamp();
|
||||
|
||||
try {
|
||||
km.create_namespace(test_ns);
|
||||
print("✅ Namespace creation successful (sufficient permissions)");
|
||||
|
||||
// Clean up
|
||||
try {
|
||||
km.delete_namespace(test_ns);
|
||||
print("✅ Namespace deletion successful");
|
||||
} catch (delete_error) {
|
||||
print("⚠️ Namespace deletion failed: " + delete_error);
|
||||
}
|
||||
|
||||
} catch (permission_error) {
|
||||
print("⚠️ Namespace creation failed (may be permission issue): " + permission_error);
|
||||
print(" This is expected if running with limited RBAC permissions");
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
print("❌ Permission handling test failed: " + error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
print("");
|
||||
|
||||
// Test empty operations
|
||||
print("Test 7: Empty Operations");
|
||||
print("------------------------");
|
||||
|
||||
try {
|
||||
// Create a temporary namespace for testing
|
||||
let test_namespace = "sal-empty-test-" + timestamp();
|
||||
let setup_km = kubernetes_manager_new("default");
|
||||
|
||||
try {
|
||||
setup_km.create_namespace(test_namespace);
|
||||
let km = kubernetes_manager_new(test_namespace);
|
||||
|
||||
// Test operations on empty namespace
|
||||
let empty_pods = km.pods_list();
|
||||
print("Empty namespace pod count: " + empty_pods.len());
|
||||
|
||||
if empty_pods.len() == 0 {
|
||||
print("✅ Empty namespace handled correctly");
|
||||
} else {
|
||||
print("⚠️ Expected empty namespace, found " + empty_pods.len() + " pods");
|
||||
}
|
||||
|
||||
// Test pattern deletion on empty namespace
|
||||
km.delete(".*");
|
||||
print("✅ Pattern deletion on empty namespace handled");
|
||||
|
||||
// Test resource counts on empty namespace
|
||||
let counts = km.resource_counts();
|
||||
print("✅ Resource counts on empty namespace: " + counts);
|
||||
|
||||
// Cleanup
|
||||
setup_km.delete_namespace(test_namespace);
|
||||
|
||||
} catch (empty_error) {
|
||||
print("❌ Empty operations test failed: " + empty_error);
|
||||
throw empty_error;
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
print("❌ Empty operations setup failed: " + error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
print("");
|
||||
|
||||
// Test concurrent operations (basic)
|
||||
print("Test 8: Basic Concurrent Operations");
|
||||
print("-----------------------------------");
|
||||
|
||||
try {
|
||||
let km = kubernetes_manager_new("default");
|
||||
|
||||
// Test multiple rapid operations
|
||||
print("Testing rapid successive operations...");
|
||||
|
||||
for i in range(0, 3) {
|
||||
let namespaces = km.namespaces_list();
|
||||
print(" Iteration " + i + ": " + namespaces.len() + " namespaces");
|
||||
}
|
||||
|
||||
print("✅ Rapid successive operations handled");
|
||||
|
||||
} catch (error) {
|
||||
print("❌ Concurrent operations test failed: " + error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
print("");
|
||||
print("=== Error Handling Test Complete ===");
|
||||
print("✅ All error handling tests completed");
|
||||
print("");
|
||||
print("Summary:");
|
||||
print("- Connection validation: ✅");
|
||||
print("- Invalid namespace handling: ✅");
|
||||
print("- Resource not found errors: ✅");
|
||||
print("- Invalid resource names: ✅");
|
||||
print("- Invalid PCRE patterns: ✅");
|
||||
print("- Permission handling: ✅");
|
||||
print("- Empty operations: ✅");
|
||||
print("- Basic concurrent operations: ✅");
|
Reference in New Issue
Block a user