From 5bb9ffffcd9efb52316538530cbe5e683994cb79 Mon Sep 17 00:00:00 2001 From: Zhengchao An Date: Sun, 23 Aug 2026 20:18:41 +0800 Subject: [PATCH] test(e2e): enforce external client prerequisites (#6402) --- .config/nextest.toml | 4 +- .github/workflows/ci.yml | 27 ++++++++++ .github/workflows/e2e-replication-nightly.yml | 8 +-- crates/e2e_test/README.md | 16 +++--- .../e2e_test/src/bucket_policy_check_test.rs | 4 -- crates/e2e_test/src/common.rs | 35 ++++++++++--- .../src/existing_object_tag_policy_test.rs | 24 +-------- crates/e2e_test/src/kms/common.rs | 17 +------ crates/e2e_test/src/kms/kms_local_test.rs | 6 +-- crates/e2e_test/src/kms/kms_vault_test.rs | 19 +------ .../src/mc_mirror_small_bucket_test.rs | 12 +---- crates/e2e_test/src/multipart_auth_test.rs | 4 -- crates/e2e_test/src/quota_test.rs | 51 ------------------- .../src/replication_extension_test.rs | 10 +--- crates/e2e_test/src/security_boundary_test.rs | 13 ++--- 15 files changed, 78 insertions(+), 172 deletions(-) diff --git a/.config/nextest.toml b/.config/nextest.toml index edf5b5df7..841368bef 100644 --- a/.config/nextest.toml +++ b/.config/nextest.toml @@ -335,8 +335,8 @@ slow-timeout = { period = "60s", terminate-after = 2, grace-period = "10s" } # # Wired by .github/workflows/e2e-replication-nightly.yml (schedule + # workflow_dispatch), which builds the rustfs binary once, installs awscurl so -# the STS dual-node test actually exercises its path (it skips gracefully with -# a visible log line when awscurl is absent), and routes scheduled failures +# the STS dual-node test actually exercises its path (the test fails when +# awscurl is absent), and routes scheduled failures # through .github/actions/schedule-failure-issue (ci-8). Explicit division of # labor with e2e-full: these tests run only in the consolidated nightly # workflow, not in the merge/main lane. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ae74ec40a..a45cbe65c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -681,6 +681,19 @@ jobs: cache-save-if: 'false' install-build-packaging-tools: 'false' + - name: Set up Python + uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 + with: + python-version: "3.12" + + - name: Install awscurl + run: | + python3 -m pip install --user --upgrade pip "awscurl==0.44" + echo "AWSCURL_PATH=$HOME/.local/bin/awscurl" >> "$GITHUB_ENV" + + - name: Verify awscurl + run: test -x "$AWSCURL_PATH" + # Download after the cache restore so the freshly built binary from the # build job always wins over anything restored into target/debug. - name: Download debug binary @@ -803,6 +816,20 @@ jobs: - name: Verify awscurl run: test -x "$AWSCURL_PATH" + - name: Install mc + env: + MC_VERSION: RELEASE.2025-08-13T08-35-41Z + MC_SHA256: 01f866e9c5f9b87c2b09116fa5d7c06695b106242d829a8bb32990c00312e891 + run: | + MC_BINARY="mc.linux-amd64.${MC_VERSION}" + curl -fsSLo "$RUNNER_TEMP/mc" "https://github.com/minio/mc/releases/download/${MC_VERSION}/${MC_BINARY}" + echo "${MC_SHA256} $RUNNER_TEMP/mc" | sha256sum --check --status + chmod +x "$RUNNER_TEMP/mc" + echo "$RUNNER_TEMP" >> "$GITHUB_PATH" + + - name: Verify mc + run: mc --version + - name: Install Vault run: | VAULT_VERSION="1.17.6" diff --git a/.github/workflows/e2e-replication-nightly.yml b/.github/workflows/e2e-replication-nightly.yml index 145ad317e..24c4aee3b 100644 --- a/.github/workflows/e2e-replication-nightly.yml +++ b/.github/workflows/e2e-replication-nightly.yml @@ -75,11 +75,7 @@ jobs: cache-save-if: ${{ github.ref == 'refs/heads/main' }} install-build-packaging-tools: 'false' - # awscurl lets the STS dual-node test actually exercise its path. Without - # it the test skips gracefully with a visible log line - # (`awscurl_available()` in crates/e2e_test/src/common.rs), so the lane - # still passes — installing it just upgrades that one test from skip to - # real coverage. + # The STS dual-node test requires awscurl and fails if it is unavailable. - name: Set up Python uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0 with: @@ -87,7 +83,7 @@ jobs: - name: Install awscurl run: | - python3 -m pip install --user --upgrade pip awscurl + python3 -m pip install --user --upgrade pip "awscurl==0.44" echo "AWSCURL_PATH=$HOME/.local/bin/awscurl" >> "$GITHUB_ENV" - name: Verify awscurl diff --git a/crates/e2e_test/README.md b/crates/e2e_test/README.md index 24567ac6f..62b609e27 100644 --- a/crates/e2e_test/README.md +++ b/crates/e2e_test/README.md @@ -123,7 +123,7 @@ via `create_s3_client(idx)` / `create_all_clients()`. See | `find_available_port` | Random free port (isolation primitive) | | `rustfs_binary_path` / `_with_features` | Locate/build the binary; honors `RUSTFS_BUILD_FEATURES` | | `requested_rustfs_build_features` / `rustfs_build_feature_enabled` | Feature-gate a test to what the binary was built with | -| `awscurl_available` + `execute_awscurl` / `awscurl_post` / `_get` / `_put` / `_delete` / `awscurl_post_sts_form_urlencoded` | Admin/STS API calls via `awscurl` (skip gracefully when absent) | +| `execute_awscurl` / `awscurl_post` / `_get` / `_put` / `_delete` / `awscurl_post_sts_form_urlencoded` | Admin/STS API calls via `awscurl`; missing binaries are test failures | | `replication_fast_env` | Env vars that shrink replication timers (from repl-4); pass to `start_rustfs_server_with_env` | | `local_http_client` / `init_logging` | Loopback HTTP client; idempotent tracing init | | `RustFSTestClusterEnvironment` (`new`/`start`/`start_node`/`stop_node`/`create_all_clients`) | Multi-node harness | @@ -189,7 +189,7 @@ cargo nextest run --profile e2e-smoke -p e2e_test cargo nextest run --profile e2e-full -p e2e_test # Cluster fault nightly lane cargo nextest run --profile e2e-nightly -p e2e_test -# Replication nightly lane; install awscurl so STS paths do not skip +# Replication nightly lane; awscurl is required for STS paths cargo nextest run --profile e2e-repl-nightly -p e2e_test # Fixed-port protocol nightly lane RUSTFS_BUILD_FEATURES=ftps,webdav,sftp \ @@ -221,9 +221,8 @@ The `s3s-e2e` CI job selects a random `RUSTFS_TEST_PORT` (see the `e2e-tests` job) to dodge this; local single-node tests already use random ports, so a lingering orphan is usually the cause of a spurious bind failure. -**`awscurl` not found.** `awscurl`-dependent tests skip gracefully with a -visible log line (`awscurl_available()`); install `awscurl` to actually run -them. +**`awscurl` not found.** `awscurl`-dependent tests fail closed with a process +spawn error. Install the pinned CI version before running their profiles. ## Related @@ -258,10 +257,9 @@ A test module may join the smoke filter only if every test in it is: 2. **Single-node** — spawns its own server via `RustFSTestEnvironment`/`start_rustfs_server` on a random port with an isolated temp dir. No `RustFSTestClusterEnvironment`, no fixed ports. -3. **Dependency-free** — no pre-started server at `localhost:9000`, no Vault, - no fixed protocol ports. Tools that may be absent on the runner (e.g. - `awscurl`) are acceptable only when the test skips gracefully with a - visible log line (see `bucket_policy_check_test.rs`). +3. **Hermetic dependencies** — no pre-started server at `localhost:9000`, no + Vault, and no fixed protocol ports. Any required CLI must be pinned and + installed by the workflow; a missing CLI must fail the test. 4. **Not `#[ignore]`** — ignored tests are activation work (backlog#1149 ci-13 / backlog#1148 ilm-3), not smoke candidates. diff --git a/crates/e2e_test/src/bucket_policy_check_test.rs b/crates/e2e_test/src/bucket_policy_check_test.rs index e71e5fe97..0b9345f06 100644 --- a/crates/e2e_test/src/bucket_policy_check_test.rs +++ b/crates/e2e_test/src/bucket_policy_check_test.rs @@ -52,10 +52,6 @@ fn create_user_client(env: &RustFSTestEnvironment, access_key: &str, secret_key: #[tokio::test] async fn test_bucket_policy_authenticated_user() -> Result<(), Box> { init_logging(); - if !crate::common::awscurl_available() { - info!("Skipping test_bucket_policy_authenticated_user because awscurl is not available"); - return Ok(()); - } info!("Starting test_bucket_policy_authenticated_user..."); let mut env = RustFSTestEnvironment::new().await?; diff --git a/crates/e2e_test/src/common.rs b/crates/e2e_test/src/common.rs index 7fad7ea76..fda121840 100644 --- a/crates/e2e_test/src/common.rs +++ b/crates/e2e_test/src/common.rs @@ -494,15 +494,20 @@ fn awscurl_binary_path() -> PathBuf { .unwrap_or_else(|| PathBuf::from("awscurl")) } -pub fn awscurl_available() -> bool { - let path = awscurl_binary_path(); - if path.components().count() > 1 || path.is_absolute() { - return path.is_file(); +fn verify_awscurl_path(path: &Path) -> std::io::Result<()> { + let output = Command::new(path).arg("--help").output()?; + if output.status.success() { + return Ok(()); } - std::env::var_os("PATH") - .map(|paths| std::env::split_paths(&paths).any(|dir| dir.join(&path).is_file())) - .unwrap_or(false) + Err(std::io::Error::other(format!( + "awscurl prerequisite check failed: {}", + String::from_utf8_lossy(&output.stderr).trim() + ))) +} + +pub fn require_awscurl() -> std::io::Result<()> { + verify_awscurl_path(&awscurl_binary_path()) } // Global initialization @@ -1747,6 +1752,22 @@ mod tests { assert_eq!(normalize_rustfs_build_features(" , "), None); } + #[test] + fn missing_awscurl_is_a_prerequisite_failure() { + let missing = std::env::temp_dir().join(format!("missing-awscurl-{}", Uuid::new_v4())); + + let error = verify_awscurl_path(&missing).expect_err("a missing awscurl binary must fail the test prerequisite"); + + assert_eq!(error.kind(), ErrorKind::NotFound); + } + + #[test] + fn available_awscurl_client_passes_prerequisite_check() { + let executable = std::env::current_exe().expect("the test executable should have a path"); + + verify_awscurl_path(&executable).expect("an available client with a working help command should pass"); + } + #[test] fn capture_log_path_uses_temp_directory_basename() { assert_eq!( diff --git a/crates/e2e_test/src/existing_object_tag_policy_test.rs b/crates/e2e_test/src/existing_object_tag_policy_test.rs index 17c34f166..7668773ed 100644 --- a/crates/e2e_test/src/existing_object_tag_policy_test.rs +++ b/crates/e2e_test/src/existing_object_tag_policy_test.rs @@ -16,9 +16,7 @@ //! session policy** (`Policy` parameter) via `awscurl --service sts` with explicit //! `Content-Type: application/x-www-form-urlencoded` on `POST /`. -use crate::common::{ - RustFSTestEnvironment, awscurl_available, awscurl_delete, awscurl_post_sts_form_urlencoded, awscurl_put, init_logging, -}; +use crate::common::{RustFSTestEnvironment, awscurl_delete, awscurl_post_sts_form_urlencoded, awscurl_put, init_logging}; use aws_sdk_s3::config::{Credentials, Region}; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{Delete, ObjectIdentifier, Tag, Tagging}; @@ -175,11 +173,6 @@ async fn cleanup_bucket_and_object(admin: &Client, bucket: &str, key: &str) { #[tokio::test] async fn test_e2e_iam_policy_existing_object_tag_get_object() -> Result<(), Box> { init_logging(); - if !awscurl_available() { - info!("Skipping test_e2e_iam_policy_existing_object_tag_get_object: awscurl not available"); - return Ok(()); - } - let suffix = Uuid::new_v4(); let user = format!("e2eiamtag-{suffix}"); let user_secret = "longSecretKeyForTest123!"; @@ -233,11 +226,6 @@ async fn test_e2e_iam_policy_existing_object_tag_get_object() -> Result<(), Box< #[tokio::test] async fn test_e2e_bucket_policy_existing_object_tag_get_object() -> Result<(), Box> { init_logging(); - if !awscurl_available() { - info!("Skipping test_e2e_bucket_policy_existing_object_tag_get_object: awscurl not available"); - return Ok(()); - } - let suffix = Uuid::new_v4(); let user = format!("e2ebptag-{suffix}"); let user_secret = "longSecretKeyForTest456!"; @@ -294,11 +282,6 @@ async fn test_e2e_bucket_policy_existing_object_tag_get_object() -> Result<(), B #[tokio::test] async fn test_e2e_sts_assume_role_session_policy_existing_object_tag() -> Result<(), Box> { init_logging(); - if !awscurl_available() { - info!("Skipping test_e2e_sts_assume_role_session_policy_existing_object_tag: awscurl not available"); - return Ok(()); - } - let suffix = Uuid::new_v4(); let parent = format!("e2e-sts-par-{suffix}"); let parent_secret = "longSecretKeyForParentSts99!"; @@ -370,11 +353,6 @@ async fn test_e2e_sts_assume_role_session_policy_existing_object_tag() -> Result #[tokio::test] async fn test_e2e_sts_session_policy_delete_objects_object_prefix_only() -> Result<(), Box> { init_logging(); - if !awscurl_available() { - info!("Skipping test_e2e_sts_session_policy_delete_objects_object_prefix_only: awscurl not available"); - return Ok(()); - } - let suffix = Uuid::new_v4(); let parent = format!("e2e-sts-del-par-{suffix}"); let parent_secret = "longSecretKeyForParentDelete99!"; diff --git a/crates/e2e_test/src/kms/common.rs b/crates/e2e_test/src/kms/common.rs index 07b21db4d..3a6c2d364 100644 --- a/crates/e2e_test/src/kms/common.rs +++ b/crates/e2e_test/src/kms/common.rs @@ -22,9 +22,7 @@ //! - KMS backend configuration (Local and Vault) //! - SSE encryption testing utilities -use crate::common::{ - RustFSTestEnvironment, awscurl_available, awscurl_get, awscurl_post, init_logging as common_init_logging, local_http_client, -}; +use crate::common::{RustFSTestEnvironment, awscurl_get, awscurl_post, init_logging as common_init_logging, local_http_client}; use aws_sdk_s3::Client; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::ServerSideEncryption; @@ -59,15 +57,6 @@ pub fn init_logging() { // Additional KMS-specific logging configuration can be added here if needed } -pub fn skip_if_kms_admin_tool_unavailable(test_name: &str) -> bool { - if awscurl_available() { - return false; - } - - info!("Skipping {} because awscurl is not available in PATH", test_name); - true -} - pub fn sse_customer_key_md5_base64(key: &str) -> String { let mut hasher = Md5::new(); hasher.update(key.as_bytes()); @@ -490,10 +479,6 @@ pub async fn test_kms_key_management( access_key: &str, secret_key: &str, ) -> Result<(), Box> { - if skip_if_kms_admin_tool_unavailable("test_kms_key_management") { - return Ok(()); - } - info!("Testing KMS key management APIs"); // Test CreateKey diff --git a/crates/e2e_test/src/kms/kms_local_test.rs b/crates/e2e_test/src/kms/kms_local_test.rs index 522b28478..4a8550b32 100644 --- a/crates/e2e_test/src/kms/kms_local_test.rs +++ b/crates/e2e_test/src/kms/kms_local_test.rs @@ -20,8 +20,7 @@ //! - Complete encryption/decryption lifecycle use super::common::{ - LocalKMSTestEnvironment, get_kms_status, skip_if_kms_admin_tool_unavailable, sse_customer_key_md5_base64, - test_kms_key_management, test_sse_c_encryption, + LocalKMSTestEnvironment, get_kms_status, sse_customer_key_md5_base64, test_kms_key_management, test_sse_c_encryption, }; use crate::common::{TEST_BUCKET, init_logging}; use tracing::{error, info}; @@ -29,9 +28,6 @@ use tracing::{error, info}; #[tokio::test] async fn test_local_kms_end_to_end() -> Result<(), Box> { init_logging(); - if skip_if_kms_admin_tool_unavailable("test_local_kms_end_to_end") { - return Ok(()); - } info!("Starting Local KMS End-to-End Test"); // Create LocalKMS test environment diff --git a/crates/e2e_test/src/kms/kms_vault_test.rs b/crates/e2e_test/src/kms/kms_vault_test.rs index 0dd19f703..c73515d95 100644 --- a/crates/e2e_test/src/kms/kms_vault_test.rs +++ b/crates/e2e_test/src/kms/kms_vault_test.rs @@ -22,8 +22,8 @@ use crate::common::{TEST_BUCKET, init_logging}; use tracing::{error, info}; use super::common::{ - VAULT_KEY_NAME, VaultTestEnvironment, get_kms_status, skip_if_kms_admin_tool_unavailable, sse_customer_key_md5_base64, - start_kms, test_all_multipart_encryption_types, test_error_scenarios, test_kms_key_management, test_sse_c_encryption, + VAULT_KEY_NAME, VaultTestEnvironment, get_kms_status, sse_customer_key_md5_base64, start_kms, + test_all_multipart_encryption_types, test_error_scenarios, test_kms_key_management, test_sse_c_encryption, test_sse_kms_encryption, test_sse_s3_encryption, }; @@ -62,9 +62,6 @@ impl VaultKmsTestContext { #[tokio::test] async fn test_vault_kms_end_to_end() -> Result<(), Box> { init_logging(); - if skip_if_kms_admin_tool_unavailable("test_vault_kms_end_to_end") { - return Ok(()); - } info!("Starting Vault KMS End-to-End Test with default key {}", VAULT_KEY_NAME); let context = VaultKmsTestContext::new().await?; @@ -117,9 +114,6 @@ async fn test_vault_kms_end_to_end() -> Result<(), Box Result<(), Box> { init_logging(); - if skip_if_kms_admin_tool_unavailable("test_vault_kms_key_isolation") { - return Ok(()); - } info!("Starting Vault KMS SSE-C key isolation test"); let context = VaultKmsTestContext::new().await?; @@ -203,9 +197,6 @@ async fn test_vault_kms_key_isolation() -> Result<(), Box Result<(), Box> { init_logging(); - if skip_if_kms_admin_tool_unavailable("test_vault_kms_large_file") { - return Ok(()); - } info!("Starting Vault KMS large file SSE-S3 test"); let context = VaultKmsTestContext::new().await?; @@ -267,9 +258,6 @@ async fn test_vault_kms_large_file() -> Result<(), Box Result<(), Box> { init_logging(); - if skip_if_kms_admin_tool_unavailable("test_vault_kms_multipart_upload") { - return Ok(()); - } info!("Starting Vault KMS multipart upload encryption suite"); let context = VaultKmsTestContext::new().await?; @@ -297,9 +285,6 @@ async fn test_vault_kms_multipart_upload() -> Result<(), Box Result<(), Box> { init_logging(); - if skip_if_kms_admin_tool_unavailable("test_vault_kms_key_operations") { - return Ok(()); - } info!("Starting Vault KMS key operations test (CRUD)"); let context = VaultKmsTestContext::new().await?; diff --git a/crates/e2e_test/src/mc_mirror_small_bucket_test.rs b/crates/e2e_test/src/mc_mirror_small_bucket_test.rs index 2a9c1a507..213da60c0 100644 --- a/crates/e2e_test/src/mc_mirror_small_bucket_test.rs +++ b/crates/e2e_test/src/mc_mirror_small_bucket_test.rs @@ -41,13 +41,6 @@ async fn create_issue_3107_fixture(root: &Path) -> TestResult { Ok(()) } -fn mc_available() -> bool { - Command::new("mc") - .arg("--version") - .output() - .is_ok_and(|output| output.status.success()) -} - fn run_mc(args: &[&str]) -> TestResult { let output = Command::new("mc").args(args).output()?; if !output.status.success() { @@ -75,10 +68,7 @@ fn count_files(root: &Path) -> usize { async fn test_mc_mirror_small_bucket_completes_without_list_timeout() -> TestResult { crate::common::init_logging(); info!("Starting issue #3107 mc mirror regression test"); - if !mc_available() { - info!("Skipping issue #3107 mc mirror regression test because mc is not installed"); - return Ok(()); - } + run_mc(&["--version"])?; let mut env = RustFSTestEnvironment::new().await?; env.start_rustfs_server(vec![]).await?; diff --git a/crates/e2e_test/src/multipart_auth_test.rs b/crates/e2e_test/src/multipart_auth_test.rs index 247cb46d7..334c55339 100644 --- a/crates/e2e_test/src/multipart_auth_test.rs +++ b/crates/e2e_test/src/multipart_auth_test.rs @@ -4278,10 +4278,6 @@ async fn test_signed_put_object_extract_preserves_pax_metadata_and_version_id() async fn test_signed_put_object_extract_authorizes_each_pax_privilege_and_retention_conditions() -> Result<(), Box> { init_logging(); - if !crate::common::awscurl_available() { - return Ok(()); - } - let mut env = RustFSTestEnvironment::new().await?; env.start_rustfs_server(vec![]).await?; diff --git a/crates/e2e_test/src/quota_test.rs b/crates/e2e_test/src/quota_test.rs index adff548ad..85d54b3f8 100644 --- a/crates/e2e_test/src/quota_test.rs +++ b/crates/e2e_test/src/quota_test.rs @@ -18,15 +18,6 @@ use http::{Method, StatusCode}; use tokio::time::{Duration, sleep, timeout}; use tracing::{debug, info}; -fn skip_without_awscurl() -> bool { - if crate::common::awscurl_available() { - return false; - } - - info!("Skipping quota test because awscurl is not available"); - true -} - /// Test environment setup for quota tests pub struct QuotaTestEnv { pub env: RustFSTestEnvironment, @@ -276,9 +267,6 @@ mod integration_tests { #[tokio::test] async fn test_quota_basic_operations() -> Result<(), Box> { init_logging(); - if skip_without_awscurl() { - return Ok(()); - } let env = QuotaTestEnv::new().await?; // Create test bucket @@ -320,9 +308,6 @@ mod integration_tests { #[tokio::test] async fn test_quota_admission_aws_chunked_declared_encoding() -> Result<(), Box> { init_logging(); - if skip_without_awscurl() { - return Ok(()); - } let env = QuotaTestEnv::new().await?; env.create_bucket().await?; @@ -371,9 +356,6 @@ mod integration_tests { #[tokio::test] async fn test_quota_update_and_clear() -> Result<(), Box> { init_logging(); - if skip_without_awscurl() { - return Ok(()); - } let env = QuotaTestEnv::new().await?; env.create_bucket().await?; @@ -406,9 +388,6 @@ mod integration_tests { #[tokio::test] async fn test_quota_delete_operations() -> Result<(), Box> { init_logging(); - if skip_without_awscurl() { - return Ok(()); - } let env = QuotaTestEnv::new().await?; env.create_bucket().await?; @@ -442,9 +421,6 @@ mod integration_tests { #[tokio::test] async fn test_quota_usage_tracking() -> Result<(), Box> { init_logging(); - if skip_without_awscurl() { - return Ok(()); - } let env = QuotaTestEnv::new().await?; env.create_bucket().await?; @@ -480,9 +456,6 @@ mod integration_tests { #[tokio::test] async fn test_quota_statistics() -> Result<(), Box> { init_logging(); - if skip_without_awscurl() { - return Ok(()); - } let env = QuotaTestEnv::new().await?; env.create_bucket().await?; @@ -513,9 +486,6 @@ mod integration_tests { #[tokio::test] async fn test_quota_check_api() -> Result<(), Box> { init_logging(); - if skip_without_awscurl() { - return Ok(()); - } let env = QuotaTestEnv::new().await?; env.create_bucket().await?; @@ -553,9 +523,6 @@ mod integration_tests { #[tokio::test] async fn test_quota_multiple_buckets() -> Result<(), Box> { init_logging(); - if skip_without_awscurl() { - return Ok(()); - } let env = QuotaTestEnv::new().await?; // Create two buckets in the same environment @@ -593,9 +560,6 @@ mod integration_tests { #[tokio::test] async fn test_quota_error_handling() -> Result<(), Box> { init_logging(); - if skip_without_awscurl() { - return Ok(()); - } let env = QuotaTestEnv::new().await?; env.create_bucket().await?; @@ -628,9 +592,6 @@ mod integration_tests { #[tokio::test] async fn test_quota_http_endpoints() -> Result<(), Box> { init_logging(); - if skip_without_awscurl() { - return Ok(()); - } let env = QuotaTestEnv::new().await?; env.create_bucket().await?; @@ -689,9 +650,6 @@ mod integration_tests { #[tokio::test] async fn test_quota_normal_user_permissions() -> Result<(), Box> { init_logging(); - if skip_without_awscurl() { - return Ok(()); - } let env = QuotaTestEnv::new().await?; env.create_bucket().await?; @@ -744,9 +702,6 @@ mod integration_tests { #[tokio::test] async fn test_quota_copy_operations() -> Result<(), Box> { init_logging(); - if skip_without_awscurl() { - return Ok(()); - } let env = QuotaTestEnv::new().await?; env.create_bucket().await?; @@ -789,9 +744,6 @@ mod integration_tests { #[tokio::test] async fn test_quota_batch_delete() -> Result<(), Box> { init_logging(); - if skip_without_awscurl() { - return Ok(()); - } let env = QuotaTestEnv::new().await?; env.create_bucket().await?; @@ -847,9 +799,6 @@ mod integration_tests { #[tokio::test] async fn test_quota_multipart_upload() -> Result<(), Box> { init_logging(); - if skip_without_awscurl() { - return Ok(()); - } let env = QuotaTestEnv::new().await?; env.create_bucket().await?; diff --git a/crates/e2e_test/src/replication_extension_test.rs b/crates/e2e_test/src/replication_extension_test.rs index 4d7b641e4..206bd50e2 100644 --- a/crates/e2e_test/src/replication_extension_test.rs +++ b/crates/e2e_test/src/replication_extension_test.rs @@ -13,9 +13,8 @@ // limitations under the License. use crate::common::{ - RustFSTestEnvironment, admin_create_user, awscurl_available, awscurl_post_sts_form_urlencoded, init_logging, - local_http_client, replication_fast_env, rustfs_binary_path, signed_request, signed_request_with_client, - signed_request_with_session_token, + RustFSTestEnvironment, admin_create_user, awscurl_post_sts_form_urlencoded, init_logging, local_http_client, + replication_fast_env, rustfs_binary_path, signed_request, signed_request_with_client, signed_request_with_session_token, }; use crate::fake_s3_target::{ FAKE_ACCESS_KEY, FAKE_SECRET_KEY, FakeS3Target, FaultAction as FakeTargetFault, Operation as FakeTargetOperation, @@ -7699,11 +7698,6 @@ async fn test_site_replication_replicates_multiple_service_accounts_real_dual_no async fn test_site_replication_replicates_service_accounts_created_from_sts_session_real_dual_node() -> TestResult { init_logging(); - if !awscurl_available() { - eprintln!("Skipping STS site replication service-account test because awscurl is unavailable"); - return Ok(()); - } - let mut source_env = RustFSTestEnvironment::new().await?; source_env .start_rustfs_server_with_env(vec![], LOOPBACK_REPLICATION_TARGET_ENV) diff --git a/crates/e2e_test/src/security_boundary_test.rs b/crates/e2e_test/src/security_boundary_test.rs index 0a62ef0f5..8c5c7d469 100644 --- a/crates/e2e_test/src/security_boundary_test.rs +++ b/crates/e2e_test/src/security_boundary_test.rs @@ -21,12 +21,11 @@ //! - SSRF prevention (internal/private endpoints rejected for tiering) //! - Race condition handling (concurrent writes converge without corruption) -use crate::common::{RustFSTestEnvironment, awscurl_available, awscurl_put, init_logging}; +use crate::common::{RustFSTestEnvironment, awscurl_put, init_logging, require_awscurl}; use aws_sdk_s3::error::ProvideErrorMetadata; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{CompletedMultipartUpload, CompletedPart, Tag, Tagging}; use std::error::Error; -use tracing::info; /// Oversized tagging payloads must be rejected by the per-object tag limit. /// @@ -225,16 +224,12 @@ async fn test_concurrent_object_operations() -> Result<(), Box Result<(), Box> { init_logging(); - if !awscurl_available() { - info!("Skipping tiering URL validation test because awscurl is not available"); - return Ok(()); - } - + require_awscurl()?; let mut env = RustFSTestEnvironment::new().await?; env.start_rustfs_server(vec![]).await?;