sal/kubernetes/tests/edge_cases_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

294 lines
9.0 KiB
Rust

//! Edge case and error scenario tests for Kubernetes module
//!
//! These tests verify proper error handling and edge case behavior.
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_deployment_with_invalid_image() {
if !should_run_k8s_tests() {
println!("Skipping Kubernetes integration tests. Set KUBERNETES_TEST_ENABLED=1 to enable.");
return;
}
let km = match KubernetesManager::new("default").await {
Ok(km) => km,
Err(_) => return,
};
// Clean up any existing test deployment
let _ = km.deployment_delete("test-invalid-image").await;
// Try to create deployment with invalid image name
let result = km
.deployment_create(
"test-invalid-image",
"invalid/image/name/that/does/not/exist:latest",
1,
None,
None,
)
.await;
// The deployment creation should succeed (Kubernetes validates images at runtime)
assert!(result.is_ok(), "Deployment creation should succeed even with invalid image");
// Clean up
let _ = km.deployment_delete("test-invalid-image").await;
}
#[tokio::test]
async fn test_deployment_with_empty_name() {
if !should_run_k8s_tests() {
return;
}
let km = match KubernetesManager::new("default").await {
Ok(km) => km,
Err(_) => return,
};
// Try to create deployment with empty name
let result = km
.deployment_create("", "nginx:latest", 1, None, None)
.await;
// Should fail due to invalid name
assert!(result.is_err(), "Deployment with empty name should fail");
}
#[tokio::test]
async fn test_deployment_with_invalid_replicas() {
if !should_run_k8s_tests() {
return;
}
let km = match KubernetesManager::new("default").await {
Ok(km) => km,
Err(_) => return,
};
// Clean up any existing test deployment
let _ = km.deployment_delete("test-invalid-replicas").await;
// Try to create deployment with negative replicas
let result = km
.deployment_create("test-invalid-replicas", "nginx:latest", -1, None, None)
.await;
// Should fail due to invalid replica count
assert!(result.is_err(), "Deployment with negative replicas should fail");
}
#[tokio::test]
async fn test_deployment_with_large_env_vars() {
if !should_run_k8s_tests() {
return;
}
let km = match KubernetesManager::new("default").await {
Ok(km) => km,
Err(_) => return,
};
// Clean up any existing test deployment
let _ = km.deployment_delete("test-large-env").await;
// Create deployment with many environment variables
let mut env_vars = HashMap::new();
for i in 0..50 {
env_vars.insert(format!("TEST_VAR_{}", i), format!("value_{}", i));
}
let result = km
.deployment_create("test-large-env", "nginx:latest", 1, None, Some(env_vars))
.await;
assert!(result.is_ok(), "Deployment with many env vars should succeed: {:?}", result);
// Verify the deployment was created
let deployment = km.deployment_get("test-large-env").await;
assert!(deployment.is_ok(), "Should be able to get deployment with many env vars");
// Verify environment variables count
let deployment = deployment.unwrap();
if let Some(spec) = &deployment.spec {
if let Some(template) = &spec.template.spec {
if let Some(container) = template.containers.first() {
if let Some(env) = &container.env {
assert_eq!(env.len(), 50, "Should have 50 environment variables");
}
}
}
}
// Clean up
let _ = km.deployment_delete("test-large-env").await;
}
#[tokio::test]
async fn test_deployment_with_special_characters_in_env_vars() {
if !should_run_k8s_tests() {
return;
}
let km = match KubernetesManager::new("default").await {
Ok(km) => km,
Err(_) => return,
};
// Clean up any existing test deployment
let _ = km.deployment_delete("test-special-env").await;
// Create deployment with special characters in environment variables
let mut env_vars = HashMap::new();
env_vars.insert("DATABASE_URL".to_string(), "postgres://user:pass@host:5432/db?ssl=true".to_string());
env_vars.insert("JSON_CONFIG".to_string(), r#"{"key": "value", "number": 123}"#.to_string());
env_vars.insert("MULTILINE_VAR".to_string(), "line1\nline2\nline3".to_string());
env_vars.insert("SPECIAL_CHARS".to_string(), "!@#$%^&*()_+-=[]{}|;:,.<>?".to_string());
let result = km
.deployment_create("test-special-env", "nginx:latest", 1, None, Some(env_vars))
.await;
assert!(result.is_ok(), "Deployment with special chars in env vars should succeed: {:?}", result);
// Verify the deployment was created and env vars are preserved
let deployment = km.deployment_get("test-special-env").await;
assert!(deployment.is_ok(), "Should be able to get deployment");
let deployment = deployment.unwrap();
if let Some(spec) = &deployment.spec {
if let Some(template) = &spec.template.spec {
if let Some(container) = template.containers.first() {
if let Some(env) = &container.env {
let env_map: HashMap<String, String> = env
.iter()
.filter_map(|e| e.value.as_ref().map(|v| (e.name.clone(), v.clone())))
.collect();
assert_eq!(
env_map.get("DATABASE_URL"),
Some(&"postgres://user:pass@host:5432/db?ssl=true".to_string())
);
assert_eq!(
env_map.get("JSON_CONFIG"),
Some(&r#"{"key": "value", "number": 123}"#.to_string())
);
assert_eq!(
env_map.get("SPECIAL_CHARS"),
Some(&"!@#$%^&*()_+-=[]{}|;:,.<>?".to_string())
);
}
}
}
}
// Clean up
let _ = km.deployment_delete("test-special-env").await;
}
#[tokio::test]
async fn test_deploy_application_with_invalid_port() {
if !should_run_k8s_tests() {
return;
}
let km = match KubernetesManager::new("default").await {
Ok(km) => km,
Err(_) => return,
};
// Try to deploy application with invalid port (negative)
let result = km
.deploy_application("test-invalid-port", "nginx:latest", 1, -80, None, None)
.await;
// Should fail due to invalid port
assert!(result.is_err(), "Deploy application with negative port should fail");
// Try with port 0
let result = km
.deploy_application("test-zero-port", "nginx:latest", 1, 0, None, None)
.await;
// Should fail due to invalid port
assert!(result.is_err(), "Deploy application with port 0 should fail");
}
#[tokio::test]
async fn test_get_nonexistent_deployment() {
if !should_run_k8s_tests() {
return;
}
let km = match KubernetesManager::new("default").await {
Ok(km) => km,
Err(_) => return,
};
// Try to get a deployment that doesn't exist
let result = km.deployment_get("nonexistent-deployment-12345").await;
// Should fail with appropriate error
assert!(result.is_err(), "Getting nonexistent deployment should fail");
}
#[tokio::test]
async fn test_delete_nonexistent_deployment() {
if !should_run_k8s_tests() {
return;
}
let km = match KubernetesManager::new("default").await {
Ok(km) => km,
Err(_) => return,
};
// Try to delete a deployment that doesn't exist
let result = km.deployment_delete("nonexistent-deployment-12345").await;
// Should fail gracefully
assert!(result.is_err(), "Deleting nonexistent deployment should fail");
}
#[tokio::test]
async fn test_deployment_with_zero_replicas() {
if !should_run_k8s_tests() {
return;
}
let km = match KubernetesManager::new("default").await {
Ok(km) => km,
Err(_) => return,
};
// Clean up any existing test deployment
let _ = km.deployment_delete("test-zero-replicas").await;
// Create deployment with zero replicas (should be valid)
let result = km
.deployment_create("test-zero-replicas", "nginx:latest", 0, None, None)
.await;
assert!(result.is_ok(), "Deployment with zero replicas should succeed: {:?}", result);
// Verify the deployment was created with 0 replicas
let deployment = km.deployment_get("test-zero-replicas").await;
assert!(deployment.is_ok(), "Should be able to get deployment with zero replicas");
let deployment = deployment.unwrap();
if let Some(spec) = &deployment.spec {
assert_eq!(spec.replicas, Some(0), "Should have 0 replicas");
}
// Clean up
let _ = km.deployment_delete("test-zero-replicas").await;
}