diff --git a/crates/e2e_test/src/admin_auth_test.rs b/crates/e2e_test/src/admin_auth_test.rs index 3cdd92c75..96e7878c4 100644 --- a/crates/e2e_test/src/admin_auth_test.rs +++ b/crates/e2e_test/src/admin_auth_test.rs @@ -38,7 +38,6 @@ mod tests { use rustfs_signer::constants::UNSIGNED_PAYLOAD; use rustfs_signer::sign_v4; use s3s::Body; - use serial_test::serial; use std::error::Error; use std::io::Read; use std::process::{Command, Stdio}; @@ -162,7 +161,6 @@ mod tests { /// A fully authenticated but non-admin credential must be rejected with /// `403 AccessDenied` on an admin API, while the root credential succeeds. #[tokio::test(flavor = "multi_thread")] - #[serial] async fn non_admin_credential_denied_on_admin_api() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -198,7 +196,6 @@ mod tests { } #[tokio::test(flavor = "multi_thread")] - #[serial] async fn non_admin_credential_denied_on_manual_transition_run() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -326,7 +323,6 @@ mod tests { /// credential is accepted and the old one is rejected, on both the S3 data /// plane and the admin plane. #[tokio::test(flavor = "multi_thread")] - #[serial] async fn root_credential_rotation_takes_effect() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -389,7 +385,6 @@ mod tests { /// runtime. We capture the child's stdout/stderr directly (the shared /// harness inherits stdio) and poll for the warning until it appears. #[tokio::test(flavor = "multi_thread")] - #[serial] async fn default_credentials_emit_startup_warning() -> Result<(), Box> { init_logging(); diff --git a/crates/e2e_test/src/admin_iam_crud_test.rs b/crates/e2e_test/src/admin_iam_crud_test.rs index 508edf810..84b50709c 100644 --- a/crates/e2e_test/src/admin_iam_crud_test.rs +++ b/crates/e2e_test/src/admin_iam_crud_test.rs @@ -33,7 +33,6 @@ use aws_sdk_s3::config::{Credentials, Region}; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::{Client, Config}; use reqwest::StatusCode; -use serial_test::serial; use std::error::Error; use tokio::time::{Duration, sleep}; @@ -178,7 +177,6 @@ async fn assert_admin_status( } #[tokio::test] -#[serial] async fn test_update_service_account_enforces_owner_and_parent_scope() -> TestResult { init_logging(); @@ -348,7 +346,6 @@ async fn test_update_service_account_enforces_owner_and_parent_scope() -> TestRe /// Full user -> policy -> service-account lifecycle, proving each management /// call takes effect on the data plane, not just that the endpoint answers 200. #[tokio::test] -#[serial] async fn test_admin_user_policy_service_account_crud_lifecycle() -> TestResult { init_logging(); @@ -573,7 +570,6 @@ async fn test_admin_user_policy_service_account_crud_lifecycle() -> TestResult { /// non-admin credential with 403 AccessDenied (sec-4 assertion pattern; the /// gate implementation itself is owned by sec-4 / admin_auth_test). #[tokio::test] -#[serial] async fn test_admin_iam_endpoints_deny_non_admin_credential() -> TestResult { init_logging(); diff --git a/crates/e2e_test/src/admin_timeout_regression_test.rs b/crates/e2e_test/src/admin_timeout_regression_test.rs index c561e5d76..94a91f03e 100644 --- a/crates/e2e_test/src/admin_timeout_regression_test.rs +++ b/crates/e2e_test/src/admin_timeout_regression_test.rs @@ -21,7 +21,6 @@ use rustfs_signer::constants::UNSIGNED_PAYLOAD; use rustfs_signer::sign_v4; use s3s::Body; use serde::Deserialize; -use serial_test::serial; use std::error::Error; use std::process::Command; use tokio::time::{Duration, sleep, timeout}; @@ -100,7 +99,6 @@ fn offline_server_count(info: &InfoMessage) -> usize { } #[tokio::test(flavor = "multi_thread")] -#[serial] async fn test_single_admin_timeout_does_not_immediately_mark_peer_offline() -> Result<(), Box> { init_logging(); diff --git a/crates/e2e_test/src/anonymous_access_test.rs b/crates/e2e_test/src/anonymous_access_test.rs index 0891ac0a9..68a4f4095 100644 --- a/crates/e2e_test/src/anonymous_access_test.rs +++ b/crates/e2e_test/src/anonymous_access_test.rs @@ -18,7 +18,6 @@ use crate::common::{RustFSTestEnvironment, init_logging, local_http_client}; use aws_sdk_s3::types::PublicAccessBlockConfiguration; -use serial_test::serial; use tracing::info; async fn setup_public_bucket( @@ -73,7 +72,6 @@ async fn anonymous_get_object( /// Issue #2036: Anonymous GetObject should succeed when bucket policy allows it /// and no PublicAccessBlock configuration exists (ConfigNotFound). #[tokio::test] -#[serial] async fn test_anonymous_access_allowed_when_public_access_block_missing() -> Result<(), Box> { init_logging(); @@ -100,7 +98,6 @@ async fn test_anonymous_access_allowed_when_public_access_block_missing() -> Res /// Anonymous GetObject should be denied when RestrictPublicBuckets is true. #[tokio::test] -#[serial] async fn test_anonymous_access_denied_when_restrict_public_buckets_enabled() -> Result<(), Box> { init_logging(); @@ -137,7 +134,6 @@ async fn test_anonymous_access_denied_when_restrict_public_buckets_enabled() /// Anonymous GetObject should succeed when PublicAccessBlock exists but /// RestrictPublicBuckets is explicitly false. #[tokio::test] -#[serial] async fn test_anonymous_access_allowed_when_restrict_public_buckets_disabled() -> Result<(), Box> { init_logging(); @@ -176,7 +172,6 @@ async fn test_anonymous_access_allowed_when_restrict_public_buckets_disabled() /// reaches authorization through a fallback branch, and that branch has to apply the /// same public-access gate as a direct grant. #[tokio::test] -#[serial] async fn ghsa_x298_anonymous_list_object_versions_denied_when_restrict_public_buckets_enabled() -> Result<(), Box> { init_logging(); diff --git a/crates/e2e_test/src/api_rate_limit_test.rs b/crates/e2e_test/src/api_rate_limit_test.rs index 28f80517d..e7a3e682d 100644 --- a/crates/e2e_test/src/api_rate_limit_test.rs +++ b/crates/e2e_test/src/api_rate_limit_test.rs @@ -18,13 +18,11 @@ //! completely inert with default configuration. use crate::common::{RustFSTestEnvironment, init_logging, local_http_client}; -use serial_test::serial; use tracing::info; type TestResult = Result<(), Box>; #[tokio::test] -#[serial] async fn api_rate_limit_enforces_429_with_retry_after_when_enabled() -> TestResult { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -87,7 +85,6 @@ async fn api_rate_limit_enforces_429_with_retry_after_when_enabled() -> TestResu } #[tokio::test] -#[serial] async fn api_rate_limit_bucket_dimension_throttles_per_bucket() -> TestResult { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -133,7 +130,6 @@ async fn api_rate_limit_bucket_dimension_throttles_per_bucket() -> TestResult { } #[tokio::test] -#[serial] async fn api_rate_limit_stays_inert_by_default() -> TestResult { init_logging(); let mut env = RustFSTestEnvironment::new().await?; diff --git a/crates/e2e_test/src/archive_download_integrity_test.rs b/crates/e2e_test/src/archive_download_integrity_test.rs index ac23f5d70..e043c6105 100644 --- a/crates/e2e_test/src/archive_download_integrity_test.rs +++ b/crates/e2e_test/src/archive_download_integrity_test.rs @@ -24,7 +24,6 @@ mod tests { use rustfs_signer::constants::UNSIGNED_PAYLOAD; use rustfs_signer::{pre_sign_v4, sign_v4}; use s3s::Body; - use serial_test::serial; use sha2::{Digest, Sha256}; use std::error::Error; use std::io::{Cursor, Write}; @@ -339,7 +338,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_archive_put_allows_content_encoding_by_default() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -367,7 +365,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_archive_put_rejects_content_encoding_when_strict_mode_enabled() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -391,7 +388,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_archive_put_with_aws_chunked_does_not_persist_content_encoding_by_default() -> Result<(), Box> { init_logging(); @@ -427,7 +423,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_archive_put_with_aws_chunked_and_effective_encoding_roundtrips_by_default() -> Result<(), Box> { init_logging(); @@ -463,7 +458,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_archive_put_with_aws_chunked_allowed_when_strict_mode_enabled() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -498,7 +492,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_archive_put_with_aws_chunked_and_effective_encoding_rejects_when_strict_mode_enabled() -> Result<(), Box> { init_logging(); @@ -529,7 +522,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_archive_download_roundtrip_with_http_compression_enabled() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -591,7 +583,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_archive_multipart_roundtrip_preserves_bytes() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -687,7 +678,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_multipart_get_ignores_empty_conditional_etag_headers() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -723,7 +713,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_archive_multipart_with_aws_chunked_and_effective_encoding_roundtrips_by_default() -> Result<(), Box> { init_logging(); @@ -753,7 +742,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_archive_multipart_with_aws_chunked_allowed_when_strict_mode_enabled() -> Result<(), Box> { init_logging(); @@ -783,7 +771,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_archive_multipart_with_aws_chunked_and_effective_encoding_rejects_when_strict_mode_enabled() -> Result<(), Box> { init_logging(); @@ -816,7 +803,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_presigned_get_and_reverse_proxy_preserve_multipart_bytes() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; diff --git a/crates/e2e_test/src/bucket_logging_test.rs b/crates/e2e_test/src/bucket_logging_test.rs index 79d2e6843..e60483097 100644 --- a/crates/e2e_test/src/bucket_logging_test.rs +++ b/crates/e2e_test/src/bucket_logging_test.rs @@ -24,11 +24,9 @@ mod tests { }; use http::Method; use http::header::CONTENT_TYPE; - use serial_test::serial; use tracing::info; #[tokio::test] - #[serial] async fn test_dummy_bucket_compatibility_endpoints() { init_logging(); info!("Starting test: dummy-compat bucket APIs should match S3-compatible behavior"); @@ -236,7 +234,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_dummy_bucket_compatibility_endpoints_no_such_bucket() { init_logging(); info!("Starting test: dummy-compat bucket APIs should return NoSuchBucket for missing bucket"); @@ -392,7 +389,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_dummy_bucket_endpoints_http_contracts() { init_logging(); info!("Starting test: dummy-compat bucket API HTTP contracts"); diff --git a/crates/e2e_test/src/bucket_policy_check_test.rs b/crates/e2e_test/src/bucket_policy_check_test.rs index 9b958f343..e71e5fe97 100644 --- a/crates/e2e_test/src/bucket_policy_check_test.rs +++ b/crates/e2e_test/src/bucket_policy_check_test.rs @@ -18,7 +18,6 @@ use crate::common::{RustFSTestEnvironment, init_logging}; use aws_sdk_s3::config::{Credentials, Region}; use aws_sdk_s3::{Client, Config}; -use serial_test::serial; use tracing::info; async fn create_user( @@ -51,7 +50,6 @@ fn create_user_client(env: &RustFSTestEnvironment, access_key: &str, secret_key: } #[tokio::test] -#[serial] async fn test_bucket_policy_authenticated_user() -> Result<(), Box> { init_logging(); if !crate::common::awscurl_available() { diff --git a/crates/e2e_test/src/bucket_stats_regression_test.rs b/crates/e2e_test/src/bucket_stats_regression_test.rs index 3df98f1ef..7754c0639 100644 --- a/crates/e2e_test/src/bucket_stats_regression_test.rs +++ b/crates/e2e_test/src/bucket_stats_regression_test.rs @@ -35,7 +35,6 @@ mod tests { use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{BucketVersioningStatus, VersioningConfiguration}; use rustfs_data_usage::DataUsageInfo; - use serial_test::serial; use std::error::Error; use tokio::time::{Duration, sleep}; use tracing::info; @@ -59,7 +58,6 @@ mod tests { /// 3. Query admin data usage API /// 4. Verify object count > 0 #[tokio::test] - #[serial] async fn test_bucket_object_count_updates_after_put() -> TestResult { init_logging(); info!("RT-09: bucket object count updates after PUT"); @@ -126,7 +124,6 @@ mod tests { /// Regression pattern: stats remain unchanged after objects are deleted /// (rustfs#5615). #[tokio::test] - #[serial] async fn test_bucket_object_count_updates_after_delete() -> TestResult { init_logging(); info!("RT-09b: bucket object count updates after DELETE"); @@ -220,7 +217,6 @@ mod tests { /// Regression pattern: DataUsageInfo undercounts versioned bucket versions /// and delete markers (rustfs#3898). #[tokio::test] - #[serial] async fn test_versioned_bucket_stats_count_all_versions() -> TestResult { init_logging(); info!("RT-09c: versioned bucket stats count all versions"); diff --git a/crates/e2e_test/src/checksum_upload_test.rs b/crates/e2e_test/src/checksum_upload_test.rs index efa4a81b8..814d18d5a 100644 --- a/crates/e2e_test/src/checksum_upload_test.rs +++ b/crates/e2e_test/src/checksum_upload_test.rs @@ -26,7 +26,6 @@ mod tests { use base64::Engine; use md5::{Digest as Md5Digest, Md5}; use rustfs_rio::{Checksum, ChecksumType as RioChecksumType}; - use serial_test::serial; use sha2::Sha256; use tracing::info; @@ -90,7 +89,6 @@ mod tests { /// PutObject with Content-MD5: upload succeeds and GetObject returns same content. #[tokio::test] - #[serial] async fn test_put_object_with_content_md5() { init_logging(); info!("TEST: PutObject with Content-MD5"); @@ -126,7 +124,6 @@ mod tests { /// PutObject with x-amz-checksum-sha256: upload succeeds and GetObject returns same content. #[tokio::test] - #[serial] async fn test_put_object_with_checksum_sha256() { init_logging(); info!("TEST: PutObject with x-amz-checksum-sha256"); @@ -164,7 +161,6 @@ mod tests { /// PutObject with a SHA256 checksum that does NOT match the body must be /// rejected (BadDigest / checksum mismatch), NOT accepted with HTTP 200. #[tokio::test] - #[serial] async fn test_put_object_rejects_mismatched_sha256() { init_logging(); info!("TEST: PutObject rejects mismatched x-amz-checksum-sha256 (issue #4341)"); @@ -212,7 +208,6 @@ mod tests { /// After PutObject with a correct SHA256 checksum, HeadObject with /// ChecksumMode=ENABLED must return that stored base64 SHA256 digest. #[tokio::test] - #[serial] async fn test_head_object_returns_stored_sha256() { init_logging(); info!("TEST: HeadObject returns stored SHA256 with ChecksumMode=ENABLED (issue #4341)"); @@ -258,7 +253,6 @@ mod tests { /// Multipart upload with checksum: CreateMultipartUpload, UploadPart(s) with checksum_sha256, CompleteMultipartUpload; then GetObject verifies content. /// Uses part size >= 5MB (server minimum) for two parts. #[tokio::test] - #[serial] async fn test_multipart_upload_with_checksum() { init_logging(); info!("TEST: MultipartUpload with checksum (checksum_sha256 on parts)"); @@ -356,7 +350,6 @@ mod tests { /// Regression test for issue #2282: /// CRC64NVME full-object checksum should match between direct PutObject and multipart upload. #[tokio::test] - #[serial] async fn test_crc64nvme_matches_between_put_object_and_multipart_upload() { init_logging(); info!("TEST: CRC64NVME matches between direct PutObject and multipart upload"); @@ -492,7 +485,6 @@ mod tests { /// value is rejected with BadDigest and nothing is stored. Full HEAD/GET header /// echo round-trip is additionally exercised by the boto3+awscrt e2e. #[tokio::test] - #[serial] async fn test_additional_checksums_verify_on_write() { init_logging(); info!("TEST: additional checksums (XXHash3/64/128, SHA-512, MD5) verify-on-write"); diff --git a/crates/e2e_test/src/cluster_concurrency_test.rs b/crates/e2e_test/src/cluster_concurrency_test.rs index 7702dfac3..cc2f2cddc 100644 --- a/crates/e2e_test/src/cluster_concurrency_test.rs +++ b/crates/e2e_test/src/cluster_concurrency_test.rs @@ -16,7 +16,6 @@ use crate::common::RustFSTestClusterEnvironment; use aws_sdk_s3::Client; use aws_sdk_s3::error::SdkError; use bytes::Bytes; -use serial_test::serial; use std::sync::Arc; use tokio::sync::Barrier; use tracing::{info, warn}; @@ -135,7 +134,6 @@ async fn run_race_iteration( } #[tokio::test] -#[serial] async fn test_conditional_put_race_cluster() -> Result<(), Box> { crate::common::init_logging(); info!("Starting conditional PUT race test with auto cluster"); @@ -192,7 +190,6 @@ async fn test_conditional_put_race_cluster() -> Result<(), Box Result<(), Box> { crate::common::init_logging(); info!("Starting basic conditional PUT test with auto cluster"); diff --git a/crates/e2e_test/src/cluster_multidrive_pool_test.rs b/crates/e2e_test/src/cluster_multidrive_pool_test.rs index 3f9193984..3f88e5af4 100644 --- a/crates/e2e_test/src/cluster_multidrive_pool_test.rs +++ b/crates/e2e_test/src/cluster_multidrive_pool_test.rs @@ -31,7 +31,6 @@ //! (toxiproxy / socket proxy) and 5GiB large-object budgets. use crate::common::{ClusterTopology, RustFSTestClusterEnvironment}; -use serial_test::serial; type TestResult = Result<(), Box>; @@ -58,7 +57,6 @@ async fn put_get_roundtrip(cluster: &RustFSTestClusterEnvironment, key: &str, pa /// 4 nodes x 2 drives, single pool: the multi-drive layout boots and round-trips. #[tokio::test] -#[serial] async fn cluster_multidrive_single_pool_smoke() -> TestResult { crate::common::init_logging(); @@ -81,7 +79,6 @@ async fn cluster_multidrive_single_pool_smoke() -> TestResult { /// Two single-node pools, 2 drives each: the multi-pool layout boots and /// round-trips. Every pool is a distinct erasure pool (`pool_idx` 0 and 1). #[tokio::test] -#[serial] async fn cluster_two_pool_smoke() -> TestResult { crate::common::init_logging(); diff --git a/crates/e2e_test/src/compression_test.rs b/crates/e2e_test/src/compression_test.rs index 775decfa6..7014f5f18 100644 --- a/crates/e2e_test/src/compression_test.rs +++ b/crates/e2e_test/src/compression_test.rs @@ -3,7 +3,6 @@ use crate::common::{RustFSTestEnvironment, init_logging, rustfs_binary_path}; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{CompletedMultipartUpload, CompletedPart}; -use serial_test::serial; use std::fs; use std::path::PathBuf; use std::process::Command; @@ -102,7 +101,6 @@ async fn start_rustfs_with_compression(env: &mut RustFSTestEnvironment) -> Resul } #[tokio::test] -#[serial] async fn test_compression_roundtrip() -> Result<(), Box> { init_logging(); info!("Starting compression roundtrip test"); @@ -230,7 +228,6 @@ async fn fetch_range( /// (rustfs/rustfs#5957: multipart uploads previously bypassed disk compression /// entirely). #[tokio::test] -#[serial] async fn test_compression_multipart_roundtrip() -> Result<(), Box> { init_logging(); info!("Starting multipart compression roundtrip test"); @@ -349,7 +346,6 @@ const MPU_HIGH_RATIO_BUCKET: &str = "compression-mpu-high-ratio-bucket"; /// reproduced the mid-payload Pending truncation (rustfs/rustfs#5957). Every GET shape must return /// the exact original bytes, and the stored size must show the data really was compressed. #[tokio::test] -#[serial] async fn test_compression_multipart_high_ratio_binary_roundtrip() -> Result<(), Box> { init_logging(); info!("Starting multipart high-ratio binary compression roundtrip test"); @@ -446,7 +442,6 @@ const MPU_COPY_RANGE_LEN: usize = 5 * 1024 * 1024; /// range must be decompressed on read and re-compressed into the destination part, so the final /// object has to match "source prefix + uploaded tail" byte for byte. #[tokio::test] -#[serial] async fn test_compression_multipart_upload_part_copy_roundtrip() -> Result<(), Box> { init_logging(); info!("Starting multipart upload-part-copy compression roundtrip test"); @@ -570,7 +565,6 @@ const MPU_THREE_PARTS_TAIL_SIZE: usize = 512 * 1024; /// Three-part upload with uneven part sizes: each partNumber GET must map back to exactly one /// compressed part stream, and a suffix range must resolve inside the trailing part. #[tokio::test] -#[serial] async fn test_compression_multipart_three_parts_part_number_gets() -> Result<(), Box> { init_logging(); info!("Starting three-part multipart compression partNumber test"); @@ -689,7 +683,6 @@ async fn start_rustfs_with_compression_and_sse( /// shape must still return the original plaintext bytes. Physical size must shrink because the /// compression runs before encryption. #[tokio::test] -#[serial] async fn test_compression_multipart_sse_s3_roundtrip() -> Result<(), Box> { use aws_sdk_s3::types::ServerSideEncryption; diff --git a/crates/e2e_test/src/connection_cap_test.rs b/crates/e2e_test/src/connection_cap_test.rs index bb835a712..b59584164 100644 --- a/crates/e2e_test/src/connection_cap_test.rs +++ b/crates/e2e_test/src/connection_cap_test.rs @@ -18,7 +18,6 @@ //! concurrency — a queued connection is served only after a held one closes. use crate::common::{RustFSTestEnvironment, init_logging}; -use serial_test::serial; use std::time::Duration; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::TcpStream; @@ -57,7 +56,6 @@ async fn read_response_head(stream: &mut TcpStream, dur: Duration) -> Option TestResult { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -89,7 +87,6 @@ async fn open_and_stall(addr: &str) -> std::io::Result { } #[tokio::test] -#[serial] async fn connection_cap_blocks_excess_connections_until_permits_free() -> TestResult { init_logging(); let mut env = RustFSTestEnvironment::new().await?; diff --git a/crates/e2e_test/src/console_smoke_test.rs b/crates/e2e_test/src/console_smoke_test.rs index cca86b7e3..431eee313 100644 --- a/crates/e2e_test/src/console_smoke_test.rs +++ b/crates/e2e_test/src/console_smoke_test.rs @@ -33,7 +33,6 @@ //! serve the unauthenticated console endpoints at all. use crate::common::{RustFSTestEnvironment, init_logging, local_http_client}; -use serial_test::serial; use std::error::Error; use tokio::time::{Duration, sleep}; @@ -58,7 +57,6 @@ async fn wait_for_console_ready(console_base: &str) -> Result TestResult { init_logging(); diff --git a/crates/e2e_test/src/content_encoding_test.rs b/crates/e2e_test/src/content_encoding_test.rs index f99117424..abd0bb1ba 100644 --- a/crates/e2e_test/src/content_encoding_test.rs +++ b/crates/e2e_test/src/content_encoding_test.rs @@ -22,12 +22,10 @@ mod tests { use crate::common::{RustFSTestEnvironment, init_logging}; use aws_sdk_s3::primitives::ByteStream; - use serial_test::serial; use tracing::info; /// Verify Content-Encoding header roundtrips through PUT, GET, and HEAD operations #[tokio::test] - #[serial] async fn test_content_encoding_roundtrip() { init_logging(); info!("Starting Content-Encoding roundtrip test"); @@ -105,7 +103,6 @@ mod tests { /// Issue #1857: Content-Encoding "aws-chunked" is used by SigV4 streaming clients and must /// not be stored or returned. Upload with aws-chunked and verify GET/HEAD do not return it. #[tokio::test] - #[serial] async fn test_content_encoding_aws_chunked_not_returned_issue_1857() { init_logging(); info!("Issue #1857: aws-chunked must not be persisted or returned"); @@ -161,7 +158,6 @@ mod tests { /// Issue #2475 / Route A: when aws-chunked is combined with an effective object encoding, /// only the effective encoding should roundtrip through GET/HEAD. #[tokio::test] - #[serial] async fn test_content_encoding_aws_chunked_with_effective_encoding_roundtrip() { init_logging(); info!("aws-chunked,gzip should persist only gzip"); diff --git a/crates/e2e_test/src/copy_object_checksum_test.rs b/crates/e2e_test/src/copy_object_checksum_test.rs index bdd6251a9..b4ac11bbb 100644 --- a/crates/e2e_test/src/copy_object_checksum_test.rs +++ b/crates/e2e_test/src/copy_object_checksum_test.rs @@ -30,7 +30,6 @@ mod tests { use base64::Engine as _; use base64::engine::general_purpose::STANDARD as BASE64; use rustfs_rio::{Checksum, ChecksumType as RioChecksumType}; - use serial_test::serial; use sha2::{Digest, Sha256}; use tracing::info; @@ -114,7 +113,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_copy_supports_all_checksum_algorithms() { init_logging(); @@ -196,7 +194,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_copy_without_algorithm_preserves_every_supported_source_checksum() { init_logging(); @@ -262,7 +259,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_copy_without_algorithm_preserves_composite_checksum_type() { init_logging(); @@ -352,7 +348,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_copy_rejects_unknown_algorithm_without_destination_mutation() { init_logging(); @@ -453,7 +448,6 @@ mod tests { /// bytes, return it in `CopyObjectResult.ChecksumSHA256`, and persist it so a checksum-mode /// HEAD on the destination returns the identical value. #[tokio::test] - #[serial] async fn test_copy_with_checksum_algorithm_returns_and_persists_sha256() { init_logging(); info!("Issue #4996: CopyObject with ChecksumAlgorithm=SHA256 must return and persist the checksum"); @@ -523,7 +517,6 @@ mod tests { /// No algorithm requested: when the source object already carries a checksum, the copy must /// preserve it on the destination (AWS default), visible via a checksum-mode HEAD. #[tokio::test] - #[serial] async fn test_copy_without_algorithm_preserves_source_checksum() { init_logging(); info!("Issue #4996: CopyObject without ChecksumAlgorithm must preserve the source object's checksum"); @@ -603,7 +596,6 @@ mod tests { /// checksum-not-inherited path, and exercises the CRC32 code path (a different branch of /// ChecksumType::from_string than SHA256). #[tokio::test] - #[serial] async fn test_copy_requested_algorithm_overrides_source_checksum() { init_logging(); info!("Issue #4996: a requested CopyObject checksum algorithm must override the source object's algorithm"); diff --git a/crates/e2e_test/src/copy_object_metadata_test.rs b/crates/e2e_test/src/copy_object_metadata_test.rs index f56fe7f41..289c2abc2 100644 --- a/crates/e2e_test/src/copy_object_metadata_test.rs +++ b/crates/e2e_test/src/copy_object_metadata_test.rs @@ -22,11 +22,9 @@ mod tests { use aws_sdk_s3::types::{ BucketVersioningStatus, CompletedMultipartUpload, CompletedPart, MetadataDirective, StorageClass, VersioningConfiguration, }; - use serial_test::serial; use tracing::info; #[tokio::test] - #[serial] async fn copy_object_standard_metadata_copy_replace_and_clear() { init_logging(); info!("Issue #2789: self-copy metadata replacement must preserve object data"); @@ -300,7 +298,6 @@ mod tests { } #[tokio::test] - #[serial] async fn copy_object_replace_accepts_each_standard_field_independently() { init_logging(); let mut env = RustFSTestEnvironment::new().await.expect("Failed to create test environment"); @@ -416,7 +413,6 @@ mod tests { } #[tokio::test] - #[serial] async fn copy_object_replace_handles_versioned_multipart_source() { init_logging(); let mut env = RustFSTestEnvironment::new().await.expect("Failed to create test environment"); @@ -530,7 +526,6 @@ mod tests { } #[tokio::test] - #[serial] async fn invalid_replacement_metadata_does_not_mutate_destination() { init_logging(); let mut env = RustFSTestEnvironment::new().await.expect("Failed to create test environment"); diff --git a/crates/e2e_test/src/copy_object_tagging_test.rs b/crates/e2e_test/src/copy_object_tagging_test.rs index 23861a705..ad1103658 100644 --- a/crates/e2e_test/src/copy_object_tagging_test.rs +++ b/crates/e2e_test/src/copy_object_tagging_test.rs @@ -21,7 +21,6 @@ mod tests { use aws_sdk_s3::error::ProvideErrorMetadata; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{BucketVersioningStatus, MetadataDirective, TaggingDirective, VersioningConfiguration}; - use serial_test::serial; use std::collections::BTreeMap; async fn object_tags(client: &Client, bucket: &str, key: &str) -> BTreeMap { @@ -39,7 +38,6 @@ mod tests { } #[tokio::test] - #[serial] async fn copy_object_applies_copy_replace_and_empty_tagging_directives() { init_logging(); let mut env = RustFSTestEnvironment::new() @@ -305,7 +303,6 @@ mod tests { } #[tokio::test] - #[serial] async fn copy_object_tag_replacement_honors_request_tag_policy_denial() -> Result<(), Box> { init_logging(); diff --git a/crates/e2e_test/src/copy_object_version_restore_test.rs b/crates/e2e_test/src/copy_object_version_restore_test.rs index 25958bc35..e99da5843 100644 --- a/crates/e2e_test/src/copy_object_version_restore_test.rs +++ b/crates/e2e_test/src/copy_object_version_restore_test.rs @@ -21,11 +21,9 @@ mod tests { use crate::common::{RustFSTestEnvironment, init_logging}; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{BucketVersioningStatus, VersioningConfiguration}; - use serial_test::serial; use tracing::info; #[tokio::test] - #[serial] async fn test_self_copy_of_historical_version_restores_data_and_metadata() { init_logging(); info!("Issue #4238: self-copy of a historical version must be allowed and preserve metadata"); @@ -165,7 +163,6 @@ mod tests { /// version copied via `x-amz-copy-source-version-id` (SDK `CopySourceVersionId`), kept distinct /// from the newly created destination `x-amz-version-id`. #[tokio::test] - #[serial] async fn test_copy_of_non_latest_source_version_returns_copy_source_version_id() { init_logging(); info!("Issue #4976: versioned CopyObject must return x-amz-copy-source-version-id for the exact source version"); diff --git a/crates/e2e_test/src/copy_source_invalid_date_test.rs b/crates/e2e_test/src/copy_source_invalid_date_test.rs index 1513dddce..09f15a31b 100644 --- a/crates/e2e_test/src/copy_source_invalid_date_test.rs +++ b/crates/e2e_test/src/copy_source_invalid_date_test.rs @@ -47,7 +47,6 @@ mod tests { use rustfs_signer::constants::UNSIGNED_PAYLOAD; use rustfs_signer::sign_v4; use s3s::Body; - use serial_test::serial; use std::error::Error; /// Signed raw `PUT` copy request with an explicit copy-source conditional @@ -84,7 +83,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_copy_source_if_unmodified_since_valid_and_invalid() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; diff --git a/crates/e2e_test/src/create_bucket_region_test.rs b/crates/e2e_test/src/create_bucket_region_test.rs index 44f3ea13b..7f19b2297 100644 --- a/crates/e2e_test/src/create_bucket_region_test.rs +++ b/crates/e2e_test/src/create_bucket_region_test.rs @@ -25,13 +25,11 @@ mod tests { use crate::common::{RustFSTestEnvironment, init_logging}; use aws_sdk_s3::types::{BucketLocationConstraint, CreateBucketConfiguration}; - use serial_test::serial; use std::error::Error; /// `CreateBucket` with a `LocationConstraint` body must pass SigV4 validation /// and create the bucket, mirroring `minio-go` `MakeBucket(bucket, "us-east-1")`. #[tokio::test] - #[serial] async fn test_create_bucket_with_us_east_1_location_constraint() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -62,7 +60,6 @@ mod tests { /// A plain `CreateBucket` (no body) must also succeed; guards against a /// regression where an empty body would be hashed incorrectly during SigV4. #[tokio::test] - #[serial] async fn test_create_bucket_without_location_constraint() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; diff --git a/crates/e2e_test/src/data_usage_test.rs b/crates/e2e_test/src/data_usage_test.rs index d99d0750a..2dfd56eb5 100644 --- a/crates/e2e_test/src/data_usage_test.rs +++ b/crates/e2e_test/src/data_usage_test.rs @@ -15,7 +15,6 @@ use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{BucketVersioningStatus, VersioningConfiguration}; use rustfs_data_usage::DataUsageInfo; -use serial_test::serial; use tokio::time::{Duration, sleep}; use crate::common::{FAST_DATA_USAGE_SCANNER_ENV, RustFSTestEnvironment, TEST_BUCKET, awscurl_get, init_logging}; @@ -60,7 +59,6 @@ where /// Regression test for data usage accuracy (issue #1012). /// Launches rustfs, writes 1000 objects, then asserts admin data usage reports the full count. #[tokio::test(flavor = "multi_thread")] -#[serial] #[ignore = "Starts a rustfs server and requires awscurl; enable when running full E2E"] async fn data_usage_reports_all_objects() -> Result<(), Box> { init_logging(); @@ -118,7 +116,6 @@ async fn data_usage_reports_all_objects() -> Result<(), Box Result<(), Box> { init_logging(); diff --git a/crates/e2e_test/src/delete_marker_migration_semantics_test.rs b/crates/e2e_test/src/delete_marker_migration_semantics_test.rs index 5a51c053a..8ae3b75c3 100644 --- a/crates/e2e_test/src/delete_marker_migration_semantics_test.rs +++ b/crates/e2e_test/src/delete_marker_migration_semantics_test.rs @@ -18,7 +18,6 @@ mod tests { use aws_sdk_s3::Client; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{BucketVersioningStatus, VersioningConfiguration}; - use serial_test::serial; async fn create_versioned_bucket(client: &Client, bucket: &str) { client @@ -72,7 +71,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_versioning_only_delete_marker_has_minio_compatible_visibility_for_migration_proof() { init_logging(); let mut env = RustFSTestEnvironment::new().await.expect("create test environment"); @@ -113,7 +111,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_versioning_delete_marker_plus_history_remains_visible_for_migration_proof() { init_logging(); let mut env = RustFSTestEnvironment::new().await.expect("create test environment"); diff --git a/crates/e2e_test/src/delete_object_no_content_length_test.rs b/crates/e2e_test/src/delete_object_no_content_length_test.rs index 76bee5e3d..6f74ebf3a 100644 --- a/crates/e2e_test/src/delete_object_no_content_length_test.rs +++ b/crates/e2e_test/src/delete_object_no_content_length_test.rs @@ -24,7 +24,6 @@ mod tests { use rustfs_signer::constants::UNSIGNED_PAYLOAD; use rustfs_signer::sign_v4; use s3s::Body; - use serial_test::serial; use std::error::Error; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::TcpStream; @@ -92,7 +91,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_delete_object_version_without_content_length_succeeds() -> Result<(), Box> { init_logging(); info!("🧪 TEST: signed DELETE Object?versionId succeeds without Content-Length"); diff --git a/crates/e2e_test/src/delete_objects_versioning_test.rs b/crates/e2e_test/src/delete_objects_versioning_test.rs index 41f872370..acab0d320 100644 --- a/crates/e2e_test/src/delete_objects_versioning_test.rs +++ b/crates/e2e_test/src/delete_objects_versioning_test.rs @@ -29,7 +29,6 @@ mod tests { use crate::common::{RustFSTestEnvironment, init_logging}; use aws_sdk_s3::Client; use aws_sdk_s3::types::{BucketVersioningStatus, Delete, ObjectIdentifier, VersioningConfiguration}; - use serial_test::serial; use tracing::info; fn create_s3_client(env: &RustFSTestEnvironment) -> Client { @@ -42,7 +41,6 @@ mod tests { /// a versioned bucket, calling `list_object_versions` **immediately** (with /// no sleep) returns the newly-created DeleteMarker with `is_latest = true`. #[tokio::test] - #[serial] async fn test_delete_objects_delete_marker_immediately_visible() { init_logging(); info!("🧪 TEST: DeleteMarker from delete_objects is immediately visible via list_object_versions"); @@ -190,7 +188,6 @@ mod tests { /// a single `delete_objects` call all have their delete markers visible /// immediately afterwards. #[tokio::test] - #[serial] async fn test_delete_objects_multiple_keys_delete_markers_immediately_visible() { init_logging(); info!("🧪 TEST: Multiple delete markers from delete_objects are immediately visible"); diff --git a/crates/e2e_test/src/delete_regression_test.rs b/crates/e2e_test/src/delete_regression_test.rs index 1f61a55c2..3bcc6fa5c 100644 --- a/crates/e2e_test/src/delete_regression_test.rs +++ b/crates/e2e_test/src/delete_regression_test.rs @@ -33,7 +33,6 @@ mod tests { use crate::common::{RustFSTestEnvironment, init_logging}; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{BucketVersioningStatus, Delete, ObjectIdentifier, VersioningConfiguration}; - use serial_test::serial; use std::error::Error; use tracing::info; @@ -51,7 +50,6 @@ mod tests { /// 4. Verify the object is NOT in LIST /// 5. Verify HEAD returns 404 #[tokio::test] - #[serial] async fn test_delete_removes_object_from_list() -> TestResult { init_logging(); info!("RT-05: delete removes object from list"); @@ -132,7 +130,6 @@ mod tests { /// Regression pattern: batch delete returns success but some objects /// remain in LIST. #[tokio::test] - #[serial] async fn test_batch_delete_removes_all_objects() -> TestResult { init_logging(); info!("RT-05c: batch delete removes all objects"); @@ -212,7 +209,6 @@ mod tests { /// Covers the pattern where permanent deletion of a specific version /// fails with FileAccessDenied (rustfs#4978). #[tokio::test] - #[serial] async fn test_versioned_permanent_delete() -> TestResult { init_logging(); info!("RT-05d: versioned permanent delete"); @@ -283,7 +279,6 @@ mod tests { /// Covers the pattern where creating a delete marker and then listing /// versions shows incorrect state (rustfs#760). #[tokio::test] - #[serial] async fn test_versioned_delete_marker_and_list_consistency() -> TestResult { init_logging(); info!("RT-05e: versioned delete marker and list consistency"); @@ -379,7 +374,6 @@ mod tests { /// Regression pattern: after delete, the object data files remain on disk /// (rustfs#5029: Node Does Not Remove Files After Reconnect). #[tokio::test] - #[serial] async fn test_delete_removes_object_head_returns_404() -> TestResult { init_logging(); info!("RT-05f: delete → HEAD 404 consistency"); diff --git a/crates/e2e_test/src/distributed_startup_regression_test.rs b/crates/e2e_test/src/distributed_startup_regression_test.rs index b7387b50b..ff2da755b 100644 --- a/crates/e2e_test/src/distributed_startup_regression_test.rs +++ b/crates/e2e_test/src/distributed_startup_regression_test.rs @@ -32,7 +32,6 @@ mod tests { use crate::common::{RustFSTestClusterEnvironment, init_logging}; use aws_sdk_s3::primitives::ByteStream; - use serial_test::serial; use std::error::Error; use tokio::time::{Duration, sleep}; use tracing::info; @@ -50,7 +49,6 @@ mod tests { /// 3. Verify all nodes report healthy /// 4. Verify S3 operations work through any node #[tokio::test] - #[serial] async fn test_four_node_cluster_startup_and_health() -> TestResult { init_logging(); info!("RT-10: 4-node cluster startup and health"); @@ -103,7 +101,6 @@ mod tests { /// Regression pattern: after a node restart, it cannot rejoin the cluster /// or enters a faulty state (rustfs#2601). #[tokio::test] - #[serial] async fn test_cluster_survives_node_restart() -> TestResult { init_logging(); info!("RT-10b: cluster survives node restart"); @@ -168,7 +165,6 @@ mod tests { /// Regression pattern: bucket metadata is not replicated to all nodes, /// causing NoSuchBucket errors on some nodes (rustfs#3191). #[tokio::test] - #[serial] async fn test_bucket_visible_from_all_nodes() -> TestResult { init_logging(); info!("RT-10c: bucket visible from all nodes"); 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 9a26e95db..17c34f166 100644 --- a/crates/e2e_test/src/existing_object_tag_policy_test.rs +++ b/crates/e2e_test/src/existing_object_tag_policy_test.rs @@ -23,7 +23,6 @@ use aws_sdk_s3::config::{Credentials, Region}; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{Delete, ObjectIdentifier, Tag, Tagging}; use aws_sdk_s3::{Client, Config}; -use serial_test::serial; use tracing::info; use uuid::Uuid; @@ -174,7 +173,6 @@ async fn cleanup_bucket_and_object(admin: &Client, bucket: &str, key: &str) { /// IAM identity policy: GetObject allowed only when `s3:ExistingObjectTag/security` == `public`. #[tokio::test] -#[serial] async fn test_e2e_iam_policy_existing_object_tag_get_object() -> Result<(), Box> { init_logging(); if !awscurl_available() { @@ -233,7 +231,6 @@ async fn test_e2e_iam_policy_existing_object_tag_get_object() -> Result<(), Box< /// Bucket policy: same `ExistingObjectTag` condition; user has no canned IAM policy attached. #[tokio::test] -#[serial] async fn test_e2e_bucket_policy_existing_object_tag_get_object() -> Result<(), Box> { init_logging(); if !awscurl_available() { @@ -295,7 +292,6 @@ async fn test_e2e_bucket_policy_existing_object_tag_get_object() -> Result<(), B /// STS `AssumeRole` with inline `Policy` (session policy): GetObject only when `ExistingObjectTag/security` is `public`. #[tokio::test] -#[serial] async fn test_e2e_sts_assume_role_session_policy_existing_object_tag() -> Result<(), Box> { init_logging(); if !awscurl_available() { @@ -372,7 +368,6 @@ async fn test_e2e_sts_assume_role_session_policy_existing_object_tag() -> Result /// STS inline session policy: DeleteObjects must evaluate `s3:DeleteObject` per requested object key. #[tokio::test] -#[serial] async fn test_e2e_sts_session_policy_delete_objects_object_prefix_only() -> Result<(), Box> { init_logging(); if !awscurl_available() { diff --git a/crates/e2e_test/src/get_codec_streaming_compat_test.rs b/crates/e2e_test/src/get_codec_streaming_compat_test.rs index eb758aa7f..4fdc8326f 100644 --- a/crates/e2e_test/src/get_codec_streaming_compat_test.rs +++ b/crates/e2e_test/src/get_codec_streaming_compat_test.rs @@ -66,7 +66,6 @@ mod tests { use aws_sdk_s3::error::ProvideErrorMetadata; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{CompletedMultipartUpload, CompletedPart}; - use serial_test::serial; use sha2::{Digest, Sha256}; use std::collections::BTreeMap; use std::error::Error; @@ -277,7 +276,6 @@ mod tests { } #[tokio::test] - #[serial] async fn codec_streaming_matches_legacy_duplex_body_and_headers() -> TestResult { init_logging(); diff --git a/crates/e2e_test/src/group_delete_test.rs b/crates/e2e_test/src/group_delete_test.rs index 147feb89d..38d053f99 100644 --- a/crates/e2e_test/src/group_delete_test.rs +++ b/crates/e2e_test/src/group_delete_test.rs @@ -17,7 +17,6 @@ use crate::common::{RustFSTestEnvironment, admin_request, awscurl_delete, awscurl_get, awscurl_put, init_logging}; use aws_sdk_s3::config::{Credentials, Region}; use aws_sdk_s3::{Client, Config}; -use serial_test::serial; use tracing::info; fn create_user_s3_client(env: &RustFSTestEnvironment, access_key: &str, secret_key: &str) -> Client { @@ -84,7 +83,6 @@ async fn update_group_members_rejects_invalid_new_group_names() -> Result<(), Bo /// Test that deleting a group with members fails, and deleting an empty group succeeds. #[tokio::test(flavor = "multi_thread")] -#[serial] #[ignore = "requires awscurl and spawns a real RustFS server"] async fn test_delete_group_requires_empty_membership() -> Result<(), Box> { init_logging(); @@ -144,7 +142,6 @@ async fn test_delete_group_requires_empty_membership() -> Result<(), Box Result<(), Box> { init_logging(); @@ -212,7 +209,6 @@ async fn test_user_with_only_group_gets_group_policies() -> Result<(), Box Result<(), Box> { init_logging(); diff --git a/crates/e2e_test/src/head_object_consistency_test.rs b/crates/e2e_test/src/head_object_consistency_test.rs index 93e7b8a4e..a7499224b 100644 --- a/crates/e2e_test/src/head_object_consistency_test.rs +++ b/crates/e2e_test/src/head_object_consistency_test.rs @@ -16,7 +16,6 @@ use crate::common::{RustFSTestEnvironment, init_logging, local_http_client}; use aws_sdk_s3::presigning::PresigningConfig; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{CompletedMultipartUpload, CompletedPart}; -use serial_test::serial; use std::time::Duration; use tracing::info; @@ -29,7 +28,6 @@ fn list_contains_key(output: &aws_sdk_s3::operation::list_objects_v2::ListObject } #[tokio::test] -#[serial] async fn head_object_consistency_after_write_and_multipart_and_presigned_head() -> Result<(), Box> { init_logging(); diff --git a/crates/e2e_test/src/head_object_range_test.rs b/crates/e2e_test/src/head_object_range_test.rs index 5cc4b7a12..577440020 100644 --- a/crates/e2e_test/src/head_object_range_test.rs +++ b/crates/e2e_test/src/head_object_range_test.rs @@ -1,6 +1,5 @@ use crate::common::{RustFSTestEnvironment, init_logging}; use aws_sdk_s3::primitives::ByteStream; -use serial_test::serial; use tracing::info; const RANGE_HEAD_BUCKET: &str = "range-head-test-bucket"; @@ -8,7 +7,6 @@ const RANGE_HEAD_KEY: &str = "range-head-object.bin"; const ACCEPT_RANGES_BYTES: &str = "bytes"; #[tokio::test] -#[serial] async fn head_object_advertises_accept_ranges() -> Result<(), Box> { init_logging(); info!("Starting HeadObject Accept-Ranges regression test"); diff --git a/crates/e2e_test/src/heal_erasure_disk_rebuild_test.rs b/crates/e2e_test/src/heal_erasure_disk_rebuild_test.rs index 749f21d7f..dac1eef5e 100644 --- a/crates/e2e_test/src/heal_erasure_disk_rebuild_test.rs +++ b/crates/e2e_test/src/heal_erasure_disk_rebuild_test.rs @@ -19,7 +19,6 @@ mod tests { use crate::chaos::signed_admin_post; use crate::common::{RustFSTestClusterEnvironment, RustFSTestEnvironment, init_logging}; use aws_sdk_s3::primitives::ByteStream; - use serial_test::serial; use std::collections::HashSet; use std::error::Error; use std::path::{Path, PathBuf}; @@ -63,7 +62,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_auto_heal_rebuilds_runtime_wiped_disk_without_restart() { init_logging(); info!("Issue #1533: auto heal should rebuild a runtime-wiped disk in a 4-disk single-node erasure set without restart"); @@ -182,7 +180,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_admin_deep_heal_rebuilds_cleared_disk_in_single_node_erasure_set() { init_logging(); info!("Discussion #2964: admin deep heal should rebuild a wiped disk in a 4-disk single-node erasure set"); @@ -332,7 +329,6 @@ mod tests { } #[tokio::test(flavor = "multi_thread")] - #[serial] async fn test_cluster_root_heal_rebuilds_replaced_remote_disk() -> Result<(), Box> { init_logging(); info!("Root recursive heal should rebuild data on a remote node after its disk is replaced and the node rejoins"); @@ -444,7 +440,6 @@ mod tests { /// topology early-return or the merge hard-fail) turns the down-window /// response into a 500 and fails this test. #[tokio::test] - #[serial] async fn test_background_heal_status_degrades_while_peer_down_and_recovers_after_rejoin() -> Result<(), Box> { init_logging(); diff --git a/crates/e2e_test/src/internode_rpc_signature_e2e_test.rs b/crates/e2e_test/src/internode_rpc_signature_e2e_test.rs index c7632d013..bb751fe55 100644 --- a/crates/e2e_test/src/internode_rpc_signature_e2e_test.rs +++ b/crates/e2e_test/src/internode_rpc_signature_e2e_test.rs @@ -101,7 +101,6 @@ use rustfs_config::{ }; use rustfs_protos::canonical_make_volume_request_body; use rustfs_protos::proto_gen::node_service::{MakeVolumeRequest, MakeVolumeResponse, PingRequest, PingResponse}; -use serial_test::serial; use sha2::{Digest, Sha256}; use std::error::Error; use tonic::{Code, Request, Response, Status}; @@ -397,7 +396,6 @@ fn assert_rejected(result: Result, expected: Code, e /// Grouped into one server start because each case is independent and spawning /// a `rustfs` process per assertion would dominate the runtime. #[tokio::test] -#[serial] async fn internode_rpc_signature_default_posture_e2e() -> TestResult { init_logging(); align_rpc_secret_with_server(); @@ -424,7 +422,6 @@ async fn internode_rpc_signature_default_posture_e2e() -> TestResult { /// epoch is learned from a real response, then the same server is restarted in place to prove its /// replacement epoch rejects the captured request even though the nonce cache is necessarily new. #[tokio::test] -#[serial] async fn replay_scope_rejects_replay_path_transplant_and_stale_epoch_e2e() -> TestResult { init_logging(); align_rpc_secret_with_server(); @@ -497,7 +494,6 @@ async fn replay_scope_rejects_replay_path_transplant_and_stale_epoch_e2e() -> Te /// A mutating v2 request cannot use that lane; once the epoch proof is returned, the first v3 /// mutation succeeds. This protects a server restart without reopening a general downgrade path. #[tokio::test] -#[serial] async fn replay_scope_strict_requires_v3_after_ping_bootstrap_e2e() -> TestResult { init_logging(); align_rpc_secret_with_server(); @@ -704,7 +700,6 @@ async fn legacy_only_signature_is_accepted_in_default_posture(url: &str) { /// /// The paired v2 positive control rules out "strict simply breaks everything". #[tokio::test] -#[serial] async fn signature_strict_rejects_legacy_only_downgrade() -> TestResult { init_logging(); align_rpc_secret_with_server(); @@ -741,7 +736,6 @@ async fn signature_strict_rejects_legacy_only_downgrade() -> TestResult { /// takes the still-open legacy lane), which is what pins the rejection to the /// handler's digest gate; the cited message confirms which check spoke. #[tokio::test] -#[serial] async fn body_digest_strict_rejects_digestless_mutation() -> TestResult { init_logging(); align_rpc_secret_with_server(); diff --git a/crates/e2e_test/src/kms/bucket_default_encryption_test.rs b/crates/e2e_test/src/kms/bucket_default_encryption_test.rs index 965b33d02..fecba2b89 100644 --- a/crates/e2e_test/src/kms/bucket_default_encryption_test.rs +++ b/crates/e2e_test/src/kms/bucket_default_encryption_test.rs @@ -27,12 +27,10 @@ use aws_sdk_s3::types::{ ServerSideEncryptionByDefault, ServerSideEncryptionConfiguration, ServerSideEncryptionRule, }; use rustfs_rio::{Checksum, ChecksumType}; -use serial_test::serial; use tracing::{debug, info, warn}; /// Test 1: When bucket is configured with default SSE-S3 encryption, put_object should automatically apply encryption #[tokio::test] -#[serial] async fn test_bucket_default_sse_s3_put_object() -> Result<(), Box> { init_logging(); info!("Testing bucket default SSE-S3 encryption impact on put_object"); @@ -155,7 +153,6 @@ async fn test_bucket_default_sse_s3_put_object() -> Result<(), Box Result<(), Box> { init_logging(); info!("Testing bucket default SSE-KMS encryption impact on put_object"); @@ -275,7 +272,6 @@ async fn test_bucket_default_sse_kms_put_object() -> Result<(), Box Result<(), Box> { init_logging(); info!("Testing bucket default encryption impact on create_multipart_upload"); @@ -473,7 +469,6 @@ async fn test_bucket_default_sse_kms_multipart_crc32() -> Result<(), Box Result<(), Box> { init_logging(); info!("Testing explicitly specified encryption parameters override bucket default configuration"); @@ -569,7 +564,6 @@ async fn test_explicit_encryption_overrides_bucket_default() -> Result<(), Box Result<(), Box> { init_logging(); info!("Testing SSE-KMS without explicit key ID populates default key"); diff --git a/crates/e2e_test/src/kms/configured_roundtrip_test.rs b/crates/e2e_test/src/kms/configured_roundtrip_test.rs index a666ef8d7..512105d4f 100644 --- a/crates/e2e_test/src/kms/configured_roundtrip_test.rs +++ b/crates/e2e_test/src/kms/configured_roundtrip_test.rs @@ -20,7 +20,6 @@ use super::common::{ }; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{BucketVersioningStatus, ServerSideEncryption, VersioningConfiguration}; -use serial_test::serial; use std::error::Error; use uuid::Uuid; @@ -386,7 +385,6 @@ async fn assert_versioned_sse_kms_roundtrip_and_cleanup( } #[tokio::test] -#[serial] async fn test_configured_local_kms_admin_and_versioned_cleanup() -> TestResult { let mut env = LocalKMSTestEnvironment::new().await?; env.base_env.start_rustfs_server(Vec::new()).await?; @@ -434,7 +432,6 @@ async fn test_configured_local_kms_admin_and_versioned_cleanup() -> TestResult { } #[tokio::test] -#[serial] #[ignore = "requires a Vault binary"] async fn test_configured_vault_kms_admin_and_versioned_cleanup() -> TestResult { let mut env = VaultTestEnvironment::new().await?; diff --git a/crates/e2e_test/src/kms/copy_object_self_copy_sse_test.rs b/crates/e2e_test/src/kms/copy_object_self_copy_sse_test.rs index 85abf316e..1cf19a565 100644 --- a/crates/e2e_test/src/kms/copy_object_self_copy_sse_test.rs +++ b/crates/e2e_test/src/kms/copy_object_self_copy_sse_test.rs @@ -32,11 +32,9 @@ use aws_sdk_s3::types::{ MetadataDirective, ServerSideEncryption, ServerSideEncryptionByDefault, ServerSideEncryptionConfiguration, ServerSideEncryptionRule, }; -use serial_test::serial; use tracing::info; #[tokio::test] -#[serial] async fn test_metadata_replace_self_copy_of_sse_object_stays_decryptable() { init_logging(); info!("same-key CopyObject with REPLACE metadata must not re-key an SSE-S3 object"); @@ -136,7 +134,6 @@ async fn test_metadata_replace_self_copy_of_sse_object_stays_decryptable() { } #[tokio::test] -#[serial] async fn test_metadata_replace_self_copy_dropping_sse_rewrites_plaintext() { init_logging(); info!("same-key CopyObject that drops SSE must rewrite the data, not orphan the ciphertext"); @@ -233,7 +230,6 @@ async fn test_metadata_replace_self_copy_dropping_sse_rewrites_plaintext() { } #[tokio::test] -#[serial] async fn test_metadata_replace_self_copy_under_bucket_default_sse_stays_decryptable() { init_logging(); info!("bucket default encryption must also keep a same-key copy off the metadata-only path"); diff --git a/crates/e2e_test/src/kms/copy_object_version_restore_sse_test.rs b/crates/e2e_test/src/kms/copy_object_version_restore_sse_test.rs index 34dd682d7..3241a217d 100644 --- a/crates/e2e_test/src/kms/copy_object_version_restore_sse_test.rs +++ b/crates/e2e_test/src/kms/copy_object_version_restore_sse_test.rs @@ -25,11 +25,9 @@ use super::common::{LocalKMSTestEnvironment, create_key_with_specific_id}; use crate::common::init_logging; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{BucketVersioningStatus, ServerSideEncryption, VersioningConfiguration}; -use serial_test::serial; use tracing::info; #[tokio::test] -#[serial] async fn test_self_copy_of_historical_sse_s3_version_is_readable() { init_logging(); info!("Issue #4238 (SSE): restoring an encrypted historical version must stay decryptable"); diff --git a/crates/e2e_test/src/kms/encryption_metadata_test.rs b/crates/e2e_test/src/kms/encryption_metadata_test.rs index e1e082df8..a316668f6 100644 --- a/crates/e2e_test/src/kms/encryption_metadata_test.rs +++ b/crates/e2e_test/src/kms/encryption_metadata_test.rs @@ -22,7 +22,6 @@ use aws_sdk_s3::types::{ CompletedMultipartUpload, CompletedPart, ServerSideEncryption, ServerSideEncryptionByDefault, ServerSideEncryptionConfiguration, ServerSideEncryptionRule, }; -use serial_test::serial; use std::collections::{HashMap, VecDeque}; use tracing::info; @@ -82,7 +81,6 @@ pub(super) fn assert_storage_encrypted(storage_root: &std::path::Path, bucket: & } #[tokio::test] -#[serial] async fn test_head_reports_managed_metadata_for_sse_s3() -> Result<(), Box> { init_logging(); info!("Validating SSE-S3 managed encryption metadata exposure"); @@ -143,7 +141,6 @@ async fn test_head_reports_managed_metadata_for_sse_s3() -> Result<(), Box Result<(), Box> { init_logging(); info!("Validating SSE-KMS managed encryption metadata (including copy)"); @@ -247,7 +244,6 @@ async fn test_head_reports_managed_metadata_for_sse_kms_and_copy() -> Result<(), } #[tokio::test] -#[serial] async fn test_multipart_upload_writes_encrypted_data() -> Result<(), Box> { init_logging(); info!("Validating ciphertext persistence for multipart SSE-KMS uploads"); diff --git a/crates/e2e_test/src/kms/kms_authorization_negative_matrix_test.rs b/crates/e2e_test/src/kms/kms_authorization_negative_matrix_test.rs index bc6ef5b24..a6fd6cb43 100644 --- a/crates/e2e_test/src/kms/kms_authorization_negative_matrix_test.rs +++ b/crates/e2e_test/src/kms/kms_authorization_negative_matrix_test.rs @@ -35,7 +35,6 @@ use aws_sdk_s3::config::{Config, Credentials, Region}; use aws_sdk_s3::error::ProvideErrorMetadata; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::ServerSideEncryption; -use serial_test::serial; use std::time::Duration; use tracing::info; @@ -209,7 +208,6 @@ fn disable_body(key_id: &str) -> String { /// Data-path matrix: SSE-KMS writes and reads are authorized against the resolved key. #[tokio::test] -#[serial] async fn sse_kms_per_key_authorization_negative_matrix() -> TestResult { init_logging(); @@ -355,7 +353,6 @@ async fn sse_kms_per_key_authorization_negative_matrix() -> TestResult { /// Runs without the SSE enforcement switch: admin scoping is unconditional, and /// leaving the switch off proves the two planes are independent. #[tokio::test] -#[serial] async fn kms_admin_per_key_authorization_negative_matrix() -> TestResult { init_logging(); diff --git a/crates/e2e_test/src/kms/kms_comprehensive_test.rs b/crates/e2e_test/src/kms/kms_comprehensive_test.rs index b4a61a7f6..584ae64eb 100644 --- a/crates/e2e_test/src/kms/kms_comprehensive_test.rs +++ b/crates/e2e_test/src/kms/kms_comprehensive_test.rs @@ -24,13 +24,11 @@ use super::common::{ test_sse_kms_encryption, test_sse_s3_encryption, }; use crate::common::{TEST_BUCKET, init_logging}; -use serial_test::serial; use tokio::time::{Duration, sleep}; use tracing::info; /// Comprehensive test: Full KMS workflow with all encryption types #[tokio::test] -#[serial] async fn test_comprehensive_kms_full_workflow() -> Result<(), Box> { init_logging(); info!("🏁 Start the KMS full-featured synthesis test"); @@ -99,7 +97,6 @@ async fn test_mixed_encryption_workload( /// Comprehensive stress test: Large dataset with multiple encryption types #[tokio::test] -#[serial] async fn test_comprehensive_stress_test() -> Result<(), Box> { init_logging(); info!("💪 Start the KMS stress test"); @@ -134,7 +131,6 @@ async fn test_comprehensive_stress_test() -> Result<(), Box Result<(), Box> { init_logging(); info!("🔐 Begin the comprehensive test of encryption key isolation"); @@ -206,7 +202,6 @@ async fn test_comprehensive_key_isolation() -> Result<(), Box Result<(), Box> { init_logging(); info!("⚡ Started comprehensive testing of concurrent encryption operations"); @@ -252,7 +247,6 @@ async fn test_comprehensive_concurrent_operations() -> Result<(), Box Result<(), Box> { init_logging(); info!("📊 Start KMS performance benchmarking"); diff --git a/crates/e2e_test/src/kms/kms_edge_cases_test.rs b/crates/e2e_test/src/kms/kms_edge_cases_test.rs index fe4dcb66d..9d9d1a765 100644 --- a/crates/e2e_test/src/kms/kms_edge_cases_test.rs +++ b/crates/e2e_test/src/kms/kms_edge_cases_test.rs @@ -26,7 +26,6 @@ use crate::common::{TEST_BUCKET, init_logging}; use aws_sdk_s3::types::ServerSideEncryption; use base64::Engine; use md5::{Digest as Md5Digest, Md5}; -use serial_test::serial; use std::sync::Arc; use tokio::sync::Semaphore; use tracing::{info, warn}; @@ -39,7 +38,6 @@ fn md5_hex(input: impl AsRef<[u8]>) -> String { /// Test encryption of zero-byte files (empty files) #[tokio::test] -#[serial] async fn test_kms_zero_byte_file_encryption() -> Result<(), Box> { init_logging(); info!("🧪 Testing KMS encryption with zero-byte files"); @@ -113,7 +111,6 @@ async fn test_kms_zero_byte_file_encryption() -> Result<(), Box Result<(), Box> { init_logging(); info!("🧪 Testing KMS encryption with single-byte files"); @@ -206,7 +203,6 @@ async fn test_kms_single_byte_file_encryption() -> Result<(), Box Result<(), Box> { init_logging(); info!("🧪 Testing KMS multipart upload boundary conditions"); @@ -282,7 +278,6 @@ async fn test_kms_multipart_boundary_conditions() -> Result<(), Box Result<(), Box> { init_logging(); info!("🧪 Testing KMS invalid key scenarios and error handling"); @@ -370,7 +365,6 @@ async fn test_kms_invalid_key_scenarios() -> Result<(), Box Result<(), Box> { init_logging(); info!("🧪 Testing KMS concurrent encryption operations"); @@ -478,7 +472,6 @@ async fn test_kms_concurrent_encryption() -> Result<(), Box Result<(), Box> { init_logging(); info!("🧪 Testing KMS key validation and security properties"); diff --git a/crates/e2e_test/src/kms/kms_fault_recovery_test.rs b/crates/e2e_test/src/kms/kms_fault_recovery_test.rs index 2325281ee..fa6c08170 100644 --- a/crates/e2e_test/src/kms/kms_fault_recovery_test.rs +++ b/crates/e2e_test/src/kms/kms_fault_recovery_test.rs @@ -24,7 +24,6 @@ use super::common::LocalKMSTestEnvironment; use crate::common::{TEST_BUCKET, init_logging}; use aws_sdk_s3::types::ServerSideEncryption; -use serial_test::serial; use std::fs; use std::time::Duration; use tokio::time::sleep; @@ -32,7 +31,6 @@ use tracing::{info, warn}; /// Test KMS behavior when key directory is temporarily unavailable #[tokio::test] -#[serial] async fn test_kms_key_directory_unavailable() -> Result<(), Box> { init_logging(); info!("🧪 Testing KMS behavior with unavailable key directory"); @@ -123,7 +121,6 @@ async fn test_kms_key_directory_unavailable() -> Result<(), Box Result<(), Box> { init_logging(); info!("🧪 Testing KMS behavior with corrupted key files"); @@ -215,7 +212,6 @@ async fn test_kms_corrupted_key_files() -> Result<(), Box Result<(), Box> { init_logging(); info!("🧪 Testing KMS multipart upload interruption and recovery"); @@ -399,7 +395,6 @@ async fn test_kms_multipart_upload_interruption() -> Result<(), Box Result<(), Box> { init_logging(); info!("🧪 Testing KMS behavior under resource constraints"); diff --git a/crates/e2e_test/src/kms/kms_ilm_sse_kms_test.rs b/crates/e2e_test/src/kms/kms_ilm_sse_kms_test.rs index 173e87767..3058f4be9 100644 --- a/crates/e2e_test/src/kms/kms_ilm_sse_kms_test.rs +++ b/crates/e2e_test/src/kms/kms_ilm_sse_kms_test.rs @@ -51,7 +51,6 @@ use aws_sdk_s3::types::{ TransitionStorageClass, }; use serde::Deserialize; -use serial_test::serial; use std::time::{Duration as StdDuration, Instant}; use tracing::info; @@ -424,7 +423,6 @@ async fn wait_for_restore_complete(client: &Client, bucket: &str, key: &str, dea /// filter as the cause of the deletion and proves the encrypted bucket stays /// readable end to end after the scanner has run. #[tokio::test] -#[serial] async fn ilm_expiration_on_sse_kms_bucket_under_enforcement() -> TestResult { init_logging(); @@ -485,7 +483,6 @@ async fn ilm_expiration_on_sse_kms_bucket_under_enforcement() -> TestResult { /// (the mechanism `reliant/tiering.rs` established), so the test does not /// depend on scanner scheduling; the 1s scanner cycle stays on as a backstop. #[tokio::test] -#[serial] async fn ilm_transition_on_sse_kms_bucket_under_enforcement_reads_back() -> TestResult { init_logging(); diff --git a/crates/e2e_test/src/kms/kms_local_test.rs b/crates/e2e_test/src/kms/kms_local_test.rs index 82b44a154..ccda86989 100644 --- a/crates/e2e_test/src/kms/kms_local_test.rs +++ b/crates/e2e_test/src/kms/kms_local_test.rs @@ -24,11 +24,9 @@ use super::common::{ test_kms_key_management, test_sse_c_encryption, }; use crate::common::{TEST_BUCKET, init_logging}; -use serial_test::serial; use tracing::{error, info}; #[tokio::test] -#[serial] 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") { @@ -114,7 +112,6 @@ async fn test_local_kms_end_to_end() -> Result<(), Box Result<(), Box> { init_logging(); info!("🧪 Step 1: Test the basic single-file encryption function"); @@ -85,7 +83,6 @@ async fn test_step1_basic_single_file_encryption() -> Result<(), Box Result<(), Box> { init_logging(); info!("🧪 Step 2: Test unencrypted shard uploads"); @@ -184,7 +181,6 @@ async fn test_step2_basic_multipart_upload_without_encryption() -> Result<(), Bo /// Step 3: Test Shard Upload + SSE-S3 Encryption (Focus Test) #[tokio::test] -#[serial] async fn test_step3_multipart_upload_with_sse_s3() -> Result<(), Box> { init_logging(); info!("🧪 Step 3: Test Shard Upload + SSE-S3 Encryption"); @@ -308,7 +304,6 @@ async fn test_step3_multipart_upload_with_sse_s3() -> Result<(), Box Result<(), Box> { init_logging(); info!("🧪 Step 4: test large-file multipart encryption"); @@ -434,7 +429,6 @@ async fn test_step4_large_multipart_upload_with_encryption() -> Result<(), Box Result<(), Box> { init_logging(); info!("🧪 Step 5: test multipart uploads for every encryption mode"); diff --git a/crates/e2e_test/src/kms/test_runner.rs b/crates/e2e_test/src/kms/test_runner.rs index d5e831b79..558c14631 100644 --- a/crates/e2e_test/src/kms/test_runner.rs +++ b/crates/e2e_test/src/kms/test_runner.rs @@ -19,7 +19,6 @@ //! filtering, and comprehensive reporting capabilities. use crate::common::init_logging; -use serial_test::serial; use std::time::Instant; use tokio::time::{Duration, sleep}; use tracing::{debug, error, info, warn}; @@ -458,7 +457,6 @@ impl KMSTestSuite { /// Quick test suite for critical tests only #[tokio::test] -#[serial] async fn test_kms_critical_suite() -> Result<(), Box> { let config = TestSuiteConfig { categories: vec![TestCategory::CoreFunctionality, TestCategory::MultipartEncryption], @@ -481,7 +479,6 @@ async fn test_kms_critical_suite() -> Result<(), Box Result<(), Box> { let suite = KMSTestSuite::new(); let results = suite.run_test_suite().await; diff --git a/crates/e2e_test/src/leading_slash_key_test.rs b/crates/e2e_test/src/leading_slash_key_test.rs index 4de4812df..841c4f060 100644 --- a/crates/e2e_test/src/leading_slash_key_test.rs +++ b/crates/e2e_test/src/leading_slash_key_test.rs @@ -24,7 +24,6 @@ mod tests { use crate::common::{RustFSTestEnvironment, init_logging}; use aws_sdk_s3::Client; use aws_sdk_s3::primitives::ByteStream; - use serial_test::serial; use std::error::Error; use tracing::info; @@ -36,7 +35,6 @@ mod tests { /// PUT with a leading-slash key must succeed and the object must be /// readable under the normalized key (leading slash stripped). #[tokio::test] - #[serial] async fn test_put_object_with_leading_slash_key() -> Result<(), Box> { init_logging(); info!("Starting test: PUT object with leading slash in key (Issue #2427)"); @@ -94,7 +92,6 @@ mod tests { /// Duplicate and repeated slashes after a leading slash collapse MinIO-style. #[tokio::test] - #[serial] async fn test_put_object_with_duplicate_slashes_normalized() -> Result<(), Box> { init_logging(); info!("Starting test: duplicate slash normalization (Issue #2427)"); diff --git a/crates/e2e_test/src/lifecycle_regression_test.rs b/crates/e2e_test/src/lifecycle_regression_test.rs index e2e1c039e..3a3615dd4 100644 --- a/crates/e2e_test/src/lifecycle_regression_test.rs +++ b/crates/e2e_test/src/lifecycle_regression_test.rs @@ -36,7 +36,6 @@ mod tests { BucketLifecycleConfiguration, BucketVersioningStatus, ExpirationStatus, LifecycleExpiration, LifecycleRule, LifecycleRuleFilter, NoncurrentVersionExpiration, VersioningConfiguration, }; - use serial_test::serial; use std::error::Error; use tracing::info; @@ -80,7 +79,6 @@ mod tests { /// /// This tests the rule persistence path (rustfs#4963: 3 days → 0 days). #[tokio::test] - #[serial] async fn test_lifecycle_expiration_rule_persists_correctly() -> TestResult { init_logging(); info!("RT-03: lifecycle expiration rule persists correctly"); @@ -148,7 +146,6 @@ mod tests { /// Covers the pattern where noncurrent version expiration rules are /// accepted but old versions are never cleaned up. #[tokio::test] - #[serial] async fn test_lifecycle_noncurrent_version_expiration_rule_persists() -> TestResult { init_logging(); info!("RT-03b: noncurrent version expiration rule persists"); @@ -233,7 +230,6 @@ mod tests { /// after restart. Transition rules require a configured remote tier /// (tested in reliant/tiering.rs), so this test uses expiration only. #[tokio::test] - #[serial] async fn test_lifecycle_prefix_rule_persists() -> TestResult { init_logging(); info!("RT-04: lifecycle prefix rule persists"); @@ -294,7 +290,6 @@ mod tests { /// Regression pattern: DELETE on a versioned object fails or does not /// create a delete marker, or the delete marker is not visible in LIST. #[tokio::test] - #[serial] async fn test_delete_marker_creation_and_visibility() -> TestResult { init_logging(); info!("RT-05b: delete marker creation and visibility"); diff --git a/crates/e2e_test/src/list_buckets_double_slash_test.rs b/crates/e2e_test/src/list_buckets_double_slash_test.rs index ddbb68307..592b252b4 100644 --- a/crates/e2e_test/src/list_buckets_double_slash_test.rs +++ b/crates/e2e_test/src/list_buckets_double_slash_test.rs @@ -27,7 +27,6 @@ mod tests { use rustfs_signer::constants::UNSIGNED_PAYLOAD; use rustfs_signer::sign_v4; use s3s::Body; - use serial_test::serial; use std::error::Error; /// Sends a SigV4-signed `GET` where the signature is computed over `sign_path` @@ -67,7 +66,6 @@ mod tests { /// `GET /` (path-style service call) returns `ListBuckets`. #[tokio::test] - #[serial] async fn test_list_buckets_single_slash() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -86,7 +84,6 @@ mod tests { /// compat layer rewrites `//` to `/` before `s3s` parses/verifies the request, /// so both routing and signature verification operate on `/`. #[tokio::test] - #[serial] async fn test_list_buckets_double_slash_browser_compat() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -105,7 +102,6 @@ mod tests { /// (`GET //bucket`) must be left untouched by the compat layer — it is not a /// `ListBuckets` request and s3s continues to reject the empty bucket name. #[tokio::test] - #[serial] async fn test_double_slash_rewrite_is_narrowly_scoped() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; diff --git a/crates/e2e_test/src/list_buckets_iam_filter_test.rs b/crates/e2e_test/src/list_buckets_iam_filter_test.rs index ca748be1a..ac15e0713 100644 --- a/crates/e2e_test/src/list_buckets_iam_filter_test.rs +++ b/crates/e2e_test/src/list_buckets_iam_filter_test.rs @@ -15,7 +15,6 @@ use crate::common::{RustFSTestEnvironment, admin_ok, build_test_s3_config, build_test_sts_client, init_logging}; use aws_sdk_s3::Client; use aws_sdk_s3::error::ProvideErrorMetadata; -use serial_test::serial; use tokio::time::{Duration, Instant}; fn user_client(env: &RustFSTestEnvironment, access_key: &str, secret_key: &str, session_token: Option<&str>) -> Client { @@ -76,7 +75,6 @@ async fn create_service_account( } #[tokio::test] -#[serial] async fn list_buckets_filters_with_iam_bucket_resources() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; diff --git a/crates/e2e_test/src/list_object_versions_metadata_extension_test.rs b/crates/e2e_test/src/list_object_versions_metadata_extension_test.rs index 150c45090..1e5fd0977 100644 --- a/crates/e2e_test/src/list_object_versions_metadata_extension_test.rs +++ b/crates/e2e_test/src/list_object_versions_metadata_extension_test.rs @@ -24,7 +24,6 @@ mod tests { use rustfs_signer::constants::UNSIGNED_PAYLOAD; use rustfs_signer::sign_v4; use s3s::Body; - use serial_test::serial; use std::error::Error; use tracing::info; @@ -54,7 +53,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_list_object_versions_metadata_extension_returns_metadata_tags_and_internal() -> Result<(), Box> { init_logging(); diff --git a/crates/e2e_test/src/list_object_versions_regression_test.rs b/crates/e2e_test/src/list_object_versions_regression_test.rs index b7365a8de..0c29dc110 100644 --- a/crates/e2e_test/src/list_object_versions_regression_test.rs +++ b/crates/e2e_test/src/list_object_versions_regression_test.rs @@ -21,7 +21,6 @@ mod tests { use aws_sdk_s3::Client; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{BucketVersioningStatus, VersioningConfiguration}; - use serial_test::serial; use tracing::info; fn create_s3_client(env: &RustFSTestEnvironment) -> Client { @@ -29,7 +28,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_list_object_versions_immediately_returns_latest_put_after_delete_marker() { init_logging(); info!("🧪 TEST: ListObjectVersions returns the newest version immediately after put -> delete -> put"); @@ -182,7 +180,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_list_object_versions_prefix_with_marker_object_returns_children() { init_logging(); info!("🧪 TEST: ListObjectVersions returns prefix children when a marker object also exists"); diff --git a/crates/e2e_test/src/list_objects_duplicates_test.rs b/crates/e2e_test/src/list_objects_duplicates_test.rs index 2d7a74351..9b8349dcc 100644 --- a/crates/e2e_test/src/list_objects_duplicates_test.rs +++ b/crates/e2e_test/src/list_objects_duplicates_test.rs @@ -17,7 +17,6 @@ mod tests { use crate::common::{RustFSTestEnvironment, init_logging}; use aws_sdk_s3::Client; use aws_sdk_s3::primitives::ByteStream; - use serial_test::serial; use tracing::info; /// Helper function to create an S3 client for testing @@ -60,7 +59,6 @@ mod tests { /// The bug was that "folder/" (the object) and "folder/" (derived prefix) were both added to CommonPrefixes /// when delimiter was "/" because the deduplication check was explicitly skipped for "/" delimiter. #[tokio::test] - #[serial] async fn test_list_objects_v2_unique_common_prefixes() { init_logging(); info!("Starting test: ListObjectsV2 should return unique CommonPrefixes"); @@ -140,7 +138,6 @@ mod tests { /// When both "marker/subdir/" and "marker/subdir/file.txt" exist, listing with /// Prefix="marker/" must not duplicate "marker/subdir/file.txt" in Contents. #[tokio::test] - #[serial] async fn test_list_objects_v2_unique_contents_with_explicit_directory_markers() { init_logging(); info!("Starting test: ListObjectsV2 should return unique keys with explicit directory markers"); @@ -208,7 +205,6 @@ mod tests { /// and never produce the prefix entry `a/`. Delimiter="/" listings then /// returned Contents `a` but silently dropped CommonPrefix `a/`. #[tokio::test] - #[serial] async fn test_list_objects_v2_object_and_same_named_prefix_coexist() { init_logging(); info!("Starting test: ListObjectsV2 should return both object `a` and CommonPrefix `a/`"); diff --git a/crates/e2e_test/src/list_objects_v2_metadata_extension_test.rs b/crates/e2e_test/src/list_objects_v2_metadata_extension_test.rs index 72be61b6c..2cad0cc68 100644 --- a/crates/e2e_test/src/list_objects_v2_metadata_extension_test.rs +++ b/crates/e2e_test/src/list_objects_v2_metadata_extension_test.rs @@ -23,7 +23,6 @@ mod tests { use rustfs_signer::constants::UNSIGNED_PAYLOAD; use rustfs_signer::sign_v4; use s3s::Body; - use serial_test::serial; use std::error::Error; use tracing::info; @@ -53,7 +52,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_list_objects_v2_metadata_extension_returns_metadata_tags_and_internal() -> Result<(), Box> { init_logging(); diff --git a/crates/e2e_test/src/list_objects_v2_pagination_test.rs b/crates/e2e_test/src/list_objects_v2_pagination_test.rs index c970713d8..70b00467b 100644 --- a/crates/e2e_test/src/list_objects_v2_pagination_test.rs +++ b/crates/e2e_test/src/list_objects_v2_pagination_test.rs @@ -30,7 +30,6 @@ mod tests { use crate::common::{RustFSTestEnvironment, init_logging}; use aws_sdk_s3::Client; use aws_sdk_s3::primitives::ByteStream; - use serial_test::serial; use std::collections::HashSet; use tracing::info; @@ -61,7 +60,6 @@ mod tests { /// Test for Issue #2775: continuation forwarding must not /// skip a child directory when the prefix component repeats in the key. #[tokio::test] - #[serial] async fn test_list_objects_v2_repeated_prefix_continuation() { init_logging(); info!("Starting test: ListObjectsV2 repeated-prefix continuation"); @@ -187,7 +185,6 @@ mod tests { /// This is the core bug from issue #1596: the server was returning /// IsTruncated=true even when all objects fit within the requested max_keys. #[tokio::test] - #[serial] async fn test_list_objects_v2_not_truncated_when_all_objects_returned() { init_logging(); info!("Starting test: ListObjectsV2 should not be truncated when all objects fit within max_keys"); @@ -252,7 +249,6 @@ mod tests { /// 2. NextContinuationToken is returned (not NextMarker) /// 3. Using ContinuationToken fetches the remaining objects #[tokio::test] - #[serial] async fn test_list_objects_v2_pagination_with_continuation_token() { init_logging(); info!("Starting test: ListObjectsV2 pagination with continuation token"); @@ -394,7 +390,6 @@ mod tests { /// Edge case: when max_keys exactly equals the number of objects, /// IsTruncated should be false. #[tokio::test] - #[serial] async fn test_list_objects_v2_max_keys_equals_object_count() { init_logging(); info!("Starting test: ListObjectsV2 with max_keys equal to object count"); @@ -455,7 +450,6 @@ mod tests { /// /// Edge case: IsTruncated should be false for empty bucket. #[tokio::test] - #[serial] async fn test_list_objects_v2_empty_bucket() { init_logging(); info!("Starting test: ListObjectsV2 with empty bucket"); @@ -495,7 +489,6 @@ mod tests { /// Test ListObjectsV2 caps max_keys above the service limit and still paginates. #[tokio::test] - #[serial] async fn test_list_objects_v2_max_keys_above_limit_returns_token() { init_logging(); info!("Starting test: ListObjectsV2 with max_keys above limit"); @@ -563,7 +556,6 @@ mod tests { /// S3 semantics: when max_keys is 0, the response should include no objects /// and IsTruncated should be false. #[tokio::test] - #[serial] async fn test_list_objects_v2_max_keys_zero() { init_logging(); info!("Starting test: ListObjectsV2 with max_keys=0"); @@ -620,7 +612,6 @@ mod tests { /// With max_keys=1000, all 5 visible results (3 prefixes + 2 objects) fit in one /// page, so IsTruncated must be false even though raw entry count is much larger. #[tokio::test] - #[serial] async fn test_list_objects_v2_delimiter_collapsed_prefix_no_false_truncation() { init_logging(); info!("Starting test: ListObjectsV2 delimiter collapsed-prefix no false truncation"); @@ -744,7 +735,6 @@ mod tests { /// Each page returns up to 50 CommonPrefixes. The server must correctly set /// IsTruncated and provide a valid continuation token across all pages. #[tokio::test] - #[serial] async fn test_list_objects_v2_delimiter_small_page_traverses_all() { init_logging(); info!("Starting test: ListObjectsV2 delimiter small page traverses all keys"); @@ -867,7 +857,6 @@ mod tests { /// but after delimiter collapse only 10 CommonPrefixes are visible (10 < 1000). /// IsTruncated must be false since there are no additional visible results. #[tokio::test] - #[serial] async fn test_list_objects_v2_raw_exceeds_maxkeys_but_visible_below() { init_logging(); info!("Starting test: ListObjectsV2 raw > MaxKeys but visible < MaxKeys after collapse"); @@ -970,7 +959,6 @@ mod tests { /// This complements test_list_objects_v2_max_keys_above_limit_returns_token which /// tests the non-delimiter case. #[tokio::test] - #[serial] async fn test_list_objects_v2_maxkeys_above_limit_with_delimiter() { init_logging(); info!("Starting test: ListObjectsV2 MaxKeys above limit with delimiter"); @@ -1041,7 +1029,6 @@ mod tests { /// the next page: with keys `a`, `a.txt`, `zz` and max_keys=1, page 2 /// returned `zz` and `a.txt` was never listed. #[tokio::test] - #[serial] async fn test_list_objects_v2_continuation_keeps_keys_after_marker_stem() { init_logging(); info!("Starting test: continuation must not skip keys sorting below the cursor tag"); diff --git a/crates/e2e_test/src/listing_regression_test.rs b/crates/e2e_test/src/listing_regression_test.rs index 914b3aab3..ee2569f29 100644 --- a/crates/e2e_test/src/listing_regression_test.rs +++ b/crates/e2e_test/src/listing_regression_test.rs @@ -31,7 +31,6 @@ mod tests { use crate::common::{RustFSTestEnvironment, init_logging}; use aws_sdk_s3::primitives::ByteStream; - use serial_test::serial; use std::collections::HashSet; use std::error::Error; use tracing::info; @@ -49,7 +48,6 @@ mod tests { /// 3. Verify all 100 keys are returned exactly once /// 4. Verify no duplicates or skipped keys #[tokio::test] - #[serial] async fn test_list_objects_v2_completeness_100_objects() -> TestResult { init_logging(); info!("RT-06: listing completeness with 100 objects"); @@ -133,7 +131,6 @@ mod tests { /// Regression pattern: prefix filter returns empty or includes wrong keys /// (rustfs#5051: empty results for shallow prefixes). #[tokio::test] - #[serial] async fn test_list_objects_v2_prefix_filter_correctness() -> TestResult { init_logging(); info!("RT-06b: prefix filter correctness"); @@ -233,7 +230,6 @@ mod tests { /// Regression pattern: delimiter handling produces incorrect CommonPrefixes /// or misses objects at the delimiter boundary. #[tokio::test] - #[serial] async fn test_list_objects_v2_delimiter_common_prefixes() -> TestResult { init_logging(); info!("RT-06c: delimiter and CommonPrefixes"); @@ -290,7 +286,6 @@ mod tests { /// Regression pattern: IsTruncated=false when there are more objects /// (rustfs#4810: walk_dir timeout truncation with false IsTruncated). #[tokio::test] - #[serial] async fn test_list_objects_v2_is_truncated_correctness() -> TestResult { init_logging(); info!("RT-06d: IsTruncated correctness"); 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 6654a8663..2a9c1a507 100644 --- a/crates/e2e_test/src/mc_mirror_small_bucket_test.rs +++ b/crates/e2e_test/src/mc_mirror_small_bucket_test.rs @@ -13,7 +13,6 @@ // limitations under the License. use crate::common::{DEFAULT_ACCESS_KEY, DEFAULT_SECRET_KEY, RustFSTestEnvironment}; -use serial_test::serial; use std::path::Path; use std::process::Command; use std::time::Duration; @@ -73,7 +72,6 @@ fn count_files(root: &Path) -> usize { } #[tokio::test] -#[serial] async fn test_mc_mirror_small_bucket_completes_without_list_timeout() -> TestResult { crate::common::init_logging(); info!("Starting issue #3107 mc mirror regression test"); diff --git a/crates/e2e_test/src/namespace_lock_quorum_test.rs b/crates/e2e_test/src/namespace_lock_quorum_test.rs index 9b9e1d53f..0af609ecc 100644 --- a/crates/e2e_test/src/namespace_lock_quorum_test.rs +++ b/crates/e2e_test/src/namespace_lock_quorum_test.rs @@ -16,7 +16,6 @@ use crate::common::RustFSTestClusterEnvironment; use aws_sdk_s3::Client; use aws_sdk_s3::error::SdkError; use bytes::Bytes; -use serial_test::serial; use std::sync::Arc; use tokio::sync::Barrier; use tracing::{info, warn}; @@ -51,7 +50,6 @@ fn format_s3_error(err: SdkError TestResult { crate::common::init_logging(); info!("Starting namespace lock quorum regression test with auto cluster"); @@ -128,7 +126,6 @@ async fn test_concurrent_cluster_overwrites_do_not_fail_namespace_lock_quorum() /// `StorageError::other(...)` → `StorageError::Io(...)`, which fell through to /// `S3ErrorCode::InternalError` (500) in the error mapping. #[tokio::test] -#[serial] async fn test_concurrent_put_same_key_never_returns_500() -> TestResult { crate::common::init_logging(); info!("Starting concurrent PUT 500 regression test"); diff --git a/crates/e2e_test/src/negative_sigv4_test.rs b/crates/e2e_test/src/negative_sigv4_test.rs index f0539e0a0..a6a440383 100644 --- a/crates/e2e_test/src/negative_sigv4_test.rs +++ b/crates/e2e_test/src/negative_sigv4_test.rs @@ -37,7 +37,6 @@ use crate::common::{RustFSTestEnvironment, init_logging, local_http_client}; use aws_sdk_s3::primitives::ByteStream; use rustfs_signer::constants::UNSIGNED_PAYLOAD; use rustfs_signer::request_signature_v4::{SIGN_V4_ALGORITHM, get_scope, get_signature, get_signing_key}; -use serial_test::serial; use std::fmt::Write as _; use time::macros::format_description; use time::{Duration, OffsetDateTime}; @@ -183,7 +182,6 @@ async fn setup(env: &mut RustFSTestEnvironment) -> Result<(), Box Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -214,7 +212,6 @@ async fn valid_header_sigv4_request_succeeds() -> Result<(), Box Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -254,7 +251,6 @@ async fn tampered_signature_returns_signature_does_not_match() -> Result<(), Box /// (b) A valid AccessKeyId paired with the wrong secret key must be rejected /// with SignatureDoesNotMatch / 403. #[tokio::test] -#[serial] async fn wrong_secret_key_returns_signature_does_not_match() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -279,7 +275,6 @@ async fn wrong_secret_key_returns_signature_does_not_match() -> Result<(), Box Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -320,7 +315,6 @@ async fn tampered_payload_is_rejected() -> Result<(), Box Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -344,7 +338,6 @@ async fn skewed_date_returns_request_time_too_skewed() -> Result<(), Box Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; diff --git a/crates/e2e_test/src/notification_startup_regression_test.rs b/crates/e2e_test/src/notification_startup_regression_test.rs index f554d3cfd..0d0feed98 100644 --- a/crates/e2e_test/src/notification_startup_regression_test.rs +++ b/crates/e2e_test/src/notification_startup_regression_test.rs @@ -32,7 +32,6 @@ mod tests { use crate::common::{RustFSTestEnvironment, init_logging}; use aws_sdk_s3::types::{BucketVersioningStatus, VersioningConfiguration}; - use serial_test::serial; use std::error::Error; use tracing::info; @@ -47,7 +46,6 @@ mod tests { /// starts successfully with notification enabled and can serve S3 requests. /// A full webhook delivery test is in notification_webhook_test.rs. #[tokio::test] - #[serial] async fn test_notification_enabled_server_starts_cleanly() -> TestResult { init_logging(); info!("RT-01: notification enabled server starts cleanly"); @@ -92,7 +90,6 @@ mod tests { /// 3. Restart server /// 4. Verify notification config still exists #[tokio::test] - #[serial] async fn test_notification_config_survives_restart() -> TestResult { init_logging(); info!("RT-02: notification config survives restart"); diff --git a/crates/e2e_test/src/notification_webhook_test.rs b/crates/e2e_test/src/notification_webhook_test.rs index e63cea554..1eec17343 100644 --- a/crates/e2e_test/src/notification_webhook_test.rs +++ b/crates/e2e_test/src/notification_webhook_test.rs @@ -47,7 +47,6 @@ use rustfs_utils::egress::ENV_OUTBOUND_ALLOW_ORIGINS; use rustfs_utils::http::headers::{AMZ_REQUEST_ID, REQUEST_ID_HEADER}; use s3s::Body; use serde_json::Value; -use serial_test::serial; use std::error::Error; use std::io::Cursor; use std::path::Path; @@ -625,7 +624,6 @@ fn assert_generated_request_id_correlation(record: &Value, request_id: &str) { /// RUSTFS_NOTIFY_ENABLE, an HTTPS webhook using a configured CA must become /// online and receive a real S3 event POST. #[tokio::test] -#[serial] async fn test_https_webhook_target_delivers_event_with_notify_env_enabled() -> TestResult { init_logging(); @@ -680,7 +678,6 @@ async fn test_https_webhook_target_delivers_event_with_notify_env_enabled() -> T /// PUT / multipart-complete / DELETE each deliver one event with correct fields, /// and the prefix/suffix filter drops non-matching keys. #[tokio::test] -#[serial] async fn test_webhook_event_delivery_and_filtering() -> TestResult { init_logging(); @@ -900,7 +897,6 @@ async fn test_webhook_event_delivery_and_filtering() -> TestResult { /// An event queued while the target endpoint rejects delivery survives on the /// durable store and is redelivered once the endpoint comes back. #[tokio::test] -#[serial] async fn test_webhook_redelivers_event_after_target_recovers() -> TestResult { init_logging(); diff --git a/crates/e2e_test/src/object_lambda_test.rs b/crates/e2e_test/src/object_lambda_test.rs index 69d2e46ef..66f259e6d 100644 --- a/crates/e2e_test/src/object_lambda_test.rs +++ b/crates/e2e_test/src/object_lambda_test.rs @@ -20,7 +20,6 @@ use rustfs_signer::constants::UNSIGNED_PAYLOAD; use rustfs_signer::{pre_sign_v4, sign_v4}; use rustfs_utils::egress::ENV_OUTBOUND_ALLOW_ORIGINS; use s3s::Body; -use serial_test::serial; use std::collections::HashMap; use std::error::Error; use time::OffsetDateTime; @@ -548,7 +547,6 @@ async fn read_listen_notification_event( } #[tokio::test] -#[serial] async fn test_notification_target_persists_across_restart_and_delete() -> Result<(), Box> { init_logging(); @@ -608,7 +606,6 @@ async fn test_notification_target_persists_across_restart_and_delete() -> Result } #[tokio::test] -#[serial] async fn test_notification_target_with_path_is_online_via_transport_probe() -> Result<(), Box> { init_logging(); @@ -641,7 +638,6 @@ async fn test_notification_target_with_path_is_online_via_transport_probe() -> R } #[tokio::test] -#[serial] async fn test_get_object_lambda_accepts_presigned_requests() -> Result<(), Box> { init_logging(); @@ -682,7 +678,6 @@ async fn test_get_object_lambda_accepts_presigned_requests() -> Result<(), Box Result<(), Box> { init_logging(); @@ -722,7 +717,6 @@ async fn test_get_object_lambda_accepts_named_webhook_target_arn() -> Result<(), } #[tokio::test] -#[serial] async fn test_get_object_lambda_invokes_runtime_webhook_target() -> Result<(), Box> { init_logging(); @@ -790,7 +784,6 @@ async fn test_get_object_lambda_invokes_runtime_webhook_target() -> Result<(), B } #[tokio::test] -#[serial] async fn test_get_object_lambda_passthroughs_non_success_webhook_response() -> Result<(), Box> { init_logging(); @@ -850,7 +843,6 @@ async fn test_get_object_lambda_passthroughs_non_success_webhook_response() -> R } #[tokio::test] -#[serial] async fn test_get_object_lambda_rejects_success_response_without_auth_headers() -> Result<(), Box> { init_logging(); @@ -896,7 +888,6 @@ async fn test_get_object_lambda_rejects_success_response_without_auth_headers() } #[tokio::test] -#[serial] async fn test_get_object_lambda_rejects_success_response_with_mismatched_auth_headers() -> Result<(), Box> { init_logging(); @@ -943,7 +934,6 @@ async fn test_get_object_lambda_rejects_success_response_with_mismatched_auth_he } #[tokio::test] -#[serial] async fn test_get_object_lambda_rejects_unsupported_target_type() -> Result<(), Box> { init_logging(); @@ -980,7 +970,6 @@ async fn test_get_object_lambda_rejects_unsupported_target_type() -> Result<(), } #[tokio::test] -#[serial] async fn test_get_object_lambda_rejects_unconfigured_target() -> Result<(), Box> { init_logging(); @@ -1017,7 +1006,6 @@ async fn test_get_object_lambda_rejects_unconfigured_target() -> Result<(), Box< } #[tokio::test] -#[serial] async fn test_get_object_lambda_rejects_disabled_target() -> Result<(), Box> { init_logging(); @@ -1063,7 +1051,6 @@ async fn test_get_object_lambda_rejects_disabled_target() -> Result<(), Box Result<(), Box> { init_logging(); @@ -1106,7 +1093,6 @@ async fn test_configure_object_lambda_target_rejects_invalid_endpoint() -> Resul } #[tokio::test] -#[serial] async fn test_configure_object_lambda_notify_webhook_rejects_response_header_timeout_key() -> Result<(), Box> { init_logging(); @@ -1140,7 +1126,6 @@ async fn test_configure_object_lambda_notify_webhook_rejects_response_header_tim } #[tokio::test] -#[serial] async fn test_listen_notification_emits_after_put_object() -> Result<(), Box> { init_logging(); @@ -1184,7 +1169,6 @@ async fn test_listen_notification_emits_after_put_object() -> Result<(), Box Result<(), Box> { init_logging(); @@ -1219,7 +1203,6 @@ async fn test_listen_notification_emits_on_empty_bucket_when_notify_disabled() - } #[tokio::test] -#[serial] async fn test_listen_notification_fans_in_remote_node_events() -> Result<(), Box> { init_logging(); diff --git a/crates/e2e_test/src/overwrite_cleanup_regression_test.rs b/crates/e2e_test/src/overwrite_cleanup_regression_test.rs index f41113b12..7be7c26ea 100644 --- a/crates/e2e_test/src/overwrite_cleanup_regression_test.rs +++ b/crates/e2e_test/src/overwrite_cleanup_regression_test.rs @@ -13,7 +13,6 @@ // limitations under the License. use aws_sdk_s3::primitives::ByteStream; -use serial_test::serial; use std::path::{Path, PathBuf}; use uuid::Uuid; @@ -24,7 +23,6 @@ const TEST_OBJECT: &str = "large-object.bin"; const PAYLOAD_SIZE: usize = 512 * 1024; #[tokio::test(flavor = "multi_thread")] -#[serial] async fn unversioned_overwrite_removes_previous_physical_data_dir() -> Result<(), Box> { init_logging(); diff --git a/crates/e2e_test/src/presigned_negative_test.rs b/crates/e2e_test/src/presigned_negative_test.rs index 767cc7ca5..31df39fd0 100644 --- a/crates/e2e_test/src/presigned_negative_test.rs +++ b/crates/e2e_test/src/presigned_negative_test.rs @@ -43,7 +43,6 @@ use aws_sdk_s3::presigning::{PresignedRequest, PresigningConfig}; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::{Client, Config}; use aws_smithy_http_client::Builder as SmithyHttpClientBuilder; -use serial_test::serial; use std::time::{Duration, SystemTime}; use tracing::info; @@ -157,7 +156,6 @@ async fn setup(env: &mut RustFSTestEnvironment) -> Result<(), Box Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -182,7 +180,6 @@ async fn valid_presigned_get_succeeds() -> Result<(), Box Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -211,7 +208,6 @@ async fn valid_presigned_put_succeeds() -> Result<(), Box Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -236,7 +232,6 @@ async fn expired_presigned_get_is_rejected() -> Result<(), Box Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -262,7 +257,6 @@ async fn tampered_signature_returns_signature_does_not_match() -> Result<(), Box /// (c) A presigned URL generated with the WRONG secret (but the real access key /// id) must be rejected with 403 / SignatureDoesNotMatch. #[tokio::test] -#[serial] async fn wrong_secret_key_returns_signature_does_not_match() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -290,7 +284,6 @@ async fn wrong_secret_key_returns_signature_does_not_match() -> Result<(), Box Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -325,7 +318,6 @@ async fn tampered_target_key_returns_signature_does_not_match() -> Result<(), Bo /// (e / acceptance 4 negative half) Tampering the signature of a presigned PUT /// must be rejected with 403 / SignatureDoesNotMatch — the write must not land. #[tokio::test] -#[serial] async fn tampered_presigned_put_returns_signature_does_not_match() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; diff --git a/crates/e2e_test/src/protocols/test_runner.rs b/crates/e2e_test/src/protocols/test_runner.rs index 0a578804d..7150ab2cd 100644 --- a/crates/e2e_test/src/protocols/test_runner.rs +++ b/crates/e2e_test/src/protocols/test_runner.rs @@ -22,7 +22,6 @@ use crate::protocols::sftp_compliance::{ }; use crate::protocols::sftp_core::{test_sftp_core_operations, test_sftp_idle_timeout_disconnects}; use crate::protocols::webdav_core::test_webdav_core_operations; -use serial_test::serial; use std::time::Instant; use tokio::time::{Duration, sleep}; use tracing::{error, info}; @@ -229,7 +228,6 @@ fn all_protocol_tests() -> Vec { /// Test suite #[tokio::test] -#[serial] async fn test_protocol_core_suite() -> Result<(), Box> { let suite = ProtocolTestSuite::new(); let results = suite.run_test_suite().await; diff --git a/crates/e2e_test/src/quota_test.rs b/crates/e2e_test/src/quota_test.rs index 87eee5f37..e7c095674 100644 --- a/crates/e2e_test/src/quota_test.rs +++ b/crates/e2e_test/src/quota_test.rs @@ -15,7 +15,6 @@ use crate::common::{RustFSTestEnvironment, admin_request, awscurl_delete, awscurl_get, awscurl_post, awscurl_put, init_logging}; use aws_sdk_s3::Client; use http::{Method, StatusCode}; -use serial_test::serial; use tokio::time::{Duration, sleep, timeout}; use tracing::{debug, info}; @@ -255,7 +254,6 @@ mod integration_tests { use aws_sdk_s3::error::ProvideErrorMetadata; #[tokio::test] - #[serial] async fn test_quota_basic_operations() -> Result<(), Box> { init_logging(); if skip_without_awscurl() { @@ -300,7 +298,6 @@ mod integration_tests { /// with 400 UnexpectedContent, and an over-quota aws-chunked PUT must still get the quota /// rejection. #[tokio::test] - #[serial] async fn test_quota_admission_aws_chunked_declared_encoding() -> Result<(), Box> { init_logging(); if skip_without_awscurl() { @@ -352,7 +349,6 @@ mod integration_tests { } #[tokio::test] - #[serial] async fn test_quota_update_and_clear() -> Result<(), Box> { init_logging(); if skip_without_awscurl() { @@ -388,7 +384,6 @@ mod integration_tests { } #[tokio::test] - #[serial] async fn test_quota_delete_operations() -> Result<(), Box> { init_logging(); if skip_without_awscurl() { @@ -425,7 +420,6 @@ mod integration_tests { } #[tokio::test] - #[serial] async fn test_quota_usage_tracking() -> Result<(), Box> { init_logging(); if skip_without_awscurl() { @@ -464,7 +458,6 @@ mod integration_tests { } #[tokio::test] - #[serial] async fn test_quota_statistics() -> Result<(), Box> { init_logging(); if skip_without_awscurl() { @@ -498,7 +491,6 @@ mod integration_tests { } #[tokio::test] - #[serial] async fn test_quota_check_api() -> Result<(), Box> { init_logging(); if skip_without_awscurl() { @@ -539,7 +531,6 @@ mod integration_tests { } #[tokio::test] - #[serial] async fn test_quota_multiple_buckets() -> Result<(), Box> { init_logging(); if skip_without_awscurl() { @@ -580,7 +571,6 @@ mod integration_tests { } #[tokio::test] - #[serial] async fn test_quota_error_handling() -> Result<(), Box> { init_logging(); if skip_without_awscurl() { @@ -616,7 +606,6 @@ mod integration_tests { } #[tokio::test] - #[serial] async fn test_quota_http_endpoints() -> Result<(), Box> { init_logging(); if skip_without_awscurl() { @@ -682,7 +671,6 @@ mod integration_tests { /// Test that a normal user with `readwrite` policy can read quota but cannot set/clear quota. #[tokio::test] - #[serial] async fn test_quota_normal_user_permissions() -> Result<(), Box> { init_logging(); if skip_without_awscurl() { @@ -738,7 +726,6 @@ mod integration_tests { } #[tokio::test] - #[serial] async fn test_quota_copy_operations() -> Result<(), Box> { init_logging(); if skip_without_awscurl() { @@ -784,7 +771,6 @@ mod integration_tests { } #[tokio::test] - #[serial] async fn test_quota_batch_delete() -> Result<(), Box> { init_logging(); if skip_without_awscurl() { @@ -843,7 +829,6 @@ mod integration_tests { } #[tokio::test] - #[serial] async fn test_quota_multipart_upload() -> Result<(), Box> { init_logging(); if skip_without_awscurl() { diff --git a/crates/e2e_test/src/reliant/conditional_writes.rs b/crates/e2e_test/src/reliant/conditional_writes.rs index 843ecc4e0..166ce66f5 100644 --- a/crates/e2e_test/src/reliant/conditional_writes.rs +++ b/crates/e2e_test/src/reliant/conditional_writes.rs @@ -6,7 +6,6 @@ use aws_sdk_s3::config::{Credentials, Region}; use aws_sdk_s3::error::SdkError; use aws_sdk_s3::types::{CompletedMultipartUpload, CompletedPart}; use bytes::Bytes; -use serial_test::serial; use std::error::Error; const ENDPOINT: &str = "http://localhost:9000"; @@ -89,7 +88,6 @@ fn generate_test_key(prefix: &str) -> String { } #[tokio::test] -#[serial] #[ignore = "requires running RustFS server at localhost:9000"] async fn test_conditional_put_okay() -> Result<(), Box> { let client = create_aws_s3_client().await?; @@ -132,7 +130,6 @@ async fn test_conditional_put_okay() -> Result<(), Box> { } #[tokio::test] -#[serial] #[ignore = "requires running RustFS server at localhost:9000"] async fn test_conditional_put_failed() -> Result<(), Box> { let client = create_aws_s3_client().await?; @@ -195,7 +192,6 @@ async fn test_conditional_put_failed() -> Result<(), Box> } #[tokio::test] -#[serial] #[ignore = "requires running RustFS server at localhost:9000"] async fn test_conditional_put_when_object_does_not_exist() -> Result<(), Box> { let client = create_aws_s3_client().await?; @@ -240,7 +236,6 @@ async fn test_conditional_put_when_object_does_not_exist() -> Result<(), Box Result<(), Box> { let client = create_aws_s3_client().await?; diff --git a/crates/e2e_test/src/reliant/get_deleted_object_test.rs b/crates/e2e_test/src/reliant/get_deleted_object_test.rs index b34159ec1..2b87a11c6 100644 --- a/crates/e2e_test/src/reliant/get_deleted_object_test.rs +++ b/crates/e2e_test/src/reliant/get_deleted_object_test.rs @@ -24,7 +24,6 @@ use aws_sdk_s3::Client; use aws_sdk_s3::config::{Credentials, Region}; use aws_sdk_s3::error::SdkError; use bytes::Bytes; -use serial_test::serial; use std::error::Error; use tracing::info; @@ -70,7 +69,6 @@ async fn setup_test_bucket(client: &Client) -> Result<(), Box> { } #[tokio::test] -#[serial] #[ignore = "requires running RustFS server at localhost:9000"] async fn test_get_deleted_object_returns_nosuchkey() -> Result<(), Box> { // Initialize logging @@ -144,7 +142,6 @@ async fn test_get_deleted_object_returns_nosuchkey() -> Result<(), Box Result<(), Box> { let _ = tracing_subscriber::fmt() @@ -196,7 +193,6 @@ async fn test_head_deleted_object_returns_nosuchkey() -> Result<(), Box Result<(), Box> { let _ = tracing_subscriber::fmt() @@ -233,7 +229,6 @@ async fn test_get_nonexistent_object_returns_nosuchkey() -> Result<(), Box Result<(), Box> { let _ = tracing_subscriber::fmt() diff --git a/crates/e2e_test/src/reliant/head_deleted_object_versioning_test.rs b/crates/e2e_test/src/reliant/head_deleted_object_versioning_test.rs index a4d471754..b89579bde 100644 --- a/crates/e2e_test/src/reliant/head_deleted_object_versioning_test.rs +++ b/crates/e2e_test/src/reliant/head_deleted_object_versioning_test.rs @@ -25,7 +25,6 @@ use aws_sdk_s3::config::{Credentials, Region}; use aws_sdk_s3::error::SdkError; use aws_sdk_s3::types::{BucketVersioningStatus, VersioningConfiguration}; use bytes::Bytes; -use serial_test::serial; use std::error::Error; use tracing::info; @@ -85,7 +84,6 @@ async fn setup_test_bucket(client: &Client) -> Result<(), Box> { /// Test that HeadObject on a deleted object returns NoSuchKey when versioning is enabled #[tokio::test] -#[serial] #[ignore = "requires running RustFS server at localhost:9000"] async fn test_head_deleted_object_versioning_returns_nosuchkey() -> Result<(), Box> { let _ = tracing_subscriber::fmt() diff --git a/crates/e2e_test/src/reliant/head_tls_bodyless_test.rs b/crates/e2e_test/src/reliant/head_tls_bodyless_test.rs index 6ef214a17..a535e431e 100644 --- a/crates/e2e_test/src/reliant/head_tls_bodyless_test.rs +++ b/crates/e2e_test/src/reliant/head_tls_bodyless_test.rs @@ -30,7 +30,6 @@ use reqwest::{Certificate, Client, Response, StatusCode}; use rustfs_signer::constants::UNSIGNED_PAYLOAD; use rustfs_signer::sign_v4; use s3s::Body; -use serial_test::serial; use std::error::Error; use std::path::Path; use std::process::Command; @@ -157,7 +156,6 @@ async fn start_tls_rustfs_server(env: &mut RustFSTestEnvironment, tls_dir: &Path } #[tokio::test] -#[serial] async fn test_head_missing_object_over_tls_http2_is_bodyless() -> Result<(), Box> { init_logging(); diff --git a/crates/e2e_test/src/reliant/sql.rs b/crates/e2e_test/src/reliant/sql.rs index 35ef8bcae..6f63ddab0 100644 --- a/crates/e2e_test/src/reliant/sql.rs +++ b/crates/e2e_test/src/reliant/sql.rs @@ -20,7 +20,6 @@ use aws_sdk_s3::types::{ CsvInput, CsvOutput, ExpressionType, FileHeaderInfo, InputSerialization, JsonInput, JsonOutput, JsonType, OutputSerialization, }; use bytes::Bytes; -use serial_test::serial; use std::error::Error; const ENDPOINT: &str = "http://localhost:9000"; @@ -118,7 +117,6 @@ async fn process_select_response( } #[tokio::test(flavor = "multi_thread", worker_threads = 4)] -#[serial] #[ignore = "requires running RustFS server at localhost:9000"] async fn test_select_object_content_csv_basic() -> Result<(), Box> { let client = create_aws_s3_client().await?; @@ -160,7 +158,6 @@ async fn test_select_object_content_csv_basic() -> Result<(), Box> { } #[tokio::test(flavor = "multi_thread", worker_threads = 4)] -#[serial] #[ignore = "requires running RustFS server at localhost:9000"] async fn test_select_object_content_csv_aggregation() -> Result<(), Box> { let client = create_aws_s3_client().await?; @@ -206,7 +203,6 @@ async fn test_select_object_content_csv_aggregation() -> Result<(), Box Result<(), Box> { let client = create_aws_s3_client().await?; @@ -248,7 +244,6 @@ async fn test_select_object_content_json_basic() -> Result<(), Box> { } #[tokio::test(flavor = "multi_thread", worker_threads = 4)] -#[serial] #[ignore = "requires running RustFS server at localhost:9000"] async fn test_select_object_content_csv_limit() -> Result<(), Box> { let client = create_aws_s3_client().await?; @@ -291,7 +286,6 @@ async fn test_select_object_content_csv_limit() -> Result<(), Box> { } #[tokio::test(flavor = "multi_thread", worker_threads = 4)] -#[serial] #[ignore = "requires running RustFS server at localhost:9000"] async fn test_select_object_content_csv_order_by() -> Result<(), Box> { let client = create_aws_s3_client().await?; @@ -337,7 +331,6 @@ async fn test_select_object_content_csv_order_by() -> Result<(), Box> } #[tokio::test(flavor = "multi_thread", worker_threads = 4)] -#[serial] #[ignore = "requires running RustFS server at localhost:9000"] async fn test_select_object_content_error_handling() -> Result<(), Box> { let client = create_aws_s3_client().await?; @@ -373,7 +366,6 @@ async fn test_select_object_content_error_handling() -> Result<(), Box Result<(), Box> { let client = create_aws_s3_client().await?; diff --git a/crates/e2e_test/src/replication_extension_test.rs b/crates/e2e_test/src/replication_extension_test.rs index b9645deba..d0282c83a 100644 --- a/crates/e2e_test/src/replication_extension_test.rs +++ b/crates/e2e_test/src/replication_extension_test.rs @@ -60,7 +60,6 @@ use rustfs_signer::constants::UNSIGNED_PAYLOAD; use rustfs_signer::sign_v4; use s3s::Body; use s3s::header::X_AMZ_REPLICATION_STATUS; -use serial_test::serial; use sha2::{Digest, Sha256}; use std::collections::BTreeMap; use std::convert::Infallible; @@ -4630,7 +4629,6 @@ async fn test_bucket_replication_sse_c_multipart_passthrough() -> TestResult { /// fails without any PUT reaching the target (capability cache, proven from /// the target journal); plaintext objects still replicate COMPLETED. #[tokio::test] -#[serial] async fn test_ssec_replication_fails_closed_when_target_drops_passthrough_headers() -> TestResult { init_logging(); @@ -4740,7 +4738,6 @@ async fn test_ssec_replication_fails_closed_when_target_drops_passthrough_header /// a capability limit, and a plaintext-only deployment against a MinIO-like /// target must not turn red. #[tokio::test] -#[serial] async fn test_replication_check_flags_ssec_passthrough_dropping_target() -> TestResult { init_logging(); @@ -4831,7 +4828,6 @@ async fn test_replication_check_flags_ssec_passthrough_dropping_target() -> Test /// HEAD-back audit against the recovered RustFS target — and the replica must /// be readable with the customer key. #[tokio::test] -#[serial] async fn test_bucket_replication_sse_c_heals_after_target_outage() -> TestResult { init_logging(); @@ -4924,7 +4920,6 @@ async fn test_bucket_replication_sse_c_heals_after_target_outage() -> TestResult /// the existing-object resync (`replicate_all` transport, N2-audited), land as /// a REPLICA, and read back with the customer key. #[tokio::test] -#[serial] async fn test_bucket_replication_sse_c_existing_object_resync() -> TestResult { init_logging(); @@ -8819,7 +8814,6 @@ async fn start_read_proxy_lab( /// headers are forwarded verbatim, and an inbound request that was itself /// proxied is answered locally (404) without touching the target. #[tokio::test] -#[serial] async fn test_get_and_head_proxy_unreplicated_object_to_replication_target() -> TestResult { init_logging(); @@ -9002,7 +8996,6 @@ async fn test_get_and_head_proxy_unreplicated_object_to_replication_target() -> /// proxied to the replication target with the anti-loop marker, mirroring /// MinIO `proxyGetTaggingToRepTarget`. #[tokio::test] -#[serial] async fn test_get_object_tagging_proxies_unreplicated_object_to_replication_target() -> TestResult { init_logging(); diff --git a/crates/e2e_test/src/security_boundary_test.rs b/crates/e2e_test/src/security_boundary_test.rs index 1f5fdda83..0a62ef0f5 100644 --- a/crates/e2e_test/src/security_boundary_test.rs +++ b/crates/e2e_test/src/security_boundary_test.rs @@ -25,7 +25,6 @@ use crate::common::{RustFSTestEnvironment, awscurl_available, awscurl_put, init_ use aws_sdk_s3::error::ProvideErrorMetadata; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{CompletedMultipartUpload, CompletedPart, Tag, Tagging}; -use serial_test::serial; use std::error::Error; use tracing::info; @@ -36,7 +35,6 @@ use tracing::info; /// far beyond that limit and assert the server rejects it with the specific /// error, rather than accepting an arbitrarily large control-plane body. #[tokio::test] -#[serial] async fn test_large_xml_body_rejection() -> Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -92,7 +90,6 @@ async fn test_large_xml_body_rejection() -> Result<(), Box Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -149,7 +146,6 @@ async fn test_excessive_multipart_parts() -> Result<(), Box Result<(), Box> { init_logging(); let mut env = RustFSTestEnvironment::new().await?; @@ -232,7 +228,6 @@ async fn test_concurrent_object_operations() -> Result<(), Box Result<(), Box> { init_logging(); if !awscurl_available() { diff --git a/crates/e2e_test/src/server_startup_failfast_test.rs b/crates/e2e_test/src/server_startup_failfast_test.rs index 784a08e56..410779405 100644 --- a/crates/e2e_test/src/server_startup_failfast_test.rs +++ b/crates/e2e_test/src/server_startup_failfast_test.rs @@ -23,7 +23,6 @@ #[cfg(test)] mod tests { use crate::common::{RustFSTestEnvironment, init_logging, rustfs_binary_path}; - use serial_test::serial; use std::net::TcpListener; use std::time::{Duration, Instant}; @@ -31,7 +30,6 @@ mod tests { /// while :9001 is occupied: the server exits at startup, and the harness /// must surface that promptly rather than waiting out the 60s timeout. #[tokio::test] - #[serial] async fn test_start_fails_fast_when_server_exits_during_startup() { init_logging(); diff --git a/crates/e2e_test/src/snowball_auto_extract_test.rs b/crates/e2e_test/src/snowball_auto_extract_test.rs index aad32e7cc..2077af321 100644 --- a/crates/e2e_test/src/snowball_auto_extract_test.rs +++ b/crates/e2e_test/src/snowball_auto_extract_test.rs @@ -17,7 +17,6 @@ mod tests { use crate::common::{RustFSTestEnvironment, init_logging}; use aws_sdk_s3::error::ProvideErrorMetadata; use aws_sdk_s3::primitives::ByteStream; - use serial_test::serial; use std::error::Error; use std::io::Cursor; @@ -101,7 +100,6 @@ mod tests { } #[tokio::test] - #[serial] async fn snowball_auto_extract_supports_minio_prefix_and_directory_markers() -> Result<(), Box> { init_logging(); @@ -138,7 +136,6 @@ mod tests { } #[tokio::test] - #[serial] async fn snowball_auto_extract_supports_standard_headers_with_combined_extract_options() -> Result<(), Box> { init_logging(); @@ -229,7 +226,6 @@ mod tests { } #[tokio::test] - #[serial] async fn snowball_auto_extract_ignores_directories_when_requested() -> Result<(), Box> { init_logging(); @@ -268,7 +264,6 @@ mod tests { } #[tokio::test] - #[serial] async fn snowball_auto_extract_ignores_invalid_entries_when_requested() -> Result<(), Box> { init_logging(); @@ -304,7 +299,6 @@ mod tests { } #[tokio::test] - #[serial] async fn snowball_auto_extract_rejects_parent_dir_entry_without_cross_bucket_write() -> Result<(), Box> { init_logging(); @@ -347,7 +341,6 @@ mod tests { } #[tokio::test] - #[serial] async fn snowball_auto_extract_prefers_exact_minio_prefix_over_suffix_fallback() -> Result<(), Box> { init_logging(); diff --git a/crates/e2e_test/src/special_chars_test.rs b/crates/e2e_test/src/special_chars_test.rs index 8989b02f3..a4df48e78 100644 --- a/crates/e2e_test/src/special_chars_test.rs +++ b/crates/e2e_test/src/special_chars_test.rs @@ -34,7 +34,6 @@ mod tests { use rustfs_signer::constants::UNSIGNED_PAYLOAD; use rustfs_signer::sign_v4; use s3s::Body; - use serial_test::serial; use std::error::Error; use tracing::{debug, info}; @@ -93,7 +92,6 @@ mod tests { /// mc cp README.md "local/dummy/a%20f+/b/c/3/README.md" /// ``` #[tokio::test] - #[serial] async fn test_object_with_space_in_path() { init_logging(); info!("Starting test: object with space in path"); @@ -175,7 +173,6 @@ mod tests { /// /test/data/org_main-org/dashboards/ES+net/LHC+Data+Challenge/firefly-details.json /// ``` #[tokio::test] - #[serial] async fn test_object_with_plus_in_path() { init_logging(); info!("Starting test: object with plus sign in path"); @@ -245,7 +242,6 @@ mod tests { /// Test with mixed special characters #[tokio::test] - #[serial] async fn test_object_with_mixed_special_chars() { init_logging(); info!("Starting test: object with mixed special characters"); @@ -305,7 +301,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_signed_get_missing_object_with_trailing_equals_returns_no_such_key() -> Result<(), Box> { init_logging(); @@ -334,7 +329,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_signed_get_existing_object_with_trailing_equals_returns_content() -> Result<(), Box> { init_logging(); @@ -373,7 +367,6 @@ mod tests { /// Test DELETE operation with special characters #[tokio::test] - #[serial] async fn test_delete_object_with_special_chars() { init_logging(); info!("Starting test: DELETE object with special characters"); @@ -421,7 +414,6 @@ mod tests { /// Test exact scenario from the issue #[tokio::test] - #[serial] async fn test_issue_scenario_exact() { init_logging(); info!("Starting test: Exact scenario from GitHub issue"); @@ -494,7 +486,6 @@ mod tests { /// Test HEAD object with special characters #[tokio::test] - #[serial] async fn test_head_object_with_special_chars() { init_logging(); info!("Starting test: HEAD object with special characters"); @@ -538,7 +529,6 @@ mod tests { /// Test COPY object with special characters in both source and destination #[tokio::test] - #[serial] async fn test_copy_object_with_special_chars() { init_logging(); info!("Starting test: COPY object with special characters"); @@ -597,7 +587,6 @@ mod tests { /// Test Unicode characters in object keys #[tokio::test] - #[serial] async fn test_unicode_characters_in_path() { init_logging(); info!("Starting test: Unicode characters in object paths"); @@ -661,7 +650,6 @@ mod tests { /// Test special characters in different parts of the path #[tokio::test] - #[serial] async fn test_special_chars_in_different_path_positions() { init_logging(); info!("Starting test: Special characters in different path positions"); @@ -719,7 +707,6 @@ mod tests { /// Test that control characters are properly rejected #[tokio::test] - #[serial] async fn test_control_characters_rejected() { init_logging(); info!("Starting test: Control characters should be rejected"); @@ -769,7 +756,6 @@ mod tests { /// Test LIST with various special character prefixes #[tokio::test] - #[serial] async fn test_list_with_special_char_prefixes() { init_logging(); info!("Starting test: LIST with special character prefixes"); @@ -838,7 +824,6 @@ mod tests { /// Test delimiter-based listing with special characters #[tokio::test] - #[serial] async fn test_list_with_delimiter_and_special_chars() { init_logging(); info!("Starting test: LIST with delimiter and special characters"); diff --git a/crates/e2e_test/src/stale_multipart_cleanup_cluster_test.rs b/crates/e2e_test/src/stale_multipart_cleanup_cluster_test.rs index 618b79b61..c5fc45e17 100644 --- a/crates/e2e_test/src/stale_multipart_cleanup_cluster_test.rs +++ b/crates/e2e_test/src/stale_multipart_cleanup_cluster_test.rs @@ -16,7 +16,6 @@ use crate::common::{RustFSTestClusterEnvironment, init_logging}; use aws_sdk_s3::error::SdkError; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::CompletedMultipartUpload; -use serial_test::serial; use tokio::time::{Duration, sleep}; use tracing::info; use uuid::Uuid; @@ -101,7 +100,6 @@ async fn wait_for_cleanup_on_all_nodes( } #[tokio::test] -#[serial] async fn test_stale_multipart_cleanup_removes_incomplete_upload_across_cluster() -> Result<(), Box> { init_logging(); diff --git a/crates/e2e_test/src/sts_query_compat_test.rs b/crates/e2e_test/src/sts_query_compat_test.rs index 517cc1c82..4f96c2e5c 100644 --- a/crates/e2e_test/src/sts_query_compat_test.rs +++ b/crates/e2e_test/src/sts_query_compat_test.rs @@ -25,7 +25,6 @@ use hyper::server::conn::http1; use hyper::service::service_fn; use hyper_util::rt::TokioIo; use serde_json::Value; -use serial_test::serial; use std::collections::BTreeSet; use std::convert::Infallible; use std::error::Error; @@ -350,7 +349,6 @@ impl Drop for OpaMock { } #[tokio::test] -#[serial] async fn test_sts_query_responses_are_aws_sdk_compatible() -> TestResult { init_logging(); @@ -487,7 +485,6 @@ async fn test_sts_query_responses_are_aws_sdk_compatible() -> TestResult { } #[tokio::test] -#[serial] async fn test_sts_assume_role_opa_contract() -> TestResult { init_logging(); @@ -559,7 +556,6 @@ async fn test_sts_assume_role_opa_contract() -> TestResult { } #[tokio::test] -#[serial] async fn test_list_buckets_opa_contract() -> TestResult { init_logging(); @@ -645,7 +641,6 @@ async fn test_list_buckets_opa_contract() -> TestResult { } #[tokio::test] -#[serial] async fn test_sts_and_list_buckets_fail_closed_while_opa_is_initializing() -> TestResult { init_logging(); @@ -662,7 +657,6 @@ async fn test_sts_and_list_buckets_fail_closed_while_opa_is_initializing() -> Te } #[tokio::test] -#[serial] async fn test_sts_and_list_buckets_fail_closed_after_opa_validation_failure() -> TestResult { init_logging(); @@ -679,7 +673,6 @@ async fn test_sts_and_list_buckets_fail_closed_after_opa_validation_failure() -> } #[tokio::test] -#[serial] async fn test_sts_query_rate_limit_error_is_aws_sdk_compatible() -> TestResult { init_logging(); diff --git a/crates/e2e_test/src/tier_transition_regression_test.rs b/crates/e2e_test/src/tier_transition_regression_test.rs index 5349e3084..26c2922e1 100644 --- a/crates/e2e_test/src/tier_transition_regression_test.rs +++ b/crates/e2e_test/src/tier_transition_regression_test.rs @@ -30,7 +30,6 @@ mod tests { use crate::common::{RustFSTestEnvironment, admin_ok, init_logging}; use serde_json::Value; - use serial_test::serial; use std::error::Error; use tracing::info; @@ -42,7 +41,6 @@ mod tests { /// validates that an expiration-only rule (the persistence path) survives /// a server restart. #[tokio::test] - #[serial] async fn test_lifecycle_rule_persists_after_restart() -> TestResult { init_logging(); info!("RT-13: lifecycle rule persists after restart"); @@ -105,7 +103,6 @@ mod tests { /// Regression pattern: tier add/verify/delete API fails or the tier /// configuration is not persisted (rustfs#5218). #[tokio::test] - #[serial] async fn test_admin_tier_list_endpoint_returns_json() -> TestResult { init_logging(); info!("RT-13b: admin tier list endpoint returns JSON"); @@ -135,7 +132,6 @@ mod tests { /// is not persisted (rustfs#5013), causing the scanner to not run or /// use stale settings. #[tokio::test] - #[serial] async fn test_scanner_config_persists_after_restart() -> TestResult { init_logging(); info!("RT-13c: scanner config persists after restart"); diff --git a/crates/e2e_test/src/tls_hot_reload_test.rs b/crates/e2e_test/src/tls_hot_reload_test.rs index 59c5894ce..b8f752627 100644 --- a/crates/e2e_test/src/tls_hot_reload_test.rs +++ b/crates/e2e_test/src/tls_hot_reload_test.rs @@ -34,7 +34,6 @@ use rcgen::generate_simple_self_signed; use rustls::client::danger::{HandshakeSignatureValid, ServerCertVerified, ServerCertVerifier}; use rustls::pki_types::{CertificateDer, ServerName, UnixTime}; use rustls::{ClientConfig, ClientConnection, DigitallySignedStruct, Error as RustlsError, SignatureScheme, StreamOwned}; -use serial_test::serial; use sha2::{Digest, Sha256}; use std::error::Error; use std::io::{Read, Write}; @@ -242,7 +241,6 @@ async fn roundtrip_and_return(mut session: TlsSession) -> Result TestResult { init_logging(); // Install the process-wide rustls crypto provider (idempotent). diff --git a/crates/e2e_test/src/version_id_regression_test.rs b/crates/e2e_test/src/version_id_regression_test.rs index 1ff2e34ef..75d19e5db 100644 --- a/crates/e2e_test/src/version_id_regression_test.rs +++ b/crates/e2e_test/src/version_id_regression_test.rs @@ -27,7 +27,6 @@ mod tests { use aws_sdk_s3::Client; use aws_sdk_s3::primitives::ByteStream; use aws_sdk_s3::types::{BucketVersioningStatus, CompletedMultipartUpload, CompletedPart, VersioningConfiguration}; - use serial_test::serial; use tracing::info; fn create_s3_client(env: &RustFSTestEnvironment) -> Client { @@ -86,7 +85,6 @@ mod tests { /// Test 1: PutObject should return version_id when versioning is enabled /// This directly addresses the Veeam issue from #1066 #[tokio::test] - #[serial] async fn test_put_object_returns_version_id_with_versioning() { init_logging(); info!("🧪 TEST: PutObject returns version_id with versioning enabled"); @@ -130,7 +128,6 @@ mod tests { /// Test 2: CopyObject should return version_id when versioning is enabled #[tokio::test] - #[serial] async fn test_copy_object_returns_version_id_with_versioning() { init_logging(); info!("🧪 TEST: CopyObject returns version_id with versioning enabled"); @@ -185,7 +182,6 @@ mod tests { /// Test 3: CompleteMultipartUpload should return version_id when versioning is enabled #[tokio::test] - #[serial] async fn test_multipart_upload_returns_version_id_with_versioning() { init_logging(); info!("🧪 TEST: CompleteMultipartUpload returns version_id with versioning enabled"); @@ -260,7 +256,6 @@ mod tests { /// Test 4: PutObject should NOT return version_id when versioning is NOT enabled /// This ensures we didn't break non-versioned buckets #[tokio::test] - #[serial] async fn test_put_object_without_versioning() { init_logging(); info!("🧪 TEST: PutObject behavior without versioning (no regression)"); @@ -296,7 +291,6 @@ mod tests { /// Test 5: Basic S3 operations still work correctly (no regression) #[tokio::test] - #[serial] async fn test_basic_s3_operations_no_regression() { init_logging(); info!("🧪 TEST: Basic S3 operations work correctly (no regression)"); @@ -363,7 +357,6 @@ mod tests { /// Test 6: Veeam-specific scenario simulation /// Simulates the exact workflow that Veeam uses when backing up data #[tokio::test] - #[serial] async fn test_veeam_backup_workflow_simulation() { init_logging(); info!("🧪 TEST: Veeam VBR backup workflow simulation (Issue #1066)"); @@ -413,7 +406,6 @@ mod tests { } #[tokio::test] - #[serial] async fn test_terraform_put_after_delete() -> Result<(), Box> { init_logging(); @@ -456,7 +448,6 @@ mod tests { /// Test 7: PutObject should omit version_id when versioning is Suspended #[tokio::test] - #[serial] async fn test_put_object_omits_version_id_with_suspended_versioning() { init_logging(); info!("🧪 TEST: PutObject omits version_id with versioning suspended"); @@ -500,7 +491,6 @@ mod tests { /// Test 8: CopyObject should omit version_id when versioning is Suspended #[tokio::test] - #[serial] async fn test_copy_object_omits_version_id_with_suspended_versioning() { init_logging(); info!("🧪 TEST: CopyObject omits version_id with versioning suspended"); @@ -551,7 +541,6 @@ mod tests { /// Test 9: CompleteMultipartUpload should omit version_id when versioning is Suspended #[tokio::test] - #[serial] async fn test_multipart_upload_omits_version_id_with_suspended_versioning() { init_logging(); info!("🧪 TEST: CompleteMultipartUpload omits version_id with versioning suspended");