Files
wrkflw/tests/cleanup_test.rs
2025-04-30 16:14:28 +05:30

237 lines
7.2 KiB
Rust

use bollard::Docker;
use std::process::Command;
use std::time::Duration;
use uuid::Uuid;
use wrkflw::{
cleanup_on_exit,
executor::docker,
runtime::emulation::{self, EmulationRuntime},
};
// Skip the tests when running cargo test with --skip docker
fn should_skip_docker_tests() -> bool {
std::env::var("TEST_SKIP_DOCKER").is_ok() || !docker::is_available()
}
// Skip the tests when running cargo test with --skip processes
fn should_skip_process_tests() -> bool {
std::env::var("TEST_SKIP_PROCESSES").is_ok() || std::env::var("CI").is_ok()
}
#[tokio::test]
async fn test_docker_container_cleanup() {
// Skip test based on flags or environment
if should_skip_docker_tests() {
println!("Skipping Docker container cleanup test");
return;
}
// Skip if running in CI environment for Linux
if cfg!(target_os = "linux") && std::env::var("CI").is_ok() {
println!("Skipping Docker container cleanup test in Linux CI environment");
return;
}
// Connect to Docker
let docker = match Docker::connect_with_local_defaults() {
Ok(client) => client,
Err(_) => {
println!("Could not connect to Docker, skipping test");
return;
}
};
// Create a test container by manually tracking it
// In a real test, we would create an actual container, but we're just simulating that here
let container_id = format!("test-container-{}", Uuid::new_v4());
docker::track_container(&container_id);
// Run cleanup
let _ = docker::cleanup_containers(&docker).await;
// Since we can't directly check the tracking status,
// we'll use cleanup_on_exit and check for any errors
match cleanup_on_exit().await {
() => println!("Cleanup completed successfully"),
}
}
#[tokio::test]
async fn test_docker_network_cleanup() {
// Skip test based on flags or environment
if should_skip_docker_tests() {
println!("Skipping Docker network cleanup test");
return;
}
// Skip if running in CI environment for Linux
if cfg!(target_os = "linux") && std::env::var("CI").is_ok() {
println!("Skipping Docker network cleanup test in Linux CI environment");
return;
}
// Connect to Docker
let docker = match Docker::connect_with_local_defaults() {
Ok(client) => client,
Err(_) => {
println!("Could not connect to Docker, skipping test");
return;
}
};
// Create a test network
let network_id = match docker::create_job_network(&docker).await {
Ok(id) => id,
Err(_) => {
println!("Could not create test network, skipping test");
return;
}
};
// Run cleanup
match docker::cleanup_networks(&docker).await {
Ok(_) => println!("Network cleanup completed successfully"),
Err(e) => println!("Network cleanup error: {}", e),
}
// Attempt to remove the network again - this should fail if cleanup worked
match docker.remove_network(&network_id).await {
Ok(_) => println!("Network still exists, cleanup may not have worked"),
Err(_) => println!("Network was properly cleaned up"),
}
}
#[tokio::test]
async fn test_emulation_workspace_cleanup() {
// Create an emulation runtime instance
let _runtime = EmulationRuntime::new();
// Run cleanup
emulation::cleanup_resources().await;
// We can only verify that the cleanup operation doesn't crash
// since we can't access the private tracking collections
println!("Emulation workspace cleanup completed");
}
#[tokio::test]
#[ignore] // This test uses process manipulation which can be problematic
async fn test_emulation_process_cleanup() {
// Skip tests on CI or environments where spawning processes might be restricted
if should_skip_process_tests() {
println!("Skipping process cleanup test");
return;
}
// Create a process for testing
let process_id = if cfg!(unix) {
// Use sleep on Unix but DO NOT use & to background
// Instead run it directly and track the actual process
let child = Command::new("sleep")
.arg("10") // Shorter sleep time
.spawn();
match child {
Ok(child) => {
let pid = child.id();
// Track the process for cleanup
emulation::track_process(pid as u32);
pid as u32
}
Err(_) => {
println!("Could not create test process, skipping test");
return;
}
}
} else if cfg!(windows) {
// On Windows, use a different long-running command
let child = Command::new("timeout")
.args(&["/t", "10", "/nobreak"])
.spawn();
match child {
Ok(child) => {
let pid = child.id();
// Track the process for cleanup
emulation::track_process(pid as u32);
pid as u32
}
Err(_) => {
println!("Could not create test process, skipping test");
return;
}
}
} else {
println!("Unsupported platform, skipping test");
return;
};
// Run cleanup resources which includes process cleanup
emulation::cleanup_resources().await;
// On Unix, verify process is no longer running
if cfg!(unix) {
// Allow a short delay for process termination
tokio::time::sleep(Duration::from_millis(100)).await;
// Check if process exists
let process_exists = unsafe {
libc::kill(process_id as i32, 0) == 0
|| std::io::Error::last_os_error().raw_os_error() != Some(libc::ESRCH)
};
assert!(
!process_exists,
"Process should be terminated after cleanup"
);
}
}
#[tokio::test]
async fn test_cleanup_on_exit_function() {
// Skip if Docker is not available
if should_skip_docker_tests() {
println!("Docker not available, skipping test");
return;
}
// Connect to Docker
let docker = match Docker::connect_with_local_defaults() {
Ok(client) => client,
Err(_) => {
println!("Could not connect to Docker, skipping test");
return;
}
};
// Create some resources for cleanup
// Track a container
let container_id = format!("test-container-{}", Uuid::new_v4());
docker::track_container(&container_id);
// Create a network
let _ = match docker::create_job_network(&docker).await {
Ok(id) => id,
Err(_) => {
println!("Could not create test network, skipping test");
return;
}
};
// Create an emulation workspace
let _runtime = EmulationRuntime::new();
// Run cleanup function
match tokio::time::timeout(Duration::from_secs(15), cleanup_on_exit()).await {
Ok(_) => println!("Cleanup completed successfully"),
Err(_) => {
println!("Cleanup timed out after 15 seconds");
// Attempt manual cleanup
let _ = docker::cleanup_containers(&docker).await;
let _ = docker::cleanup_networks(&docker).await;
emulation::cleanup_resources().await;
}
}
}