From 9a21c5a1e0cf64fa7208e6b444bd88c9a31c2285 Mon Sep 17 00:00:00 2001 From: Luke McCrone Date: Thu, 16 Apr 2026 16:31:00 -0300 Subject: [PATCH] test: GetObject - add query tests, go/bats improved header/object reply handling --- .../complete_multipart_upload_rest.sh | 58 +++++---- tests/drivers/file.sh | 74 ++++++++++- tests/drivers/get_object/get_object_rest.sh | 65 +++++++++- tests/drivers/head_object/head_object_rest.sh | 10 +- tests/drivers/rest.sh | 122 +++++++++--------- tests/rest_scripts/command/curlRequest.go | 11 +- .../rest_scripts/command/s3RequestBuilder.go | 2 + tests/rest_scripts/generateCommand.go | 6 + tests/tags/tags.yaml | 26 +++- tests/test_rest_get_object.sh | 119 ++++++++++++++++- 10 files changed, 396 insertions(+), 97 deletions(-) diff --git a/tests/drivers/complete_multipart_upload/complete_multipart_upload_rest.sh b/tests/drivers/complete_multipart_upload/complete_multipart_upload_rest.sh index 386604ee..fcc2407d 100644 --- a/tests/drivers/complete_multipart_upload/complete_multipart_upload_rest.sh +++ b/tests/drivers/complete_multipart_upload/complete_multipart_upload_rest.sh @@ -210,32 +210,7 @@ perform_multipart_upload_rest() { if ! check_param_count_v2 "bucket, key, four parts" 6 $#; then return 1 fi - if ! upload_id=$(create_multipart_upload_rest "$1" "$2" "" "parse_upload_id" 2>&1); then - log 2 "error creating multipart upload: $upload_id" - return 1 - fi - if ! etag=$(upload_part_rest "$1" "$2" "$upload_id" 1 "$3" 2>&1); then - log 2 "error uploading part 1" - return 1 - fi - parts_payload="$etag1" - if ! etag=$(upload_part_rest "$1" "$2" "$upload_id" 2 "$4" 2>&1); then - log 2 "error uploading part 2: $etag" - return 1 - fi - parts_payload+="$etag2" - if ! etag=$(upload_part_rest "$1" "$2" "$upload_id" 3 "$5" 2>&1); then - log 2 "error uploading part 3: $etag" - return 1 - fi - parts_payload+="$etag3" - if ! etag=$(upload_part_rest "$1" "$2" "$upload_id" 4 "$6" 2>&1); then - log 2 "error uploading part 4: $etag" - return 1 - fi - parts_payload+="$etag4" - if ! complete_multipart_upload_rest "$1" "$2" "$upload_id" "$parts_payload"; then - log 2 "error completing multipart upload" + if ! perform_multipart_upload_rest_variable_parts "$@"; then return 1 fi return 0 @@ -264,3 +239,34 @@ upload_check_parts() { fi return 0 } + +perform_multipart_upload_rest_variable_parts() { + if ! check_param_count_gt "bucket, key, at least two part locations" 4 $#; then + return 1 + fi + local response + + if ! response=$(create_multipart_upload_rest "$1" "$2" "" "parse_upload_id" 2>&1); then + log 2 "error creating multipart upload: $response" + return 1 + fi + upload_id="$response" + + local parts_payload="" idx=1 + for part in "${@:3}"; do + if ! response=$(upload_part_rest "$1" "$2" "$upload_id" "$idx" "$part" 2>&1); then + log 2 "error uploading part $idx: $response" + return 1 + fi + etag="$response" + parts_payload+="$etag$idx" + idx=$((idx+1)) + done + log 5 "final payload: $parts_payload" + + if ! complete_multipart_upload_rest "$1" "$2" "$upload_id" "$parts_payload"; then + log 2 "error completing multipart upload" + return 1 + fi + return 0 +} diff --git a/tests/drivers/file.sh b/tests/drivers/file.sh index e645868c..a28c501d 100644 --- a/tests/drivers/file.sh +++ b/tests/drivers/file.sh @@ -223,6 +223,22 @@ get_file_name() { return 0 } +get_file_names() { + if ! check_param_count_v2 "file name count" 1 $#; then + return 1 + fi + local file_names=() + for ((i=0; i<$1; i++)); do + if ! response=$(get_file_name 2>&1); then + log 2 "error getting file name: $response" + return 1 + fi + file_names+=("$response") + done + echo "${file_names[*]}" + return 0 +} + get_file_name_with_prefix() { if ! check_param_count_v2 "prefix" 1 $#; then return 1 @@ -458,13 +474,69 @@ get_file_size() { fi fi echo "$file_size" + return 0 +} + +split_file_irregular() { + if ! check_param_count_v2 "file name, piece size" 2 $#; then + return 1 + fi + + local file="$1" + local piece_size="$2" + + local file_size="" + if ! file_size=$(get_file_size "$file"); then + log 2 "error getting file size for '$file'" + return 1 + fi + + if [[ -z "$piece_size" || ! "$piece_size" =~ ^[0-9]+$ ]]; then + log 2 "invalid piece size '$piece_size' (must be integer bytes)" + return 1 + fi + if [ "$piece_size" -le 0 ]; then + log 2 "invalid piece size '$piece_size' (must be > 0)" + return 1 + fi + + local offset=0 + local idx=0 + local part_file="" + local part_files=() + + while [ "$offset" -lt "$file_size" ]; do + local remaining=$((file_size - offset)) + local count="$piece_size" + if [ "$remaining" -lt "$piece_size" ]; then + count="$remaining" + fi + + part_file=$(printf '%s-%02d' "$file" "$idx") + if ! error=$(dd if="$file" of="$part_file" bs=1 count="$count" skip="$offset" 2>&1); then + log 2 "error creating file part: $error" + return 1 + fi + + part_files+=("$part_file") + offset=$((offset + count)) + idx=$((idx + 1)) + done + + if [ "${#part_files[@]}" -eq 0 ]; then + log 2 "no split files created" + return 1 + fi + + printf '%s\n' "${part_files[*]}" + return 0 } # split file into pieces to test multipart upload # param: file location # return 0 for success, 1 for error split_file() { - if ! check_param_count_v2 "file name, number of pieces" 2 $#; then + if ! check_param_count_ge_le "file name, number of pieces, piece size (optional)" 2 3 $#; then return 1 fi # -n l/K : Split into K pieces without breaking lines (or use 'K' for raw bytes) diff --git a/tests/drivers/get_object/get_object_rest.sh b/tests/drivers/get_object/get_object_rest.sh index 448e21a7..bdf110e7 100644 --- a/tests/drivers/get_object/get_object_rest.sh +++ b/tests/drivers/get_object/get_object_rest.sh @@ -30,4 +30,67 @@ get_object_success_or_access_denied() { fi fi return 0 -} \ No newline at end of file +} + +test_get_object_with_custom_content_header() { + if ! check_param_count_v2 "header key, value" 2 $#; then + return 1 + fi + if ! response=$(setup_bucket_and_file_v3 "$BUCKET_ONE_NAME" 2>&1); then + log 2 "error setting up bucket and file: $response" + return 1 + fi + read -r bucket_name file_name <<< "$response" + + if ! result=$(put_object_rest "$TEST_FILE_FOLDER/$file_name" "$bucket_name" "$file_name" 2>&1); then + log 2 "error putting object: $result" + return 1 + fi + if ! result=$(send_rest_go_command_callback "200" "check_for_header_key_and_value" "-bucketName" "$bucket_name" "-objectKey" "$file_name" "-query" "response-$1=$2" \ + "--" "$1" "$2" 2>&1); then + log 2 "error sending command and checking header: $result" + return 1 + fi + return 0 +} + +validate_partial_content_response() { + if ! check_param_count_v2 "header data, part number, downloaded part file, original part file, original file size, first part size" 6 $#; then + return 1 + fi + + starting_byte=$((($2-1)*$6)) + ending_byte=$(($2*$6-1)) + if [ "$5" -lt "$ending_byte" ]; then + ending_byte="$(($5-1))" + fi + content_range_string="bytes $starting_byte-$ending_byte/$5" + if ! result=$(check_for_header_key_and_value "$1" "Content-Range" "$content_range_string" 2>&1); then + log 2 "error checking for header key and value: $result" + return 1 + fi + + if ! result=$(compare_files "$3" "$4" 2>&1); then + log 2 "error comparing data files: $result" + return 1 + fi + return 0 +} + +send_get_object_with_part_number_validate_response() { + if ! check_param_count_v2 "bucket name, key, part number, part data file, original file size, first part size" 6 $#; then + return 1 + fi + if ! response=$(get_file_names 2 2>&1); then + log 2 "error getting file names: $response" + return 1 + fi + read -r header_file output_file <<< "$response" + log 5 "output file: $output_file" + if ! send_rest_go_command_callback "206" "validate_partial_content_response" "-bucketName" "$1" "-objectKey" "$2" "-query" "partNumber=$3" \ + "-headerFile" "$TEST_FILE_FOLDER/$header_file" "-outputFile" "$TEST_FILE_FOLDER/$output_file" "--" "$3" "$4" "$TEST_FILE_FOLDER/$output_file" "$5" "$6"; then + log 2 "error sending rest go command" + return 1 + fi + return 0 +} diff --git a/tests/drivers/head_object/head_object_rest.sh b/tests/drivers/head_object/head_object_rest.sh index dc6873ba..e027ab8c 100644 --- a/tests/drivers/head_object/head_object_rest.sh +++ b/tests/drivers/head_object/head_object_rest.sh @@ -215,11 +215,11 @@ check_metadata() { } check_header_key_and_value() { - if ! check_param_count_v2 "data file" 1 $#; then + if ! check_param_count_v2 "data file, header key, header value" 3 $#; then return 1 fi - if ! check_for_header_key_and_value "$1" "$header_key" "$header_value"; then - log 2 "error checking header key '$header_key' and value '$header_value'" + if ! check_for_header_key_and_value "$1" "$2" "$3"; then + log 2 "error checking header key '$2' and value '$3'" return 1 fi return 0 @@ -229,10 +229,8 @@ head_object_check_header_key_and_value() { if ! check_param_count_v2 "bucket, key, expected key, expected value" 4 $#; then return 1 fi - header_key="$3" - header_value="$4" if ! send_rest_go_command_callback "200" "check_header_key_and_value" "-bucketName" "$1" "-objectKey" "$2" \ - "-method" "HEAD"; then + "-method" "HEAD" "--" "$3" "$4"; then log 2 "error with head object command or callback" return 1 fi diff --git a/tests/drivers/rest.sh b/tests/drivers/rest.sh index 608427c2..7cbf67bc 100644 --- a/tests/drivers/rest.sh +++ b/tests/drivers/rest.sh @@ -35,16 +35,15 @@ check_rest_go_expected_error() { if ! check_param_count_v2 "response file, expected http code, expected error code, expected error" 4 $#; then return 1 fi - result="$(cat "$1")" local response - if ! response=$(bypass_continues "$result" 2>&1); then + if ! response=$(bypass_continues "$1" 2>&1); then log 2 "error bypassing continues: $response" return 1 fi status_code=$(echo -n "$response" | awk '{print $2}') if [ "$2" != "$status_code" ]; then - log 2 "expected curl response '$2', was '$status_code' (response: '$result')" + log 2 "expected curl response '$2', was '$status_code' (response: '$(cat "$1")')" return 1 fi if ! check_xml_error_contains "$1" "$3" "$4"; then @@ -101,17 +100,16 @@ check_rest_expected_header_error() { if ! check_param_count_v2 "file, expected response, expected error" 3 $#; then return 1 fi - result="$(cat "$1")" local response - if ! response=$(bypass_continues "$result" 2>&1); then + if ! response=$(bypass_continues "$1" 2>&1); then log 2 "error bypassing continues: $response" return 1 fi status_code=$(echo "$response" | awk '{print $2}') status_message=$(echo "$response" | cut -d' ' -f3- | tr -d '\r') if [ "$2" != "$status_code" ]; then - log 2 "expected curl response '$2', was '$status_code' ($(echo -n "$result"))" + log 2 "expected curl response '$2', was '$status_code' ($(cat "$1"))" return 1 fi if [ "$status_message" != "$3" ]; then @@ -192,7 +190,25 @@ rest_go_command_perform_send() { log 2 "error getting XML file name: $xml_file" return 1 fi - if ! curl_command=$(go run ./tests/rest_scripts/generateCommand.go -awsAccessKeyId "$AWS_ACCESS_KEY_ID" -awsSecretAccessKey "$AWS_SECRET_ACCESS_KEY" -awsRegion "$AWS_REGION" -url "$AWS_ENDPOINT_URL" "-writeXMLPayloadToFile" "$xml_file" "$@" 2>&1); then + local header_file="" output_file="" params=("$@") + for ((i=0; i < $#; i++)); do + if [ "${!i}" == "-headerFile" ]; then + next_idx=$((i+1)) + header_file=${!next_idx} + elif [ "${!i}" == "-outputFile" ]; then + next_idx=$((i+1)) + output_file=${!next_idx} + fi + done + if [ "$output_file" == "" ]; then + if ! response=$(get_file_name 2>&1); then + log 2 "error getting output file name: $response" + return 1 + fi + output_file="$TEST_FILE_FOLDER/$response" + params+=("-outputFile" "$output_file") + fi + if ! curl_command=$(go run ./tests/rest_scripts/generateCommand.go -awsAccessKeyId "$AWS_ACCESS_KEY_ID" -awsSecretAccessKey "$AWS_SECRET_ACCESS_KEY" -awsRegion "$AWS_REGION" -url "$AWS_ENDPOINT_URL" "-writeXMLPayloadToFile" "$TEST_FILE_FOLDER/$xml_file" "${params[@]}" 2>&1); then log 2 "error: $curl_command" return 1 fi @@ -200,11 +216,16 @@ rest_go_command_perform_send() { mapfile -t curl_command_array < <( printf '%s' "$curl_command" | python3 -c 'import shlex, sys; [print(arg) for arg in shlex.split(sys.stdin.read())]' ) - if ! result=$(send_command "${curl_command_array[@]}" 2>&1); then - log 2 "error sending command: $result" + if ! response=$(send_command "${curl_command_array[@]}" 2>&1); then + log 2 "error sending command: $response" return 1 fi - echo "$result" + if [ "$header_file" != "" ]; then + response_file="$header_file" + else + response_file="$output_file" + fi + echo "$response_file" return 0 } @@ -239,16 +260,12 @@ send_rest_go_command_expect_error_callback() { mapfile -t callback_params < <(get_callback_params "${all_params[@]}") fi - if ! result=$(rest_go_command_perform_send "${go_param_array[@]}" 2>&1); then - log 2 "error sending rest go command: $result" + if ! response=$(rest_go_command_perform_send "${go_param_array[@]}" 2>&1); then + log 2 "error sending rest go command: $response" return 1 fi - if ! file_name=$(get_file_name 2>&1); then - log 2 "error getting file name: $file_name" - return 1 - fi - echo -n "$result" > "$TEST_FILE_FOLDER/$file_name" - if ! check_rest_go_expected_error "$TEST_FILE_FOLDER/$file_name" "$1" "$2" "$3"; then + response_file="$response" + if ! check_rest_go_expected_error "$response_file" "$1" "$2" "$3"; then log 2 "error checking expected header error" return 1 fi @@ -260,13 +277,13 @@ send_rest_go_command_expect_error_callback() { } bypass_continues() { - if ! check_param_count_v2 "raw response" 1 $#; then + if ! check_param_count_v2 "raw response file" 1 $#; then return 1 fi local status_line_idx=1 status_code="" continue_count=0 while ((continue_count<10)); do - status_line=$(sed -n "${status_line_idx}p" <<< "$1") + status_line=$(sed -n "${status_line_idx}p" < "$1") status_code=$(echo "$status_line" | awk '{print $2}') if [ "$status_code" != "100" ]; then break @@ -337,49 +354,34 @@ send_rest_go_command_callback() { mapfile -t callback_params < <(get_callback_params "${all_params[@]}") fi - if ! result=$(rest_go_command_perform_send "${go_param_array[@]}" 2>&1); then - log 2 "error sending rest go command: $result" + if ! response=$(rest_go_command_perform_send "${go_param_array[@]}" 2>&1); then + log 2 "error sending rest go command: $response" return 1 fi - if ! response=$(bypass_continues "$result" 2>&1); then + response_file="$response" + + if ! response=$(bypass_continues "$response_file" 2>&1); then log 2 "error bypassing continues: $response" return 1 fi status_code=$(echo -n "$response" | awk '{print $2}') if [ "$1" != "$status_code" ]; then - log 2 "expected curl response '$1', was '$status_code' (response: '$result')" + log 2 "expected curl response '$1', was '$status_code' (response: '$(cat "$response_file")')" return 1 fi if [ "$2" == "" ]; then - echo "$result" + echo "$response_file" return 0 fi - if ! callback_result=$(call_callback "$result" "$2" 2>&1); then - log 2 "callback error: $callback_result" + if ! response=$("$2" "$response_file" "${callback_params[@]}" 2>&1); then + log 2 "callback error: $response" return 1 fi + callback_result="$response" echo "$callback_result" return 0 } -call_callback() { - if ! check_param_count_v2 "response, callback" 2 $#; then - return 1 - fi - if ! output_file_name=$(get_file_name 2>&1); then - log 2 "error generating output file name: $output_file_name" - return 1 - fi - echo -n "$1" > "$TEST_FILE_FOLDER/$output_file_name" - local callback_output - if ! callback_output=$("$2" "$TEST_FILE_FOLDER/$output_file_name" "${callback_params[@]}" 2>&1); then - log 2 "error in callback: $callback_output" - return 1 - fi - echo "$callback_output" - return 0 -} - # return 0 for key match, 1 for no key match, 2 for value mismatch check_key_and_value_pair_for_match() { if ! check_param_count_v2 "read key, read value, expected key, expected value" 4 $#; then @@ -401,6 +403,7 @@ check_for_header_key_and_value() { fi while IFS=$': \r' read -r key value; do local check_result=0 + value="${value%$'\r'}" check_key_and_value_pair_for_match "$key" "$value" "$2" "$3" || check_result=$? if [ "$check_result" -eq 2 ]; then return 1 @@ -464,23 +467,27 @@ send_rest_go_command_expect_error_with_specific_arg_name_value() { } check_specific_argument_names_and_values() { - if ! check_param_count_v2 "data file" 1 $#; then + if ! check_param_count_gt "data file, arg names and values" 1 $#; then return 1 fi - for ((idx=0; idx<${#arg_names_and_values[@]}; idx+=2)); do - if ! check_error_parameter "$1" "${arg_names_and_values[$idx]}" "${arg_names_and_values[(($idx+1))]}"; then - log 2 "error checking '${arg_names_and_values[$idx]}' parameter" + local data_file="$1" + shift + + while [ "$1" != "" ]; do + if ! check_error_parameter "$data_file" "$1" "$2"; then + log 2 "error checking '$1' parameter with value '$2'" return 1 fi + shift 2 done + return 0 } send_rest_go_command_expect_error_with_specific_arg_names_values() { if ! check_param_count_gt "response code, error code, message, arg count, pairs of arg names and values, params" 6 $#; then return 1 fi - arg_names_and_values=("${@:5:$4}") - if ! send_rest_go_command_expect_error_callback "$1" "$2" "$3" "check_specific_argument_names_and_values" "${@:((5+$4))}"; then + if ! send_rest_go_command_expect_error_callback "$1" "$2" "$3" "check_specific_argument_names_and_values" "${@:((5+$4))}" "--" "${@:5:$4}"; then log 2 "error checking error response values" return 1 fi @@ -488,10 +495,10 @@ send_rest_go_command_expect_error_with_specific_arg_names_values() { } check_header_key_and_value() { - if ! check_param_count_v2 "data file" 1 $#; then + if ! check_param_count_v2 "data file, header key, header value" 3 $#; then return 1 fi - if ! check_for_header_key_and_value "$1" "$header_key" "$header_value"; then + if ! check_for_header_key_and_value "$1" "$2" "$3"; then log 2 "error checking header key and value" return 1 fi @@ -502,9 +509,7 @@ send_rest_go_command_check_header_key_and_value() { if ! check_param_count_gt "response code, header key, header values, params" 3 $#; then return 1 fi - header_key="$2" - header_value="$3" - if ! send_rest_go_command_callback "$1" "check_header_key_and_value" "${@:4}"; then + if ! send_rest_go_command_callback "$1" "check_header_key_and_value" "${@:4}" "--" "$2" "$3"; then log 2 "error sending command and checking header key and value" return 1 fi @@ -515,11 +520,10 @@ send_rest_go_command_write_response_to_file() { if ! check_param_count_gt "file, params" 2 $#; then return 1 fi - if ! rest_go_command_perform_send "${@:2}"; then - log 2 "error sending rest go command" + if ! response=$(rest_go_command_perform_send "${@:2}" "-outputFile" "$1" 2>&1); then + log 2 "error sending rest go command: $response" return 1 fi - echo -n "$result" > "$1" return 0 } diff --git a/tests/rest_scripts/command/curlRequest.go b/tests/rest_scripts/command/curlRequest.go index 99b88371..b42edcf8 100644 --- a/tests/rest_scripts/command/curlRequest.go +++ b/tests/rest_scripts/command/curlRequest.go @@ -28,7 +28,10 @@ func (c *CurlCommand) DeriveHeaderValues() error { } func (c *CurlCommand) Render() error { - curlOpts := "-iks" + curlOpts := "-ks" + if c.Config.HeaderFile == "" { + curlOpts += "i" + } if c.Config.Method == "HEAD" { curlOpts += "I" } @@ -66,6 +69,12 @@ func (c *CurlCommand) Render() error { return err } } + if c.Config.HeaderFile != "" { + curlCommand = append(curlCommand, "-D", fmt.Sprintf("\"%s\"", c.Config.HeaderFile)) + } + if c.Config.OutputFile != "" { + curlCommand = append(curlCommand, "-o", fmt.Sprintf("\"%s\"", c.Config.OutputFile)) + } c.curlCommandString = strings.Join(curlCommand, " ") logger.PrintDebug("curl command: %s", c.curlCommandString) return nil diff --git a/tests/rest_scripts/command/s3RequestBuilder.go b/tests/rest_scripts/command/s3RequestBuilder.go index 7954f9a3..bb8ff10d 100644 --- a/tests/rest_scripts/command/s3RequestBuilder.go +++ b/tests/rest_scripts/command/s3RequestBuilder.go @@ -78,6 +78,8 @@ type S3RequestConfigData struct { OmitDate bool CustomDate string WriteXMLPayloadToFile string + OutputFile string + HeaderFile string } type S3RequestBuilder struct { diff --git a/tests/rest_scripts/generateCommand.go b/tests/rest_scripts/generateCommand.go index 9cce417d..339107d5 100644 --- a/tests/rest_scripts/generateCommand.go +++ b/tests/rest_scripts/generateCommand.go @@ -50,6 +50,8 @@ var commandType *string var checksumType *string var customSHA256Hash *string var customDate *string +var outputFile *string +var headerFile *string type arrayFlags []string @@ -151,6 +153,8 @@ func main() { OmitDate: *omitDate, CustomDate: *customDate, WriteXMLPayloadToFile: *writeXMLPayloadToFile, + OutputFile: *outputFile, + HeaderFile: *headerFile, }, } @@ -267,6 +271,8 @@ func checkFlags() error { locationConstraint = flag.String("locationConstraint", "", "Location constraint for bucket creation") flag.Var(&corsRules, "corsRule", "CORS rule for PutBucketCORS command (can add multiple)") writeXMLPayloadToFile = flag.String("writeXMLPayloadToFile", "", "for curl commands, file to write XML payloads to") + outputFile = flag.String("outputFile", "", "for curl commands, location to save retrieved file data (to stdout if empty)") + headerFile = flag.String("headerFile", "", "for curl commands, location to save header file data (to stdout or outputFile if empty)") // Parse the flags flag.Parse() diff --git a/tests/tags/tags.yaml b/tests/tags/tags.yaml index be32871e..4eaad5f2 100644 --- a/tests/tags/tags.yaml +++ b/tests/tags/tags.yaml @@ -4,10 +4,14 @@ tags: feature: invalid-method: desc: "Tests for invalid methods" + invalid-header: + desc: "Tests for invalid headers" malformed-message: desc: "Tests for severely malformed messages" minimal-request: desc: "Tests that do not use any optional query or header values" + multipart: + desc: "Multipart upload" required-headers: desc: "Required headers such as 'Authorization' and 'x-amz-date'" user: @@ -18,6 +22,8 @@ tags: openssl: desc: "REST OpenSSL commands" command: + GetObject: + desc: "GetObject command" ListBuckets: desc: "ListBuckets command" header: @@ -25,8 +31,10 @@ tags: desc: "Authorization header" host: desc: "host header" + range: + desc: "ranged download tests" x-amz-content-sha256: - desc: "x-amz-content-sha256 header" + desc: "x-amz-content-sha256 header (payload hash and/or type)" x-amz-date: desc: "x-amz-date header" query: @@ -36,5 +44,19 @@ tags: desc: "ListBuckets/ListObjects continuation token query" max-buckets: desc: "Maximum amount of buckets returned by ListBuckets command" + partNumber: + desc: "partNumber query for multiparts and gets" prefix: - desc: "bucket or object prefix query" \ No newline at end of file + desc: "bucket or object prefix query" + response-cache-control: + desc: "override cache-control header response" + response-content-disposition: + desc: "override content-disposition header response" + response-content-encoding: + desc: "override content-encoding header response" + response-content-language: + desc: "override content-language header response" + response-content-type: + desc: "override content-type header response" + response-expires: + desc: "override expires header response" diff --git a/tests/test_rest_get_object.sh b/tests/test_rest_get_object.sh index bef7cbc5..c97013d1 100755 --- a/tests/test_rest_get_object.sh +++ b/tests/test_rest_get_object.sh @@ -18,9 +18,11 @@ load ./bats-support/load load ./bats-assert/load source ./tests/commands/get_object.sh +source ./tests/drivers/complete_multipart_upload/complete_multipart_upload_rest.sh source ./tests/drivers/create_bucket/create_bucket_rest.sh source ./tests/setup.sh +# tags: curl, GetObject, HeadObject, range @test "REST - range download and compare" { run get_file_name assert_success @@ -41,6 +43,7 @@ source ./tests/setup.sh assert_success } +# tags: rest, PutObject, GetObject @test "REST - put, get object, encoded name" { run get_bucket_name "$BUCKET_ONE_NAME" assert_success @@ -66,7 +69,8 @@ source ./tests/setup.sh assert_success } -@test "REST - GetObject w/STREAMING-AWS4-HMAC-SHA256-PAYLOAD type" { +# tags: rest, GetObject,x-amz-content-sha256 +@test "REST - GetObject w/invalid payload type" { run get_file_name assert_success test_file="$output" @@ -81,3 +85,116 @@ source ./tests/setup.sh run get_object_rest_with_invalid_streaming_type "$bucket_name" "$test_file" assert_success } + +# tags: curl,GetObject,partNumber +@test "REST - GetObject - part number 2 w/o multipart upload" { + run setup_bucket_and_file_v3 "$BUCKET_ONE_NAME" + assert_success + read -r bucket_name file_name <<< "$output" + + run put_object_rest "$TEST_FILE_FOLDER/$file_name" "$bucket_name" "$file_name" + assert_success + + run send_rest_go_command_expect_error "416" "InvalidPartNumber" "not satisfiable" "-bucketName" "$bucket_name" "-objectKey" "$file_name" "-query" "partNumber=2" + assert_success +} + +# tags: curl,GetObject,partNumber +@test "REST - GetObject - part number 1 returns 206, Content-Range header" { + if [ "$DIRECT" != "true" ]; then + skip "https://github.com/versity/versitygw/issues/2074" + fi + run setup_bucket_and_file_v3 "$BUCKET_ONE_NAME" + assert_success + read -r bucket_name file_name <<< "$output" + + run put_object_rest "$TEST_FILE_FOLDER/$file_name" "$bucket_name" "$file_name" + assert_success + + run send_rest_go_command_callback "206" "check_for_header_key_and_value" "-bucketName" "$bucket_name" "-objectKey" "$file_name" "-query" "partNumber=1" \ + "--" "Content-Range" "bytes 0-9/10" + assert_success +} + +# tags: curl,GetObject,invalid-header +@test "REST - GetObject - response query - invalid response type" { + if [ "$DIRECT" != "true" ]; then + skip "https://github.com/versity/versitygw/issues/2075" + fi + run setup_bucket_and_file_v3 "$BUCKET_ONE_NAME" + assert_success + read -r bucket_name file_name <<< "$output" + + run put_object_rest "$TEST_FILE_FOLDER/$file_name" "$bucket_name" "$file_name" + assert_success + + local bad_response_query="response-gibberish" + run send_rest_go_command_expect_error "400" "InvalidArgument" "$bad_response_query is not in the set of overridable response headers" \ + "-bucketName" "$bucket_name" "-objectKey" "$file_name" "-query" "$bad_response_query=dummy" + assert_success +} + +# tags: curl,GetObject,response-cache-control +@test "REST - GetObject - response-cache-control" { + run test_get_object_with_custom_content_header "cache-control" "dummy" + assert_success +} + +# tags: curl,GetObject,response-content-disposition +@test "REST - GetObject - response-content-disposition" { + run test_get_object_with_custom_content_header "content-disposition" "dummy" + assert_success +} + +# tags: curl,GetObject,response-content-encoding +@test "REST - GetObject - response-content-encoding" { + run test_get_object_with_custom_content_header "content-encoding" "dummy" + assert_success +} + +# tags: curl,GetObject,response-content-language +@test "REST - GetObject - response-content-language" { + run test_get_object_with_custom_content_header "content-language" "dummy" + assert_success +} + +# tags: curl,GetObject,response-content-type +@test "REST - GetObject - response-content-type" { + run test_get_object_with_custom_content_header "content-type" "dummy" + assert_success +} + +# tags: curl,GetObject,response-expires +@test "REST - GetObject - response-expires" { + run test_get_object_with_custom_content_header "expires" "dummy+ one" + assert_success +} + +# tags: curl,GetObject,multipart,partNumber +@test "REST - GetObject - partNumber w/multipart" { + run setup_bucket_and_large_file_v3 "$BUCKET_ONE_NAME" 8 + assert_success + read -r bucket_name test_file <<< "$output" + + run split_file_irregular "$TEST_FILE_FOLDER/$test_file" 5242880 + assert_success + read -r part_one part_two <<< "$output" + log 5 "part one: $part_one, part two: $part_two" + + run perform_multipart_upload_rest_variable_parts "$bucket_name" "$test_file" "$part_one" "$part_two" + assert_success + + run get_file_size "$part_one" + assert_success + part_size="$output" + + run get_file_size "$TEST_FILE_FOLDER/$test_file" + assert_success + file_size="$output" + + run send_get_object_with_part_number_validate_response "$bucket_name" "$test_file" "1" "$part_one" "$file_size" "$part_size" + assert_success + + run send_get_object_with_part_number_validate_response "$bucket_name" "$test_file" "2" "$part_two" "$file_size" "$part_size" + assert_success +}