mirror of
https://github.com/versity/versitygw.git
synced 2026-08-28 03:46:17 +00:00
test: PutObject, locking, versioning, retention testing
This commit is contained in:
@@ -28,7 +28,7 @@ copy_object() {
|
||||
error=$(send_command aws --no-verify-ssl s3api copy-object --copy-source "$2" --bucket "$3" --key "$4" 2>&1) || exit_code=$?
|
||||
elif [[ $1 == 's3cmd' ]]; then
|
||||
log 5 "s3cmd ${S3CMD_OPTS[*]} --no-check-certificate cp s3://$2 s3://$3/$4"
|
||||
error=$(send_command s3cmd "${S3CMD_OPTS[@]}" --no-check-certificate cp "s3://$2" s3://"$3/$4" 2>&1) || exit_code=$?
|
||||
error=$(send_command s3cmd "${S3CMD_OPTS[@]}" --no-check-certificate --region "$AWS_REGION" cp "s3://$2" s3://"$3/$4" 2>&1) || exit_code=$?
|
||||
elif [[ $1 == 'mc' ]]; then
|
||||
error=$(send_command mc --insecure cp "$MC_ALIAS/$2" "$MC_ALIAS/$3/$4" 2>&1) || exit_code=$?
|
||||
else
|
||||
|
||||
@@ -59,7 +59,7 @@ create_bucket_invalid_name() {
|
||||
elif [[ $1 == 's3api' ]]; then
|
||||
bucket_create_error=$(aws --no-verify-ssl s3api create-bucket --bucket "s3://" 2>&1) || exit_code=$?
|
||||
elif [[ $1 == 's3cmd' ]]; then
|
||||
bucket_create_error=$(s3cmd "${S3CMD_OPTS[@]}" --no-check-certificate mb "s3://" 2>&1) || exit_code=$?
|
||||
bucket_create_error=$(s3cmd "${S3CMD_OPTS[@]}" --no-check-certificate mb --region="$AWS_REGION" "s3://" 2>&1) || exit_code=$?
|
||||
elif [[ $1 == 'mc' ]]; then
|
||||
bucket_create_error=$(mc --insecure mb "$MC_ALIAS/." 2>&1) || exit_code=$?
|
||||
else
|
||||
@@ -82,7 +82,7 @@ create_bucket_with_user() {
|
||||
if [[ $1 == "aws" ]] || [[ $1 == "s3api" ]]; then
|
||||
error=$(AWS_ACCESS_KEY_ID="$3" AWS_SECRET_ACCESS_KEY="$4" send_command aws --no-verify-ssl s3 mb s3://"$2" 2>&1) || exit_code=$?
|
||||
elif [[ $1 == "s3cmd" ]]; then
|
||||
error=$(send_command s3cmd "${S3CMD_OPTS[@]}" --no-check-certificate mb --access_key="$3" --secret_key="$4" s3://"$2" 2>&1) || exit_code=$?
|
||||
error=$(send_command s3cmd "${S3CMD_OPTS[@]}" --no-check-certificate mb --access_key="$3" --secret_key="$4" --region="$AWS_REGION" s3://"$2" 2>&1) || exit_code=$?
|
||||
elif [[ $1 == "mc" ]]; then
|
||||
error=$(send_command mc --insecure mb "$MC_ALIAS"/"$2" 2>&1) || exit_code=$?
|
||||
else
|
||||
|
||||
@@ -85,6 +85,17 @@ delete_object_version_rest() {
|
||||
return 0
|
||||
}
|
||||
|
||||
delete_object_version_rest_expect_error() {
|
||||
if ! check_param_count_v2 "bucket name, object name, version ID, expected code, expected error, expected message" 6 $#; then
|
||||
return 1
|
||||
fi
|
||||
if ! send_rest_command_expect_error "BUCKET_NAME=$1 OBJECT_KEY=$2 VERSION_ID=$3" "./tests/rest_scripts/delete_object.sh" "$4" "$5" "$6"; then
|
||||
log 2 "error deleting object: $result"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
delete_object_version_bypass_retention() {
|
||||
if ! check_param_count "delete_object_version_bypass_retention" "bucket, key, version ID" 3 $#; then
|
||||
return 1
|
||||
|
||||
@@ -87,7 +87,7 @@ get_bucket_policy_s3cmd() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! info=$(send_command s3cmd "${S3CMD_OPTS[@]}" --no-check-certificate info "s3://$1" 2>&1); then
|
||||
if ! info=$(send_command s3cmd "${S3CMD_OPTS[@]}" --no-check-certificate --region "$AWS_REGION" info "s3://$1" 2>&1); then
|
||||
log 2 "error getting bucket policy: $info"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -26,7 +26,7 @@ put_bucket_policy() {
|
||||
if [[ $1 == 's3api' ]]; then
|
||||
policy=$(send_command aws --no-verify-ssl s3api put-bucket-policy --bucket "$2" --policy "file://$3" 2>&1) || put_policy_result=$?
|
||||
elif [[ $1 == 's3cmd' ]]; then
|
||||
policy=$(send_command s3cmd "${S3CMD_OPTS[@]}" --no-check-certificate setpolicy "$3" "s3://$2" 2>&1) || put_policy_result=$?
|
||||
policy=$(send_command s3cmd "${S3CMD_OPTS[@]}" --no-check-certificate --region "$AWS_REGION" setpolicy "$3" "s3://$2" 2>&1) || put_policy_result=$?
|
||||
elif [[ $1 == 'mc' ]]; then
|
||||
policy=$(send_command mc --insecure anonymous set-json "$3" "$MC_ALIAS/$2" 2>&1) || put_policy_result=$?
|
||||
elif [ "$1" == 'rest' ]; then
|
||||
|
||||
@@ -30,7 +30,7 @@ put_object() {
|
||||
elif [[ $1 == 's3api' ]]; then
|
||||
error=$(send_command aws --no-verify-ssl s3api put-object --body "$2" --bucket "$3" --key "$4" 2>&1) || exit_code=$?
|
||||
elif [[ $1 == 's3cmd' ]]; then
|
||||
error=$(send_command s3cmd "${S3CMD_OPTS[@]}" --no-check-certificate put "$2" s3://"$3/$4" 2>&1) || exit_code=$?
|
||||
error=$(send_command s3cmd "${S3CMD_OPTS[@]}" --no-check-certificate --region "$AWS_REGION" put "$2" s3://"$3/$4" 2>&1) || exit_code=$?
|
||||
elif [[ $1 == 'mc' ]]; then
|
||||
error=$(send_command mc --insecure put "$2" "$MC_ALIAS/$3/$4" 2>&1) || exit_code=$?
|
||||
elif [[ $1 == 'rest' ]]; then
|
||||
|
||||
@@ -27,6 +27,28 @@ put_object_lock_configuration() {
|
||||
return 0
|
||||
}
|
||||
|
||||
put_object_lock_configuration_rest() {
|
||||
if ! check_param_count_v2 "bucket name, params" 2 $#; then
|
||||
return 1
|
||||
fi
|
||||
if ! send_rest_command "BUCKET_NAME=$1 $2" "./tests/rest_scripts/put_object_lock_configuration.sh"; then
|
||||
log 2 "error sending put object lock config command or error mismatch"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
put_object_lock_configuration_rest_expect_error() {
|
||||
if ! check_param_count_v2 "bucket name, params, expected response code, expected error code, expected message" 5 $#; then
|
||||
return 1
|
||||
fi
|
||||
if ! send_rest_command_expect_error "BUCKET_NAME=$1 $2" "./tests/rest_scripts/put_object_lock_configuration.sh" "$3" "$4" "$5"; then
|
||||
log 2 "error sending put object lock config command or error mismatch"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
remove_retention_policy_rest() {
|
||||
if ! check_param_count "remove_retention_policy_rest" "bucket" 1 $#; then
|
||||
return 1
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
# under the License.
|
||||
|
||||
source ./tests/commands/list_objects_v2.sh
|
||||
source ./tests/drivers/list_object_versions/list_object_versions_rest.sh
|
||||
source ./tests/drivers/xml.sh
|
||||
source ./tests/util/util_legal_hold.sh
|
||||
|
||||
@@ -102,3 +103,50 @@ delete_object_version_with_or_without_retention_base64() {
|
||||
log 5 "successfully deleted version with key '$key', id '$id'"
|
||||
return 0
|
||||
}
|
||||
|
||||
put_object_with_lock_mode_and_delete_latest_version() {
|
||||
if ! check_param_count_v2 "file, bucket, key, later time" 4 $#; then
|
||||
return 1
|
||||
fi
|
||||
if ! send_rest_go_command "200" \
|
||||
"-bucketName" "$2" "-objectKey" "$3" "-payloadFile" "$1" \
|
||||
"-method" "PUT" "-contentMD5" "-signedParams" "x-amz-object-lock-mode:GOVERNANCE,x-amz-object-lock-retain-until-date:$4"; then
|
||||
log 2 "error sending put object command with object lock"
|
||||
return 1
|
||||
fi
|
||||
if ! send_rest_go_command_callback "200" "parse_latest_version_id" \
|
||||
"-method" "GET" "-bucketName" "$2" "-query" "versions="; then
|
||||
log 2 "error checking versions before deletion"
|
||||
return 1
|
||||
fi
|
||||
if ! delete_object_version_rest_expect_error "$2" "$3" "$version_id" "403" "AccessDenied" "object protected by object lock"; then
|
||||
log 2 "shouldn't have been able to delete"
|
||||
return 1
|
||||
fi
|
||||
sleep 15
|
||||
if ! delete_object_version "$2" "$3" "$version_id"; then
|
||||
log 2 "error deleting object version"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
attempt_to_delete_version_after_retention_policy() {
|
||||
if ! check_param_count_v2 "file, bucket name, key" 3 $#; then
|
||||
return 1
|
||||
fi
|
||||
if ! send_rest_go_command "200" \
|
||||
"-bucketName" "$2" "-objectKey" "$3" "-payloadFile" "$1" "-method" "PUT" "-contentMD5"; then
|
||||
log 2 "error sending put object command"
|
||||
return 1
|
||||
fi
|
||||
if ! send_rest_go_command_callback "200" "parse_latest_version_id" \
|
||||
"-method" "GET" "-bucketName" "$2" "-query" "versions="; then
|
||||
log 2 "error checking versions before deletion"
|
||||
return 1
|
||||
fi
|
||||
if ! delete_object_version_rest_expect_error "$2" "$3" "$version_id" "403" "AccessDenied" "object protected by object lock"; then
|
||||
log 2 "shouldn't have been able to delete"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -14,23 +14,23 @@
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
parse_non_latest_version_id() {
|
||||
if ! check_param_count_v2 "data file" 1 $#; then
|
||||
parse_version_id() {
|
||||
if ! check_param_count_v2 "data file, IsLatest val" 2 $#; then
|
||||
return 1
|
||||
fi
|
||||
log 5 "data: $(cat "$1")"
|
||||
not_latest_string="//*[local-name()=\"Version\"][*[local-name()=\"IsLatest\" and text()=\"false\"]]"
|
||||
log 5 "match string: $not_latest_string"
|
||||
version_string="//*[local-name()=\"Version\"][*[local-name()=\"IsLatest\" and text()=\"$2\"]]"
|
||||
log 5 "match string: $version_string"
|
||||
if ! get_xml_data "$1" "$1.xml"; then
|
||||
log 2 "error getting XML data"
|
||||
return 1
|
||||
fi
|
||||
if ! not_latest=$(xmllint --xpath "$not_latest_string" "$1.xml" 2>&1); then
|
||||
log 2 "error getting result: $not_latest"
|
||||
if ! version=$(xmllint --xpath "$version_string" "$1.xml" 2>&1); then
|
||||
log 2 "error getting result: $version"
|
||||
return 1
|
||||
fi
|
||||
log 5 "not latest: $not_latest"
|
||||
if ! version_id=$(xmllint --xpath "//*[local-name()=\"VersionId\"]/text()" <(echo "$not_latest" | head -n 1) 2>&1); then
|
||||
log 5 "latest: $2, version: $version"
|
||||
if ! version_id=$(xmllint --xpath "//*[local-name()=\"VersionId\"]/text()" <(echo "$version" | head -n 1) 2>&1); then
|
||||
log 2 "error getting version ID: $version_id"
|
||||
return 1
|
||||
fi
|
||||
@@ -38,6 +38,17 @@ parse_non_latest_version_id() {
|
||||
return 0
|
||||
}
|
||||
|
||||
parse_non_latest_version_id() {
|
||||
if ! check_param_count_v2 "data file" 1 $#; then
|
||||
return 1
|
||||
fi
|
||||
if ! parse_version_id "$1" "false"; then
|
||||
log 2 "error getting non-latest version ID"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
get_non_latest_version() {
|
||||
if ! check_param_count_v2 "bucket" $# 1; then
|
||||
return 1
|
||||
@@ -48,3 +59,88 @@ get_non_latest_version() {
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
check_object_versions_before_deletion() {
|
||||
if ! check_param_count_v2 "data file" 1 $#; then
|
||||
return 1
|
||||
fi
|
||||
if ! get_xml_data "$1" "$1.tmp"; then
|
||||
log 2 "error getting XML data"
|
||||
return 1
|
||||
fi
|
||||
if ! parse_versions_rest "$1.tmp"; then
|
||||
log 2 "error parsing versions"
|
||||
return 1
|
||||
fi
|
||||
if [ "${#version_ids[@]}" -ne 1 ]; then
|
||||
log 2 "expected version ID count of 1, was '${#version_ids[@]}'"
|
||||
return 1
|
||||
fi
|
||||
version_id="${version_ids[0]}"
|
||||
log 5 "version ID: $version_id"
|
||||
return 0
|
||||
}
|
||||
|
||||
check_object_versions_after_deletion() {
|
||||
if ! check_param_count_v2 "data file" 1 $#; then
|
||||
return 1
|
||||
fi
|
||||
if ! get_xml_data "$1" "$1.tmp"; then
|
||||
log 2 "error getting XML data"
|
||||
return 1
|
||||
fi
|
||||
if ! parse_versions_rest "$1.tmp"; then
|
||||
log 2 "error parsing versions"
|
||||
return 1
|
||||
fi
|
||||
if [ "${#version_ids[@]}" -ne 2 ]; then
|
||||
log 2 "expected version ID count of 2, was '${#version_ids[@]}'"
|
||||
return 1
|
||||
fi
|
||||
if [ "${version_ids[0]}" != "$version_id" ]; then
|
||||
log 2 "expected version ID of '$version_id', was '${version_ids[0]}'"
|
||||
return 1
|
||||
fi
|
||||
if [ "${version_islatests[0]}" != "false" ]; then
|
||||
log 2 "expected 'IsLatest' of version ID to be false, was '${version_islatests[0]}'"
|
||||
return 1
|
||||
fi
|
||||
if [ "${version_islatests[1]}" != "true" ]; then
|
||||
log 2 "expected 'IsLatest' of delete marker to be true, was '${version_islatests[1]}'"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
list_object_versions_before_and_after_retention_deletion() {
|
||||
if ! check_param_count_v2 "bucket name, file" 2 $#; then
|
||||
return 1
|
||||
fi
|
||||
if ! send_rest_go_command_callback "200" "check_object_versions_before_deletion" \
|
||||
"-method" "GET" "-bucketName" "$1" "-query" "versions="; then
|
||||
log 2 "error checking versions before deletion"
|
||||
return 1
|
||||
fi
|
||||
if ! delete_object_rest "$1" "$2"; then
|
||||
log 2 "error deleting file"
|
||||
return 1
|
||||
fi
|
||||
if ! send_rest_go_command_callback "200" "check_object_versions_after_deletion" \
|
||||
"-method" "GET" "-bucketName" "$1" "-query" "versions="; then
|
||||
log 2 "error checking versions before deletion"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
parse_latest_version_id() {
|
||||
if ! check_param_count_v2 "data file" 1 $#; then
|
||||
return 1
|
||||
fi
|
||||
if ! parse_version_id "$1" "true"; then
|
||||
log 2 "error getting latest version ID"
|
||||
return 1
|
||||
fi
|
||||
log 5 "version ID: $version_id"
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -289,3 +289,31 @@ check_for_header_key_and_value() {
|
||||
log 2 "no header key '$2' found"
|
||||
return 1
|
||||
}
|
||||
|
||||
check_argument_name_and_value() {
|
||||
if ! check_param_count_v2 "data file" 1 $#; then
|
||||
return 1
|
||||
fi
|
||||
if ! check_error_parameter "$1" "ArgumentName" "$argument_name"; then
|
||||
log 2 "error checking 'ArgumentName' parameter"
|
||||
return 1
|
||||
fi
|
||||
if ! check_error_parameter "$1" "ArgumentValue" "$argument_value"; then
|
||||
log 2 "error checking 'ArgumentValue' parameter"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
send_rest_go_command_expect_error_with_arg_name_value() {
|
||||
if ! check_param_count_gt "response code, error code, message, arg name, arg value, params" 5 $#; then
|
||||
return 1
|
||||
fi
|
||||
argument_name=$4
|
||||
argument_value=$5
|
||||
if ! send_rest_go_command_expect_error_callback "$1" "$2" "$3" "check_argument_name_and_value" "${@:6}"; then
|
||||
log 2 "error checking error response values"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ check_for_and_load_test_file_and_params() {
|
||||
iam="folder"
|
||||
fi
|
||||
iam_types+=("$iam")
|
||||
if [ $(( idx % 4 )) -eq 0 ]; then
|
||||
if [ $(( idx % 10 )) -eq 0 ]; then
|
||||
region="us-west-1"
|
||||
else
|
||||
region="us-east-1"
|
||||
|
||||
@@ -34,17 +34,23 @@ omit_content_md5="${OMIT_CONTENT_MD5:=false}"
|
||||
|
||||
payload="<?xml version=\"1.0\" encoding=\"UTF-8\"?>
|
||||
<ObjectLockConfiguration xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\">
|
||||
<ObjectLockEnabled>Enabled</ObjectLockEnabled>"
|
||||
<ObjectLockEnabled>Enabled</ObjectLockEnabled>"
|
||||
if [ "$retention_rule" != "false" ]; then
|
||||
payload+="<Rule>
|
||||
<DefaultRetention>
|
||||
<Days>$retention_days<Days>
|
||||
<Mode>$retention_mode</Mode>
|
||||
<Years>$retention_years</Years>
|
||||
</DefaultRetention>
|
||||
payload+="
|
||||
<Rule>
|
||||
<DefaultRetention>"
|
||||
if [ "$retention_days" != "" ]; then
|
||||
payload+="<Days>$retention_days</Days>"
|
||||
fi
|
||||
payload+="<Mode>$retention_mode</Mode>"
|
||||
if [ "$retention_years" != "" ]; then
|
||||
payload+="<Years>$retention_years</Years>"
|
||||
fi
|
||||
payload+="</DefaultRetention>
|
||||
</Rule>"
|
||||
fi
|
||||
payload+="</ObjectLockConfiguration>"
|
||||
payload+="
|
||||
</ObjectLockConfiguration>"
|
||||
|
||||
payload_hash="$(echo -n "$payload" | sha256sum | awk '{print $1}')"
|
||||
if [ "$omit_content_md5" == "false" ]; then
|
||||
|
||||
@@ -19,6 +19,8 @@ load ./bats-assert/load
|
||||
|
||||
source ./tests/setup.sh
|
||||
source ./tests/drivers/create_bucket/create_bucket_rest.sh
|
||||
source ./tests/drivers/list_object_versions/list_object_versions_rest.sh
|
||||
source ./tests/util/util_time.sh
|
||||
|
||||
@test "ListObjectVersions - accidental query of versions on object returns correct error" {
|
||||
if [ "$DIRECT" != "true" ]; then
|
||||
@@ -36,4 +38,36 @@ source ./tests/drivers/create_bucket/create_bucket_rest.sh
|
||||
run send_rest_go_command_expect_error "400" "InvalidRequest" "There is no such thing as the ?versions sub-resource for a key" \
|
||||
"-bucketName" "$bucket_name" "-objectKey" "$test_file" "-query" "versions="
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "ListObjectVersions - version changes after deletion w/retention policy" {
|
||||
if [ "$DIRECT" != "true" ]; then
|
||||
skip "https://github.com/versity/versitygw/issues/1741"
|
||||
fi
|
||||
test_file="test_file"
|
||||
|
||||
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_bucket_versioning_rest "$bucket_name" "Enabled"
|
||||
assert_success
|
||||
|
||||
run put_object_lock_configuration_rest "$bucket_name" ""
|
||||
assert_success
|
||||
|
||||
run get_time_seconds_in_future 30
|
||||
assert_success
|
||||
later_date=${output}Z
|
||||
|
||||
run send_rest_go_command "200" \
|
||||
"-bucketName" "$bucket_name" "-objectKey" "$test_file" "-payloadFile" "$TEST_FILE_FOLDER/$test_file" \
|
||||
"-method" "PUT" "-contentMD5" "-signedParams" "x-amz-object-lock-mode:GOVERNANCE,x-amz-object-lock-retain-until-date:$later_date"
|
||||
assert_success
|
||||
|
||||
run list_object_versions_before_and_after_retention_deletion "$bucket_name" "$test_file"
|
||||
assert_success
|
||||
}
|
||||
Executable
+34
@@ -0,0 +1,34 @@
|
||||
#!/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 - PutBucketVersioning - empty payload" {
|
||||
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" "MissingRequestBodyError" "Request Body is empty" \
|
||||
"-bucketName" "$bucket_name" "-method" "PUT" "-query" "versioning="
|
||||
assert_success
|
||||
}
|
||||
@@ -21,8 +21,10 @@ source ./tests/setup.sh
|
||||
source ./tests/drivers/file.sh
|
||||
source ./tests/drivers/create_bucket/create_bucket_rest.sh
|
||||
source ./tests/drivers/head_object/head_object_rest.sh
|
||||
source ./tests/drivers/list_object_versions/list_object_versions_rest.sh
|
||||
source ./tests/drivers/put_object/put_object_rest.sh
|
||||
source ./tests/util/util_public_access_block.sh
|
||||
source ./tests/util/util_time.sh
|
||||
|
||||
test_file="test_file"
|
||||
export RUN_USERS=true
|
||||
@@ -462,3 +464,102 @@ export RUN_USERS=true
|
||||
run head_object_check_header_key_and_value "$bucket_name" "$test_file" "Content-Disposition" "dummy"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "REST - PutObject - x-amz-object-lock-retain-until-date - invalid format" {
|
||||
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_rest_go_command_expect_error "400" "InvalidArgument" "must be provided in ISO 8601 format" "-bucketName" "$bucket_name" \
|
||||
"-objectKey" "$test_file" "-payloadFile" "$TEST_FILE_FOLDER/$test_file" \
|
||||
"-method" "PUT" "-contentMD5" "-signedParams" "x-amz-object-lock-mode:abc,x-amz-object-lock-retain-until-date:abc"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "REST - PutObject - x-amz-object-lock-retain-until-date - earlier date" {
|
||||
if [ "$DIRECT" != "true" ]; then
|
||||
skip "https://github.com/versity/versitygw/issues/1734"
|
||||
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
|
||||
|
||||
earlier_date="2025-12-25T12:00:00Z"
|
||||
run send_rest_go_command_expect_error_with_arg_name_value "400" "InvalidArgument" "must be in the future" \
|
||||
"x-amz-object-lock-retain-until-date" "$earlier_date" "-bucketName" "$bucket_name" "-objectKey" "$test_file" "-payloadFile" "$TEST_FILE_FOLDER/$test_file" \
|
||||
"-method" "PUT" "-contentMD5" "-signedParams" "x-amz-object-lock-mode:abc,x-amz-object-lock-retain-until-date:$earlier_date"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "REST - PutObject - x-amz-object-lock-mode - invalid mode" {
|
||||
if [ "$DIRECT" != "true" ]; then
|
||||
skip "https://github.com/versity/versitygw/issues/1736"
|
||||
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 get_time_seconds_in_future 10
|
||||
assert_success
|
||||
later_date=${output}Z
|
||||
|
||||
lock_mode="abc"
|
||||
run send_rest_go_command_expect_error_with_arg_name_value "400" "InvalidArgument" "Unknown wormMode directive" \
|
||||
"x-amz-object-lock-mode" "$lock_mode" "-bucketName" "$bucket_name" "-objectKey" "$test_file" "-payloadFile" "$TEST_FILE_FOLDER/$test_file" \
|
||||
"-method" "PUT" "-contentMD5" "-signedParams" "x-amz-object-lock-mode:$lock_mode,x-amz-object-lock-retain-until-date:$later_date"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "TEST - REST - PutObject - not allowed without content-MD5 with lock configuration" {
|
||||
if [ "$DIRECT" != "true" ]; then
|
||||
skip "https://github.com/versity/versitygw/issues/1740"
|
||||
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_bucket_versioning_rest "$bucket_name" "Enabled"
|
||||
assert_success
|
||||
|
||||
run put_object_lock_configuration_rest "$bucket_name" "RETENTION_MODE=GOVERNANCE RETENTION_RULE=true RETENTION_DAYS=1"
|
||||
assert_success
|
||||
|
||||
run send_rest_go_command_expect_error "400" "InvalidRequest" "is required for Put Object requests with Object Lock parameters" \
|
||||
"-bucketName" "$bucket_name" "-objectKey" "$test_file" "-payloadFile" "$TEST_FILE_FOLDER/$test_file" \
|
||||
"-method" "PUT"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "REST - PutObject - object lock - success" {
|
||||
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_bucket_versioning_rest "$bucket_name" "Enabled"
|
||||
assert_success
|
||||
|
||||
run put_object_lock_configuration_rest "$bucket_name" ""
|
||||
assert_success
|
||||
|
||||
run get_time_seconds_in_future 15
|
||||
assert_success
|
||||
later_date=${output}Z
|
||||
|
||||
run put_object_with_lock_mode_and_delete_latest_version "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file" "$later_date"
|
||||
assert_success
|
||||
}
|
||||
|
||||
Executable
+73
@@ -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/drivers/create_bucket/create_bucket_rest.sh
|
||||
|
||||
@test "REST - PutObjectLockConfig - missing payload" {
|
||||
run get_bucket_name "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
bucket_name="$output"
|
||||
|
||||
run setup_bucket_v2 "$bucket_name"
|
||||
assert_success
|
||||
|
||||
run put_bucket_versioning_rest "$bucket_name" "Enabled"
|
||||
assert_success
|
||||
|
||||
run send_rest_go_command_expect_error "400" "MissingRequestBodyError" "Request Body is empty" \
|
||||
"-bucketName" "$bucket_name" "-method" "PUT" "-query" "object-lock=" "-contentMD5"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "REST - PutObjectLockConfig - zero day config, correct error code" {
|
||||
run get_bucket_name "$BUCKET_ONE_NAME"
|
||||
assert_success
|
||||
bucket_name="$output"
|
||||
|
||||
run setup_bucket_v2 "$bucket_name"
|
||||
assert_success
|
||||
|
||||
run put_bucket_versioning_rest "$bucket_name" "Enabled"
|
||||
assert_success
|
||||
|
||||
run put_object_lock_configuration_rest_expect_error "$bucket_name" "RETENTION_MODE=GOVERNANCE RETENTION_RULE=true \
|
||||
RETENTION_DAYS=0" "400" "InvalidArgument" "Default retention period must be a positive integer value"
|
||||
assert_success
|
||||
}
|
||||
|
||||
@test "REST - PutObjectLockConfig - default retention period works" {
|
||||
test_file="test_file"
|
||||
|
||||
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_bucket_versioning_rest "$bucket_name" "Enabled"
|
||||
assert_success
|
||||
|
||||
run put_object_lock_configuration_rest "$bucket_name" "RETENTION_MODE=GOVERNANCE RETENTION_RULE=true RETENTION_DAYS=1"
|
||||
assert_success
|
||||
|
||||
run attempt_to_delete_version_after_retention_policy "$TEST_FILE_FOLDER/$test_file" "$bucket_name" "$test_file"
|
||||
assert_success
|
||||
}
|
||||
@@ -23,28 +23,6 @@ check_if_versioning_enabled() {
|
||||
return 1
|
||||
}
|
||||
|
||||
parse_version_data_by_type() {
|
||||
if ! check_param_count "parse_version_data_by_type" "client, data" 2 $#; then
|
||||
return 1
|
||||
fi
|
||||
if [ "$1" == "rest" ]; then
|
||||
log 5 "version data: $versions"
|
||||
if ! parse_versions_rest "$versions"; then
|
||||
log 2 "error parsing REST object versions"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
if ! parse_version_data "$versions" '.Versions[]'; then
|
||||
log 2 "error parsing Versions elements"
|
||||
return 1
|
||||
fi
|
||||
if ! parse_version_data "$versions" '.DeleteMarkers[]'; then
|
||||
log 2 "error getting DeleteMarkers elements"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
parse_version_data() {
|
||||
if ! check_param_count "parse_version_data" "raw data, element name" 2 $#; then
|
||||
return 1
|
||||
@@ -102,10 +80,10 @@ check_versioning_status_rest() {
|
||||
}
|
||||
|
||||
echo_versions() {
|
||||
if ! check_param_count_v2 "'Version' or 'DeleteMarker', 'Key' or 'VersionId', file" 3 $#; then
|
||||
if ! check_param_count_v2 "'Version' or 'DeleteMarker', 'Key' or 'VersionId' or 'IsLatest', file" 3 $#; then
|
||||
return 1
|
||||
fi
|
||||
if ! keys=$(echo -n "$versions" | xmllint --xpath "//*[local-name()=\"$1\"]/*[local-name()=\"$2\"]/text()" - | xmlstarlet unesc 2>&1); then
|
||||
if ! keys=$(xmllint --xpath "//*[local-name()=\"$1\"]/*[local-name()=\"$2\"]/text()" "$3" | xmlstarlet unesc 2>&1); then
|
||||
if [[ "$keys" == *"XPath set is empty"* ]]; then
|
||||
return 0
|
||||
fi
|
||||
@@ -113,12 +91,6 @@ echo_versions() {
|
||||
return 1
|
||||
fi
|
||||
log 5 "keys to append: ${keys[*]}"
|
||||
if ! result=$(truncate -s 0 "$3" 2>&1); then
|
||||
log 2 "error truncating file: $result"
|
||||
fi
|
||||
for key in "${keys[@]}"; do
|
||||
echo "$key" >> "$3"
|
||||
done
|
||||
echo "${keys[*]}"
|
||||
}
|
||||
|
||||
@@ -151,31 +123,50 @@ parse_base64_versions_rest() {
|
||||
}
|
||||
|
||||
parse_versions_rest() {
|
||||
if ! check_param_count_v2 "data file" 1 $#; then
|
||||
return 1
|
||||
fi
|
||||
log 5 "versions file: $(cat "$1")"
|
||||
base64_pairs=()
|
||||
if ! keys=$(echo_versions "Version" "Key" "$TEST_FILE_FOLDER/version_keys.txt"); then
|
||||
version_keys=()
|
||||
version_ids=()
|
||||
version_islatests=()
|
||||
if ! keys=$(echo_versions "Version" "Key" "$1"); then
|
||||
log 2 "error getting Version Key values: $keys"
|
||||
return 1
|
||||
fi
|
||||
# shellcheck disable=SC2206
|
||||
version_keys+=($keys)
|
||||
if ! ids=$(echo_versions "Version" "VersionId" "$TEST_FILE_FOLDER/version_ids.txt"); then
|
||||
if ! ids=$(echo_versions "Version" "VersionId" "$1"); then
|
||||
log 2 "error getting Version VersionId values: $ids"
|
||||
return 1
|
||||
fi
|
||||
# shellcheck disable=SC2206
|
||||
version_ids+=($ids)
|
||||
if ! keys=$(echo_versions "DeleteMarker" "Key" "$TEST_FILE_FOLDER/delete_marker_keys.txt"); then
|
||||
if ! is_latest=$(echo_versions "Version" "IsLatest" "$1"); then
|
||||
log 2 "error getting Version IsLatest values: $is_latest"
|
||||
return 1
|
||||
fi
|
||||
# shellcheck disable=SC2206
|
||||
version_islatests+=($is_latest)
|
||||
if ! keys=$(echo_versions "DeleteMarker" "Key" "$1"); then
|
||||
log 2 "error getting DeleteMarker Key values: $keys"
|
||||
return 1
|
||||
fi
|
||||
# shellcheck disable=SC2206
|
||||
version_keys+=($keys)
|
||||
if ! ids=$(echo_versions "DeleteMarker" "VersionId" "$TEST_FILE_FOLDER/delete_marker_ids.txt"); then
|
||||
if ! ids=$(echo_versions "DeleteMarker" "VersionId" "$1"); then
|
||||
log 2 "error getting DeleteMarker VersionId values: $ids"
|
||||
return 1
|
||||
fi
|
||||
# shellcheck disable=SC2206
|
||||
version_ids+=($ids)
|
||||
if ! is_latest=$(echo_versions "DeleteMarker" "IsLatest" "$1"); then
|
||||
log 2 "error getting DeleteMarker IsLatest values: $is_latest"
|
||||
return 1
|
||||
fi
|
||||
# shellcheck disable=SC2206
|
||||
version_islatests+=($is_latest)
|
||||
log 5 "version keys: ${version_keys[*]}"
|
||||
log 5 "version IDs: ${version_ids[*]}"
|
||||
log 5 "base64 pairs: ${base64_pairs[*]}"
|
||||
|
||||
Reference in New Issue
Block a user