1#!/bin/bash 2# 3# Copyright (c) 2015-2021 MinIO, Inc. 4# 5# This file is part of MinIO Object Storage stack 6# 7# This program is free software: you can redistribute it and/or modify 8# it under the terms of the GNU Affero General Public License as published by 9# the Free Software Foundation, either version 3 of the License, or 10# (at your option) any later version. 11# 12# This program is distributed in the hope that it will be useful 13# but WITHOUT ANY WARRANTY; without even the implied warranty of 14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15# GNU Affero General Public License for more details. 16# 17# You should have received a copy of the GNU Affero General Public License 18# along with this program. If not, see <http://www.gnu.org/licenses/>. 19# 20 21################################################################################ 22# 23# This script is usable by mc functional tests, mint tests and MinIO verification 24# tests. 25# 26# * As mc functional tests, just run this script. It uses mc executable binary 27# in current working directory or in the path. The tests uses play.min.io 28# as MinIO server. 29# 30# * For other, call this script with environment variables MINT_MODE, 31# MINT_DATA_DIR, SERVER_ENDPOINT, ACCESS_KEY, SECRET_KEY and ENABLE_HTTPS. It 32# uses mc executable binary in current working directory and uses given MinIO 33# server to run tests. MINT_MODE is set by mint to specify what category of 34# tests to run. 35# 36################################################################################ 37 38# Force bytewise sorting for CLI tools 39LANG=C 40 41if [ -n "$MINT_MODE" ]; then 42 if [ -z "${MINT_DATA_DIR+x}" ]; then 43 echo "MINT_DATA_DIR not defined" 44 exit 1 45 fi 46 if [ -z "${SERVER_ENDPOINT+x}" ]; then 47 echo "SERVER_ENDPOINT not defined" 48 exit 1 49 fi 50 if [ -z "${ACCESS_KEY+x}" ]; then 51 echo "ACCESS_KEY not defined" 52 exit 1 53 fi 54 if [ -z "${SECRET_KEY+x}" ]; then 55 echo "SECRET_KEY not defined" 56 exit 1 57 fi 58fi 59 60if [ -z "${SERVER_ENDPOINT+x}" ]; then 61 SERVER_ENDPOINT="play.min.io" 62 ACCESS_KEY="Q3AM3UQ867SPQQA43P2F" 63 SECRET_KEY="zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG" 64 ENABLE_HTTPS=1 65fi 66 67WORK_DIR="$PWD" 68DATA_DIR="$MINT_DATA_DIR" 69if [ -z "$MINT_MODE" ]; then 70 WORK_DIR="$PWD/.run-$RANDOM" 71 DATA_DIR="$WORK_DIR/data" 72fi 73 74FILE_0_B="$DATA_DIR/datafile-0-b" 75FILE_1_MB="$DATA_DIR/datafile-1-MB" 76FILE_65_MB="$DATA_DIR/datafile-65-MB" 77declare FILE_0_B_MD5SUM 78declare FILE_1_MB_MD5SUM 79declare FILE_65_MB_MD5SUM 80 81ENDPOINT="https://$SERVER_ENDPOINT" 82if [ "$ENABLE_HTTPS" != "1" ]; then 83 ENDPOINT="http://$SERVER_ENDPOINT" 84fi 85 86SERVER_ALIAS="myminio" 87SERVER_ALIAS_TLS="myminio-ssl" 88 89BUCKET_NAME="mc-test-bucket-$RANDOM" 90WATCH_OUT_FILE="$WORK_DIR/watch.out-$RANDOM" 91 92MC_CONFIG_DIR="/tmp/.mc-$RANDOM" 93MC="$PWD/mc" 94declare -a MC_CMD 95 96function get_md5sum() 97{ 98 filename="$1" 99 out=$(md5sum "$filename" 2>/dev/null) 100 rv=$? 101 if [ "$rv" -eq 0 ]; then 102 echo $(awk '{ print $1 }' <<< "$out") 103 fi 104 105 return "$rv" 106} 107 108function get_time() 109{ 110 date +%s%N 111} 112 113function get_duration() 114{ 115 start_time=$1 116 end_time=$(get_time) 117 118 echo $(( (end_time - start_time) / 1000000 )) 119} 120 121function log_success() 122{ 123 if [ -n "$MINT_MODE" ]; then 124 printf '{"name": "mc", "duration": "%d", "function": "%s", "status": "PASS"}\n' "$(get_duration "$1")" "$2" 125 fi 126} 127 128function show() 129{ 130 if [ -z "$MINT_MODE" ]; then 131 func_name="$1" 132 echo "Running $func_name()" 133 fi 134} 135 136function show_on_success() 137{ 138 rv="$1" 139 shift 140 141 if [ "$rv" -eq 0 ]; then 142 echo "$@" 143 fi 144 145 return "$rv" 146} 147 148function show_on_failure() 149{ 150 rv="$1" 151 shift 152 153 if [ "$rv" -ne 0 ]; then 154 echo "$@" 155 fi 156 157 return "$rv" 158} 159 160function assert() 161{ 162 expected_rv="$1" 163 shift 164 start_time="$1" 165 shift 166 func_name="$1" 167 shift 168 169 err=$("$@") 170 rv=$? 171 if [ "$rv" -ne "$expected_rv" ]; then 172 if [ -n "$MINT_MODE" ]; then 173 err=$(printf "$err" | python -c 'import sys,json; print(json.dumps(sys.stdin.read()))') 174 ## err is already JSON string, no need to double quote 175 printf '{"name": "mc", "duration": "%d", "function": "%s", "status": "FAIL", "error": %s}\n' "$(get_duration "$start_time")" "$func_name" "$err" 176 else 177 echo "mc: $func_name: $err" 178 fi 179 180 if [ "$rv" -eq 0 ]; then 181 exit 1 182 fi 183 184 exit "$rv" 185 fi 186 187 return 0 188} 189 190function assert_success() { 191 assert 0 "$@" 192} 193 194function assert_failure() { 195 assert 1 "$@" 196} 197 198function mc_cmd() 199{ 200 cmd=( "${MC_CMD[@]}" "$@" ) 201 err_file="$WORK_DIR/cmd.out.$RANDOM" 202 203 "${cmd[@]}" >"$err_file" 2>&1 204 rv=$? 205 if [ "$rv" -ne 0 ]; then 206 printf '%q ' "${cmd[@]}" 207 echo " >>> " 208 cat "$err_file" 209 fi 210 211 rm -f "$err_file" 212 return "$rv" 213} 214 215function check_md5sum() 216{ 217 expected_checksum="$1" 218 shift 219 filename="$@" 220 221 checksum="$(get_md5sum "$filename")" 222 rv=$? 223 if [ "$rv" -ne 0 ]; then 224 echo "unable to get md5sum for $filename" 225 return "$rv" 226 fi 227 228 if [ "$checksum" != "$expected_checksum" ]; then 229 echo "$filename: md5sum mismatch" 230 return 1 231 fi 232 233 return 0 234} 235 236function test_make_bucket() 237{ 238 show "${FUNCNAME[0]}" 239 240 start_time=$(get_time) 241 bucket_name="mc-test-bucket-$RANDOM" 242 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd mb "${SERVER_ALIAS}/${bucket_name}" 243 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rb "${SERVER_ALIAS}/${bucket_name}" 244 245 log_success "$start_time" "${FUNCNAME[0]}" 246} 247 248function test_make_bucket_error() { 249 show "${FUNCNAME[0]}" 250 251 start_time=$(get_time) 252 bucket_name="MC-test%bucket%$RANDOM" 253 assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd mb "${SERVER_ALIAS}/${bucket_name}" 254 255 log_success "$start_time" "${FUNCNAME[0]}" 256} 257 258function test_rb() 259{ 260 show "${FUNCNAME[0]}" 261 262 start_time=$(get_time) 263 bucket1="mc-test-bucket-$RANDOM-1" 264 bucket2="mc-test-bucket-$RANDOM-2" 265 object_name="mc-test-object-$RANDOM" 266 267 # Tets rb when the bucket is empty 268 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd mb "${SERVER_ALIAS}/${bucket1}" 269 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rb "${SERVER_ALIAS}/${bucket1}" 270 271 # Test rb with --force flag when the bucket is not empty 272 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd mb "${SERVER_ALIAS}/${bucket1}" 273 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "${FILE_1_MB}" "${SERVER_ALIAS}/${bucket1}/${object_name}" 274 assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd rb "${SERVER_ALIAS}/${bucket1}" 275 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rb --force "${SERVER_ALIAS}/${bucket1}" 276 277 # Test rb with --force and --dangerous to remove a site content 278 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd mb "${SERVER_ALIAS}/${bucket1}" 279 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd mb "${SERVER_ALIAS}/${bucket2}" 280 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "${FILE_1_MB}" "${SERVER_ALIAS}/${bucket1}/${object_name}" 281 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "${FILE_1_MB}" "${SERVER_ALIAS}/${bucket2}/${object_name}" 282 assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd rb --force "${SERVER_ALIAS}/" 283 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rb --force --dangerous "${SERVER_ALIAS}" 284 285 log_success "$start_time" "${FUNCNAME[0]}" 286} 287 288function setup() 289{ 290 start_time=$(get_time) 291 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd mb "${SERVER_ALIAS}/${BUCKET_NAME}" 292} 293 294function teardown() 295{ 296 start_time=$(get_time) 297 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rb --force "${SERVER_ALIAS}/${BUCKET_NAME}" 298} 299 300function test_put_object() 301{ 302 show "${FUNCNAME[0]}" 303 304 start_time=$(get_time) 305 object_name="mc-test-object-$RANDOM" 306 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 307 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 308 309 log_success "$start_time" "${FUNCNAME[0]}" 310} 311 312function test_put_object_error() 313{ 314 show "${FUNCNAME[0]}" 315 start_time=$(get_time) 316 317 object_long_name=$(printf "mc-test-object-%01100d" 1) 318 assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd cp "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_long_name}" 319 320 log_success "$start_time" "${FUNCNAME[0]}" 321} 322 323function test_put_object_multipart() 324{ 325 show "${FUNCNAME[0]}" 326 327 start_time=$(get_time) 328 object_name="mc-test-object-$RANDOM" 329 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "${FILE_65_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 330 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 331 332 log_success "$start_time" "${FUNCNAME[0]}" 333} 334 335function test_put_object_0byte() 336{ 337 show "${FUNCNAME[0]}" 338 339 start_time=$(get_time) 340 object_name="mc-test-object-$RANDOM" 341 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "${FILE_0_B}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 342 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" "${object_name}.downloaded" 343 assert_success "$start_time" "${FUNCNAME[0]}" check_md5sum "$FILE_0_B_MD5SUM" "${object_name}.downloaded" 344 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${object_name}.downloaded" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 345 346 log_success "$start_time" "${FUNCNAME[0]}" 347} 348 349## Test mc cp command with storage-class flag set 350function test_put_object_with_storage_class() 351{ 352 show "${FUNCNAME[0]}" 353 354 start_time=$(get_time) 355 object_name="mc-test-object-$RANDOM" 356 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp --storage-class REDUCED_REDUNDANCY "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 357 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 358 359 log_success "$start_time" "${FUNCNAME[0]}" 360} 361 362## Test mc cp command with storage-class flag set to incorrect value 363function test_put_object_with_storage_class_error() 364{ 365 show "${FUNCNAME[0]}" 366 367 start_time=$(get_time) 368 object_name="mc-test-object-$RANDOM" 369 assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd cp --storage-class REDUCED "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 370 371 log_success "$start_time" "${FUNCNAME[0]}" 372} 373 374## Test mc cp command with valid metadata string 375function test_put_object_with_metadata() 376{ 377 show "${FUNCNAME[0]}" 378 379 start_time=$(get_time) 380 object_name="mc-test-object-$RANDOM" 381 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp --attr key1=val1\;key2=val2 "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 382 diff -bB <(echo "val1") <("${MC_CMD[@]}" --json stat "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" | jq -r '.metadata."X-Amz-Meta-Key1"') >/dev/null 2>&1 383 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "unable to put object with metadata" 384 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 385 log_success "$start_time" "${FUNCNAME[0]}" 386 387} 388 389function test_get_object() 390{ 391 show "${FUNCNAME[0]}" 392 393 start_time=$(get_time) 394 object_name="mc-test-object-$RANDOM" 395 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 396 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" "${object_name}.downloaded" 397 assert_success "$start_time" "${FUNCNAME[0]}" check_md5sum "$FILE_1_MB_MD5SUM" "${object_name}.downloaded" 398 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${object_name}.downloaded" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 399 400 log_success "$start_time" "${FUNCNAME[0]}" 401} 402 403function test_get_object_multipart() 404{ 405 show "${FUNCNAME[0]}" 406 407 start_time=$(get_time) 408 object_name="mc-test-object-$RANDOM" 409 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "${FILE_65_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 410 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" "${object_name}.downloaded" 411 assert_success "$start_time" "${FUNCNAME[0]}" check_md5sum "$FILE_65_MB_MD5SUM" "${object_name}.downloaded" 412 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${object_name}.downloaded" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 413 414 log_success "$start_time" "${FUNCNAME[0]}" 415} 416 417function test_presigned_post_policy_error() 418{ 419 show "${FUNCNAME[0]}" 420 421 start_time=$(get_time) 422 object_name="mc-test-object-$RANDOM" 423 424 out=$("${MC_CMD[@]}" --json share upload "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}") 425 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "unable to get presigned post policy and put object url" 426 427 # Support IPv6 address, IPv6 is specifed as [host]:9000 form, we should 428 # replace '['']' with their escaped values as '\[' '\]'. 429 # 430 # Without escaping '['']', 'sed' command interprets them as expressions 431 # which fails our requirement of replacing $endpoint/$bucket URLs in the 432 # subsequent operations. 433 endpoint=$(echo "$ENDPOINT" | sed 's|[][]|\\&|g') 434 435 # Extract share field of json output, and append object name to the URL 436 upload=$(echo "$out" | jq -r .share | sed "s|<FILE>|$FILE_1_MB|g" | sed "s|curl|curl -sSg|g" | sed "s|${endpoint}/${BUCKET_NAME}/|${endpoint}/${BUCKET_NAME}/${object_name}|g") 437 438 # In case of virtual host style URL path, the previous replace would have failed. 439 # One of the following two commands will append the object name in that scenario. 440 upload=$(echo "$upload" | sed "s|http://${BUCKET_NAME}.${SERVER_ENDPOINT}/|http://${BUCKET_NAME}.${SERVER_ENDPOINT}/${object_name}|g") 441 upload=$(echo "$upload" | sed "s|https://${BUCKET_NAME}.${SERVER_ENDPOINT}/|https://${BUCKET_NAME}.${SERVER_ENDPOINT}/${object_name}|g") 442 443 ret=$($upload 2>&1 | grep -oP '(?<=Code>)[^<]+') 444 # Check if the command execution failed. 445 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "unknown failure in upload of $FILE_1_MB using presigned post policy" 446 if [ -z "$ret" ]; then 447 448 # Check if the upload succeeded. We expect it to fail. 449 assert_failure "$start_time" "${FUNCNAME[0]}" show_on_success 0 "upload of $FILE_1_MB using presigned post policy should have failed" 450 fi 451 452 if [ "$ret" != "MethodNotAllowed" ]; then 453 assert_failure "$start_time" "${FUNCNAME[0]}" show_on_success 0 "upload of $FILE_1_MB using presigned post policy should have failed with MethodNotAllowed error, instead failed with $ret error" 454 fi 455 log_success "$start_time" "${FUNCNAME[0]}" 456} 457 458function test_presigned_put_object() 459{ 460 show "${FUNCNAME[0]}" 461 462 start_time=$(get_time) 463 object_name="mc-test-object-$RANDOM" 464 465 out=$("${MC_CMD[@]}" --json share upload "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}") 466 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "unable to get presigned put object url" 467 upload=$(echo "$out" | jq -r .share | sed "s|<FILE>|$FILE_1_MB|g" | sed "s|curl|curl -sSg|g") 468 $upload >/dev/null 2>&1 469 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "unable to upload $FILE_1_MB presigned put object url" 470 471 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" "${object_name}.downloaded" 472 assert_success "$start_time" "${FUNCNAME[0]}" check_md5sum "$FILE_1_MB_MD5SUM" "${object_name}.downloaded" 473 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${object_name}.downloaded" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 474 475 log_success "$start_time" "${FUNCNAME[0]}" 476} 477 478function test_presigned_get_object() 479{ 480 show "${FUNCNAME[0]}" 481 482 start_time=$(get_time) 483 object_name="mc-test-object-$RANDOM" 484 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 485 486 out=$("${MC_CMD[@]}" --json share download "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}") 487 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "unable to get presigned get object url" 488 download_url=$(echo "$out" | jq -r .share) 489 curl -sSg --output "${object_name}.downloaded" -X GET "$download_url" 490 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "unable to download $download_url" 491 492 assert_success "$start_time" "${FUNCNAME[0]}" check_md5sum "$FILE_1_MB_MD5SUM" "${object_name}.downloaded" 493 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${object_name}.downloaded" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 494 495 log_success "$start_time" "${FUNCNAME[0]}" 496} 497 498function test_cat_object() 499{ 500 show "${FUNCNAME[0]}" 501 502 start_time=$(get_time) 503 object_name="mc-test-object-$RANDOM" 504 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 505 "${MC_CMD[@]}" cat "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" > "${object_name}.downloaded" 506 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "unable to download object using 'mc cat'" 507 assert_success "$start_time" "${FUNCNAME[0]}" check_md5sum "$FILE_1_MB_MD5SUM" "${object_name}.downloaded" 508 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${object_name}.downloaded" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 509 510 log_success "$start_time" "${FUNCNAME[0]}" 511} 512 513function test_cat_stdin() 514{ 515 show "${FUNCNAME[0]}" 516 517 start_time=$(get_time) 518 object_name="mc-test-object-$RANDOM" 519 echo "testcontent" | "${MC_CMD[@]}" cat > stdin.output 520 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "unable to redirect stdin to stdout using 'mc cat'" 521 assert_success "$start_time" "${FUNCNAME[0]}" check_md5sum "42ed9fb3563d8e9c7bb522be443033f4" stdin.output 522 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm stdin.output 523 524 log_success "$start_time" "${FUNCNAME[0]}" 525} 526 527 528function test_mirror_list_objects() 529{ 530 show "${FUNCNAME[0]}" 531 532 start_time=$(get_time) 533 bucket_name="mc-test-bucket-$RANDOM" 534 object_name="mc-test-object-$RANDOM" 535 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd mb "${SERVER_ALIAS}/${bucket_name}" 536 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd mirror "$DATA_DIR" "${SERVER_ALIAS}/${bucket_name}" 537 538 diff -bB <(ls "$DATA_DIR") <("${MC_CMD[@]}" --json ls "${SERVER_ALIAS}/${bucket_name}/" | jq -r .key) >/dev/null 2>&1 539 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "mirror and list differs" 540 541 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rb --force "${SERVER_ALIAS}/${bucket_name}" 542 543 log_success "$start_time" "${FUNCNAME[0]}" 544} 545 546## Tests mc mirror command with --storage-class flag set 547function test_mirror_list_objects_storage_class() 548{ 549 show "${FUNCNAME[0]}" 550 551 start_time=$(get_time) 552 bucket_name="mc-test-bucket-$RANDOM" 553 object_name="mc-test-object-$RANDOM" 554 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd mb "${SERVER_ALIAS}/${bucket_name}" 555 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd mirror --storage-class REDUCED_REDUNDANCY "$DATA_DIR" "${SERVER_ALIAS}/${bucket_name}" 556 557 diff -bB <(ls "$DATA_DIR") <("${MC_CMD[@]}" --json ls "${SERVER_ALIAS}/${bucket_name}/" | jq -r .key) >/dev/null 2>&1 558 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "mirror and list differs" 559 560 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rb --force "${SERVER_ALIAS}/${bucket_name}" 561 562 log_success "$start_time" "${FUNCNAME[0]}" 563} 564 565## Tests find command with --older-than set to 1day, should be empty. 566function test_find_empty() { 567 show "${FUNCNAME[0]}" 568 569 start_time=$(get_time) 570 bucket_name="mc-test-bucket-$RANDOM" 571 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd mb "${SERVER_ALIAS}/${bucket_name}" 572 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd mirror "$DATA_DIR" "${SERVER_ALIAS}/${bucket_name}" 573 574 # find --older-than 1 day should be empty, so we compare with empty string. 575 diff -bB <(echo "") <("${MC_CMD[@]}" find "${SERVER_ALIAS}/${bucket_name}" --json --older-than 1d | jq -r .key | sed "s/${SERVER_ALIAS}\/${bucket_name}\///g") >/dev/null 2>&1 576 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "mirror and list differs" 577 578 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rb --force "${SERVER_ALIAS}/${bucket_name}" 579 580 log_success "$start_time" "${FUNCNAME[0]}" 581} 582 583## Tests find command, should list. 584function test_find() { 585 show "${FUNCNAME[0]}" 586 587 start_time=$(get_time) 588 bucket_name="mc-test-bucket-$RANDOM" 589 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd mb "${SERVER_ALIAS}/${bucket_name}" 590 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd mirror "$DATA_DIR" "${SERVER_ALIAS}/${bucket_name}" 591 592 diff -bB <(ls "$DATA_DIR") <("${MC_CMD[@]}" --json find "${SERVER_ALIAS}/${bucket_name}/" | jq -r .key | sed "s/${SERVER_ALIAS}\/${bucket_name}\///g") >/dev/null 2>&1 593 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "mirror and list differs" 594 595 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rb --force "${SERVER_ALIAS}/${bucket_name}" 596 597 log_success "$start_time" "${FUNCNAME[0]}" 598} 599 600function test_watch_object() 601{ 602 show "${FUNCNAME[0]}" 603 604 start_time=$(get_time) 605 bucket_name="mc-test-bucket-$RANDOM" 606 object_name="mc-test-object-$RANDOM" 607 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd mb "${SERVER_ALIAS}/${bucket_name}" 608 609 # start a process to watch on bucket 610 "${MC_CMD[@]}" --json watch "${SERVER_ALIAS}/${bucket_name}" > "$WATCH_OUT_FILE" & 611 watch_cmd_pid=$! 612 sleep 1 613 614 ( assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "${FILE_1_MB}" "${SERVER_ALIAS}/${bucket_name}/${object_name}" ) 615 rv=$? 616 if [ "$rv" -ne 0 ]; then 617 kill "$watch_cmd_pid" 618 exit "$rv" 619 fi 620 621 sleep 1 622 if ! jq -r .events.type "$WATCH_OUT_FILE" | grep -qi ObjectCreated; then 623 kill "$watch_cmd_pid" 624 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure 1 "ObjectCreated event not found" 625 fi 626 627 ( assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${SERVER_ALIAS}/${bucket_name}/${object_name}" ) 628 rv=$? 629 if [ "$rv" -ne 0 ]; then 630 kill "$watch_cmd_pid" 631 exit "$rv" 632 fi 633 634 sleep 1 635 if ! jq -r .events.type "$WATCH_OUT_FILE" | grep -qi ObjectRemoved; then 636 kill "$watch_cmd_pid" 637 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure 1 "ObjectRemoved event not found" 638 fi 639 640 kill "$watch_cmd_pid" 641 642 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rb --force "${SERVER_ALIAS}/${bucket_name}" 643 644 log_success "$start_time" "${FUNCNAME[0]}" 645} 646 647 648function test_config_host_add() 649{ 650 show "${FUNCNAME[0]}" 651 start_time=$(get_time) 652 653 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd alias set "${SERVER_ALIAS}1" "$ENDPOINT" "$ACCESS_KEY" "$SECRET_KEY" 654 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd alias list "${SERVER_ALIAS}1" 655 656 log_success "$start_time" "${FUNCNAME[0]}" 657} 658 659function test_config_host_add_error() 660{ 661 show "${FUNCNAME[0]}" 662 start_time=$(get_time) 663 664 out=$("${MC_CMD[@]}" --json alias set "${SERVER_ALIAS}1" "$ENDPOINT" "$ACCESS_KEY" "invalid-secret") 665 assert_failure "$start_time" "${FUNCNAME[0]}" show_on_success $? "adding host should fail" 666 got_code=$(echo "$out" | jq -r .error.cause.error.Code) 667 if [ "${got_code}" != "SignatureDoesNotMatch" ]; then 668 assert_failure "$start_time" "${FUNCNAME[0]}" show_on_failure 1 "incorrect error code ${got_code} returned by server" 669 fi 670 671 log_success "$start_time" "${FUNCNAME[0]}" 672} 673 674function test_put_object_with_sse() 675{ 676 show "${FUNCNAME[0]}" 677 start_time=$(get_time) 678 object_name="mc-test-object-$RANDOM" 679 cli_flag="${SERVER_ALIAS}/${BUCKET_NAME}=32byteslongsecretkeymustbegiven1" 680 # put encrypted object; then delete with correct secret key 681 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp --encrypt-key "${cli_flag}" "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 682 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm --encrypt-key "${cli_flag}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 683 log_success "$start_time" "${FUNCNAME[0]}" 684} 685 686function test_put_object_with_encoded_sse() 687{ 688 show "${FUNCNAME[0]}" 689 start_time=$(get_time) 690 object_name="mc-test-object-$RANDOM" 691 cli_flag="${SERVER_ALIAS}/${BUCKET_NAME}=MzJieXRlc2xvbmdzZWNyZWFiY2RlZmcJZ2l2ZW5uMjE=" 692 # put encrypted object; then delete with correct secret key 693 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp --encrypt-key "${cli_flag}" "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 694 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm --encrypt-key "${cli_flag}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 695 log_success "$start_time" "${FUNCNAME[0]}" 696} 697 698function test_put_object_with_sse_error() 699{ 700 show "${FUNCNAME[0]}" 701 start_time=$(get_time) 702 object_name="mc-test-object-$RANDOM" 703 cli_flag="${SERVER_ALIAS}/${BUCKET_NAME}=32byteslongsecretkeymustbegiven" 704 # put object with invalid encryption key; should fail 705 assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd cp --encrypt-key "${cli_flag}" "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 706 log_success "$start_time" "${FUNCNAME[0]}" 707} 708 709function test_cat_object_with_sse() 710{ 711 show "${FUNCNAME[0]}" 712 start_time=$(get_time) 713 object_name="mc-test-object-$RANDOM" 714 cli_flag="${SERVER_ALIAS}/${BUCKET_NAME}=32byteslongsecretkeymustbegiven1" 715 # put encrypted object; then cat object correct secret key 716 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp --encrypt-key "${cli_flag}" "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 717 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cat --encrypt-key "${cli_flag}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 718 log_success "$start_time" "${FUNCNAME[0]}" 719} 720 721function test_cat_object_with_sse_error() 722{ 723 show "${FUNCNAME[0]}" 724 start_time=$(get_time) 725 object_name="mc-test-object-$RANDOM" 726 cli_flag="${SERVER_ALIAS}/${BUCKET_NAME}=32byteslongsecretkeymustbegiven1" 727 # put encrypted object; then cat object with no secret key 728 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp --encrypt-key "${cli_flag}" "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 729 assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd cat "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 730 log_success "$start_time" "${FUNCNAME[0]}" 731} 732 733# Test "mc cp -r" command of a directory with and without a leading slash 734function test_copy_directory() 735{ 736 show "${FUNCNAME[0]}" 737 738 random_dir="dir-$RANDOM-$RANDOM" 739 tmpdir="$(mktemp -d)" 740 741 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${random_dir}/object-name" 742 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "unable to upload an object" 743 744 # Copy a directory with a trailing slash 745 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp -r "${SERVER_ALIAS}/${BUCKET_NAME}/${random_dir}/" "${tmpdir}/" 746 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "unable to copy a directory with a trailing slash" 747 assert_success "$start_time" "${FUNCNAME[0]}" check_md5sum "$FILE_1_MB_MD5SUM" "${tmpdir}/object-name" 748 assert_success "$start_time" "${FUNCNAME[0]}" rm "${tmpdir}/object-name" 749 750 # Copy a directory without a trailing slash 751 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp -r "${SERVER_ALIAS}/${BUCKET_NAME}/${random_dir}" "${tmpdir}/" 752 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "unable to copy a directory without a trailing slash" 753 assert_success "$start_time" "${FUNCNAME[0]}" check_md5sum "$FILE_1_MB_MD5SUM" "${tmpdir}/${random_dir}/object-name" 754 755 # Cleanup 756 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm -r --force "${SERVER_ALIAS}/${BUCKET_NAME}/${random_dir}/" 757 assert_success "$start_time" "${FUNCNAME[0]}" rm -r "${tmpdir}" 758 759 log_success "$start_time" "${FUNCNAME[0]}" 760} 761 762# Test "mc cp -a" command to see if it preserves file system attributes 763function test_copy_object_preserve_filesystem_attr() 764{ 765 show "${FUNCNAME[0]}" 766 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp -a "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 767 diff -bB <("${MC_CMD[@]}" --json stat "${FILE_1_MB}" | jq -r '.metadata."X-Amz-Meta-Mc-Attrs"') >/dev/null 2>&1 <("${MC_CMD[@]}" --json stat "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" | jq -r '.metadata."X-Amz-Meta-Mc-Attrs"') >/dev/null 2>&1 768 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "unable to put object with file system attribute" 769 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 770 log_success "$start_time" "${FUNCNAME[0]}" 771} 772 773function test_copy_object_with_sse_rewrite() 774{ 775 # test server side copy and remove operation - target is unencrypted while source is encrypted 776 show "${FUNCNAME[0]}" 777 start_time=$(get_time) 778 prefix="prefix" 779 object_name="mc-test-object-$RANDOM" 780 781 cli_flag="${SERVER_ALIAS}/${BUCKET_NAME}/${prefix}=32byteslongsecretkeymustbegiven1" 782 # create encrypted object on server 783 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp --encrypt-key "${cli_flag}" "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${prefix}/${object_name}" 784 # now do a server side copy and store it unencrypted. 785 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp --encrypt-key "${cli_flag}" "${SERVER_ALIAS}/${BUCKET_NAME}/${prefix}/${object_name}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 786 # cat the unencrypted destination object. should return data without any error 787 "${MC_CMD[@]}" cat "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" >"${object_name}.downloaded" 788 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "unable to download object using 'mc cat'" 789 assert_success "$start_time" "${FUNCNAME[0]}" check_md5sum "$FILE_1_MB_MD5SUM" "${object_name}.downloaded" 790 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${object_name}.downloaded" 791 # mc rm on with multi-object delete, deletes encrypted object without encryption key. 792 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm --encrypt-key "${cli_flag}" "${SERVER_ALIAS}/${BUCKET_NAME}/${prefix}/${object_name}" 793 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 794 795 log_success "$start_time" "${FUNCNAME[0]}" 796} 797 798function test_copy_object_with_sse_dest() 799{ 800 # test server side copy and remove operation - target is encrypted with different key 801 show "${FUNCNAME[0]}" 802 start_time=$(get_time) 803 prefix="prefix" 804 object_name="mc-test-object-$RANDOM" 805 806 cli_flag1="${SERVER_ALIAS}/${BUCKET_NAME}/${prefix}=32byteslongsecretkeymustbegiven1" 807 cli_flag2="${SERVER_ALIAS}/${BUCKET_NAME}=32byteslongsecretkeymustbegiven2" 808 809 # create encrypted object on server 810 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp --encrypt-key "${cli_flag1}" "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${prefix}/${object_name}" 811 # now do a server side copy and store it eith different encryption key. 812 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp --encrypt-key "${cli_flag1},${cli_flag2}" "${SERVER_ALIAS}/${BUCKET_NAME}/${prefix}/${object_name}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 813 # cat the destination object with the new key. should return data without any error 814 "${MC_CMD[@]}" cat --encrypt-key "${cli_flag2}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" > "${object_name}.downloaded" 815 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "unable to download object using 'mc cat'" 816 assert_success "$start_time" "${FUNCNAME[0]}" check_md5sum "$FILE_1_MB_MD5SUM" "${object_name}.downloaded" 817 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${object_name}.downloaded" 818 # mc rm on src object with first encryption key should pass 819 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm --encrypt-key "${cli_flag1}" "${SERVER_ALIAS}/${BUCKET_NAME}/${prefix}/${object_name}" 820 # mc rm on encrypted destination object with second encryption key should pass 821 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm --encrypt-key "${cli_flag2}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 822 823 log_success "$start_time" "${FUNCNAME[0]}" 824} 825 826function test_sse_key_rotation() 827{ 828 # test server side copy and remove operation - target is encrypted with different key 829 show "${FUNCNAME[0]}" 830 start_time=$(get_time) 831 prefix="prefix" 832 object_name="mc-test-object-$RANDOM" 833 old_key="32byteslongsecretkeymustbegiven1" 834 new_key="32byteslongsecretkeymustbegiven2" 835 cli_flag1="${SERVER_ALIAS}/${BUCKET_NAME}/${prefix}=${old_key}" 836 cli_flag2="${SERVER_ALIAS_TLS}/${BUCKET_NAME}=${new_key}" 837 838 # create encrypted object on server 839 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp --encrypt-key "${cli_flag1}" "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${prefix}/${object_name}" 840 # now do a server side copy on same object and do a key rotation 841 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp --encrypt-key "${cli_flag1},${cli_flag2}" "${SERVER_ALIAS}/${BUCKET_NAME}/${prefix}/${object_name}" "${SERVER_ALIAS_TLS}/${BUCKET_NAME}/${object_name}" 842 # cat the object with the new key. should return data without any error 843 "${MC_CMD[@]}" cat --encrypt-key "${cli_flag2}" "${SERVER_ALIAS_TLS}/${BUCKET_NAME}/${object_name}" > "${object_name}.downloaded" 844 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "unable to download object using 'mc cat'" 845 assert_success "$start_time" "${FUNCNAME[0]}" check_md5sum "$FILE_1_MB_MD5SUM" "${object_name}.downloaded" 846 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${object_name}.downloaded" 847 # mc rm on encrypted object with succeed anyways, without encrypted keys. 848 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${SERVER_ALIAS_TLS}/${BUCKET_NAME}/${object_name}" 849 850 log_success "$start_time" "${FUNCNAME[0]}" 851} 852 853function test_mirror_with_sse() 854{ 855 # test if mirror operation works with encrypted objects 856 show "${FUNCNAME[0]}" 857 858 start_time=$(get_time) 859 bucket_name="mc-test-bucket-$RANDOM" 860 cli_flag="${SERVER_ALIAS}/${bucket_name}=32byteslongsecretkeymustbegiven1" 861 862 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd mb "${SERVER_ALIAS}/${bucket_name}" 863 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd mirror --encrypt-key "${cli_flag}" "$DATA_DIR" "${SERVER_ALIAS}/${bucket_name}" 864 diff -bB <(ls "$DATA_DIR") <("${MC_CMD[@]}" --json ls "${SERVER_ALIAS}/${bucket_name}/" | jq -r .key) >/dev/null 2>&1 865 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure $? "mirror and list differs" 866 # Remove the test bucket with its contents 867 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rb --force "${SERVER_ALIAS}/${bucket_name}" 868 869 log_success "$start_time" "${FUNCNAME[0]}" 870} 871 872function test_rm_object_with_sse() 873{ 874 show "${FUNCNAME[0]}" 875 876 # test whether remove fails for encrypted object if secret key not provided. 877 start_time=$(get_time) 878 object_name="mc-test-object-$RANDOM" 879 cli_flag="${SERVER_ALIAS}/${BUCKET_NAME}=32byteslongsecretkeymustbegiven1" 880 881 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp --encrypt-key "${cli_flag}" "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 882 # rm will not fail even if the encryption keys are not provided, since mc rm uses multi-object delete. 883 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 884 885 log_success "$start_time" "${FUNCNAME[0]}" 886} 887 888function test_get_object_with_sse() 889{ 890 show "${FUNCNAME[0]}" 891 892 start_time=$(get_time) 893 object_name="mc-test-object-$RANDOM" 894 cli_flag="${SERVER_ALIAS}/${BUCKET_NAME}=32byteslongsecretkeymustbegiven1" 895 896 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp --encrypt-key "${cli_flag}" "${FILE_1_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 897 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp --encrypt-key "${cli_flag}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" "${object_name}.downloaded" 898 assert_success "$start_time" "${FUNCNAME[0]}" check_md5sum "$FILE_1_MB_MD5SUM" "${object_name}.downloaded" 899 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm --encrypt-key "${cli_flag}" "${object_name}.downloaded" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 900 901 log_success "$start_time" "${FUNCNAME[0]}" 902} 903 904function test_put_object_multipart_sse() 905{ 906 show "${FUNCNAME[0]}" 907 908 start_time=$(get_time) 909 object_name="mc-test-object-$RANDOM" 910 cli_flag="${SERVER_ALIAS}/${BUCKET_NAME}=32byteslongsecretkeymustbegiven1" 911 912 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp --encrypt-key "${cli_flag}" "${FILE_65_MB}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 913 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm --encrypt-key "${cli_flag}" "${SERVER_ALIAS}/${BUCKET_NAME}/${object_name}" 914 915 log_success "$start_time" "${FUNCNAME[0]}" 916} 917 918function test_admin_users() 919{ 920 show "${FUNCNAME[0]}" 921 922 start_time=$(get_time) 923 924 # create a user 925 username=foo 926 password=foobar12345 927 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd admin user add "$SERVER_ALIAS" "$username" "$password" 928 929 # check that user appears in the user list 930 "${MC_CMD[@]}" --json admin user list "${SERVER_ALIAS}" | jq -r '.accessKey' | grep --quiet "^${username}$" 931 rv=$? 932 assert_success "$start_time" "${FUNCNAME[0]}" show_on_failure ${rv} "user ${username} did NOT appear in the list of users returned by server" 933 934 # setup temporary alias to make requests as the created user. 935 scheme="https" 936 if [ "$ENABLE_HTTPS" != "1" ]; then 937 scheme="http" 938 fi 939 object1_name="mc-test-object-$RANDOM" 940 object2_name="mc-test-object-$RANDOM" 941 export MC_HOST_foo=${scheme}://${username}:${password}@${SERVER_ENDPOINT} 942 943 # check that the user can write objects with readwrite policy 944 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd admin policy set "$SERVER_ALIAS" readwrite user="${username}" 945 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "$FILE_1_MB" "foo/${BUCKET_NAME}/${object1_name}" 946 947 # check that the user cannot write objects with readonly policy 948 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd admin policy set "$SERVER_ALIAS" readonly user="$username" 949 assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd cp "$FILE_1_MB" "foo/${BUCKET_NAME}/${object2_name}" 950 951 # check that the user can read with readonly policy 952 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cat "foo/${BUCKET_NAME}/${object1_name}" 953 954 # check that user can delete with readwrite policy 955 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd admin policy set "$SERVER_ALIAS" readwrite user="${username}" 956 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd rm "foo/${BUCKET_NAME}/${object1_name}" 957 958 # check that user cannot perform admin actions with readwrite policy 959 assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd admin info "foo" 960 961 # create object1_name for subsequent tests. 962 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cp "$FILE_1_MB" "foo/${BUCKET_NAME}/${object1_name}" 963 964 # check that user can be disabled 965 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd admin user disable "$SERVER_ALIAS" "$username" 966 967 # check that disabled cannot perform any action 968 assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd cat "foo/${BUCKET_NAME}/${object1_name}" 969 970 # check that user can be enabled and can then perform an allowed action 971 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd admin user enable "$SERVER_ALIAS" "$username" 972 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd cat "foo/${BUCKET_NAME}/${object1_name}" 973 974 # check that user can be removed, and then is no longer available 975 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd admin user remove "$SERVER_ALIAS" "$username" 976 assert_failure "$start_time" "${FUNCNAME[0]}" mc_cmd cat "foo/${BUCKET_NAME}/${object1_name}" 977 978 unset MC_HOST_foo 979 980 log_success "$start_time" "${FUNCNAME[0]}" 981} 982 983function run_test() 984{ 985 test_make_bucket 986 test_make_bucket_error 987 test_rb 988 989 setup 990 test_put_object 991 test_put_object_error 992 test_put_object_0byte 993 test_put_object_with_storage_class 994 test_put_object_with_storage_class_error 995 test_put_object_with_metadata 996 test_put_object_multipart 997 test_get_object 998 test_get_object_multipart 999 test_presigned_post_policy_error 1000 test_presigned_put_object 1001 test_presigned_get_object 1002 test_cat_object 1003 test_cat_stdin 1004 test_copy_directory 1005 test_mirror_list_objects 1006 test_mirror_list_objects_storage_class 1007 test_copy_object_preserve_filesystem_attr 1008 test_find 1009 test_find_empty 1010 if [ -z "$MINT_MODE" ]; then 1011 test_watch_object 1012 fi 1013 1014 if [ "$ENABLE_HTTPS" == "1" ]; then 1015 test_put_object_with_sse 1016 test_put_object_with_encoded_sse 1017 test_put_object_with_sse_error 1018 test_put_object_multipart_sse 1019 test_get_object_with_sse 1020 test_cat_object_with_sse 1021 test_cat_object_with_sse_error 1022 test_copy_object_with_sse_rewrite 1023 test_copy_object_with_sse_dest 1024 test_sse_key_rotation 1025 test_mirror_with_sse 1026 test_rm_object_with_sse 1027 fi 1028 1029 test_config_host_add 1030 test_config_host_add_error 1031 1032 if [ "$ENABLE_ADMIN" == "1" ]; then 1033 test_admin_users 1034 fi 1035 1036 teardown 1037} 1038 1039function __init__() 1040{ 1041 set -e 1042 # For Mint, setup is already done. For others, setup the environment 1043 if [ -z "$MINT_MODE" ]; then 1044 mkdir -p "$WORK_DIR" 1045 mkdir -p "$DATA_DIR" 1046 1047 # If mc executable binary is not available in current directory, use it in the path. 1048 if [ ! -x "$MC" ]; then 1049 if ! MC=$(which mc 2>/dev/null); then 1050 echo "'mc' executable binary not found in current directory and in path" 1051 exit 1 1052 fi 1053 fi 1054 fi 1055 1056 if [ ! -x "$MC" ]; then 1057 echo "$MC executable binary not found" 1058 exit 1 1059 fi 1060 1061 mkdir -p "$MC_CONFIG_DIR" 1062 MC_CMD=( "${MC}" --config-dir "$MC_CONFIG_DIR" --quiet --no-color ) 1063 1064 if [ ! -e "$FILE_0_B" ]; then 1065 base64 /dev/urandom | head -c 0 >"$FILE_0_B" 1066 fi 1067 1068 if [ ! -e "$FILE_1_MB" ]; then 1069 base64 /dev/urandom | head -c 1048576 >"$FILE_1_MB" 1070 fi 1071 1072 if [ ! -e "$FILE_65_MB" ]; then 1073 base64 /dev/urandom | head -c 68157440 >"$FILE_65_MB" 1074 fi 1075 1076 set -E 1077 set -o pipefail 1078 1079 FILE_0_B_MD5SUM="$(get_md5sum "$FILE_0_B")" 1080 if [ $? -ne 0 ]; then 1081 echo "unable to get md5sum of $FILE_0_B" 1082 exit 1 1083 fi 1084 1085 FILE_1_MB_MD5SUM="$(get_md5sum "$FILE_1_MB")" 1086 if [ $? -ne 0 ]; then 1087 echo "unable to get md5sum of $FILE_1_MB" 1088 exit 1 1089 fi 1090 1091 FILE_65_MB_MD5SUM="$(get_md5sum "$FILE_65_MB")" 1092 if [ $? -ne 0 ]; then 1093 echo "unable to get md5sum of $FILE_65_MB" 1094 exit 1 1095 fi 1096 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd alias set "${SERVER_ALIAS}" "$ENDPOINT" "$ACCESS_KEY" "$SECRET_KEY" 1097 assert_success "$start_time" "${FUNCNAME[0]}" mc_cmd alias set "${SERVER_ALIAS_TLS}" "$ENDPOINT" "$ACCESS_KEY" "$SECRET_KEY" 1098 1099 set +e 1100} 1101 1102function main() 1103{ 1104 ( run_test ) 1105 rv=$? 1106 1107 rm -fr "$MC_CONFIG_DIR" "$WATCH_OUT_FILE" 1108 if [ -z "$MINT_MODE" ]; then 1109 rm -fr "$WORK_DIR" "$DATA_DIR" 1110 fi 1111 1112 exit "$rv" 1113} 1114 1115__init__ "$@" 1116main "$@" 1117