test(s3): reclassify passing compatibility cases (#2586)

Co-authored-by: houseme <housemecn@gmail.com>
This commit is contained in:
安正超
2026-04-18 17:15:29 +08:00
committed by GitHub
parent 2d0b3227c5
commit ac443a90ce
6 changed files with 120 additions and 255 deletions

View File

@@ -144,9 +144,11 @@ DEPLOY_MODE=existing S3_HOST=192.168.1.100 S3_PORT=9000 ./scripts/s3-tests/run.s
- `MAXFAIL`: Stop after N failures (default: `1`)
- `XDIST`: Enable parallel execution with N workers (default: `0`, disabled)
- `MARKEXPR`: pytest marker expression for filtering tests
- Default: `not lifecycle and not versioning and not s3website and not bucket_logging and not encryption`
- Excludes features not yet supported by RustFS to reduce test execution time
- Can be customized to test specific features or remove exclusions
- Default: no marker filtering; file-based test lists control the selected tests
- Can be customized to test specific marker groups
- `TESTEXPR`: optional pytest `-k` expression for custom runs
- Default: exact pytest node ids loaded from `implemented_tests.txt`
- Setting `TESTEXPR` overrides the implemented test list
### Configuration Files
@@ -182,9 +184,6 @@ DATA_ROOT=/tmp ./scripts/s3-tests/run.sh
# Run specific test markers (e.g., test multipart uploads only)
MARKEXPR="multipart" ./scripts/s3-tests/run.sh
# Remove feature exclusions (test all features, including unsupported ones)
MARKEXPR="" ./scripts/s3-tests/run.sh
```
### Binary File Mode

View File

@@ -122,18 +122,13 @@ test_bucket_policy_get_obj_existing_tag
test_bucket_policy_get_obj_tagging_existing_tag
test_bucket_policy_put_obj_copy_source
test_bucket_policy_put_obj_copy_source_meta
test_bucket_policy_put_obj_kms_noenc
test_bucket_policy_put_obj_request_obj_tag
test_bucket_policy_put_obj_s3_incorrect_algo_sse_s3
test_bucket_policy_put_obj_s3_noenc
test_bucket_policy_put_obj_tagging_existing_tag
test_bucket_policy_set_condition_operator_end_with_IfExists
test_bucket_policy_upload_part_copy
test_bucket_recreate_new_acl
test_bucket_recreate_overwrite_acl
test_copy_object_ifmatch_failed
test_copy_object_ifmatch_good
test_copy_object_ifnonematch_failed
test_copy_object_ifnonematch_good
test_cors_presigned_get_object_tenant_v2
test_cors_presigned_get_object_v2
@@ -164,27 +159,11 @@ test_delete_objects_if_match_size
test_delete_objects_version_if_match
test_delete_objects_version_if_match_last_modified_time
test_delete_objects_version_if_match_size
test_delete_tags_obj_public
test_encrypted_transfer_13b
test_encrypted_transfer_1MB
test_encrypted_transfer_1b
test_encrypted_transfer_1kb
test_encryption_sse_c_deny_algo_with_bucket_policy
test_encryption_sse_c_enforced_with_bucket_policy
test_encryption_sse_c_multipart_invalid_chunks_1
test_encryption_sse_c_multipart_invalid_chunks_2
test_encryption_sse_c_multipart_upload
test_encryption_sse_c_post_object_authenticated_request
test_encryption_sse_c_unaligned_multipart_upload
test_expected_bucket_owner
test_get_multipart_checksum_object_attributes
test_get_multipart_object_attributes
test_get_obj_tagging
test_get_object_attributes
test_get_paginated_multipart_object_attributes
test_get_single_multipart_object_attributes
test_get_sse_c_encrypted_object_attributes
test_get_tags_acl_public
test_head_bucket_usage
test_lifecycle_cloud_multiple_transition
test_lifecycle_cloud_transition
@@ -193,7 +172,8 @@ test_lifecycle_deletemarker_expiration
test_lifecycle_deletemarker_expiration_with_days_tag
test_lifecycle_expiration
test_lifecycle_expiration_date
test_lifecycle_expiration_header_and_tags_head
test_lifecycle_expiration_days0
test_lifecycle_expiration_header_put
test_lifecycle_expiration_header_head
test_lifecycle_expiration_header_tags_head
test_lifecycle_expiration_newer_noncurrent
@@ -215,18 +195,10 @@ test_list_buckets_anonymous
test_list_buckets_paginated
test_list_multipart_upload
test_list_multipart_upload_owner
test_multipart_checksum_sha256
test_multipart_copy_multiple_sizes
test_multipart_copy_versioned
test_multipart_get_part
test_multipart_put_current_object_if_match
test_multipart_put_current_object_if_none_match
test_multipart_put_object_if_match
test_multipart_single_get_part
test_multipart_sse_c_get_part
test_multipart_upload
test_multipart_upload_contents
test_multipart_upload_resend_part
test_multipart_upload_small
test_multipart_use_cksum_helper_crc32
test_multipart_use_cksum_helper_crc32c
@@ -235,10 +207,7 @@ test_multipart_use_cksum_helper_sha1
test_multipart_use_cksum_helper_sha256
test_non_multipart_get_part
test_non_multipart_sse_c_get_part
test_object_copy_canned_acl
test_object_header_acl_grants
test_object_raw_get_x_amz_expires_not_expired
test_object_raw_get_x_amz_expires_not_expired_tenant
test_object_raw_get_x_amz_expires_out_max_range
test_object_raw_get_x_amz_expires_out_positive_range
test_object_raw_put_authenticated_expired
@@ -263,54 +232,16 @@ test_put_bucket_logging_tenant_s
test_put_bucket_ownership_bucket_owner_enforced
test_put_bucket_ownership_bucket_owner_preferred
test_put_bucket_ownership_object_writer
test_put_current_object_if_match
test_put_current_object_if_none_match
test_put_delete_tags
test_put_max_tags
test_put_modify_tags
test_put_obj_with_tags
test_put_object_current_if_match
test_put_object_if_match
test_put_tags_acl_public
test_ranged_big_request_response_code
test_ranged_request_response_code
test_ranged_request_return_trailing_bytes_response_code
test_ranged_request_skip_leading_bytes_response_code
test_read_through
test_restore_noncur_obj
test_restore_object_permanent
test_restore_object_temporary
test_sse_kms_default_post_object_authenticated_request
test_sse_kms_default_upload_1b
test_sse_kms_default_upload_1kb
test_sse_kms_default_upload_1mb
test_sse_kms_default_upload_8mb
test_sse_kms_method_head
test_sse_kms_multipart_invalid_chunks_1
test_sse_kms_multipart_invalid_chunks_2
test_sse_kms_multipart_upload
test_sse_kms_post_object_authenticated_request
test_sse_kms_present
test_sse_kms_transfer_13b
test_sse_kms_transfer_1MB
test_sse_kms_transfer_1b
test_sse_kms_transfer_1kb
test_sse_s3_default_method_head
test_sse_s3_default_multipart_upload
test_sse_s3_default_post_object_authenticated_request
test_sse_s3_default_upload_1b
test_sse_s3_default_upload_1kb
test_sse_s3_default_upload_1mb
test_sse_s3_default_upload_8mb
test_sse_s3_encrypted_upload_1b
test_sse_s3_encrypted_upload_1kb
test_sse_s3_encrypted_upload_1mb
test_sse_s3_encrypted_upload_8mb
test_versioned_object_acl_no_version_specified
test_versioning_copy_obj_version
test_versioning_multi_object_delete_with_marker_create
test_versioning_obj_create_overwrite_multipart
test_versioning_obj_suspended_copy
test_versioning_stack_delete_merkers
# Intentionally unsupported by design: ACL-related tests

View File

@@ -19,8 +19,6 @@
# - Conditional GET: If-Match, If-None-Match, If-Modified-Since
#
# - SSE-C: Server-side encryption with customer-provided keys
# - Object ownership: Bucket ownership controls
#
# - SSE-KMS: KMS-related edge cases
# - Bucket Policy: Multipart upload authorization, SSE condition keys, grant header conditions
# - Versioning: Concurrent multi-object delete
@@ -157,7 +155,6 @@ test_ranged_request_empty_object
test_ranged_request_invalid_range
test_set_multipart_tagging
test_upload_part_copy_percent_encoded_key
test_api_error_from_storage_error_mappings
test_get_object_torrent
# Object attributes
@@ -219,9 +216,6 @@ test_bucket_policy_allow_notprincipal
test_bucket_policy_put_obj_kms_s3
test_bucket_policy_put_obj_s3_kms
# Object ownership
test_create_bucket_no_ownership_controls
# Bucket encryption
test_put_bucket_encryption_kms
test_put_bucket_encryption_s3
@@ -229,11 +223,8 @@ test_get_bucket_encryption_kms
test_get_bucket_encryption_s3
test_delete_bucket_encryption_kms
test_delete_bucket_encryption_s3
test_lifecycle_expiration_days0
# Lifecycle tests
test_lifecycle_delete
test_lifecycle_expiration_header_put
test_lifecycle_get
test_lifecycle_get_no_id
test_lifecycle_id_too_long
@@ -310,7 +301,6 @@ test_object_copy_replacing_metadata
test_object_copy_retaining_metadata
test_object_copy_same_bucket
test_object_copy_to_itself
test_object_copy_to_itself_with_metadata
test_object_copy_verify_contenttype
test_object_copy_versioned_bucket
test_object_copy_versioned_url_encoding
@@ -443,3 +433,78 @@ test_object_delete_key_bucket_gone
# Multipart copy range validation
test_multipart_copy_invalid_range
# Reclassified standard tests
test_bucket_policy_put_obj_kms_noenc
test_bucket_policy_put_obj_s3_incorrect_algo_sse_s3
test_bucket_policy_put_obj_s3_noenc
test_copy_object_ifmatch_good
test_copy_object_ifnonematch_failed
test_delete_tags_obj_public
test_encrypted_transfer_13b
test_encrypted_transfer_1MB
test_encrypted_transfer_1b
test_encrypted_transfer_1kb
test_encryption_sse_c_deny_algo_with_bucket_policy
test_encryption_sse_c_enforced_with_bucket_policy
test_encryption_sse_c_post_object_authenticated_request
test_expected_bucket_owner
test_get_multipart_object_attributes
test_get_obj_tagging
test_get_object_attributes
test_get_paginated_multipart_object_attributes
test_get_single_multipart_object_attributes
test_get_sse_c_encrypted_object_attributes
test_get_tags_acl_public
test_lifecycle_expiration_header_and_tags_head
test_multipart_checksum_sha256
test_multipart_copy_multiple_sizes
test_multipart_copy_versioned
test_multipart_put_current_object_if_match
test_multipart_put_current_object_if_none_match
test_multipart_put_object_if_match
test_multipart_upload_contents
test_multipart_upload_resend_part
test_object_copy_canned_acl
test_object_raw_get_x_amz_expires_not_expired
test_object_raw_get_x_amz_expires_not_expired_tenant
test_put_current_object_if_match
test_put_current_object_if_none_match
test_put_delete_tags
test_put_max_tags
test_put_modify_tags
test_put_obj_with_tags
test_put_object_if_match
test_put_tags_acl_public
test_ranged_big_request_response_code
test_ranged_request_response_code
test_ranged_request_return_trailing_bytes_response_code
test_ranged_request_skip_leading_bytes_response_code
test_sse_kms_default_post_object_authenticated_request
test_sse_kms_default_upload_1b
test_sse_kms_default_upload_1kb
test_sse_kms_default_upload_1mb
test_sse_kms_default_upload_8mb
test_sse_kms_method_head
test_sse_kms_multipart_invalid_chunks_1
test_sse_kms_multipart_invalid_chunks_2
test_sse_kms_present
test_sse_kms_transfer_13b
test_sse_kms_transfer_1MB
test_sse_kms_transfer_1b
test_sse_kms_transfer_1kb
test_sse_s3_default_method_head
test_sse_s3_default_post_object_authenticated_request
test_sse_s3_default_upload_1b
test_sse_s3_default_upload_1kb
test_sse_s3_default_upload_1mb
test_sse_s3_default_upload_8mb
test_sse_s3_encrypted_upload_1b
test_sse_s3_encrypted_upload_1kb
test_sse_s3_encrypted_upload_1mb
test_sse_s3_encrypted_upload_8mb
test_versioning_copy_obj_version
test_versioning_obj_create_overwrite_multipart
test_versioning_obj_suspended_copy
test_rm_bucket_logging
test_versioned_concurrent_object_create_concurrent_remove

View File

@@ -10,7 +10,6 @@
# - X-RGW-* headers: Ceph proprietary headers
# - allowUnordered: Ceph-specific query parameter
# - Bucket Logging: Ceph-specific logging extensions
# - Object Lock: Ceph-specific lock behavior differences
# - Lifecycle: Ceph-specific lifecycle expiration behavior
# - SSE-KMS: Ceph-specific KMS extensions
# - Error format differences: Minor response format variations
@@ -129,18 +128,13 @@ test_bucket_policy_get_obj_existing_tag
test_bucket_policy_get_obj_tagging_existing_tag
test_bucket_policy_put_obj_copy_source
test_bucket_policy_put_obj_copy_source_meta
test_bucket_policy_put_obj_kms_noenc
test_bucket_policy_put_obj_request_obj_tag
test_bucket_policy_put_obj_s3_incorrect_algo_sse_s3
test_bucket_policy_put_obj_s3_noenc
test_bucket_policy_put_obj_tagging_existing_tag
test_bucket_policy_set_condition_operator_end_with_IfExists
test_bucket_policy_upload_part_copy
test_bucket_recreate_new_acl
test_bucket_recreate_overwrite_acl
test_copy_object_ifmatch_failed
test_copy_object_ifmatch_good
test_copy_object_ifnonematch_failed
test_copy_object_ifnonematch_good
test_cors_presigned_get_object_tenant_v2
test_cors_presigned_get_object_v2
@@ -171,27 +165,11 @@ test_delete_objects_if_match_size
test_delete_objects_version_if_match
test_delete_objects_version_if_match_last_modified_time
test_delete_objects_version_if_match_size
test_delete_tags_obj_public
test_encrypted_transfer_13b
test_encrypted_transfer_1MB
test_encrypted_transfer_1b
test_encrypted_transfer_1kb
test_encryption_sse_c_deny_algo_with_bucket_policy
test_encryption_sse_c_enforced_with_bucket_policy
test_encryption_sse_c_multipart_invalid_chunks_1
test_encryption_sse_c_multipart_invalid_chunks_2
test_encryption_sse_c_multipart_upload
test_encryption_sse_c_post_object_authenticated_request
test_encryption_sse_c_unaligned_multipart_upload
test_expected_bucket_owner
test_get_multipart_checksum_object_attributes
test_get_multipart_object_attributes
test_get_obj_tagging
test_get_object_attributes
test_get_paginated_multipart_object_attributes
test_get_single_multipart_object_attributes
test_get_sse_c_encrypted_object_attributes
test_get_tags_acl_public
test_head_bucket_usage
test_lifecycle_cloud_multiple_transition
test_lifecycle_cloud_transition
@@ -200,7 +178,8 @@ test_lifecycle_deletemarker_expiration
test_lifecycle_deletemarker_expiration_with_days_tag
test_lifecycle_expiration
test_lifecycle_expiration_date
test_lifecycle_expiration_header_and_tags_head
test_lifecycle_expiration_days0
test_lifecycle_expiration_header_put
test_lifecycle_expiration_header_head
test_lifecycle_expiration_header_tags_head
test_lifecycle_expiration_newer_noncurrent
@@ -222,18 +201,10 @@ test_list_buckets_anonymous
test_list_buckets_paginated
test_list_multipart_upload
test_list_multipart_upload_owner
test_multipart_checksum_sha256
test_multipart_copy_multiple_sizes
test_multipart_copy_versioned
test_multipart_get_part
test_multipart_put_current_object_if_match
test_multipart_put_current_object_if_none_match
test_multipart_put_object_if_match
test_multipart_single_get_part
test_multipart_sse_c_get_part
test_multipart_upload
test_multipart_upload_contents
test_multipart_upload_resend_part
test_multipart_upload_small
test_multipart_use_cksum_helper_crc32
test_multipart_use_cksum_helper_crc32c
@@ -242,42 +213,7 @@ test_multipart_use_cksum_helper_sha1
test_multipart_use_cksum_helper_sha256
test_non_multipart_get_part
test_non_multipart_sse_c_get_part
test_object_copy_canned_acl
test_object_header_acl_grants
test_object_lock_changing_mode_from_compliance
test_object_lock_changing_mode_from_governance_with_bypass
test_object_lock_changing_mode_from_governance_without_bypass
test_object_lock_delete_multipart_object_with_legal_hold_on
test_object_lock_delete_multipart_object_with_retention
test_object_lock_delete_object_with_legal_hold_off
test_object_lock_delete_object_with_legal_hold_on
test_object_lock_delete_object_with_retention
test_object_lock_delete_object_with_retention_and_marker
test_object_lock_get_legal_hold
test_object_lock_get_obj_lock
test_object_lock_get_obj_metadata
test_object_lock_get_obj_retention
test_object_lock_get_obj_retention_iso8601
test_object_lock_multi_delete_object_with_retention
test_object_lock_put_legal_hold
test_object_lock_put_legal_hold_invalid_status
test_object_lock_put_obj_lock
test_object_lock_put_obj_lock_invalid_days
test_object_lock_put_obj_lock_invalid_mode
test_object_lock_put_obj_lock_invalid_status
test_object_lock_put_obj_lock_invalid_years
test_object_lock_put_obj_lock_with_days_and_years
test_object_lock_put_obj_retention
test_object_lock_put_obj_retention_increase_period
test_object_lock_put_obj_retention_invalid_mode
test_object_lock_put_obj_retention_override_default_retention
test_object_lock_put_obj_retention_shorten_period
test_object_lock_put_obj_retention_shorten_period_bypass
test_object_lock_put_obj_retention_versionid
test_object_lock_suspend_versioning
test_object_lock_uploading_obj
test_object_raw_get_x_amz_expires_not_expired
test_object_raw_get_x_amz_expires_not_expired_tenant
test_object_raw_get_x_amz_expires_out_max_range
test_object_raw_get_x_amz_expires_out_positive_range
test_object_raw_put_authenticated_expired
@@ -302,52 +238,14 @@ test_put_bucket_logging_tenant_s
test_put_bucket_ownership_bucket_owner_enforced
test_put_bucket_ownership_bucket_owner_preferred
test_put_bucket_ownership_object_writer
test_put_current_object_if_match
test_put_current_object_if_none_match
test_put_delete_tags
test_put_max_tags
test_put_modify_tags
test_put_obj_with_tags
test_put_object_current_if_match
test_put_object_if_match
test_put_tags_acl_public
test_ranged_big_request_response_code
test_ranged_request_response_code
test_ranged_request_return_trailing_bytes_response_code
test_ranged_request_skip_leading_bytes_response_code
test_read_through
test_restore_noncur_obj
test_restore_object_permanent
test_restore_object_temporary
test_sse_kms_default_post_object_authenticated_request
test_sse_kms_default_upload_1b
test_sse_kms_default_upload_1kb
test_sse_kms_default_upload_1mb
test_sse_kms_default_upload_8mb
test_sse_kms_method_head
test_sse_kms_multipart_invalid_chunks_1
test_sse_kms_multipart_invalid_chunks_2
test_sse_kms_multipart_upload
test_sse_kms_post_object_authenticated_request
test_sse_kms_present
test_sse_kms_transfer_13b
test_sse_kms_transfer_1MB
test_sse_kms_transfer_1b
test_sse_kms_transfer_1kb
test_sse_s3_default_method_head
test_sse_s3_default_multipart_upload
test_sse_s3_default_post_object_authenticated_request
test_sse_s3_default_upload_1b
test_sse_s3_default_upload_1kb
test_sse_s3_default_upload_1mb
test_sse_s3_default_upload_8mb
test_sse_s3_encrypted_upload_1b
test_sse_s3_encrypted_upload_1kb
test_sse_s3_encrypted_upload_1mb
test_sse_s3_encrypted_upload_8mb
test_versioned_object_acl_no_version_specified
test_versioning_copy_obj_version
test_versioning_multi_object_delete_with_marker_create
test_versioning_obj_create_overwrite_multipart
test_versioning_obj_suspended_copy
test_versioning_stack_delete_merkers

View File

@@ -78,17 +78,20 @@ TEST_LISTS_DIR="${SCRIPT_DIR}"
IMPLEMENTED_TESTS_FILE="${TEST_LISTS_DIR}/implemented_tests.txt"
UNIMPLEMENTED_TESTS_FILE="${TEST_LISTS_DIR}/unimplemented_tests.txt"
EXCLUDED_TESTS_FILE="${TEST_LISTS_DIR}/excluded_tests.txt"
LEGACY_NON_STANDARD_TESTS_FILE="${TEST_LISTS_DIR}/non_standard_tests.txt"
S3_TEST_FILE="s3tests/functional/test_s3.py"
# =============================================================================
# build_testexpr_from_file: Read test names from file and build pytest -k expr
# load_testnodes_from_file: Read test names and build exact pytest node ids
# =============================================================================
# Reads test names from a file (one per line, ignoring comments and empty lines)
# and builds a pytest -k expression to include only those tests.
# Pytest -k matches substrings, so similar test names can accidentally include or
# exclude each other. The default file-based path uses exact node ids instead.
# =============================================================================
build_testexpr_from_file() {
TEST_NODE_ARGS=()
USE_FILE_TEST_NODES=false
load_testnodes_from_file() {
local file="$1"
local expr=""
local line=""
if [[ ! -f "${file}" ]]; then
log_error "Test list file not found: ${file}"
@@ -102,36 +105,27 @@ build_testexpr_from_file() {
line=$(echo "$line" | xargs)
[[ -z "$line" ]] && continue
if [[ -n "${expr}" ]]; then
expr+=" or "
fi
expr+="${line}"
TEST_NODE_ARGS+=("${S3_TEST_FILE}::${line}")
done < "${file}"
echo "${expr}"
}
# =============================================================================
# MARKEXPR: pytest marker expression (safety net for marker-based filtering)
# MARKEXPR: pytest marker expression
# =============================================================================
# Even though we use file-based test selection, we keep marker exclusions
# as a safety net to ensure excluded tests do not slip through.
# File-based test selection is authoritative. Keep the default marker expression
# non-restrictive so implemented tests that carry upstream compatibility markers
# are still run when they are listed in implemented_tests.txt.
# =============================================================================
if [[ -z "${MARKEXPR:-}" ]]; then
# Minimal marker exclusions as safety net (file-based filtering is primary)
MARKEXPR="not fails_on_aws and not fails_on_rgw and not fails_on_dbstore"
# Valid pytest -m expression that does not match any real marker.
MARKEXPR="not rustfs_never_marker"
fi
# =============================================================================
# TESTEXPR: pytest -k expression to select specific tests
# TESTEXPR: optional pytest -k expression to select specific tests
# =============================================================================
# By default, builds an inclusion expression from implemented_tests.txt,
# combined with an exclusion expression from excluded_tests.txt and
# unimplemented_tests.txt to prevent substring-matching collisions.
#
# For example, "test_object_raw_get" in the include list would also match
# "test_object_raw_get_x_amz_expires_not_expired" via pytest -k substring
# matching. The exclusion guard ensures only intended tests run.
# By default, loads exact pytest node ids from implemented_tests.txt.
# Set TESTEXPR to override this with a custom pytest -k expression.
#
# The file-based approach provides:
# 1. Clear visibility of which tests are run
@@ -141,41 +135,14 @@ fi
if [[ -z "${TESTEXPR:-}" ]]; then
if [[ -f "${IMPLEMENTED_TESTS_FILE}" ]]; then
log_info "Loading test list from: ${IMPLEMENTED_TESTS_FILE}"
INCLUDE_EXPR=$(build_testexpr_from_file "${IMPLEMENTED_TESTS_FILE}")
if [[ -z "${INCLUDE_EXPR}" ]]; then
load_testnodes_from_file "${IMPLEMENTED_TESTS_FILE}"
TEST_COUNT="${#TEST_NODE_ARGS[@]}"
if [[ "${TEST_COUNT}" -eq 0 ]]; then
log_error "No tests found in ${IMPLEMENTED_TESTS_FILE}"
exit 1
fi
TEST_COUNT=$(grep -v '^#' "${IMPLEMENTED_TESTS_FILE}" | grep -v '^[[:space:]]*$' | wc -l | xargs)
log_info "Loaded ${TEST_COUNT} tests from implemented_tests.txt"
# Build exclusion expression from excluded and unimplemented lists
# to guard against pytest -k substring matching false positives
EXCLUDE_EXPR=""
EXCLUDE_FILES=("${EXCLUDED_TESTS_FILE}" "${UNIMPLEMENTED_TESTS_FILE}")
if [[ ! -f "${EXCLUDED_TESTS_FILE}" && -f "${LEGACY_NON_STANDARD_TESTS_FILE}" ]]; then
log_warn "excluded_tests.txt not found, fallback to legacy non_standard_tests.txt"
EXCLUDE_FILES=("${LEGACY_NON_STANDARD_TESTS_FILE}" "${UNIMPLEMENTED_TESTS_FILE}")
fi
for exclude_file in "${EXCLUDE_FILES[@]}"; do
if [[ -f "${exclude_file}" ]]; then
FILE_EXPR=$(build_testexpr_from_file "${exclude_file}")
if [[ -n "${FILE_EXPR}" ]]; then
if [[ -n "${EXCLUDE_EXPR}" ]]; then
EXCLUDE_EXPR+=" or "
fi
EXCLUDE_EXPR+="${FILE_EXPR}"
fi
fi
done
if [[ -n "${EXCLUDE_EXPR}" ]]; then
TESTEXPR="(${INCLUDE_EXPR}) and not (${EXCLUDE_EXPR})"
log_info "Added exclusion guard from excluded + unimplemented lists"
else
TESTEXPR="${INCLUDE_EXPR}"
fi
USE_FILE_TEST_NODES=true
log_info "Loaded ${TEST_COUNT} exact test nodes from implemented_tests.txt"
else
log_warn "Test list file not found: ${IMPLEMENTED_TESTS_FILE}"
log_warn "Falling back to exclusion-based filtering"
@@ -249,8 +216,8 @@ Environment Variables:
S3_ALT_SECRET_KEY - Alt user secret key (default: rustfsalt)
MAXFAIL - Stop after N failures (default: 1)
XDIST - Enable parallel execution with N workers (default: 0)
MARKEXPR - pytest marker expression (default: safety net exclusions)
TESTEXPR - pytest -k expression (default: from implemented_tests.txt)
MARKEXPR - pytest marker expression (default: no marker filtering)
TESTEXPR - pytest -k expression (overrides implemented_tests.txt node list)
S3TESTS_CONF_TEMPLATE - Path to s3tests config template (default: .github/s3tests/s3tests.conf)
S3TESTS_CONF - Path to generated s3tests config (default: s3tests.conf)
DATA_ROOT - Root directory for test data storage (default: target)
@@ -841,6 +808,13 @@ fi
# Resolve config path (absolute path for tox)
CONF_OUTPUT_PATH="${PROJECT_ROOT}/${S3TESTS_CONF}"
PYTEST_SELECTION_ARGS=()
if [[ "${USE_FILE_TEST_NODES}" == "true" ]]; then
PYTEST_SELECTION_ARGS=("${TEST_NODE_ARGS[@]}")
else
PYTEST_SELECTION_ARGS=("${S3_TEST_FILE}" -k "${TESTEXPR}")
fi
# Run tests from s3tests/functional
S3TEST_CONF="${CONF_OUTPUT_PATH}" \
tox -- \
@@ -848,9 +822,8 @@ S3TEST_CONF="${CONF_OUTPUT_PATH}" \
--maxfail="${MAXFAIL}" \
--junitxml="${ARTIFACTS_DIR}/junit.xml" \
${XDIST_ARGS} \
s3tests/functional/test_s3.py \
"${PYTEST_SELECTION_ARGS[@]}" \
-m "${MARKEXPR}" \
-k "${TESTEXPR}" \
2>&1 | tee "${ARTIFACTS_DIR}/pytest.log"
TEST_EXIT_CODE=${PIPESTATUS[0]}

View File

@@ -11,6 +11,7 @@
# Failed tests
test_bucket_create_delete_bucket_ownership
test_create_bucket_no_ownership_controls
test_bucket_logging_owner
test_object_copy_not_owned_bucket
test_bucket_policy_multipart
@@ -19,7 +20,6 @@ test_put_bucket_logging
test_put_bucket_logging_errors
test_put_bucket_logging_permissions
test_put_bucket_logging_policy_wildcard
test_rm_bucket_logging
# Skipped tests (require IAM account or multiple storage classes)
test_bucket_policy_deny_self_denied_policy
@@ -31,5 +31,4 @@ test_lifecycle_transition_encrypted
# Tests with known issues (need further investigation)
test_bucket_policy_different_tenant
test_bucket_policy_tenanted_bucket
# Flaky in CI: version count assertion (expects 5, gets 1) - timing/concurrency
test_versioned_concurrent_object_create_concurrent_remove
test_object_copy_to_itself_with_metadata