sal/kubernetes/tests/crud_operations_test.rs
Mahmoud-Emad 6b12001ca2 feat: Add Kubernetes examples and update dependencies
- Add Kubernetes examples demonstrating deployment of various
  applications (PostgreSQL, Redis, generic). This improves the
  documentation and provides practical usage examples.
- Add `tokio` dependency for async examples. This enables the use
  of asynchronous operations in the examples.
- Add `once_cell` dependency for improved resource management in
  Kubernetes module. This allows efficient management of
  singletons and other resources.
2025-07-10 00:40:11 +03:00

254 lines
8.3 KiB
Rust

//! CRUD operations tests for SAL Kubernetes
//!
//! These tests verify that all Create, Read, Update, Delete operations work correctly.
#[cfg(test)]
mod crud_tests {
use sal_kubernetes::KubernetesManager;
use std::collections::HashMap;
/// Check if Kubernetes integration tests should run
fn should_run_k8s_tests() -> bool {
std::env::var("KUBERNETES_TEST_ENABLED").unwrap_or_default() == "1"
}
#[tokio::test]
async fn test_complete_crud_operations() {
if !should_run_k8s_tests() {
println!("Skipping CRUD test. Set KUBERNETES_TEST_ENABLED=1 to enable.");
return;
}
println!("🔍 Testing complete CRUD operations...");
// Create a test namespace for our operations
let test_namespace = "sal-crud-test";
let km = KubernetesManager::new("default")
.await
.expect("Should connect to cluster");
// Clean up any existing test namespace
let _ = km.namespace_delete(test_namespace).await;
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
// CREATE operations
println!("\n=== CREATE Operations ===");
// 1. Create namespace
km.namespace_create(test_namespace)
.await
.expect("Should create test namespace");
println!("✅ Created namespace: {}", test_namespace);
// Switch to test namespace
let test_km = KubernetesManager::new(test_namespace)
.await
.expect("Should connect to test namespace");
// 2. Create ConfigMap
let mut config_data = HashMap::new();
config_data.insert(
"app.properties".to_string(),
"debug=true\nport=8080".to_string(),
);
config_data.insert(
"config.yaml".to_string(),
"key: value\nenv: test".to_string(),
);
let configmap = test_km
.configmap_create("test-config", config_data)
.await
.expect("Should create ConfigMap");
println!(
"✅ Created ConfigMap: {}",
configmap.metadata.name.unwrap_or_default()
);
// 3. Create Secret
let mut secret_data = HashMap::new();
secret_data.insert("username".to_string(), "testuser".to_string());
secret_data.insert("password".to_string(), "secret123".to_string());
let secret = test_km
.secret_create("test-secret", secret_data, None)
.await
.expect("Should create Secret");
println!(
"✅ Created Secret: {}",
secret.metadata.name.unwrap_or_default()
);
// 4. Create Pod
let mut pod_labels = HashMap::new();
pod_labels.insert("app".to_string(), "test-app".to_string());
pod_labels.insert("version".to_string(), "v1".to_string());
let pod = test_km
.pod_create("test-pod", "nginx:alpine", Some(pod_labels.clone()), None)
.await
.expect("Should create Pod");
println!("✅ Created Pod: {}", pod.metadata.name.unwrap_or_default());
// 5. Create Service
let service = test_km
.service_create("test-service", pod_labels.clone(), 80, Some(80))
.await
.expect("Should create Service");
println!(
"✅ Created Service: {}",
service.metadata.name.unwrap_or_default()
);
// 6. Create Deployment
let deployment = test_km
.deployment_create("test-deployment", "nginx:alpine", 2, Some(pod_labels), None)
.await
.expect("Should create Deployment");
println!(
"✅ Created Deployment: {}",
deployment.metadata.name.unwrap_or_default()
);
// READ operations
println!("\n=== READ Operations ===");
// List all resources
let pods = test_km.pods_list().await.expect("Should list pods");
println!("✅ Listed {} pods", pods.len());
let services = test_km.services_list().await.expect("Should list services");
println!("✅ Listed {} services", services.len());
let deployments = test_km
.deployments_list()
.await
.expect("Should list deployments");
println!("✅ Listed {} deployments", deployments.len());
let configmaps = test_km
.configmaps_list()
.await
.expect("Should list configmaps");
println!("✅ Listed {} configmaps", configmaps.len());
let secrets = test_km.secrets_list().await.expect("Should list secrets");
println!("✅ Listed {} secrets", secrets.len());
// Get specific resources
let pod = test_km.pod_get("test-pod").await.expect("Should get pod");
println!(
"✅ Retrieved pod: {}",
pod.metadata.name.unwrap_or_default()
);
let service = test_km
.service_get("test-service")
.await
.expect("Should get service");
println!(
"✅ Retrieved service: {}",
service.metadata.name.unwrap_or_default()
);
let deployment = test_km
.deployment_get("test-deployment")
.await
.expect("Should get deployment");
println!(
"✅ Retrieved deployment: {}",
deployment.metadata.name.unwrap_or_default()
);
// Resource counts
let counts = test_km
.resource_counts()
.await
.expect("Should get resource counts");
println!("✅ Resource counts: {:?}", counts);
// DELETE operations
println!("\n=== DELETE Operations ===");
// Delete individual resources
test_km
.pod_delete("test-pod")
.await
.expect("Should delete pod");
println!("✅ Deleted pod");
test_km
.service_delete("test-service")
.await
.expect("Should delete service");
println!("✅ Deleted service");
test_km
.deployment_delete("test-deployment")
.await
.expect("Should delete deployment");
println!("✅ Deleted deployment");
test_km
.configmap_delete("test-config")
.await
.expect("Should delete configmap");
println!("✅ Deleted configmap");
test_km
.secret_delete("test-secret")
.await
.expect("Should delete secret");
println!("✅ Deleted secret");
// Verify resources are deleted
let final_counts = test_km
.resource_counts()
.await
.expect("Should get final resource counts");
println!("✅ Final resource counts: {:?}", final_counts);
// Delete the test namespace
km.namespace_delete(test_namespace)
.await
.expect("Should delete test namespace");
println!("✅ Deleted test namespace");
println!("\n🎉 All CRUD operations completed successfully!");
}
#[tokio::test]
async fn test_error_handling_in_crud() {
if !should_run_k8s_tests() {
println!("Skipping CRUD error handling test. Set KUBERNETES_TEST_ENABLED=1 to enable.");
return;
}
println!("🔍 Testing error handling in CRUD operations...");
let km = KubernetesManager::new("default")
.await
.expect("Should connect to cluster");
// Test creating resources with invalid names
let result = km.pod_create("", "nginx", None, None).await;
assert!(result.is_err(), "Should fail with empty pod name");
println!("✅ Empty pod name properly rejected");
// Test getting non-existent resources
let result = km.pod_get("non-existent-pod").await;
assert!(result.is_err(), "Should fail to get non-existent pod");
println!("✅ Non-existent pod properly handled");
// Test deleting non-existent resources
let result = km.service_delete("non-existent-service").await;
assert!(
result.is_err(),
"Should fail to delete non-existent service"
);
println!("✅ Non-existent service deletion properly handled");
println!("✅ Error handling in CRUD operations is robust");
}
}