diff --git a/tests/README.md b/tests/README.md index b3e3e1b..30d18d2 100644 --- a/tests/README.md +++ b/tests/README.md @@ -179,7 +179,7 @@ A single instance can be run with `docker-compose -f docker-compose-bats.yml up **CREATE_STATIC_USERS_IF_NONEXISTENT**: setup_user_v2, if **AUTOCREATE_USERS** is set to **false**, generate non-existing users if they don't exist, but don't delete them, as with user autogeneration -**DIRECT_POST_COMMAND_DELAY**: in direct mode, time to wait before sending new commands to try to prevent propagation delay issues +**DIRECT_POST_COMMAND_DELAY**: in v1 direct mode, time to wait before sending new commands to try to prevent propagation delay issues **SKIP_ACL_TESTING**: avoid ACL tests for systems which do not use ACLs @@ -187,6 +187,8 @@ A single instance can be run with `docker-compose -f docker-compose-bats.yml up **SKIP_USERS_TESTS**: skip versitygw-specific users tests, set to **false** to test against other S3 gateways +**MAX_OPENSSL_COMMAND_LOG_BYTES**: number of OpenSSL command bytes to display in command log, can prevent the display of too many chars in the case of large payload commands, -1 means display whole command + ## REST Scripts REST scripts are included for calls to S3's REST API in the `./tests/rest_scripts/` folder. To call a script, the following parameters are needed: diff --git a/tests/commands/put_object_tagging.sh b/tests/commands/put_object_tagging.sh index 1611d80..f694c30 100644 --- a/tests/commands/put_object_tagging.sh +++ b/tests/commands/put_object_tagging.sh @@ -14,9 +14,10 @@ # specific language governing permissions and limitations # under the License. +source ./tests/util/util_rest.sh + put_object_tagging() { - if [ $# -ne 5 ]; then - log 2 "'put-object-tagging' command missing command type, bucket, object name, file, key, and/or value" + if ! check_param_count_v2 "command type, bucket, object key, tag key, value" 5 $#; then return 1 fi local error diff --git a/tests/drivers/file.sh b/tests/drivers/file.sh index d8d09a8..0d49577 100644 --- a/tests/drivers/file.sh +++ b/tests/drivers/file.sh @@ -151,3 +151,11 @@ chunked_upload_trailer_success() { fi return 0 } + +get_file_name() { + if ! uuid=$(uuidgen 2>&1); then + log 2 "error getting UUID: $uuid" + return 1 + fi + echo "test-file-${uuid}" +} diff --git a/tests/drivers/get_object_attributes/get_object_attributes_rest.sh b/tests/drivers/get_object_attributes/get_object_attributes_rest.sh index 6b2f1d2..c597b02 100644 --- a/tests/drivers/get_object_attributes/get_object_attributes_rest.sh +++ b/tests/drivers/get_object_attributes/get_object_attributes_rest.sh @@ -14,6 +14,8 @@ # specific language governing permissions and limitations # under the License. +source ./tests/util/util_list_parts.sh + upload_and_check_attributes() { if ! check_param_count_v2 "bucket, test file, file size" 3 $#; then return 1 diff --git a/tests/drivers/openssl.sh b/tests/drivers/openssl.sh index dda43ad..45698e4 100644 --- a/tests/drivers/openssl.sh +++ b/tests/drivers/openssl.sh @@ -16,6 +16,32 @@ source ./tests/drivers/xml.sh +write_openssl_command_to_command_log() { + if ! check_param_count_v2 "command file" 1 $#; then + return 1 + fi + max_chars=1024 + if [ -n "$MAX_OPENSSL_COMMAND_LOG_BYTES" ]; then + max_chars="$MAX_OPENSSL_COMMAND_LOG_BYTES" + fi + if ! file_size=$(get_file_size "$1"); then + return 1 + fi + if [ "$max_chars" -eq -1 ] || [ "$file_size" -lt "$max_chars" ]; then + log_data=$(perl -pe 's/\x00//g' "$1" | perl -pe 's/\r//g') + else + log_data=$(head -c "$max_chars" "$1" | perl -pe 's/\x00//g' | perl -pe 's/\r//g') + log_data+="" + fi + while IFS=$' ' read -r -a line_words; do + if ! mask_arg_array "${line_words[@]}"; then + return 1 + fi + # shellcheck disable=SC2154 + echo "${masked_args[*]}" >> "$COMMAND_LOG" + done <<< "$log_data" +} + send_via_openssl() { if ! check_param_count_v2 "command file" 1 $#; then return 1 @@ -25,6 +51,9 @@ send_via_openssl() { host+=":443" fi log 5 "connecting to $host" + if [ -n "$COMMAND_LOG" ]; then + write_openssl_command_to_command_log "$1" + fi if ! result=$(openssl s_client -connect "$host" -ign_eof < "$1" 2>&1); then log 2 "error sending openssl command: $result" return 1 diff --git a/tests/test_rest.sh b/tests/test_rest.sh deleted file mode 100755 index 7baa00a..0000000 --- a/tests/test_rest.sh +++ /dev/null @@ -1,504 +0,0 @@ -#!/usr/bin/env bats - -# Copyright 2024 Versity Software -# This file is licensed under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http:#www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -load ./bats-support/load -load ./bats-assert/load - -source ./tests/commands/create_multipart_upload.sh -source ./tests/commands/delete_object_tagging.sh -source ./tests/commands/get_bucket_versioning.sh -source ./tests/commands/get_object.sh -source ./tests/commands/get_object_lock_configuration.sh -source ./tests/commands/get_object_retention.sh -source ./tests/commands/list_buckets.sh -source ./tests/commands/list_object_versions.sh -source ./tests/commands/put_bucket_versioning.sh -source ./tests/commands/put_object.sh -source ./tests/commands/put_object_retention.sh -source ./tests/commands/put_object_tagging.sh -source ./tests/drivers/create_bucket/create_bucket_rest.sh -source ./tests/drivers/copy_object/copy_object_rest.sh -source ./tests/drivers/get_object_attributes/get_object_attributes_rest.sh -source ./tests/drivers/get_object_lock_config/get_object_lock_config_rest.sh -source ./tests/drivers/get_object_tagging/get_object_tagging.sh -source ./tests/drivers/get_bucket_ownership_controls/get_bucket_ownership_controls_rest.sh -source ./tests/drivers/head_object/head_object_rest.sh -source ./tests/drivers/list_objects/list_objects_rest.sh -source ./tests/drivers/file.sh -source ./tests/drivers/xml.sh -source ./tests/logger.sh -source ./tests/setup.sh -source ./tests/util/util_delete_object.sh -source ./tests/util/util_legal_hold.sh -source ./tests/util/util_list_buckets.sh -source ./tests/util/util_list_objects.sh -source ./tests/util/util_list_parts.sh -source ./tests/util/util_lock_config.sh -source ./tests/util/util_multipart_before_completion.sh -source ./tests/util/util_object.sh -source ./tests/util/util_policy.sh -source ./tests/util/util_public_access_block.sh -source ./tests/util/util_rest.sh -source ./tests/util/util_time.sh -source ./tests/util/util_versioning.sh - -export RUN_USERS=true -test_file="test_file" - -@test "test_rest_list_objects" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_and_file_v2 "$bucket_name" "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - run list_check_objects_rest "$bucket_name" - assert_success -} - -@test "test_rest_delete_object" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_and_file_v2 "$bucket_name" "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - run download_and_compare_file "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" - assert_success - - run delete_object "rest" "$bucket_name" "$test_file" - assert_success - - run get_object "rest" "$bucket_name" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" - assert_failure -} - -@test "test_rest_tagging" { - test_key="TestKey" - test_value="TestValue" - - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_and_file_v2 "$bucket_name" "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - run put_object_tagging "rest" "$bucket_name" "$test_file" "$test_key" "$test_value" - assert_success - - run check_verify_object_tags "rest" "$bucket_name" "$test_file" "$test_key" "$test_value" - assert_success - - run delete_object_tagging "rest" "$bucket_name" "$test_file" - assert_success - - run verify_no_object_tags "rest" "$bucket_name" "$test_file" - assert_success -} - -@test "test_rest_retention" { - test_key="TestKey" - test_value="TestValue" - - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_object_lock_enabled_v2 "$bucket_name" - assert_success - - run create_test_files "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - if ! five_seconds_later=$(get_time_seconds_in_future 5 "%z"); then - log 2 "error getting future time" - return 1 - fi - log 5 "later: $five_seconds_later" - run put_object_retention_rest "$bucket_name" "$test_file" "GOVERNANCE" "$five_seconds_later" - assert_success -} - -@test "REST - legal hold, get without config" { - if [ "$RECREATE_BUCKETS" == "false" ]; then - skip "test requires object lock not to be enabled" - fi - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_and_file_v2 "$bucket_name" "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - run check_legal_hold_without_lock_enabled "$bucket_name" "$test_file" "InvalidRequest" - assert_success -} - -@test "REST - legal hold, object lock enabled w/o specific object lock set" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_object_lock_enabled_v2 "$bucket_name" - assert_success - - run create_test_file "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - run check_legal_hold_without_lock_enabled "$bucket_name" "$test_file" "NoSuchObjectLockConfiguration" - assert_success -} - -@test "REST - get object attributes" { - if [ "$DIRECT" != "true" ]; then - skip "https://github.com/versity/versitygw/issues/1001" - fi - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_and_large_file_v2 "$bucket_name" "$test_file" - assert_success - - # shellcheck disable=SC2034 - file_size=$(stat -c %s "$TEST_FILE_FOLDER/$test_file" 2>/dev/null || stat -f %z "$TEST_FILE_FOLDER/$test_file" 2>/dev/null) - - run split_file "$TEST_FILE_FOLDER/$test_file" 4 - assert_success - - run upload_and_check_attributes "$bucket_name" "$test_file" "$file_size" - assert_success -} - -@test "REST - attributes - invalid param" { - if [ "$DIRECT" != "true" ]; then - skip "https://github.com/versity/versitygw/issues/1001" - fi - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_and_file_v2 "$bucket_name" "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - run check_attributes_invalid_param "$bucket_name" "$test_file" - assert_success -} - -@test "REST - attributes - checksum" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_and_file_v2 "$bucket_name" "$test_file" - assert_success - - run add_and_check_checksum "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success -} - -@test "REST - list objects v2 - invalid continuation token" { - if [ "$DIRECT" != "true" ]; then - skip "https://github.com/versity/versitygw/issues/993" - fi - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - test_file_two="test_file_2" - test_file_three="test_file_3" - run setup_bucket_and_files_v2 "$bucket_name" "$test_file" "$test_file_two" "$test_file_three" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file_two" "$bucket_name" "$test_file_two" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file_three" "$bucket_name" "$test_file_three" - assert_success - - run list_objects_check_params_get_token "$bucket_name" "$test_file" "$test_file_two" "TRUE" - assert_success - continuation_token=$output - - # interestingly, AWS appears to accept continuation tokens that are a few characters off, so have to remove three chars - run list_objects_check_continuation_error "$bucket_name" "${continuation_token:0:${#continuation_token}-3}" - assert_success -} - -@test "REST - list objects v1 - no NextMarker without delimiter" { - if [ "$DIRECT" != "true" ]; then - skip "https://github.com/versity/versitygw/issues/999" - fi - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - test_file_two="test_file_2" - run setup_bucket_and_files_v2 "$bucket_name" "$test_file" "$test_file_two" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file_two" "$bucket_name" "$test_file_two" - assert_success - - run list_objects_v1_check_nextmarker_empty "$bucket_name" - assert_success -} - -@test "REST - head object" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_and_file_v2 "$bucket_name" "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - run get_etag_rest "$bucket_name" "$test_file" - assert_success - expected_etag=$output - - run get_etag_attribute_rest "$bucket_name" "$test_file" "$expected_etag" - assert_success -} - -@test "REST - delete objects - no content-md5 header" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_v2 "$bucket_name" - assert_success - - run delete_objects_no_content_md5_header "$bucket_name" - assert_success -} - -@test "REST - delete objects command" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - test_file_two="test_file_two" - run setup_bucket_and_files_v2 "$bucket_name" "$test_file" "$test_file_two" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file_two" "$bucket_name" "$test_file_two" - assert_success - - run verify_object_exists "$bucket_name" "$test_file" - assert_success - - run verify_object_exists "$bucket_name" "$test_file_two" - assert_success - - run delete_objects_verify_success "$bucket_name" "$test_file" "$test_file_two" - assert_success - - run verify_object_not_found "$bucket_name" "$test_file" - assert_success - - run verify_object_not_found "$bucket_name" "$test_file_two" - assert_success -} - -@test "REST - PutObjectRetention - w/o request body" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_object_lock_enabled_v2 "$bucket_name" - assert_success - - run create_test_file "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - run retention_rest_without_request_body "$bucket_name" "$test_file" - assert_success -} - -@test "REST - PutObjectLegalHold - missing content-md5" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_object_lock_enabled_v2 "$bucket_name" - assert_success - - run create_test_file "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - run check_legal_hold_without_content_md5 "$bucket_name" "$test_file" - assert_success -} - -@test "REST - PutObjectLegalHold w/o payload" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_object_lock_enabled_v2 "$bucket_name" - assert_success - - run create_test_file "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - run check_legal_hold_without_payload "$bucket_name" "$test_file" - assert_success -} - -@test "REST - PutObjectLegalHold - success" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_object_lock_enabled_v2 "$bucket_name" - assert_success - - run create_test_file "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - run rest_check_legal_hold "$bucket_name" "$test_file" - assert_success -} - -@test "REST - copy object w/invalid copy source" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_and_file_v2 "$bucket_name" "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - run copy_object_invalid_copy_source "$bucket_name" - assert_success -} - -@test "REST - copy object w/copy source and payload" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_and_file_v2 "$bucket_name" "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - run copy_object_copy_source_and_payload "$bucket_name" "$test_file" "$TEST_FILE_FOLDER/$test_file" - assert_success -} - -@test "REST - range download and compare" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_and_large_file_v2 "$bucket_name" "$test_file" - assert_success - - run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" - assert_success - - run download_and_compare_file "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" 2000000 - assert_success -} - -@test "REST - put, get object, encoded name" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - file_name=" \"<>\\^\`{}|+&?%" - run setup_bucket_and_file_v2 "$bucket_name" "$file_name" - assert_success - - run put_object_rest_special_chars "$TEST_FILE_FOLDER/$file_name" "$bucket_name" "$file_name/$file_name" - assert_success - - run list_check_single_object "$bucket_name" "$file_name/$file_name" - assert_success - - run get_object_rest_special_chars "$bucket_name" "$file_name/$file_name" "$TEST_FILE_FOLDER/${file_name}-copy" - assert_success - - run compare_files "$TEST_FILE_FOLDER/$file_name" "$TEST_FILE_FOLDER/${file_name}-copy" - assert_success - - run delete_object_rest "$bucket_name" "$file_name/$file_name" - assert_success -} - -@test "REST - GetObject w/STREAMING-AWS4-HMAC-SHA256-PAYLOAD type" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_and_file_v2 "$bucket_name" "$test_file" - assert_success - - run get_object_rest_with_invalid_streaming_type "$bucket_name" "$test_file" - assert_success -} diff --git a/tests/test_rest_attributes.sh b/tests/test_rest_attributes.sh new file mode 100755 index 0000000..a7227c5 --- /dev/null +++ b/tests/test_rest_attributes.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bats + +# Copyright 2026 Versity Software +# This file is licensed under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http:#www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +load ./bats-support/load +load ./bats-assert/load + +source ./tests/setup.sh +source ./tests/drivers/create_bucket/create_bucket_rest.sh +source ./tests/drivers/get_object_attributes/get_object_attributes_rest.sh + +@test "REST - get object attributes" { + if [ "$DIRECT" != "true" ]; then + skip "https://github.com/versity/versitygw/issues/1001" + fi + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run get_file_name + assert_success + test_file="$output" + + run setup_bucket_and_large_file_v2 "$bucket_name" "$test_file" + assert_success + + run get_file_size "$TEST_FILE_FOLDER/$test_file" + assert_success + file_size=${output} + + run split_file "$TEST_FILE_FOLDER/$test_file" 4 + assert_success + + run upload_and_check_attributes "$bucket_name" "$test_file" "$file_size" + assert_success +} + +@test "REST - attributes - invalid param" { + if [ "$DIRECT" != "true" ]; then + skip "https://github.com/versity/versitygw/issues/1001" + fi + + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run get_file_name + assert_success + test_file="$output" + + run setup_bucket_and_file_v2 "$bucket_name" "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + run check_attributes_invalid_param "$bucket_name" "$test_file" + assert_success +} + +@test "REST - attributes - checksum" { + run get_file_name + assert_success + test_file="$output" + + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_and_file_v2 "$bucket_name" "$test_file" + assert_success + + run add_and_check_checksum "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success +} diff --git a/tests/test_rest_chunked.sh b/tests/test_rest_chunked.sh index e15be7e..7038440 100755 --- a/tests/test_rest_chunked.sh +++ b/tests/test_rest_chunked.sh @@ -30,7 +30,10 @@ source ./tests/util/util_file.sh assert_success bucket_name="$output" - test_file="test-file" + run get_file_name + assert_success + test_file="$output" + run setup_bucket_and_file_v2 "$bucket_name" "$test_file" assert_success @@ -46,7 +49,10 @@ source ./tests/util/util_file.sh run setup_bucket_v2 "$bucket_name" assert_success - test_file="test-file" + run get_file_name + assert_success + test_file="$output" + run create_test_file "$test_file" 8192 assert_success @@ -62,7 +68,10 @@ source ./tests/util/util_file.sh run setup_bucket_v2 "$bucket_name" assert_success - test_file="test-file" + run get_file_name + assert_success + test_file="$output" + run create_test_file "$test_file" 0 assert_success @@ -78,7 +87,10 @@ source ./tests/util/util_file.sh run setup_bucket_v2 "$bucket_name" assert_success - test_file="test-file" + run get_file_name + assert_success + test_file="$output" + run create_file_single_char "$test_file" 8192 'a' assert_success @@ -97,7 +109,10 @@ source ./tests/util/util_file.sh run setup_bucket_v2 "$bucket_name" assert_success - test_file="test-file" + run get_file_name + assert_success + test_file="$output" + run create_file_single_char "$test_file" 8192 '\0' assert_success @@ -116,7 +131,10 @@ source ./tests/util/util_file.sh run setup_bucket_v2 "$bucket_name" assert_success - test_file="test-file" + run get_file_name + assert_success + test_file="$output" + run create_test_file "$test_file" 10000 assert_success @@ -135,7 +153,10 @@ source ./tests/util/util_file.sh run setup_bucket_v2 "$bucket_name" assert_success - test_file="test-file" + run get_file_name + assert_success + test_file="$output" + run create_test_file "$test_file" 0 assert_success @@ -176,7 +197,10 @@ source ./tests/util/util_file.sh assert_success bucket_name="$output" - test_file="test-file" + run get_file_name + assert_success + test_file="$output" + run setup_bucket_and_file "$bucket_name" "$test_file" assert_success @@ -242,7 +266,10 @@ source ./tests/util/util_file.sh run setup_bucket "$bucket_name" assert_success - test_file="test-file" + run get_file_name + assert_success + test_file="$output" + run create_test_file "$test_file" 200000 assert_success @@ -252,3 +279,192 @@ source ./tests/util/util_file.sh run download_and_compare_file "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" assert_success } + +@test "REST - PutObject - STREAMING-UNSIGNED-PAYLOAD-TRAILER, x-amz-trailer of crc32, trailer missing" { + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_v2 "$bucket_name" + assert_success + + run send_openssl_go_command_expect_error "400" "MalformedTrailerError" "The request contained trailing data that was not well-formed" \ + "-client" "openssl" "-commandType" "putObject" "-bucketName" "$bucket_name" "-payload" "abcdefg" \ + "-omitPayloadTrailer" "-checksumType" "crc32" \ + "-payloadType" "STREAMING-UNSIGNED-PAYLOAD-TRAILER" "-chunkSize" "8192" "-objectKey" "key" "-signedParams" "x-amz-trailer:x-amz-checksum-crc32" + assert_success +} + +@test "REST - PutObject - STREAMING-UNSIGNED-PAYLOAD-TRAILER - 200 header returns correct checksum type" { + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run get_file_name + assert_success + test_file="$output" + + run setup_bucket_and_file_v2 "$bucket_name" "$test_file" + assert_success + + run bash -c "sha256sum $TEST_FILE_FOLDER/$test_file | awk '{print $1}' | xxd -r -p | base64" + assert_success + checksum=${output} + + run send_openssl_go_command_check_header "200" "x-amz-checksum-sha256" "$checksum" \ + "-client" "openssl" "-commandType" "putObject" "-bucketName" "$bucket_name" "-payloadFile" "$TEST_FILE_FOLDER/$test_file" "-checksumType" "sha256" \ + "-payloadType" "STREAMING-UNSIGNED-PAYLOAD-TRAILER" "-chunkSize" "8192" "-objectKey" "key" "-signedParams" "x-amz-trailer:x-amz-checksum-sha256" + assert_success +} + +@test "REST - PutObject - STREAMING-UNSIGNED-PAYLOAD-TRAILER - success (sha1)" { + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_v2 "$bucket_name" + assert_success + + run get_file_name + assert_success + test_file="$output" + + run create_test_file "$test_file" 10000 + assert_success + + run bash -c "sha1sum $TEST_FILE_FOLDER/$test_file | awk '{print $1}' | xxd -r -p | base64" + assert_success + checksum=${output} + + run send_openssl_go_command_check_header "200" "x-amz-checksum-sha1" "$checksum" \ + "-client" "openssl" "-commandType" "putObject" "-bucketName" "$bucket_name" "-payloadFile" "$TEST_FILE_FOLDER/$test_file" "-checksumType" "sha1" \ + "-payloadType" "STREAMING-UNSIGNED-PAYLOAD-TRAILER" "-chunkSize" "8192" "-objectKey" "key" "-signedParams" "x-amz-trailer:x-amz-checksum-sha1" + assert_success +} + +@test "REST - PutObject - STREAMING-UNSIGNED-PAYLOAD-TRAILER - success (crc32)" { + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_v2 "$bucket_name" + assert_success + + run get_file_name + assert_success + test_file="$output" + + run create_test_file "$test_file" 10000 + assert_success + + run bash -c "gzip -c -1 $TEST_FILE_FOLDER/$test_file | tail -c8 | od -t x4 -N 4 -A n | awk '{print $1}' | xxd -r -p | base64" + assert_success + checksum=${output} + + run send_openssl_go_command_check_header "200" "x-amz-checksum-crc32" "$checksum" \ + "-client" "openssl" "-commandType" "putObject" "-bucketName" "$bucket_name" "-payloadFile" "$TEST_FILE_FOLDER/$test_file" "-checksumType" "crc32" \ + "-payloadType" "STREAMING-UNSIGNED-PAYLOAD-TRAILER" "-chunkSize" "8192" "-objectKey" "key" "-signedParams" "x-amz-trailer:x-amz-checksum-crc32" + assert_success +} + +@test "REST - PutObject - STREAMING-UNSIGNED-PAYLOAD-TRAILER - success (crc32c)" { + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_v2 "$bucket_name" + assert_success + + run get_file_name + assert_success + test_file="$output" + + run create_test_file "$test_file" 10000 + assert_success + + run bash -c "DATA_FILE=$TEST_FILE_FOLDER/$test_file CHECKSUM_TYPE=crc32c ./tests/rest_scripts/calculate_checksum.sh" + assert_success + checksum=$output + + run send_openssl_go_command_check_header "200" "x-amz-checksum-crc32c" "$checksum" \ + "-client" "openssl" "-commandType" "putObject" "-bucketName" "$bucket_name" "-payloadFile" "$TEST_FILE_FOLDER/$test_file" "-checksumType" "crc32c" \ + "-payloadType" "STREAMING-UNSIGNED-PAYLOAD-TRAILER" "-chunkSize" "8192" "-objectKey" "key" "-checksumType" "crc32c" "-signedParams" "x-amz-trailer:x-amz-checksum-crc32c" + assert_success +} + +@test "REST - PutObject - STREAMING-UNSIGNED-PAYLOAD-TRAILER - success (crc64nvme)" { + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_v2 "$bucket_name" + assert_success + + run get_file_name + assert_success + test_file="$output" + + run create_test_file "$test_file" 10000 + assert_success + + run bash -c "DATA_FILE=$TEST_FILE_FOLDER/$test_file CHECKSUM_TYPE=crc64nvme ./tests/rest_scripts/calculate_checksum.sh" + assert_success + checksum=$output + + run send_openssl_go_command_check_header "200" "x-amz-checksum-crc64nvme" "$checksum" \ + "-client" "openssl" "-commandType" "putObject" "-bucketName" "$bucket_name" "-payloadFile" "$TEST_FILE_FOLDER/$test_file" "-checksumType" "crc64nvme" \ + "-payloadType" "STREAMING-UNSIGNED-PAYLOAD-TRAILER" "-chunkSize" "8192" "-objectKey" "key" "-signedParams" "x-amz-trailer:x-amz-checksum-crc64nvme" + assert_success +} + +@test "REST - PutObject - STREAMING-AWS4-HMAC-SHA256-PAYLOAD - missing content length" { + if [ "$DIRECT" != "true" ]; then + skip "https://github.com/versity/versitygw/issues/1623" + fi + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_v2 "$bucket_name" + assert_success + + run send_openssl_go_command_chunked_no_content_length "$bucket_name" "key" + assert_success +} + +@test "REST - PutObject - STREAMING-UNSIGNED-PAYLOAD-TRAILER, x-amz-trailer of crc32, trailer key missing" { + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_v2 "$bucket_name" + assert_success + + run send_openssl_go_command_expect_error "400" "MalformedTrailerError" "The request contained trailing data that was not well-formed" \ + "-client" "openssl" "-commandType" "putObject" "-bucketName" "$bucket_name" "-objectKey" "key" "-payload" "abcdefg" "-checksumType" "crc32c" \ + "-omitPayloadTrailerKey" \ + "-payloadType" "STREAMING-UNSIGNED-PAYLOAD-TRAILER" "-chunkSize" "8192" "-objectKey" "key" "-signedParams" "x-amz-trailer:x-amz-checksum-crc32" + assert_success +} + +@test "REST - PutObject - STREAMING-UNSIGNED-PAYLOAD-TRAILER - default crc64nvme" { + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_v2 "$bucket_name" + assert_success + + run get_file_name + assert_success + test_file="$output" + + run create_test_file "$test_file" 1024 + assert_success + + run send_openssl_go_command "200" "-bucketName" "$bucket_name" "-objectKey" "$test_file" "-commandType" "putObject" \ + "-payloadFile" "$TEST_FILE_FOLDER/$test_file" "-omitPayloadTrailer" \ + "-debug" "-logFile" "tagging.log" "-checksumType" "crc64nvme" \ + "-payloadType" "STREAMING-UNSIGNED-PAYLOAD-TRAILER" "-chunkSize" "8192" + assert_success +} diff --git a/tests/test_rest_copy_object.sh b/tests/test_rest_copy_object.sh new file mode 100755 index 0000000..b69b9b0 --- /dev/null +++ b/tests/test_rest_copy_object.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bats + +# Copyright 2026 Versity Software +# This file is licensed under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http:#www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +load ./bats-support/load +load ./bats-assert/load + +source ./tests/drivers/copy_object/copy_object_rest.sh +source ./tests/drivers/create_bucket/create_bucket_rest.sh +source ./tests/setup.sh + +@test "REST - copy object w/invalid copy source" { + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run get_file_name + assert_success + test_file=$output + + run setup_bucket_and_file_v2 "$bucket_name" "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + run copy_object_invalid_copy_source "$bucket_name" + assert_success +} + +@test "REST - copy object w/copy source and payload" { + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run get_file_name + assert_success + test_file=$output + + run setup_bucket_and_file_v2 "$bucket_name" "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + run copy_object_copy_source_and_payload "$bucket_name" "$test_file" "$TEST_FILE_FOLDER/$test_file" + assert_success +} diff --git a/tests/test_rest_delete_object.sh b/tests/test_rest_delete_object.sh new file mode 100755 index 0000000..04ed40c --- /dev/null +++ b/tests/test_rest_delete_object.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bats + +# Copyright 2026 Versity Software +# This file is licensed under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http:#www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +load ./bats-support/load +load ./bats-assert/load + +source ./tests/drivers/create_bucket/create_bucket_rest.sh +source ./tests/util/util_delete_object.sh +source ./tests/setup.sh + +@test "test_rest_delete_object" { + run get_file_name + assert_success + test_file="$output" + + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_and_file_v2 "$bucket_name" "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + run download_and_compare_file "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" + assert_success + + run delete_object "rest" "$bucket_name" "$test_file" + assert_success + + run get_object "rest" "$bucket_name" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" + assert_failure +} + +@test "REST - delete objects - no content-md5 header" { + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_v2 "$bucket_name" + assert_success + + run delete_objects_no_content_md5_header "$bucket_name" + assert_success +} + +@test "REST - delete objects command" { + run get_file_name + assert_success + test_file="$output" + + run get_file_name + assert_success + test_file_two="$output" + log 5 "$test_file $test_file_two" + + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_and_files_v2 "$bucket_name" "$test_file" "$test_file_two" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file_two" "$bucket_name" "$test_file_two" + assert_success + + run verify_object_exists "$bucket_name" "$test_file" + assert_success + + run verify_object_exists "$bucket_name" "$test_file_two" + assert_success + + run delete_objects_verify_success "$bucket_name" "$test_file" "$test_file_two" + assert_success + + run verify_object_not_found "$bucket_name" "$test_file" + assert_success + + run verify_object_not_found "$bucket_name" "$test_file_two" + assert_success +} diff --git a/tests/test_rest_get_object.sh b/tests/test_rest_get_object.sh new file mode 100755 index 0000000..e8a77c4 --- /dev/null +++ b/tests/test_rest_get_object.sh @@ -0,0 +1,82 @@ +#!/usr/bin/env bats + +# Copyright 2026 Versity Software +# This file is licensed under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http:#www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +load ./bats-support/load +load ./bats-assert/load + +source ./tests/drivers/create_bucket/create_bucket_rest.sh +source ./tests/setup.sh + +@test "REST - range download and compare" { + run get_file_name + assert_success + test_file="$output" + + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_and_large_file_v2 "$bucket_name" "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + download_chunk_size="2000000" + run download_and_compare_file "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" "$TEST_FILE_FOLDER/$test_file-copy" "$download_chunk_size" + assert_success +} + +@test "REST - put, get object, encoded name" { + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + file_name=" \"<>\\^\`{}|+&?%" + run setup_bucket_and_file_v2 "$bucket_name" "$file_name" + assert_success + + run put_object_rest_special_chars "$TEST_FILE_FOLDER/$file_name" "$bucket_name" "$file_name/$file_name" + assert_success + + run list_check_single_object "$bucket_name" "$file_name/$file_name" + assert_success + + run get_object_rest_special_chars "$bucket_name" "$file_name/$file_name" "$TEST_FILE_FOLDER/${file_name}-copy" + assert_success + + run compare_files "$TEST_FILE_FOLDER/$file_name" "$TEST_FILE_FOLDER/${file_name}-copy" + assert_success + + run delete_object_rest "$bucket_name" "$file_name/$file_name" + assert_success +} + +@test "REST - GetObject w/STREAMING-AWS4-HMAC-SHA256-PAYLOAD type" { + run get_file_name + assert_success + test_file="$output" + + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_and_file_v2 "$bucket_name" "$test_file" + assert_success + + run get_object_rest_with_invalid_streaming_type "$bucket_name" "$test_file" + assert_success +} diff --git a/tests/test_rest_get_object_legal_hold.sh b/tests/test_rest_get_object_legal_hold.sh new file mode 100755 index 0000000..5d02cae --- /dev/null +++ b/tests/test_rest_get_object_legal_hold.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bats + +# Copyright 2026 Versity Software +# This file is licensed under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http:#www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +load ./bats-support/load +load ./bats-assert/load + +source ./tests/setup.sh +source ./tests/drivers/create_bucket/create_bucket_rest.sh + +@test "REST - legal hold, get without config" { + if [ "$RECREATE_BUCKETS" == "false" ]; then + skip "test requires object lock not to be enabled" + fi + run get_file_name + assert_success + test_file="$output" + + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_and_file_v2 "$bucket_name" "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + run check_legal_hold_without_lock_enabled "$bucket_name" "$test_file" "InvalidRequest" + assert_success +} + +@test "REST - legal hold, object lock enabled w/o specific object lock set" { + run get_file_name + assert_success + test_file="$output" + + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_object_lock_enabled_v2 "$bucket_name" + assert_success + + run create_test_file "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + run check_legal_hold_without_lock_enabled "$bucket_name" "$test_file" "NoSuchObjectLockConfiguration" + assert_success +} diff --git a/tests/test_rest_get_object_tagging.sh b/tests/test_rest_get_object_tagging.sh index 4443a00..53c8ee1 100755 --- a/tests/test_rest_get_object_tagging.sh +++ b/tests/test_rest_get_object_tagging.sh @@ -18,12 +18,17 @@ load ./bats-support/load load ./bats-assert/load source ./tests/setup.sh +source ./tests/commands/delete_object_tagging.sh +source ./tests/commands/put_object_tagging.sh source ./tests/drivers/create_bucket/create_bucket_rest.sh +source ./tests/drivers/get_object_tagging/get_object_tagging.sh source ./tests/drivers/get_object_tagging/get_object_tagging_rest.sh source ./tests/drivers/put_object/put_object_rest.sh @test "REST - GetObjectTagging - no tags" { - test_file="test_file" + run get_file_name + assert_success + test_file="$output" run get_bucket_name "$BUCKET_ONE_NAME" assert_success @@ -37,7 +42,9 @@ source ./tests/drivers/put_object/put_object_rest.sh } @test "REST - GetObjectTagging - older version returns version ID" { - test_file="test_file" + run get_file_name + assert_success + test_file="$output" run get_bucket_name "$BUCKET_ONE_NAME" assert_success @@ -54,7 +61,9 @@ source ./tests/drivers/put_object/put_object_rest.sh if [ "$DIRECT" != "true" ]; then skip "https://github.com/versity/versitygw/issues/1698" fi - test_file="test_file" + run get_file_name + assert_success + test_file="$output" run get_bucket_name "$BUCKET_ONE_NAME" assert_success @@ -71,4 +80,35 @@ source ./tests/drivers/put_object/put_object_rest.sh run get_object_tagging_invalid_version_id "$bucket_name" "$test_file" assert_success -} \ No newline at end of file +} + +@test "test_rest_tagging" { + test_key="TestKey" + test_value="TestValue" + + run get_file_name + assert_success + test_file="$output" + + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_and_file_v2 "$bucket_name" "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + run put_object_tagging "rest" "$bucket_name" "$test_file" "$test_key" "$test_value" + assert_success + + run check_verify_object_tags "rest" "$bucket_name" "$test_file" "$test_key" "$test_value" + assert_success + + run delete_object_tagging "rest" "$bucket_name" "$test_file" + assert_success + + run verify_no_object_tags "rest" "$bucket_name" "$test_file" + assert_success +} diff --git a/tests/test_rest_head_object.sh b/tests/test_rest_head_object.sh new file mode 100755 index 0000000..fc37374 --- /dev/null +++ b/tests/test_rest_head_object.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bats + +# Copyright 2026 Versity Software +# This file is licensed under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http:#www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +load ./bats-support/load +load ./bats-assert/load + +source ./tests/setup.sh +source ./tests/drivers/create_bucket/create_bucket_rest.sh +source ./tests/drivers/get_object_attributes/get_object_attributes_rest.sh + +@test "REST - head object" { + run get_file_name + assert_success + test_file="$output" + + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_and_file_v2 "$bucket_name" "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + run get_etag_rest "$bucket_name" "$test_file" + assert_success + expected_etag=$output + + run get_etag_attribute_rest "$bucket_name" "$test_file" "$expected_etag" + assert_success +} diff --git a/tests/test_rest_list_objects.sh b/tests/test_rest_list_objects.sh new file mode 100755 index 0000000..c5f51a0 --- /dev/null +++ b/tests/test_rest_list_objects.sh @@ -0,0 +1,110 @@ +#!/usr/bin/env bats + +# Copyright 2024 Versity Software +# This file is licensed under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http:#www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +load ./bats-support/load +load ./bats-assert/load + +source ./tests/setup.sh +source ./tests/drivers/create_bucket/create_bucket_rest.sh + +@test "test_rest_list_objects" { + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run get_file_name + assert_success + test_file="$output" + + run setup_bucket_and_file_v2 "$bucket_name" "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + run list_check_objects_rest "$bucket_name" + assert_success +} + +@test "REST - list objects v2 - invalid continuation token" { + if [ "$DIRECT" != "true" ]; then + skip "https://github.com/versity/versitygw/issues/993" + fi + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run get_file_name + assert_success + test_file="$output" + + run get_file_name + assert_success + test_file_two="$output" + + run get_file_name + assert_success + test_file_three="$output" + + run setup_bucket_and_files_v2 "$bucket_name" "$test_file" "$test_file_two" "$test_file_three" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file_two" "$bucket_name" "$test_file_two" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file_three" "$bucket_name" "$test_file_three" + assert_success + + run list_objects_check_params_get_token "$bucket_name" "$test_file" "$test_file_two" "TRUE" + assert_success + continuation_token=$output + + # interestingly, AWS appears to accept continuation tokens that are a few characters off, so have to remove three chars + run list_objects_check_continuation_error "$bucket_name" "${continuation_token:0:${#continuation_token}-3}" + assert_success +} + +@test "REST - list objects v1 - no NextMarker without delimiter" { + if [ "$DIRECT" != "true" ]; then + skip "https://github.com/versity/versitygw/issues/999" + fi + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run get_file_name + assert_success + test_file="$output" + + run get_file_name + assert_success + test_file_two="$output" + + run setup_bucket_and_files_v2 "$bucket_name" "$test_file" "$test_file_two" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file_two" "$bucket_name" "$test_file_two" + assert_success + + run list_objects_v1_check_nextmarker_empty "$bucket_name" + assert_success +} diff --git a/tests/test_rest_put_object.sh b/tests/test_rest_put_object.sh index e5ea42a..9ce347f 100755 --- a/tests/test_rest_put_object.sh +++ b/tests/test_rest_put_object.sh @@ -247,164 +247,6 @@ export RUN_USERS=true assert_success } -@test "REST - PutObject - STREAMING-UNSIGNED-PAYLOAD-TRAILER, x-amz-trailer of crc32, trailer missing" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_v2 "$bucket_name" - assert_success - - run send_openssl_go_command_expect_error "400" "MalformedTrailerError" "The request contained trailing data that was not well-formed" \ - "-client" "openssl" "-commandType" "putObject" "-bucketName" "$bucket_name" "-payload" "abcdefg" \ - "-omitPayloadTrailer" "-checksumType" "crc32" \ - "-payloadType" "STREAMING-UNSIGNED-PAYLOAD-TRAILER" "-chunkSize" "8192" "-objectKey" "key" "-signedParams" "x-amz-trailer:x-amz-checksum-crc32" - assert_success -} - -@test "REST - PutObject - STREAMING-UNSIGNED-PAYLOAD-TRAILER - 200 header returns correct checksum type" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_and_file_v2 "$bucket_name" "$test_file" - assert_success - - checksum="$(sha256sum "$TEST_FILE_FOLDER/$test_file" | awk '{print $1}' | xxd -r -p | base64)" - - run send_openssl_go_command_check_header "200" "x-amz-checksum-sha256" "$checksum" \ - "-client" "openssl" "-commandType" "putObject" "-bucketName" "$bucket_name" "-payloadFile" "$TEST_FILE_FOLDER/$test_file" "-checksumType" "sha256" \ - "-payloadType" "STREAMING-UNSIGNED-PAYLOAD-TRAILER" "-chunkSize" "8192" "-objectKey" "key" "-signedParams" "x-amz-trailer:x-amz-checksum-sha256" - assert_success -} - -@test "REST - PutObject - STREAMING-UNSIGNED-PAYLOAD-TRAILER - success (sha1)" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_v2 "$bucket_name" - assert_success - - run create_test_file "$test_file" 10000 - assert_success - - checksum="$(sha1sum "$TEST_FILE_FOLDER/$test_file" | awk '{print $1}' | xxd -r -p | base64)" - - run send_openssl_go_command_check_header "200" "x-amz-checksum-sha1" "$checksum" \ - "-client" "openssl" "-commandType" "putObject" "-bucketName" "$bucket_name" "-payloadFile" "$TEST_FILE_FOLDER/$test_file" "-checksumType" "sha1" \ - "-payloadType" "STREAMING-UNSIGNED-PAYLOAD-TRAILER" "-chunkSize" "8192" "-objectKey" "key" "-signedParams" "x-amz-trailer:x-amz-checksum-sha1" - assert_success -} - -@test "REST - PutObject - STREAMING-UNSIGNED-PAYLOAD-TRAILER - success (crc32)" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_v2 "$bucket_name" - assert_success - - run create_test_file "$test_file" 10000 - assert_success - - checksum="$(gzip -c -1 "$TEST_FILE_FOLDER/$test_file" | tail -c8 | od -t x4 -N 4 -A n | awk '{print $1}' | xxd -r -p | base64)" - - run send_openssl_go_command_check_header "200" "x-amz-checksum-crc32" "$checksum" \ - "-client" "openssl" "-commandType" "putObject" "-bucketName" "$bucket_name" "-payloadFile" "$TEST_FILE_FOLDER/$test_file" "-checksumType" "crc32" \ - "-payloadType" "STREAMING-UNSIGNED-PAYLOAD-TRAILER" "-chunkSize" "8192" "-objectKey" "key" "-signedParams" "x-amz-trailer:x-amz-checksum-crc32" - assert_success -} - -@test "REST - PutObject - STREAMING-UNSIGNED-PAYLOAD-TRAILER - success (crc32c)" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_v2 "$bucket_name" - assert_success - - run create_test_file "$test_file" 10000 - assert_success - - if ! checksum=$(DATA_FILE="$TEST_FILE_FOLDER/$test_file" CHECKSUM_TYPE="crc32c" ./tests/rest_scripts/calculate_checksum.sh 2>&1); then - log 2 "error calculating checksum: $checksum" - return 1 - fi - - run send_openssl_go_command_check_header "200" "x-amz-checksum-crc32c" "$checksum" \ - "-client" "openssl" "-commandType" "putObject" "-bucketName" "$bucket_name" "-payloadFile" "$TEST_FILE_FOLDER/$test_file" "-checksumType" "crc32c" \ - "-payloadType" "STREAMING-UNSIGNED-PAYLOAD-TRAILER" "-chunkSize" "8192" "-objectKey" "key" "-checksumType" "crc32c" "-signedParams" "x-amz-trailer:x-amz-checksum-crc32c" - assert_success -} - -@test "REST - PutObject - STREAMING-UNSIGNED-PAYLOAD-TRAILER - success (crc64nvme)" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_v2 "$bucket_name" - assert_success - - run create_test_file "$test_file" 10000 - assert_success - - if ! checksum=$(DATA_FILE="$TEST_FILE_FOLDER/$test_file" CHECKSUM_TYPE="crc64nvme" ./tests/rest_scripts/calculate_checksum.sh 2>&1); then - log 2 "error calculating checksum: $checksum" - return 1 - fi - - run send_openssl_go_command_check_header "200" "x-amz-checksum-crc64nvme" "$checksum" \ - "-client" "openssl" "-commandType" "putObject" "-bucketName" "$bucket_name" "-payloadFile" "$TEST_FILE_FOLDER/$test_file" "-checksumType" "crc64nvme" \ - "-payloadType" "STREAMING-UNSIGNED-PAYLOAD-TRAILER" "-chunkSize" "8192" "-objectKey" "key" "-signedParams" "x-amz-trailer:x-amz-checksum-crc64nvme" - assert_success -} - -@test "REST - PutObject - STREAMING-AWS4-HMAC-SHA256-PAYLOAD - missing content length" { - if [ "$DIRECT" != "true" ]; then - skip "https://github.com/versity/versitygw/issues/1623" - fi - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_v2 "$bucket_name" - assert_success - - run send_openssl_go_command_chunked_no_content_length "$bucket_name" "key" - assert_success -} - -@test "REST - PutObject - STREAMING-UNSIGNED-PAYLOAD-TRAILER, x-amz-trailer of crc32, trailer key missing" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_v2 "$bucket_name" - assert_success - - run send_openssl_go_command_expect_error "400" "MalformedTrailerError" "The request contained trailing data that was not well-formed" \ - "-client" "openssl" "-commandType" "putObject" "-bucketName" "$bucket_name" "-objectKey" "key" "-payload" "abcdefg" "-checksumType" "crc32c" \ - "-omitPayloadTrailerKey" \ - "-payloadType" "STREAMING-UNSIGNED-PAYLOAD-TRAILER" "-chunkSize" "8192" "-objectKey" "key" "-signedParams" "x-amz-trailer:x-amz-checksum-crc32" - assert_success -} - -@test "REST - PutObject - STREAMING-UNSIGNED-PAYLOAD-TRAILER - default crc64nvme" { - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_and_file_v2 "$bucket_name" "$test_file" - assert_success - - run send_openssl_go_command "200" "-bucketName" "$bucket_name" "-objectKey" "$test_file" "-commandType" "putObject" \ - "-payloadFile" "$TEST_FILE_FOLDER/$test_file" "-omitPayloadTrailer" \ - "-debug" "-logFile" "tagging.log" "-checksumType" "crc64nvme" \ - "-payloadType" "STREAMING-UNSIGNED-PAYLOAD-TRAILER" "-chunkSize" "8192" - assert_success -} - @test "REST - PutObject - invalid x-amz-request-payer" { run get_bucket_name "$BUCKET_ONE_NAME" assert_success diff --git a/tests/test_rest_put_object_legal_hold.sh b/tests/test_rest_put_object_legal_hold.sh new file mode 100755 index 0000000..c36ccd7 --- /dev/null +++ b/tests/test_rest_put_object_legal_hold.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bats + +# Copyright 2026 Versity Software +# This file is licensed under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http:#www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +load ./bats-support/load +load ./bats-assert/load + +source ./tests/setup.sh +source ./tests/drivers/create_bucket/create_bucket_rest.sh + +@test "REST - PutObjectLegalHold - missing content-md5" { + run get_file_name + assert_success + test_file="$output" + + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_object_lock_enabled_v2 "$bucket_name" + assert_success + + run create_test_file "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + run check_legal_hold_without_content_md5 "$bucket_name" "$test_file" + assert_success +} + +@test "REST - PutObjectLegalHold w/o payload" { + run get_file_name + assert_success + test_file="$output" + + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_object_lock_enabled_v2 "$bucket_name" + assert_success + + run create_test_file "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + run check_legal_hold_without_payload "$bucket_name" "$test_file" + assert_success +} + +@test "REST - PutObjectLegalHold - success" { + run get_file_name + assert_success + test_file="$output" + + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_object_lock_enabled_v2 "$bucket_name" + assert_success + + run create_test_file "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + run rest_check_legal_hold "$bucket_name" "$test_file" + assert_success +} diff --git a/tests/test_rest_retention.sh b/tests/test_rest_retention.sh new file mode 100755 index 0000000..7668a2a --- /dev/null +++ b/tests/test_rest_retention.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bats + +# Copyright 2026 Versity Software +# This file is licensed under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http:#www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +load ./bats-support/load +load ./bats-assert/load + +source ./tests/setup.sh +source ./tests/commands/put_object_retention.sh +source ./tests/drivers/create_bucket/create_bucket_rest.sh +source ./tests/util/util_time.sh + +@test "test_rest_retention" { + run get_file_name + assert_success + test_file="$output" + + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_object_lock_enabled_v2 "$bucket_name" + assert_success + + run create_test_files "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + run get_time_seconds_in_future 5 "%z" + assert_success + five_seconds_later=${output} + + log 5 "later: $five_seconds_later" + run put_object_retention_rest "$bucket_name" "$test_file" "GOVERNANCE" "$five_seconds_later" + assert_success +} + +@test "REST - PutObjectRetention - w/o request body" { + run get_file_name + assert_success + test_file="$output" + + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_object_lock_enabled_v2 "$bucket_name" + assert_success + + run create_test_file "$test_file" + assert_success + + run put_object "rest" "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" + assert_success + + run retention_rest_without_request_body "$bucket_name" "$test_file" + assert_success +} +