diff --git a/.github/workflows/system.yml b/.github/workflows/system.yml index 91e5d49..59ab268 100644 --- a/.github/workflows/system.yml +++ b/.github/workflows/system.yml @@ -57,6 +57,18 @@ jobs: RECREATE_BUCKETS: "false" DELETE_BUCKETS_AFTER_TEST: "false" BACKEND: "posix" + - set: "REST, posix, static, rest-put-bucket-tagging, folder IAM" + IAM_TYPE: folder + RUN_SET: "rest-put-bucket-tagging" + RECREATE_BUCKETS: "false" + DELETE_BUCKETS_AFTER_TEST: "false" + BACKEND: "posix" + - set: "REST, posix, non-static, rest-put-bucket-tagging, folder IAM" + IAM_TYPE: folder + RUN_SET: "rest-put-bucket-tagging" + RECREATE_BUCKETS: "true" + DELETE_BUCKETS_AFTER_TEST: "true" + BACKEND: "posix" - set: "s3, posix, non-file count, non-static, folder IAM" IAM_TYPE: folder RUN_SET: "s3-non-file-count" diff --git a/tests/drivers/delete_bucket_tagging/delete_bucket_tagging_rest.sh b/tests/drivers/delete_bucket_tagging/delete_bucket_tagging_rest.sh new file mode 100644 index 0000000..c235a99 --- /dev/null +++ b/tests/drivers/delete_bucket_tagging/delete_bucket_tagging_rest.sh @@ -0,0 +1,31 @@ +#!/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. + +delete_tags_and_verify_deletion() { + if ! check_param_count_v2 "bucket name" 1 $#; then + return 1 + fi + if ! send_rest_go_command "204" \ + "-method" "DELETE" "-bucketName" "$1" "-query" "tagging="; then + log 2 "error sending tag deletion command" + return 1 + fi + if ! verify_no_bucket_tags_rest "$1"; then + log 2 "error verifying no bucket tags" + return 1 + fi + return 0 +} diff --git a/tests/drivers/get_bucket_tagging/get_bucket_tagging.sh b/tests/drivers/get_bucket_tagging/get_bucket_tagging.sh new file mode 100644 index 0000000..388a2f0 --- /dev/null +++ b/tests/drivers/get_bucket_tagging/get_bucket_tagging.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +# 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. + +check_bucket_tags_empty() { + if ! check_param_count_v2 "command type, bucket" 2 $#; then + return 2 + fi + if ! get_bucket_tagging "$1" "$2"; then + log 2 "failed to get tags" + return 2 + fi + check_tags_empty "$1" || local check_result=$? + # shellcheck disable=SC2086 + return $check_result +} + +verify_no_bucket_tags() { + if ! check_param_count_v2 "command type, bucket" 2 $#; then + return 1 + fi + if ! get_bucket_tagging "$1" "$2"; then + log 2 "error retrieving bucket tagging" + return 1 + fi + # shellcheck disable=SC2154 + if [[ "$tags" != "" ]]; then + log 2 "tags should be empty, but are: $tags" + return 1 + fi + return 0 +} diff --git a/tests/drivers/get_bucket_tagging/get_bucket_tagging_rest.sh b/tests/drivers/get_bucket_tagging/get_bucket_tagging_rest.sh new file mode 100644 index 0000000..6d5c897 --- /dev/null +++ b/tests/drivers/get_bucket_tagging/get_bucket_tagging_rest.sh @@ -0,0 +1,119 @@ +#!/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. + +# params: username, password, bucket, expected key, expected value +# return 0 for success, 1 for failure +get_and_check_bucket_tags_with_user() { + log 6 "get_and_check_bucket_tags" + if ! check_param_count_v2 "username, password, bucket, expected key, expected value" 5 $#; then + return 1 + fi + if ! get_bucket_tagging_with_user "$1" "$2" "$3"; then + log 2 "error retrieving bucket tagging" + return 1 + fi + # shellcheck disable=SC2154 + log 5 "TAGS: $tags" + if ! tag=$(echo "$tags" | jq -r ".TagSet[0]" 2>&1); then + log 2 "error getting tag: $tag" + return 1 + fi + if ! key=$(echo "$tag" | jq -r ".Key" 2>&1); then + log 2 "error getting key: $key" + return 1 + fi + if [ "$key" != "$4" ]; then + log 2 "key mismatch ($key, $4)" + return 1 + fi + if ! value=$(echo "$tag" | jq -r ".Value" 2>&1); then + log 2 "error getting value: $value" + return 1 + fi + if [ "$value" != "$5" ]; then + log 2 "value mismatch ($value, $5)" + return 1 + fi + return 0 +} + +# params: bucket, expected tag key, expected tag value +# fail on error +get_and_check_bucket_tags() { + if ! check_param_count_v2 "bucket, expected key, expected value" 3 $#; then + return 1 + fi + if ! get_and_check_bucket_tags_with_user "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "$1" "$2" "$3"; then + log 2 "error getting and checking bucket tags with user" + return 1 + fi + return 0 +} + +add_verify_bucket_tags_rest() { + if ! check_param_count_v2 "bucket, expected key, expected value" 3 $#; then + return 1 + fi + if ! result=$(COMMAND_LOG="$COMMAND_LOG" BUCKET_NAME="$1" TAG_KEY="$2" TAG_VALUE="$3" OUTPUT_FILE="$TEST_FILE_FOLDER/result.txt" ./tests/rest_scripts/put_bucket_tagging.sh); then + log 2 "error putting bucket tags: $result" + return 1 + fi + if [ "$result" != "204" ]; then + log 2 "expected response code of '204', was '$result' (error: $(cat "$TEST_FILE_FOLDER/result.txt"))" + return 1 + fi + if ! result=$(COMMAND_LOG="$COMMAND_LOG" BUCKET_NAME="$1" OUTPUT_FILE="$TEST_FILE_FOLDER/bucket_tagging.txt" ./tests/rest_scripts/get_bucket_tagging.sh); then + log 2 "error listing bucket tags: $result" + return 1 + fi + if [ "$result" != "200" ]; then + log 2 "expected response code of '200', was '$result' (error: $(cat "$TEST_FILE_FOLDER/bucket_tagging.txt"))" + return 1 + fi + log 5 "tags: $(cat "$TEST_FILE_FOLDER/bucket_tagging.txt")" + if ! key=$(xmllint --xpath '//*[local-name()="Key"]/text()' "$TEST_FILE_FOLDER/bucket_tagging.txt" 2>&1); then + log 2 "error retrieving key: $key" + return 1 + fi + if [ "$key" != "$2" ]; then + log 2 "key mismatch (expected '$2', actual '$key')" + return 1 + fi + if ! value=$(xmllint --xpath '//*[local-name()="Value"]/text()' "$TEST_FILE_FOLDER/bucket_tagging.txt" 2>&1); then + log 2 "error retrieving value: $value" + return 1 + fi + if [ "$value" != "$3" ]; then + log 2 "value mismatch (expected '$3', actual '$value')" + return 1 + fi + return 0 +} + +verify_no_bucket_tags_rest() { + if ! check_param_count_v2 "bucket" 1 $#; then + return 1 + fi + if ! result=$(COMMAND_LOG="$COMMAND_LOG" BUCKET_NAME="$1" OUTPUT_FILE="$TEST_FILE_FOLDER/bucket_tagging.txt" ./tests/rest_scripts/get_bucket_tagging.sh); then + log 2 "error listing bucket tags: $result" + return 1 + fi + if [ "$result" != "404" ]; then + log 2 "expected response code of '404', was '$result' (error: $(cat "$TEST_FILE_FOLDER/bucket_tagging.txt"))" + return 1 + fi + return 0 +} diff --git a/tests/drivers/get_object_tagging/get_object_tagging.sh b/tests/drivers/get_object_tagging/get_object_tagging.sh new file mode 100644 index 0000000..df53e3c --- /dev/null +++ b/tests/drivers/get_object_tagging/get_object_tagging.sh @@ -0,0 +1,126 @@ +#!/usr/bin/env bash + +# 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. + +source ./tests/commands/get_object_tagging.sh +source ./tests/drivers/get_object_tagging/get_object_tagging_rest.sh +source ./tests/drivers/get_object_tagging/get_object_tagging_s3api.sh +source ./tests/drivers/tags.sh + +get_and_verify_object_tags() { + if ! check_param_count_v2 "command type, bucket, key, tag key, tag value" 5 $#; then + return 1 + fi + get_object_tagging "$1" "$2" "$3" || get_result=$? + if [[ $get_result -ne 0 ]]; then + log 2 "failed to get tags" + return 1 + fi + if [[ $1 == 'aws' ]]; then + tag_set_key=$(echo "$tags" | jq '.TagSet[0].Key') + tag_set_value=$(echo "$tags" | jq '.TagSet[0].Value') + if [[ $tag_set_key != '"'$4'"' ]]; then + log 2 "Key mismatch ($tag_set_key, \"$4\")" + return 1 + fi + if [[ $tag_set_value != '"'$5'"' ]]; then + log 2 "Value mismatch ($tag_set_value, \"$5\")" + return 1 + fi + else + read -r tag_set_key tag_set_value <<< "$(echo "$tags" | awk 'NR==2 {print $1, $3}')" + [[ $tag_set_key == "$4" ]] || fail "Key mismatch" + [[ $tag_set_value == "$5" ]] || fail "Value mismatch" + fi + return 0 +} + +verify_no_object_tags() { + if ! check_param_count_v2 "command type, bucket, key" 3 $#; then + return 1 + fi + result=0 + get_object_tagging "$1" "$2" "$3" || result=$? + if [ $result == 1 ]; then + if [ "$1" == 'rest' ]; then + return 0 + fi + log 2 "error getting object tagging" + return 1 + fi + if [[ "$1" == 'aws' ]] || [ "$1" == 's3api' ]; then + if ! tag_set=$(echo "$tags" | jq '.TagSet' 2>&1); then + log 2 "error getting tag set: $tag_set" + return 1 + fi + if [[ $tag_set != "[]" ]] && [[ $tag_set != "" ]]; then + log 2 "tags not empty ($tag_set)" + return 1 + fi + elif [[ $tags != *"No tags found"* ]] && [[ $tags != "" ]]; then + log 2 "tags not empty (tags: $tags)" + return 1 + fi + return 0 +} + +check_verify_object_tags() { + if ! check_param_count_v2 "command type, bucket, key, tag key, tag value" 5 $#; then + return 1 + fi + if ! get_object_tagging "$1" "$2" "$3"; then + log 2 "error getting object tags" + return 1 + fi + if [[ $1 == 'aws' ]] || [[ $1 == 's3api' ]]; then + if ! parse_object_tags_s3api; then + log 2 "error parsing object tags" + return 1 + fi + elif [ "$1" == 'rest' ]; then + if ! parse_object_tags_rest; then + log 2 "error parsing object tags" + return 1 + fi + elif [[ $1 == 'mc' ]]; then + read -r tag_set_key tag_set_value <<< "$(echo "$tags" | awk 'NR==2 {print $1, $3}')" + else + log 2 "unrecognized client for check_verify_object_tags: $1" + return 1 + fi + if [[ $tag_set_key != "$4" ]]; then + log 2 "Key mismatch ($tag_set_key, $4)" + return 1 + fi + if [[ $tag_set_value != "$5" ]]; then + log 2 "Value mismatch ($tag_set_value, $5)" + return 1 + fi + return 0 +} + +check_object_tags_empty() { + if ! check_param_count_v2 "command type, bucket, key" 3 $#; then + return 1 + fi + if ! get_object_tagging "$1" "$2" "$3"; then + log 2 "failed to get tags" + return 2 + fi + check_tags_empty "$1" || local check_result=$? + # shellcheck disable=SC2086 + return $check_result +} + diff --git a/tests/drivers/get_object_tagging/get_object_tagging_rest.sh b/tests/drivers/get_object_tagging/get_object_tagging_rest.sh new file mode 100644 index 0000000..d5b1ee1 --- /dev/null +++ b/tests/drivers/get_object_tagging/get_object_tagging_rest.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +# 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. + +parse_object_tags_rest() { + if ! tag_set_key=$(xmllint --xpath '//*[local-name()="Key"]/text()' "$TEST_FILE_FOLDER/object_tags.txt" 2>&1); then + log 2 "error getting key: $tag_set_key" + return 1 + fi + if ! tag_set_value=$(xmllint --xpath '//*[local-name()="Value"]/text()' "$TEST_FILE_FOLDER/object_tags.txt" 2>&1); then + log 2 "error getting value: $value" + return 1 + fi + return 0 +} diff --git a/tests/drivers/get_object_tagging/get_object_tagging_s3api.sh b/tests/drivers/get_object_tagging/get_object_tagging_s3api.sh new file mode 100644 index 0000000..c1e41eb --- /dev/null +++ b/tests/drivers/get_object_tagging/get_object_tagging_s3api.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +# 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. + +parse_object_tags_s3api() { + if ! tag_set_key=$(echo "$tags" | jq -r '.TagSet[0].Key' 2>&1); then + log 2 "error retrieving tag key: $tag_set_key" + return 1 + fi + if ! tag_set_value=$(echo "$tags" | jq -r '.TagSet[0].Value' 2>&1); then + log 2 "error retrieving tag value: $tag_set_value" + return 1 + fi + return 0 +} diff --git a/tests/drivers/put_bucket_tagging/put_bucket_tagging_rest.sh b/tests/drivers/put_bucket_tagging/put_bucket_tagging_rest.sh index c69191d..63d1cb4 100644 --- a/tests/drivers/put_bucket_tagging/put_bucket_tagging_rest.sh +++ b/tests/drivers/put_bucket_tagging/put_bucket_tagging_rest.sh @@ -41,4 +41,30 @@ check_invalid_content_md5() { return 1 fi return 0 +} + +put_bucket_tagging_check_invalid_key_fields() { + if ! check_param_count_v2 "bucket, invalid key" 2 $#; then + return 1 + fi + if ! setup_bucket_v2 "$1"; then + log 2 "error setting up bucket '$1'" + return 1 + fi + invalid_tag_key="$2" + run send_rest_go_command_expect_error_callback "400" "InvalidTag" "The TagKey you have provided is invalid" \ + "check_invalid_key_field" "-commandType" "putBucketTagging" "-bucketName" "$1" "-tagKey" "$invalid_tag_key" \ + "-tagValue" "value" "-contentMD5" + assert_success +} + +check_invalid_key_field() { + if ! check_param_count_v2 "data file" 1 $#; then + return 1 + fi + if ! check_error_parameter "$1" "TagKey" "$invalid_tag_key"; then + log 2 "error checking 'TagKey' value" + return 1 + fi + return 0 } \ No newline at end of file diff --git a/tests/drivers/tags.sh b/tests/drivers/tags.sh new file mode 100644 index 0000000..1a422d5 --- /dev/null +++ b/tests/drivers/tags.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +# 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. + +check_tags_empty() { + if ! check_param_count_v2 "command type" 1 $#; then + return 1 + fi + if [[ $1 == 'aws' ]]; then + # shellcheck disable=SC2154 + if [[ $tags == "" ]]; then + return 0 + fi + tag_set=$(echo "$tags" | jq '.TagSet') + if [[ $tag_set != "[]" ]]; then + log 2 "error: tags not empty: $tags" + return 1 + fi + else + if [[ $tags != "" ]] && [[ $tags != *"No tags found"* ]]; then + log 2 "Error: tags not empty: $tags" + return 1 + fi + fi + return 0 +} diff --git a/tests/drivers/xml.sh b/tests/drivers/xml.sh index 07b32e3..cc5c38a 100644 --- a/tests/drivers/xml.sh +++ b/tests/drivers/xml.sh @@ -61,17 +61,25 @@ get_element_text() { return 1 fi - if ! build_xpath_string "${@:2}"; then + if ! build_xpath_string_for_element "${@:2}"; then log 2 "error building XPath search string" return 1 fi log 5 "data: $(cat "$1")" - log 5 "xml data: $(grep '<[^/][^ >]*>' "$1")" - if ! xml_val=$(grep '<[^/][^ >]*>' "$1" | xmllint --xpath "$xpath" - 2>&1); then - log 2 "error getting XML value matching $xpath: $xml_val (file data: $(cat "$1"))" + log 5 "xpath: $xpath" + xml_data="$(grep '<[^/][^ >]*>' "$1")" + log 5 "XML data: $xml_data" + log 5 "result: $(echo -n "$xml_data" | xmllint --xpath "boolean($xpath)" - 2>&1)" + result=$(echo -n "$xml_data" | xmllint --xpath "boolean($xpath)" - 2>&1) + if [ "$result" == "false" ]; then + log 2 "element matching '$xpath' doesn't exist" return 1 fi + if ! xml_val=$(echo -n "$xml_data" | xmllint --xpath "${xpath}/text()" - 2>/dev/null); then + echo "" + return 0 + fi echo "$xml_val" } @@ -164,3 +172,18 @@ get_xml_data() { END{exit}') echo -n "$truncated" > "$2" } + +check_error_parameter() { + if ! check_param_count_v2 "data file, XML parameter, expected value" 3 $#; then + return 1 + fi + if ! value=$(get_element_text "$1" "Error" "$2" 2>&1); then + log 2 "error getting argument name: $value" + return 1 + fi + unescaped_value="$(xmlstarlet unesc "$value")" + if [ "$unescaped_value" != "$3" ]; then + log 2 "expected '$3', was '$unescaped_value'" + return 1 + fi +} diff --git a/tests/rest_scripts/command/payloadAdder.go b/tests/rest_scripts/command/payloadAdder.go new file mode 100644 index 0000000..dd8d33f --- /dev/null +++ b/tests/rest_scripts/command/payloadAdder.go @@ -0,0 +1,5 @@ +package command + +type TagAdder interface { + AddTag(tag string, value string) error +} diff --git a/tests/rest_scripts/command/putBucketTaggingCommand.go b/tests/rest_scripts/command/putBucketTaggingCommand.go new file mode 100644 index 0000000..067b328 --- /dev/null +++ b/tests/rest_scripts/command/putBucketTaggingCommand.go @@ -0,0 +1,102 @@ +package command + +import ( + "encoding/xml" + "errors" + "fmt" + "strconv" + "strings" +) + +type Tag struct { + Key string `xml:"Key"` + Value string `xml:"Value"` +} + +type TagSet struct { + Tags []Tag `xml:"Tag"` +} + +type PutBucketTaggingTags struct { + XMLName xml.Name `xml:"Tagging"` + XMLNamespace string `xml:"xmlns,attr"` + TagSet TagSet `xml:"TagSet"` +} + +type PutBucketTaggingFields struct { + TagCount int + TagKeys []string + TagValues []string +} + +type PutBucketTaggingCommand struct { + *S3Command + TagCount *int + Tags *PutBucketTaggingTags +} + +func NewPutBucketTaggingCommand(s3Command *S3Command, fields *PutBucketTaggingFields) (*PutBucketTaggingCommand, error) { + if s3Command.BucketName == "" { + return nil, errors.New("PutBucketTagging must have bucket name") + } + s3Command.Method = "PUT" + s3Command.Query = "tagging=" + command := &PutBucketTaggingCommand{ + S3Command: s3Command, + } + if len(fields.TagKeys) != len(fields.TagValues) { + return nil, errors.New("must be same number of tag keys and tag values") + } + if fields.TagCount > 0 && len(fields.TagKeys) != 0 { + return nil, errors.New("tagCount can not be set simultaneously with tagKeys or tagValues") + } + command.Tags = &PutBucketTaggingTags{ + XMLNamespace: "https://s3.amazonaws.com/doc/2006-03-01/", + } + if fields.TagCount > 0 { + command.Tags.GenerateKeyValuePairs(fields.TagCount) + + } else if len(fields.TagKeys) != 0 { + if err := command.Tags.AddTags(fields.TagKeys, fields.TagValues); err != nil { + return nil, fmt.Errorf("error adding keys and/or values to payload: %w", err) + } + } + xmlData, err := xml.Marshal(command.Tags) + if err != nil { + return nil, fmt.Errorf("error marshalling XML: %w", err) + } + command.Payload = "" + string(xmlData) + command.Payload = strings.Replace(command.Payload, "\"", "\\\"", -1) + return command, nil +} + +func (p *PutBucketTaggingTags) GenerateKeyValuePairs(count int) { + p.TagSet.Tags = make([]Tag, 0, count) + for idx := 1; idx <= count; idx++ { + key := fmt.Sprintf("key%d", idx) + value := fmt.Sprintf("value%d", idx) + p.TagSet.Tags = append(p.TagSet.Tags, Tag{ + Key: key, + Value: value, + }) + } +} + +func (p *PutBucketTaggingTags) AddTags(keys, values []string) error { + p.TagSet.Tags = make([]Tag, 0, len(keys)) + for idx, key := range keys { + unquotedKey, err := strconv.Unquote(`"` + key + `"`) + if err != nil { + return fmt.Errorf("error unquoting key: %w", err) + } + unquotedValue, err := strconv.Unquote(`"` + values[idx] + `"`) + if err != nil { + return fmt.Errorf("error unquoting key: %w", err) + } + p.TagSet.Tags = append(p.TagSet.Tags, Tag{ + Key: unquotedKey, + Value: unquotedValue, + }) + } + return nil +} diff --git a/tests/rest_scripts/command/s3CommandConverter.go b/tests/rest_scripts/command/s3CommandConverter.go new file mode 100644 index 0000000..e83236b --- /dev/null +++ b/tests/rest_scripts/command/s3CommandConverter.go @@ -0,0 +1,6 @@ +package command + +type S3CommandConverter interface { + CurlShellCommand() (string, error) + OpenSSLCommand() error +} diff --git a/tests/rest_scripts/delete_bucket.sh b/tests/rest_scripts/delete_bucket.sh index b095f45..bb089cb 100755 --- a/tests/rest_scripts/delete_bucket.sh +++ b/tests/rest_scripts/delete_bucket.sh @@ -29,7 +29,7 @@ build_canonical_request "${cr_data[@]}" # shellcheck disable=SC2119 create_canonical_hash_sts_and_signature -curl_command+=(curl -ks -w "\"%{http_code}\"" -X DELETE "https://$host/$bucket_name" +curl_command+=(curl -ks -w "\"%{http_code}\"" -X DELETE "$AWS_ENDPOINT_URL/$bucket_name" -H "\"Authorization: AWS4-HMAC-SHA256 Credential=$aws_access_key_id/$year_month_day/$aws_region/s3/aws4_request,SignedHeaders=$param_list,Signature=$signature\"") curl_command+=("${header_fields[@]}") curl_command+=(-o "$OUTPUT_FILE") diff --git a/tests/rest_scripts/delete_bucket_policy.sh b/tests/rest_scripts/delete_bucket_policy.sh index 2f9c956..93668a7 100755 --- a/tests/rest_scripts/delete_bucket_policy.sh +++ b/tests/rest_scripts/delete_bucket_policy.sh @@ -29,7 +29,7 @@ build_canonical_request "${cr_data[@]}" # shellcheck disable=SC2119 create_canonical_hash_sts_and_signature -curl_command+=(curl -ks -w "\"%{http_code}\"" -X DELETE "https://$host/$bucket_name?policy" +curl_command+=(curl -ks -w "\"%{http_code}\"" -X DELETE "$AWS_ENDPOINT_URL/$bucket_name?policy" -H "\"Authorization: AWS4-HMAC-SHA256 Credential=$aws_access_key_id/$year_month_day/$aws_region/s3/aws4_request,SignedHeaders=$param_list,Signature=$signature\"") curl_command+=("${header_fields[@]}") curl_command+=(-o "$OUTPUT_FILE") diff --git a/tests/rest_scripts/generateCommand.go b/tests/rest_scripts/generateCommand.go index c0529ac..e23da02 100644 --- a/tests/rest_scripts/generateCommand.go +++ b/tests/rest_scripts/generateCommand.go @@ -14,6 +14,10 @@ const ( OPENSSL = "openssl" ) +const ( + PutBucketTagging = "putBucketTagging" +) + var method *string var url *string var bucketName *string @@ -39,6 +43,13 @@ var filePath *string var client *string var customHostParam *string var customHostParamSet bool = false +var commandType *string + +type arrayFlags []string + +var tagCount *int +var tagKeys arrayFlags +var tagValues arrayFlags type restParams map[string]string @@ -51,8 +62,6 @@ func (r *restParams) Set(value string) error { pairs := strings.Split(value, ",") for _, pair := range pairs { kv := strings.SplitN(pair, ":", 2) - if len(kv) != 2 { - } if len(kv) != 2 { return fmt.Errorf("invalid key-value pair: %s", pair) } @@ -61,12 +70,21 @@ func (r *restParams) Set(value string) error { return nil } +func (a *arrayFlags) String() string { + return fmt.Sprintf("%v", *a) +} + +func (a *arrayFlags) Set(value string) error { + *a = append(*a, value) + return nil +} + func main() { if err := checkFlags(); err != nil { log.Fatalf("Error checking flags: %v", err) } - s3Command := &command.S3Command{ + baseCommand := &command.S3Command{ Method: *method, Url: *url, BucketName: *bucketName, @@ -91,6 +109,21 @@ func main() { CustomHostParam: *customHostParam, CustomHostParamSet: customHostParamSet, } + var s3Command command.S3CommandConverter + var err error + switch *commandType { + case PutBucketTagging: + fields := command.PutBucketTaggingFields{ + TagCount: *tagCount, + TagKeys: tagKeys, + TagValues: tagValues, + } + if s3Command, err = command.NewPutBucketTaggingCommand(baseCommand, &fields); err != nil { + log.Fatalf("Error setting up PutBucketTagging command: %v", err) + } + default: + s3Command = baseCommand + } switch *client { case CURL: curlShellCommand, err := s3Command.CurlShellCommand() @@ -105,7 +138,6 @@ func main() { default: log.Fatalln("Invalid client type: ", *client) } - } func checkFlags() error { @@ -133,6 +165,10 @@ func checkFlags() error { customHostParam = flag.String("customHostParam", "", "Custom host parameter") filePath = flag.String("filePath", "", "Path to write command (stdout if none)") client = flag.String("client", CURL, "Command-line client to use") + commandType = flag.String("commandType", "", "Command template to use, if any") + tagCount = flag.Int("tagCount", 0, "Autogenerate this amount of tags for commands with tags") + flag.Var(&tagKeys, "tagKey", "Tag key (can add multiple)") + flag.Var(&tagValues, "tagValue", "Tag value (can add multiple)") // Parse the flags flag.Parse() diff --git a/tests/rest_scripts/list_multipart_uploads.sh b/tests/rest_scripts/list_multipart_uploads.sh index a68cbf1..2d755c1 100755 --- a/tests/rest_scripts/list_multipart_uploads.sh +++ b/tests/rest_scripts/list_multipart_uploads.sh @@ -39,7 +39,7 @@ UNSIGNED-PAYLOAD" # shellcheck disable=SC2119 create_canonical_hash_sts_and_signature -curl_command+=(curl -ks -w "\"%{http_code}\"" "https://$host/$bucket_name/$key?uploads=" +curl_command+=(curl -ks -w "\"%{http_code}\"" "$AWS_ENDPOINT_URL/$bucket_name/$key?uploads=" -H "\"Authorization: AWS4-HMAC-SHA256 Credential=$aws_access_key_id/$year_month_day/$aws_region/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=$signature\"" -H "\"x-amz-content-sha256: UNSIGNED-PAYLOAD\"" -H "\"x-amz-date: $current_date_time\"" diff --git a/tests/rest_scripts/list_object_versions.sh b/tests/rest_scripts/list_object_versions.sh index 89431cf..84fe58b 100755 --- a/tests/rest_scripts/list_object_versions.sh +++ b/tests/rest_scripts/list_object_versions.sh @@ -37,7 +37,7 @@ UNSIGNED-PAYLOAD" # shellcheck disable=SC2119 create_canonical_hash_sts_and_signature -curl_command+=(curl -ks -w "\"%{http_code}\"" "https://$host/$bucket_name?versions" +curl_command+=(curl -ks -w "\"%{http_code}\"" "$AWS_ENDPOINT_URL/$bucket_name?versions" -H "\"Authorization: AWS4-HMAC-SHA256 Credential=$aws_access_key_id/$year_month_day/$aws_region/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=$signature\"" -H "\"x-amz-content-sha256: UNSIGNED-PAYLOAD\"" -H "\"x-amz-date: $current_date_time\"" diff --git a/tests/rest_scripts/list_parts.sh b/tests/rest_scripts/list_parts.sh index bb2e1c0..587fcbb 100755 --- a/tests/rest_scripts/list_parts.sh +++ b/tests/rest_scripts/list_parts.sh @@ -41,7 +41,7 @@ UNSIGNED-PAYLOAD" # shellcheck disable=SC2119 create_canonical_hash_sts_and_signature -curl_command+=(curl -ks -w "\"%{http_code}\"" "https://$host/$bucket_name/$key?uploadId=$upload_id" +curl_command+=(curl -ks -w "\"%{http_code}\"" "$AWS_ENDPOINT_URL/$bucket_name/$key?uploadId=$upload_id" -H "\"Authorization: AWS4-HMAC-SHA256 Credential=$aws_access_key_id/$year_month_day/$aws_region/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=$signature\"" -H "\"x-amz-content-sha256: UNSIGNED-PAYLOAD\"" -H "\"x-amz-date: $current_date_time\"" diff --git a/tests/rest_scripts/put_bucket_tagging.go b/tests/rest_scripts/put_bucket_tagging.go deleted file mode 100644 index 06ab7d0..0000000 --- a/tests/rest_scripts/put_bucket_tagging.go +++ /dev/null @@ -1 +0,0 @@ -package main diff --git a/tests/run.sh b/tests/run.sh index 6ab3861..0a1c723 100755 --- a/tests/run.sh +++ b/tests/run.sh @@ -45,6 +45,7 @@ show_help() { echo " rest-list-buckets Run REST list-buckets tests" echo " rest-multipart Run REST multipart tests" echo " rest-not-implemented Run REST multipart tests" + echo " rest-put-bucket-tagging Run REST put-bucket-tagging tests" echo " rest-put-object Run REST put-object tests" echo " rest-versioning Run REST versioning tests" echo " rest-bucket Run REST bucket tests" @@ -61,7 +62,7 @@ handle_param() { s3api-bucket|s3api-object|s3api-multipart|rest-base|rest-acl|rest-chunked|rest-checksum|\ rest-create-bucket|rest-head-bucket|rest-list-buckets|rest-not-implemented|\ rest-put-object|rest-versioning|rest-bucket|rest-multipart|rest-delete-bucket-ownership-controls|\ - rest-delete-bucket-tagging|setup-remove-static) + rest-delete-bucket-tagging|setup-remove-static|rest-put-bucket-tagging) run_suite "$1" ;; *) # Handle unrecognized options or positional arguments @@ -180,6 +181,8 @@ run_suite() { exit_code=1 elif ! "$HOME"/bin/bats ./tests/test_rest_not_implemented.sh; then exit_code=1 + elif ! "$HOME"/bin/bats ./tests/test_rest_put_bucket_tagging.sh; then + exit_code=1 elif ! "$HOME"/bin/bats ./tests/test_rest_put_object.sh; then exit_code=1 elif ! "$HOME"/bin/bats ./tests/test_rest_versioning.sh; then @@ -236,6 +239,10 @@ run_suite() { echo "Running REST multipart tests ..." "$HOME"/bin/bats ./tests/test_rest_multipart.sh || exit_code=$? ;; + rest-put-bucket-tagging) + echo "Running REST put-bucket-tagging tests ..." + "$HOME"/bin/bats ./tests/test_rest_put_bucket_tagging.sh || exit_code=$? + ;; rest-put-object) echo "Running REST put-object tests ..." "$HOME"/bin/bats ./tests/test_rest_put_object.sh || exit_code=$? diff --git a/tests/test_mc.sh b/tests/test_mc.sh index 9151d15..12c6894 100755 --- a/tests/test_mc.sh +++ b/tests/test_mc.sh @@ -23,9 +23,11 @@ source ./tests/commands/delete_bucket_policy.sh source ./tests/commands/get_bucket_policy.sh source ./tests/commands/put_bucket_policy.sh source ./tests/drivers/create_bucket/create_bucket_rest.sh +source ./tests/drivers/get_bucket_tagging/get_bucket_tagging.sh +source ./tests/drivers/get_bucket_tagging/get_bucket_tagging_rest.sh +source ./tests/drivers/get_object_tagging/get_object_tagging.sh source ./tests/util/util_create_bucket.sh source ./tests/util/util_head_bucket.sh -source ./tests/util/util_tags.sh export RUN_MC=true diff --git a/tests/test_rest.sh b/tests/test_rest.sh index fe3fe6b..f2f7a95 100755 --- a/tests/test_rest.sh +++ b/tests/test_rest.sh @@ -32,6 +32,7 @@ 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_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/file.sh @@ -50,7 +51,6 @@ 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_tags.sh source ./tests/util/util_time.sh source ./tests/util/util_versioning.sh diff --git a/tests/test_rest_bucket.sh b/tests/test_rest_bucket.sh index 858394d..cc59654 100755 --- a/tests/test_rest_bucket.sh +++ b/tests/test_rest_bucket.sh @@ -22,6 +22,7 @@ source ./tests/commands/head_bucket.sh source ./tests/commands/list_buckets.sh source ./tests/drivers/create_bucket/create_bucket_rest.sh source ./tests/drivers/get_bucket_ownership_controls/get_bucket_ownership_controls_rest.sh +source ./tests/drivers/get_bucket_tagging/get_bucket_tagging_rest.sh source ./tests/drivers/list_buckets/list_buckets_rest.sh source ./tests/drivers/put_bucket_tagging/put_bucket_tagging_rest.sh source ./tests/logger.sh @@ -32,7 +33,6 @@ source ./tests/util/util_list_buckets.sh source ./tests/util/util_lock_config.sh source ./tests/util/util_public_access_block.sh source ./tests/util/util_rest.sh -source ./tests/util/util_tags.sh export RUN_USERS=true @@ -48,11 +48,6 @@ export RUN_USERS=true assert_success } -@test "REST - HeadBucket - doesn't exist" { - run head_bucket_rest "$BUCKET_ONE_NAME-$(uuidgen)" - assert_failure 1 -} - @test "REST - bucket tagging - no tags" { run get_bucket_name "$BUCKET_ONE_NAME" assert_success @@ -65,21 +60,6 @@ export RUN_USERS=true assert_success } -@test "REST - bucket tagging - tags" { - test_key="testKey" - test_value="testValue" - - run get_bucket_name "$BUCKET_ONE_NAME" - assert_success - bucket_name="$output" - - run setup_bucket_v2 "$bucket_name" - assert_success - - run add_verify_bucket_tags_rest "$bucket_name" "$test_key" "$test_value" - assert_success -} - @test "REST - get, put bucket ownership controls" { run get_bucket_name "$BUCKET_ONE_NAME" assert_success diff --git a/tests/test_rest_delete_bucket_tagging.sh b/tests/test_rest_delete_bucket_tagging.sh index 77f5a01..bb5ab59 100755 --- a/tests/test_rest_delete_bucket_tagging.sh +++ b/tests/test_rest_delete_bucket_tagging.sh @@ -18,8 +18,11 @@ load ./bats-support/load load ./bats-assert/load source ./tests/setup.sh +source ./tests/drivers/rest.sh source ./tests/drivers/user.sh source ./tests/drivers/create_bucket/create_bucket_rest.sh +source ./tests/drivers/delete_bucket_tagging/delete_bucket_tagging_rest.sh +source ./tests/drivers/get_bucket_tagging/get_bucket_tagging_rest.sh export RUN_USERS=true @@ -40,3 +43,18 @@ export RUN_USERS=true "-method" "DELETE" "-bucketName" "$bucket_name" "-query" "tagging=" assert_success } + +@test "REST - DeleteBucketTagging - success" { + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_v2 "$bucket_name" + assert_success + + run add_verify_bucket_tags_rest "$bucket_name" "key" "value" + assert_success + + run delete_tags_and_verify_deletion "$bucket_name" + assert_success +} diff --git a/tests/test_rest_head_bucket.sh b/tests/test_rest_head_bucket.sh index 5a29689..fe88a3a 100755 --- a/tests/test_rest_head_bucket.sh +++ b/tests/test_rest_head_bucket.sh @@ -51,6 +51,11 @@ source ./tests/drivers/create_bucket/create_bucket_rest.sh assert_success } +@test "REST - HeadBucket - doesn't exist" { + run head_bucket_rest "$BUCKET_ONE_NAME-$(uuidgen)" + assert_failure 1 +} + @test "REST - HeadBucket - expected owner success" { run get_bucket_name "$BUCKET_ONE_NAME" assert_success diff --git a/tests/test_rest_put_bucket_tagging.sh b/tests/test_rest_put_bucket_tagging.sh new file mode 100755 index 0000000..e33eaa4 --- /dev/null +++ b/tests/test_rest_put_bucket_tagging.sh @@ -0,0 +1,121 @@ +#!/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 +source ./tests/drivers/get_bucket_tagging/get_bucket_tagging_rest.sh +source ./tests/drivers/put_bucket_tagging/put_bucket_tagging_rest.sh + +@test "REST PutBucketTagging - more than 50 tags" { + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_v2 "$bucket_name" + assert_success + + run send_rest_go_command_expect_error "400" "BadRequest" "Bucket tag count cannot be greater than 50" \ + "-commandType" "putBucketTagging" "-bucketName" "$bucket_name" "-tagCount" 51 "-contentMD5" + assert_success +} + +@test "REST PutBucketTagging - tag key with control character" { + if [ "$DIRECT" != "true" ]; then + skip "https://github.com/versity/versitygw/issues/1579" + fi + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_v2 "$bucket_name" + assert_success + + run send_rest_go_command_expect_error "400" "InvalidTag" "The TagKey you have provided is invalid" \ + "-commandType" "putBucketTagging" "-bucketName" "$bucket_name" "-tagKey" "te\tst" "-tagValue" "value" "-contentMD5" + assert_success +} + +@test "REST PutBucketTagging - duplicate tag key" { + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_v2 "$bucket_name" + assert_success + + run send_rest_go_command_expect_error "400" "InvalidTag" "Cannot provide multiple Tags with the same key" \ + "-commandType" "putBucketTagging" "-bucketName" "$bucket_name" "-tagKey" "test" "-tagValue" "one" \ + "-tagKey" "test" "-tagValue" "two" "-contentMD5" + assert_success +} + +@test "REST PutBucketTagging - tag value with control character" { + if [ "$DIRECT" != "true" ]; then + skip "https://github.com/versity/versitygw/issues/1579" + fi + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_v2 "$bucket_name" + assert_success + + run send_rest_go_command_expect_error "400" "InvalidTag" "The TagValue you have provided is invalid" \ + "-commandType" "putBucketTagging" "-bucketName" "$bucket_name" "-tagKey" "test" "-tagValue" "val\tue" "-contentMD5" + assert_success +} + +@test "REST PutBucketTagging - empty tag key" { + if [ "$DIRECT" != "true" ]; then + skip "https://github.com/versity/versitygw/issues/1583" + fi + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run put_bucket_tagging_check_invalid_key_fields "$bucket_name" "" + assert_success +} + +@test "REST PutBucketTagging - returns invalid key" { + if [ "$DIRECT" != "true" ]; then + skip "https://github.com/versity/versitygw/issues/1583" + fi + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run put_bucket_tagging_check_invalid_key_fields "$bucket_name" "te&st" + assert_success +} + +@test "REST - PutBucketTagging - success" { + test_key="testKey" + test_value="testValue" + + run get_bucket_name "$BUCKET_ONE_NAME" + assert_success + bucket_name="$output" + + run setup_bucket_v2 "$bucket_name" + assert_success + + run add_verify_bucket_tags_rest "$bucket_name" "$test_key" "$test_value" + assert_success +} diff --git a/tests/test_s3api_bucket.sh b/tests/test_s3api_bucket.sh index 1681322..dc8deb1 100755 --- a/tests/test_s3api_bucket.sh +++ b/tests/test_s3api_bucket.sh @@ -46,12 +46,13 @@ source ./tests/commands/select_object_content.sh source ./tests/drivers/file.sh source ./tests/drivers/user.sh source ./tests/drivers/get_bucket_acl/get_bucket_acl.sh +source ./tests/drivers/get_bucket_tagging/get_bucket_tagging.sh +source ./tests/drivers/get_bucket_tagging/get_bucket_tagging_rest.sh source ./tests/util/util_create_bucket.sh source ./tests/util/util_file.sh source ./tests/util/util_head_bucket.sh source ./tests/util/util_lock_config.sh source ./tests/util/util_object.sh -source ./tests/util/util_tags.sh export RUN_USERS=true diff --git a/tests/test_s3api_multipart.sh b/tests/test_s3api_multipart.sh index 8f9e40d..878f769 100755 --- a/tests/test_s3api_multipart.sh +++ b/tests/test_s3api_multipart.sh @@ -25,11 +25,11 @@ source ./tests/commands/put_object.sh source ./tests/drivers/file.sh source ./tests/drivers/head_object/head_object_s3api.sh source ./tests/drivers/create_bucket/create_bucket_rest.sh +source ./tests/drivers/get_object_tagging/get_object_tagging.sh source ./tests/util/util_file.sh source ./tests/util/util_multipart.sh source ./tests/util/util_multipart_abort.sh source ./tests/util/util_multipart_before_completion.sh -source ./tests/util/util_tags.sh export RUN_USERS=true diff --git a/tests/test_s3api_object.sh b/tests/test_s3api_object.sh index 04eb01c..d5dd787 100755 --- a/tests/test_s3api_object.sh +++ b/tests/test_s3api_object.sh @@ -22,7 +22,6 @@ source ./tests/util/util_create_bucket.sh source ./tests/util/util_file.sh source ./tests/util/util_lock_config.sh source ./tests/util/util_object.sh -source ./tests/util/util_tags.sh source ./tests/test_s3api_root_inner.sh source ./tests/test_common.sh source ./tests/test_common_acl.sh @@ -49,6 +48,7 @@ source ./tests/commands/put_object_retention.sh source ./tests/commands/put_public_access_block.sh source ./tests/commands/select_object_content.sh source ./tests/drivers/copy_object/copy_object_rest.sh +source ./tests/drivers/get_object_tagging/get_object_tagging.sh source ./tests/drivers/list_buckets/list_buckets_rest.sh export RUN_USERS=true diff --git a/tests/test_s3api_policy.sh b/tests/test_s3api_policy.sh index afbb980..8cf3d8c 100755 --- a/tests/test_s3api_policy.sh +++ b/tests/test_s3api_policy.sh @@ -27,7 +27,6 @@ source ./tests/util/util_multipart_abort.sh source ./tests/util/util_multipart_before_completion.sh source ./tests/util/util_file.sh source ./tests/util/util_policy.sh -source ./tests/util/util_tags.sh source ./tests/util/util_users.sh source ./tests/commands/get_bucket_policy.sh source ./tests/commands/get_bucket_tagging.sh @@ -36,6 +35,7 @@ source ./tests/commands/put_bucket_policy.sh source ./tests/commands/put_bucket_tagging.sh source ./tests/commands/put_object.sh source ./tests/drivers/get_bucket_acl/get_bucket_acl_s3api.sh +source ./tests/drivers/get_bucket_tagging/get_bucket_tagging_rest.sh export RUN_USERS=true diff --git a/tests/util/util_tags.sh b/tests/util/util_tags.sh deleted file mode 100644 index 13e95c6..0000000 --- a/tests/util/util_tags.sh +++ /dev/null @@ -1,312 +0,0 @@ -#!/usr/bin/env bash - -# 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. - -source ./tests/commands/get_object_tagging.sh - -# params: username, password, bucket, expected key, expected value -# return 0 for success, 1 for failure -get_and_check_bucket_tags_with_user() { - log 6 "get_and_check_bucket_tags" - if [ $# -ne 5 ]; then - log 2 "'get_and_check_bucket_tags' requires username, password, bucket, expected key, expected value" - return 1 - fi - if ! get_bucket_tagging_with_user "$1" "$2" "$3"; then - log 2 "error retrieving bucket tagging" - return 1 - fi - # shellcheck disable=SC2154 - log 5 "TAGS: $tags" - if ! tag=$(echo "$tags" | jq -r ".TagSet[0]" 2>&1); then - log 2 "error getting tag: $tag" - return 1 - fi - if ! key=$(echo "$tag" | jq -r ".Key" 2>&1); then - log 2 "error getting key: $key" - return 1 - fi - if [ "$key" != "$4" ]; then - log 2 "key mismatch ($key, $4)" - return 1 - fi - if ! value=$(echo "$tag" | jq -r ".Value" 2>&1); then - log 2 "error getting value: $value" - return 1 - fi - if [ "$value" != "$5" ]; then - log 2 "value mismatch ($value, $5)" - return 1 - fi - return 0 -} - -# params: bucket, expected tag key, expected tag value -# fail on error -get_and_check_bucket_tags() { - if [ $# -ne 3 ]; then - log 2 "'get_and_check_bucket_tags' requires bucket, expected tag key, expected tag value" - return 1 - fi - if ! get_and_check_bucket_tags_with_user "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" "$1" "$2" "$3"; then - log 2 "error getting and checking bucket tags with user" - return 1 - fi - return 0 -} - -verify_no_bucket_tags() { - if [ $# -ne 2 ]; then - log 2 "'verify_no_bucket_tags' requires bucket name" - return 1 - fi - if ! get_bucket_tagging "$1" "$2"; then - log 2 "error retrieving bucket tagging" - return 1 - fi - # shellcheck disable=SC2154 - if [[ "$tags" != "" ]]; then - log 2 "tags should be empty, but are: $tags" - return 1 - fi - return 0 -} - -verify_no_object_tags() { - if [ $# -ne 3 ]; then - log 2 "'verify_no_object_tags' requires client, bucket, object" - return 1 - fi - result=0 - get_object_tagging "$1" "$2" "$3" || result=$? - if [ $result == 1 ]; then - if [ "$1" == 'rest' ]; then - return 0 - fi - log 2 "error getting object tagging" - return 1 - fi - if [[ "$1" == 'aws' ]] || [ "$1" == 's3api' ]; then - if ! tag_set=$(echo "$tags" | jq '.TagSet' 2>&1); then - log 2 "error getting tag set: $tag_set" - return 1 - fi - if [[ $tag_set != "[]" ]] && [[ $tag_set != "" ]]; then - log 2 "tags not empty ($tag_set)" - return 1 - fi - elif [[ $tags != *"No tags found"* ]] && [[ $tags != "" ]]; then - log 2 "tags not empty (tags: $tags)" - return 1 - fi - return 0 -} - -check_verify_object_tags() { - if [ $# -ne 5 ]; then - log 2 "'check_verify_object_tags' requires client, bucket, key, expected tag key, expected tag value" - return 1 - fi - if ! get_object_tagging "$1" "$2" "$3"; then - log 2 "error getting object tags" - return 1 - fi - if [[ $1 == 'aws' ]] || [[ $1 == 's3api' ]]; then - if ! parse_object_tags_s3api; then - log 2 "error parsing object tags" - return 1 - fi - elif [ "$1" == 'rest' ]; then - if ! parse_object_tags_rest; then - log 2 "error parsing object tags" - return 1 - fi - elif [[ $1 == 'mc' ]]; then - read -r tag_set_key tag_set_value <<< "$(echo "$tags" | awk 'NR==2 {print $1, $3}')" - else - log 2 "unrecognized client for check_verify_object_tags: $1" - return 1 - fi - if [[ $tag_set_key != "$4" ]]; then - log 2 "Key mismatch ($tag_set_key, $4)" - return 1 - fi - if [[ $tag_set_value != "$5" ]]; then - log 2 "Value mismatch ($tag_set_value, $5)" - return 1 - fi - return 0 -} - -parse_object_tags_s3api() { - if ! tag_set_key=$(echo "$tags" | jq -r '.TagSet[0].Key' 2>&1); then - log 2 "error retrieving tag key: $tag_set_key" - return 1 - fi - if ! tag_set_value=$(echo "$tags" | jq -r '.TagSet[0].Value' 2>&1); then - log 2 "error retrieving tag value: $tag_set_value" - return 1 - fi - return 0 -} - -parse_object_tags_rest() { - if ! tag_set_key=$(xmllint --xpath '//*[local-name()="Key"]/text()' "$TEST_FILE_FOLDER/object_tags.txt" 2>&1); then - log 2 "error getting key: $tag_set_key" - return 1 - fi - if ! tag_set_value=$(xmllint --xpath '//*[local-name()="Value"]/text()' "$TEST_FILE_FOLDER/object_tags.txt" 2>&1); then - log 2 "error getting value: $value" - return 1 - fi - return 0 -} - -check_tags_empty() { - if [[ $# -ne 1 ]]; then - log 2 "check tags empty requires command type" - return 1 - fi - if [[ $1 == 'aws' ]]; then - if [[ $tags == "" ]]; then - return 0 - fi - tag_set=$(echo "$tags" | jq '.TagSet') - if [[ $tag_set != "[]" ]]; then - log 2 "error: tags not empty: $tags" - return 1 - fi - else - if [[ $tags != "" ]] && [[ $tags != *"No tags found"* ]]; then - log 2 "Error: tags not empty: $tags" - return 1 - fi - fi - return 0 -} - -check_object_tags_empty() { - if [[ $# -ne 3 ]]; then - log 2 "bucket tags empty check requires command type, bucket, and key" - return 2 - fi - if ! get_object_tagging "$1" "$2" "$3"; then - log 2 "failed to get tags" - return 2 - fi - check_tags_empty "$1" || local check_result=$? - # shellcheck disable=SC2086 - return $check_result -} - -check_bucket_tags_empty() { - if [[ $# -ne 2 ]]; then - log 2 "bucket tags empty check requires command type, bucket" - return 2 - fi - if ! get_bucket_tagging "$1" "$2"; then - log 2 "failed to get tags" - return 2 - fi - check_tags_empty "$1" || local check_result=$? - # shellcheck disable=SC2086 - return $check_result -} - -get_and_verify_object_tags() { - if [[ $# -ne 5 ]]; then - log 2 "get and verify object tags missing command type, bucket, key, tag key, tag value" - return 1 - fi - get_object_tagging "$1" "$2" "$3" || get_result=$? - if [[ $get_result -ne 0 ]]; then - log 2 "failed to get tags" - return 1 - fi - if [[ $1 == 'aws' ]]; then - tag_set_key=$(echo "$tags" | jq '.TagSet[0].Key') - tag_set_value=$(echo "$tags" | jq '.TagSet[0].Value') - if [[ $tag_set_key != '"'$4'"' ]]; then - log 2 "Key mismatch ($tag_set_key, \"$4\")" - return 1 - fi - if [[ $tag_set_value != '"'$5'"' ]]; then - log 2 "Value mismatch ($tag_set_value, \"$5\")" - return 1 - fi - else - read -r tag_set_key tag_set_value <<< "$(echo "$tags" | awk 'NR==2 {print $1, $3}')" - [[ $tag_set_key == "$4" ]] || fail "Key mismatch" - [[ $tag_set_value == "$5" ]] || fail "Value mismatch" - fi - return 0 -} - -verify_no_bucket_tags_rest() { - if [ $# -ne 1 ]; then - log 2 "'verify_no_bucket_tags_rest' requires bucket name" - return 1 - fi - if ! result=$(COMMAND_LOG="$COMMAND_LOG" BUCKET_NAME="$1" OUTPUT_FILE="$TEST_FILE_FOLDER/bucket_tagging.txt" ./tests/rest_scripts/get_bucket_tagging.sh); then - log 2 "error listing bucket tags: $result" - return 1 - fi - if [ "$result" != "404" ]; then - log 2 "expected response code of '404', was '$result' (error: $(cat "$TEST_FILE_FOLDER/bucket_tagging.txt"))" - return 1 - fi - return 0 -} - -add_verify_bucket_tags_rest() { - if [ $# -ne 3 ]; then - log 2 "'add_verify_bucket_tags_rest' requires bucket name, test key, test value" - return 1 - fi - if ! result=$(COMMAND_LOG="$COMMAND_LOG" BUCKET_NAME="$1" TAG_KEY="$2" TAG_VALUE="$3" OUTPUT_FILE="$TEST_FILE_FOLDER/result.txt" ./tests/rest_scripts/put_bucket_tagging.sh); then - log 2 "error putting bucket tags: $result" - return 1 - fi - if [ "$result" != "204" ]; then - log 2 "expected response code of '204', was '$result' (error: $(cat "$TEST_FILE_FOLDER/result.txt"))" - return 1 - fi - if ! result=$(COMMAND_LOG="$COMMAND_LOG" BUCKET_NAME="$1" OUTPUT_FILE="$TEST_FILE_FOLDER/bucket_tagging.txt" ./tests/rest_scripts/get_bucket_tagging.sh); then - log 2 "error listing bucket tags: $result" - return 1 - fi - if [ "$result" != "200" ]; then - log 2 "expected response code of '200', was '$result' (error: $(cat "$TEST_FILE_FOLDER/bucket_tagging.txt"))" - return 1 - fi - log 5 "tags: $(cat "$TEST_FILE_FOLDER/bucket_tagging.txt")" - if ! key=$(xmllint --xpath '//*[local-name()="Key"]/text()' "$TEST_FILE_FOLDER/bucket_tagging.txt" 2>&1); then - log 2 "error retrieving key: $key" - return 1 - fi - if [ "$key" != "$2" ]; then - log 2 "key mismatch (expected '$2', actual '$key')" - return 1 - fi - if ! value=$(xmllint --xpath '//*[local-name()="Value"]/text()' "$TEST_FILE_FOLDER/bucket_tagging.txt" 2>&1); then - log 2 "error retrieving value: $value" - return 1 - fi - if [ "$value" != "$3" ]; then - log 2 "value mismatch (expected '$3', actual '$value')" - return 1 - fi - return 0 -} diff --git a/tests/versity.sh b/tests/versity.sh index c11b9af..f0fbcbe 100644 --- a/tests/versity.sh +++ b/tests/versity.sh @@ -81,7 +81,6 @@ run_versity_app_posix() { if [ -n "$PORT" ]; then base_command+=(--port ":$PORT") fi - # TODO remove or change base_command+=(posix) if [ -n "$VERSIONING_DIR" ]; then base_command+=(--versioning-dir "$VERSIONING_DIR")