use docker_wrapper::prerequisites::ensure_docker;
use docker_wrapper::{DockerCommand, PullCommand};
async fn ensure_docker_or_skip() {
match ensure_docker().await {
Ok(_) => {}
Err(_) => {
println!("Docker not available - skipping pull integration test");
}
}
}
async fn can_reach_registry() -> bool {
match tokio::process::Command::new("ping")
.args(["-c", "1", "registry-1.docker.io"])
.output()
.await
{
Ok(output) => output.status.success(),
Err(_) => false,
}
}
#[tokio::test]
async fn test_pull_prerequisites_validation() {
match ensure_docker().await {
Ok(info) => {
println!("Pull: Prerequisites OK - Docker {}", info.version.version);
assert!(!info.version.version.is_empty());
}
Err(e) => {
println!("Pull: Prerequisites failed (expected in some CI): {e}");
}
}
}
#[tokio::test]
async fn test_pull_command_builder() {
let pull_cmd = PullCommand::new("nginx:alpine")
.all_tags()
.platform("linux/amd64")
.quiet()
.disable_content_trust();
let args = pull_cmd.build_command_args();
assert!(args.contains(&"--all-tags".to_string()));
assert!(args.contains(&"--platform".to_string()));
assert!(args.contains(&"linux/amd64".to_string()));
assert!(args.contains(&"--quiet".to_string()));
assert!(args.contains(&"--disable-content-trust".to_string()));
assert!(args.contains(&"nginx:alpine".to_string()));
assert_eq!(args.last(), Some(&"nginx:alpine".to_string()));
assert_eq!(pull_cmd.get_image(), "nginx:alpine");
assert!(pull_cmd.is_all_tags());
assert!(pull_cmd.is_quiet());
assert!(pull_cmd.is_content_trust_disabled());
assert_eq!(pull_cmd.get_platform(), Some("linux/amd64"));
println!("Pull: Command builder validation passed");
}
#[tokio::test]
async fn test_pull_hello_world() {
ensure_docker_or_skip().await;
if !can_reach_registry().await {
println!("Pull: Cannot reach registry - skipping network test");
return;
}
let pull_cmd = PullCommand::new("hello-world:latest");
match pull_cmd.execute().await {
Ok(output) => {
println!("Pull: Hello-world test passed");
assert!(output.success);
if !output.stdout_is_empty() {
let stdout = output.stdout.to_lowercase();
assert!(
stdout.contains("pull")
|| stdout.contains("digest")
|| stdout.contains("status")
|| stdout.contains("already exists")
);
}
}
Err(e) => {
println!("Pull: Hello-world test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_pull_with_quiet_mode() {
ensure_docker_or_skip().await;
if !can_reach_registry().await {
println!("Pull: Cannot reach registry - skipping network test");
return;
}
let pull_cmd = PullCommand::new("hello-world:latest").quiet();
match pull_cmd.execute().await {
Ok(output) => {
println!("Pull: Quiet mode test passed");
assert!(output.success);
if !output.stdout_is_empty() {
let stdout = output.stdout.trim();
assert!(stdout.starts_with("sha256:") || stdout.is_empty());
}
}
Err(e) => {
println!("Pull: Quiet mode test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_pull_with_platform() {
ensure_docker_or_skip().await;
if !can_reach_registry().await {
println!("Pull: Cannot reach registry - skipping network test");
return;
}
let pull_cmd = PullCommand::new("alpine:latest").platform("linux/amd64");
match pull_cmd.execute().await {
Ok(output) => {
println!("Pull: Platform test passed");
assert!(output.success);
}
Err(e) => {
println!("Pull: Platform test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_pull_nonexistent_image() {
ensure_docker_or_skip().await;
if !can_reach_registry().await {
println!("Pull: Cannot reach registry - skipping network test");
return;
}
let pull_cmd = PullCommand::new("nonexistent/invalid-image:no-such-tag");
match pull_cmd.execute().await {
Ok(output) => {
println!("Pull: Nonexistent image unexpectedly succeeded");
assert!(!output.success);
}
Err(e) => {
println!("Pull: Nonexistent image correctly failed: {e}");
}
}
}
#[tokio::test]
async fn test_pull_with_registry_prefix() {
ensure_docker_or_skip().await;
if !can_reach_registry().await {
println!("Pull: Cannot reach registry - skipping network test");
return;
}
let pull_cmd = PullCommand::new("docker.io/library/hello-world:latest");
match pull_cmd.execute().await {
Ok(output) => {
println!("Pull: Registry prefix test passed");
assert!(output.success);
}
Err(e) => {
println!("Pull: Registry prefix test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_pull_with_digest() {
ensure_docker_or_skip().await;
if !can_reach_registry().await {
println!("Pull: Cannot reach registry - skipping network test");
return;
}
let pull_cmd = PullCommand::new(
"hello-world@sha256:266b191e926f65542fa8daaec01a192c4d292bff79426f47300a046e1bc576fd",
);
match pull_cmd.execute().await {
Ok(output) => {
println!("Pull: Digest test passed");
assert!(output.success);
}
Err(e) => {
println!("Pull: Digest test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_pull_disable_content_trust() {
ensure_docker_or_skip().await;
if !can_reach_registry().await {
println!("Pull: Cannot reach registry - skipping network test");
return;
}
let pull_cmd = PullCommand::new("hello-world:latest").disable_content_trust();
match pull_cmd.execute().await {
Ok(output) => {
println!("Pull: Disable content trust test passed");
assert!(output.success);
}
Err(e) => {
println!("Pull: Disable content trust test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_pull_all_tags_small_repo() {
ensure_docker_or_skip().await;
if !can_reach_registry().await {
println!("Pull: Cannot reach registry - skipping network test");
return;
}
let pull_cmd = PullCommand::new("hello-world").all_tags().quiet();
match pull_cmd.execute().await {
Ok(output) => {
println!("Pull: All tags test passed");
assert!(output.success);
}
Err(e) => {
println!("Pull: All tags test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_pull_command_validation() {
let test_cases = vec![
("nginx", vec!["pull", "nginx"]),
("nginx:latest", vec!["pull", "nginx:latest"]),
("nginx:alpine", vec!["pull", "nginx:alpine"]),
("redis:7.0", vec!["pull", "redis:7.0"]),
("postgres:15", vec!["pull", "postgres:15"]),
];
for (image, expected_args) in test_cases {
let pull_cmd = PullCommand::new(image);
let args = pull_cmd.build_command_args();
assert_eq!(args, expected_args);
assert_eq!(pull_cmd.get_image(), image);
}
println!("Pull: Command validation test passed");
}
#[tokio::test]
async fn test_pull_extensibility() {
let mut pull_cmd = PullCommand::new("nginx");
pull_cmd
.arg("--experimental-feature")
.arg("value")
.args(vec!["--custom", "option"]);
println!("Pull: Extensibility test passed");
}
#[tokio::test]
async fn test_pull_error_handling() {
ensure_docker_or_skip().await;
let pull_cmd = PullCommand::new("");
match pull_cmd.execute().await {
Ok(output) => {
println!("Pull: Empty image name unexpectedly succeeded");
assert!(!output.success);
}
Err(e) => {
println!("Pull: Empty image name correctly failed: {e}");
}
}
}
#[tokio::test]
async fn test_pull_multiple_options() {
ensure_docker_or_skip().await;
if !can_reach_registry().await {
println!("Pull: Cannot reach registry - skipping network test");
return;
}
let pull_cmd = PullCommand::new("hello-world:latest")
.quiet()
.disable_content_trust()
.platform("linux/amd64");
match pull_cmd.execute().await {
Ok(output) => {
println!("Pull: Multiple options test passed");
assert!(output.success);
}
Err(e) => {
println!("Pull: Multiple options test failed (may be expected): {e}");
}
}
}