use docker_wrapper::command::DockerCommand;
use docker_wrapper::{RestartCommand, RunCommand, StartCommand, StopCommand};
use std::time::Duration;
use tokio::time::sleep;
async fn create_test_container(name: &str) -> Result<String, Box<dyn std::error::Error>> {
let result = RunCommand::new("alpine:latest")
.name(name)
.detach()
.cmd(vec!["sleep".to_string(), "30".to_string()])
.execute()
.await?;
Ok(result.0)
}
async fn cleanup_container(name: &str) {
let _ = StopCommand::new(name).execute().await;
let _ = docker_wrapper::command::CommandExecutor::new()
.execute_command("rm", vec!["-f".to_string(), name.to_string()])
.await;
}
#[tokio::test]
async fn test_stop_command_basic() {
let container_name = "test-stop-basic";
let _container_id = match create_test_container(container_name).await {
Ok(id) => id,
Err(_) => {
eprintln!("Skipping test - Docker not available or container creation failed");
return;
}
};
sleep(Duration::from_millis(500)).await;
let result = StopCommand::new(container_name).execute().await;
match result {
Ok(stop_result) => {
assert!(stop_result.is_success());
assert_eq!(stop_result.container_count(), 1);
assert!(stop_result.contains_container(container_name));
}
Err(e) => {
eprintln!("Stop command failed: {e}");
}
}
cleanup_container(container_name).await;
}
#[tokio::test]
async fn test_stop_command_with_timeout() {
let container_name = "test-stop-timeout";
let _container_id = match create_test_container(container_name).await {
Ok(id) => id,
Err(_) => {
eprintln!("Skipping test - Docker not available");
return;
}
};
sleep(Duration::from_millis(500)).await;
let result = StopCommand::new(container_name).timeout(5).execute().await;
match result {
Ok(stop_result) => {
assert!(stop_result.is_success());
assert!(stop_result.contains_container(container_name));
}
Err(e) => {
eprintln!("Stop with timeout failed: {e}");
}
}
cleanup_container(container_name).await;
}
#[tokio::test]
async fn test_start_command_basic() {
let container_name = "test-start-basic";
let _container_id = match create_test_container(container_name).await {
Ok(id) => id,
Err(_) => {
eprintln!("Skipping test - Docker not available");
return;
}
};
sleep(Duration::from_millis(500)).await;
let _ = StopCommand::new(container_name).execute().await;
sleep(Duration::from_millis(500)).await;
let result = StartCommand::new(container_name).execute().await;
match result {
Ok(start_result) => {
assert!(start_result.is_success());
assert_eq!(start_result.container_count(), 1);
assert!(start_result.contains_container(container_name));
}
Err(e) => {
eprintln!("Start command failed: {e}");
}
}
cleanup_container(container_name).await;
}
#[tokio::test]
async fn test_restart_command_basic() {
let container_name = "test-restart-basic";
let _container_id = match create_test_container(container_name).await {
Ok(id) => id,
Err(_) => {
eprintln!("Skipping test - Docker not available");
return;
}
};
sleep(Duration::from_millis(500)).await;
let result = RestartCommand::new(container_name).execute().await;
match result {
Ok(restart_result) => {
assert!(restart_result.is_success());
assert_eq!(restart_result.container_count(), 1);
assert!(restart_result.contains_container(container_name));
}
Err(e) => {
eprintln!("Restart command failed: {e}");
}
}
cleanup_container(container_name).await;
}
#[tokio::test]
async fn test_container_lifecycle_full_workflow() {
let container_name = "test-lifecycle-full";
let _container_id = match create_test_container(container_name).await {
Ok(id) => id,
Err(_) => {
eprintln!("Skipping test - Docker not available");
return;
}
};
sleep(Duration::from_millis(500)).await;
let stop_result = StopCommand::new(container_name).execute().await;
if let Ok(result) = stop_result {
assert!(result.is_success());
}
sleep(Duration::from_millis(500)).await;
let start_result = StartCommand::new(container_name).execute().await;
if let Ok(result) = start_result {
assert!(result.is_success());
}
sleep(Duration::from_millis(500)).await;
let restart_result = RestartCommand::new(container_name).execute().await;
if let Ok(result) = restart_result {
assert!(result.is_success());
}
cleanup_container(container_name).await;
}
#[tokio::test]
async fn test_multiple_containers_stop() {
let container_names = vec!["test-multi-stop-1", "test-multi-stop-2"];
let mut created_containers = Vec::new();
for name in &container_names {
if let Ok(_id) = create_test_container(name).await {
created_containers.push(name);
}
}
if created_containers.is_empty() {
eprintln!("Skipping test - Could not create test containers");
return;
}
sleep(Duration::from_millis(500)).await;
let result = StopCommand::new_multiple(created_containers.iter().map(|s| s.to_string()))
.execute()
.await;
match result {
Ok(stop_result) => {
assert!(stop_result.is_success());
for container_name in &created_containers {
assert!(stop_result.contains_container(container_name));
}
}
Err(e) => {
eprintln!("Multiple container stop failed: {e}");
}
}
for name in &container_names {
cleanup_container(name).await;
}
}
#[tokio::test]
async fn test_command_args_generation() {
let stop_cmd = StopCommand::new("test-container")
.signal("SIGTERM")
.timeout(30);
let stop_args = stop_cmd.args();
assert_eq!(
stop_args,
vec![
"stop",
"--signal",
"SIGTERM",
"--timeout",
"30",
"test-container"
]
);
let start_cmd = StartCommand::new("test-container").attach().interactive();
let start_args = start_cmd.args();
assert_eq!(
start_args,
vec!["start", "--attach", "--interactive", "test-container"]
);
let restart_cmd = RestartCommand::new("test-container").timeout(15);
let restart_args = restart_cmd.args();
assert_eq!(
restart_args,
vec!["restart", "--timeout", "15", "test-container"]
);
}
#[tokio::test]
async fn test_command_args() {
let stop_cmd = StopCommand::new("test");
let stop_args = stop_cmd.build_command_args();
assert_eq!(stop_args[0], "stop");
let start_cmd = StartCommand::new("test");
let start_args = start_cmd.build_command_args();
assert_eq!(start_args[0], "start");
let restart_cmd = RestartCommand::new("test");
let restart_args = restart_cmd.build_command_args();
assert_eq!(restart_args[0], "restart");
}
#[tokio::test]
async fn test_result_helper_methods() {
let stop_result = docker_wrapper::StopResult {
stdout: "container1\ncontainer2\n".to_string(),
stderr: String::new(),
stopped_containers: vec!["container1".to_string(), "container2".to_string()],
};
assert!(stop_result.is_success());
assert_eq!(stop_result.container_count(), 2);
assert_eq!(
stop_result.first_container(),
Some(&"container1".to_string())
);
assert!(stop_result.contains_container("container1"));
assert!(stop_result.contains_container("container2"));
assert!(!stop_result.contains_container("container3"));
let start_result = docker_wrapper::StartResult {
stdout: "container1\n".to_string(),
stderr: String::new(),
started_containers: vec!["container1".to_string()],
};
assert!(start_result.is_success());
assert_eq!(start_result.container_count(), 1);
assert_eq!(
start_result.first_container(),
Some(&"container1".to_string())
);
assert!(start_result.contains_container("container1"));
let restart_result = docker_wrapper::RestartResult {
stdout: String::new(),
stderr: String::new(),
restarted_containers: vec!["container1".to_string()],
};
assert!(restart_result.is_success());
assert_eq!(restart_result.container_count(), 1);
assert!(restart_result.contains_container("container1"));
}
#[tokio::test]
async fn test_error_handling() {
let result = StopCommand::new("non-existent-container-12345")
.execute()
.await;
match result {
Ok(_) => {
println!("Stop non-existent container succeeded (Docker version dependent)");
}
Err(e) => {
println!("Stop non-existent container failed as expected: {e}");
}
}
let result = StartCommand::new("non-existent-container-12345")
.execute()
.await;
match result {
Ok(_) => {
println!("Start non-existent container succeeded (unexpected)");
}
Err(e) => {
println!("Start non-existent container failed as expected: {e}");
}
}
}