mirror of
https://github.com/bahdotsh/wrkflw.git
synced 2025-12-18 12:47:44 +01:00
237 lines
7.2 KiB
Rust
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;
|
|
}
|
|
}
|
|
}
|