From df8f818b29d28b0725e169c378afea4f02513e08 Mon Sep 17 00:00:00 2001 From: Oleks V Date: Mon, 23 Feb 2026 08:09:01 -0800 Subject: [PATCH] chore: Avoid build fails on MinIO rate limits (#20472) ## Which issue does this PR close? - Closes #. ## Rationale for this change Sometimes CI failed because of docker rates limits. ``` thread 'test_s3_url_fallback' (11052) panicked at datafusion-cli/tests/cli_integration.rs:116:13: Failed to start MinIO container. Ensure Docker is running and accessible: failed to pull the image 'minio/minio:RELEASE.2025-02-28T09-55-16Z', error: Docker responded with status code 500: toomanyrequests: You have reached your unauthenticated pull rate limit. https://www.docker.com/increase-rate-limit stack backtrace: ``` Example https://github.com/apache/datafusion/actions/runs/22262073722/job/64401977127 ## What changes are included in this PR? Ignore the tests if rates limit hit only ## Are these changes tested? ## Are there any user-facing changes? --- datafusion-cli/tests/cli_integration.rs | 57 +++++++++++++++++-------- 1 file changed, 40 insertions(+), 17 deletions(-) diff --git a/datafusion-cli/tests/cli_integration.rs b/datafusion-cli/tests/cli_integration.rs index 8b8b786d6..99fc2d527 100644 --- a/datafusion-cli/tests/cli_integration.rs +++ b/datafusion-cli/tests/cli_integration.rs @@ -44,7 +44,7 @@ fn make_settings() -> Settings { settings } -async fn setup_minio_container() -> ContainerAsync { +async fn setup_minio_container() -> Result, String> { const MINIO_ROOT_USER: &str = "TEST-DataFusionLogin"; const MINIO_ROOT_PASSWORD: &str = "TEST-DataFusionPassword"; @@ -99,27 +99,23 @@ async fn setup_minio_container() -> ContainerAsync { let stdout = container.stdout_to_vec().await.unwrap_or_default(); let stderr = container.stderr_to_vec().await.unwrap_or_default(); - panic!( + return Err(format!( "Failed to execute command: {}\nError: {}\nStdout: {:?}\nStderr: {:?}", cmd_ref, e, String::from_utf8_lossy(&stdout), String::from_utf8_lossy(&stderr) - ); + )); } } - container + Ok(container) } - Err(TestcontainersError::Client(e)) => { - panic!( - "Failed to start MinIO container. Ensure Docker is running and accessible: {e}" - ); - } - Err(e) => { - panic!("Failed to start MinIO container: {e}"); - } + Err(TestcontainersError::Client(e)) => Err(format!( + "Failed to start MinIO container. Ensure Docker is running and accessible: {e}" + )), + Err(e) => Err(format!("Failed to start MinIO container: {e}")), } } @@ -253,7 +249,14 @@ async fn test_cli() { return; } - let container = setup_minio_container().await; + let container = match setup_minio_container().await { + Ok(c) => c, + Err(e) if e.contains("toomanyrequests") => { + eprintln!("Skipping test: Docker pull rate limit reached: {e}"); + return; + } + e @ Err(_) => e.unwrap(), + }; let settings = make_settings(); let _bound = settings.bind_to_scope(); @@ -286,7 +289,14 @@ async fn test_aws_options() { let settings = make_settings(); let _bound = settings.bind_to_scope(); - let container = setup_minio_container().await; + let container = match setup_minio_container().await { + Ok(c) => c, + Err(e) if e.contains("toomanyrequests") => { + eprintln!("Skipping test: Docker pull rate limit reached: {e}"); + return; + } + e @ Err(_) => e.unwrap(), + }; let port = container.get_host_port_ipv4(9000).await.unwrap(); let input = format!( @@ -377,7 +387,14 @@ async fn test_s3_url_fallback() { return; } - let container = setup_minio_container().await; + let container = match setup_minio_container().await { + Ok(c) => c, + Err(e) if e.contains("toomanyrequests") => { + eprintln!("Skipping test: Docker pull rate limit reached: {e}"); + return; + } + e @ Err(_) => e.unwrap(), + }; let mut settings = make_settings(); settings.set_snapshot_suffix("s3_url_fallback"); @@ -407,8 +424,14 @@ async fn test_object_store_profiling() { return; } - let container = setup_minio_container().await; - + let container = match setup_minio_container().await { + Ok(c) => c, + Err(e) if e.contains("toomanyrequests") => { + eprintln!("Skipping test: Docker pull rate limit reached: {e}"); + return; + } + e @ Err(_) => e.unwrap(), + }; let mut settings = make_settings(); // as the object store profiling contains timestamps and durations, we must