mirror of
https://github.com/ceph/ceph
synced 2024-12-28 06:23:08 +00:00
Merge pull request #50667 from ivancich/wip-add-reupload-testing
qa/rgw: test that multipart re-upload does not leave any orphans Reviewed-by: Cory Snyder <csnyder@iland.com>
This commit is contained in:
commit
fb9d481188
5
qa/suites/rgw/verify/tasks/mp_reupload.yaml
Normal file
5
qa/suites/rgw/verify/tasks/mp_reupload.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
tasks:
|
||||
- workunit:
|
||||
clients:
|
||||
client.0:
|
||||
- rgw/test_rgw_s3_mp_reupload.sh
|
121
qa/workunits/rgw/test_rgw_s3_mp_reupload.py
Executable file
121
qa/workunits/rgw/test_rgw_s3_mp_reupload.py
Executable file
@ -0,0 +1,121 @@
|
||||
import boto3
|
||||
import botocore.exceptions
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
#boto3.set_stream_logger(name='botocore')
|
||||
|
||||
# handles two optional system arguments:
|
||||
# <bucket-name> : default is "bkt134"
|
||||
# <0 or 1> : 0 -> upload aborted, 1 -> completed; default is completed
|
||||
|
||||
if len(sys.argv) >= 2:
|
||||
bucket_name = sys.argv[1]
|
||||
else:
|
||||
bucket_name = "bkt314738362229"
|
||||
print("bucket nams is %s" % bucket_name)
|
||||
|
||||
complete_mpu = True
|
||||
if len(sys.argv) >= 3:
|
||||
complete_mpu = int(sys.argv[2]) > 0
|
||||
|
||||
versioned_bucket = False
|
||||
if len(sys.argv) >= 4:
|
||||
versioned_bucket = int(sys.argv[3]) > 0
|
||||
|
||||
rgw_host = os.environ['RGW_HOST']
|
||||
access_key = os.environ['RGW_ACCESS_KEY']
|
||||
secret_key = os.environ['RGW_SECRET_KEY']
|
||||
|
||||
try:
|
||||
endpoint='http://%s:%d' % (rgw_host, 80)
|
||||
client = boto3.client('s3',
|
||||
endpoint_url=endpoint,
|
||||
aws_access_key_id=access_key,
|
||||
aws_secret_access_key=secret_key)
|
||||
res = client.create_bucket(Bucket=bucket_name)
|
||||
except botocore.exceptions.EndpointConnectionError:
|
||||
try:
|
||||
endpoint='https://%s:%d' % (rgw_host, 443)
|
||||
client = boto3.client('s3',
|
||||
endpoint_url=endpoint,
|
||||
verify=False,
|
||||
aws_access_key_id=access_key,
|
||||
aws_secret_access_key=secret_key)
|
||||
res = client.create_bucket(Bucket=bucket_name)
|
||||
except botocore.exceptions.EndpointConnectionError:
|
||||
endpoint='http://%s:%d' % (rgw_host, 8000)
|
||||
client = boto3.client('s3',
|
||||
endpoint_url=endpoint,
|
||||
aws_access_key_id=access_key,
|
||||
aws_secret_access_key=secret_key)
|
||||
res = client.create_bucket(Bucket=bucket_name)
|
||||
|
||||
print("endpoint is %s" % endpoint)
|
||||
|
||||
if versioned_bucket:
|
||||
res = client.put_bucket_versioning(
|
||||
Bucket=bucket_name,
|
||||
VersioningConfiguration={
|
||||
'MFADelete': 'Disabled',
|
||||
'Status': 'Enabled'}
|
||||
)
|
||||
|
||||
key = "mpu_test4"
|
||||
nparts = 2
|
||||
ndups = 11
|
||||
do_reupload = True
|
||||
|
||||
part_path = "/tmp/mp_part_5m"
|
||||
subprocess.run(["dd", "if=/dev/urandom", "of=" + part_path, "bs=1M", "count=5"], check=True)
|
||||
|
||||
f = open(part_path, 'rb')
|
||||
|
||||
res = client.create_multipart_upload(Bucket=bucket_name, Key=key)
|
||||
mpu_id = res["UploadId"]
|
||||
|
||||
print("start UploadId=%s" % (mpu_id))
|
||||
|
||||
parts = []
|
||||
parts2 = []
|
||||
|
||||
for ix in range(0,nparts):
|
||||
part_num = ix + 1
|
||||
f.seek(0)
|
||||
res = client.upload_part(Body=f, Bucket=bucket_name, Key=key,
|
||||
UploadId=mpu_id, PartNumber=part_num)
|
||||
# save
|
||||
etag = res['ETag']
|
||||
part = {'ETag': etag, 'PartNumber': part_num}
|
||||
print("phase 1 uploaded part %s" % part)
|
||||
parts.append(part)
|
||||
|
||||
if do_reupload:
|
||||
# just re-upload part 1
|
||||
part_num = 1
|
||||
for ix in range(0,ndups):
|
||||
f.seek(0)
|
||||
res = client.upload_part(Body=f, Bucket=bucket_name, Key=key,
|
||||
UploadId=mpu_id, PartNumber=part_num)
|
||||
etag = res['ETag']
|
||||
part = {'ETag': etag, 'PartNumber': part_num}
|
||||
print ("phase 2 uploaded part %s" % part)
|
||||
|
||||
# save
|
||||
etag = res['ETag']
|
||||
part = {'ETag': etag, 'PartNumber': part_num}
|
||||
parts2.append(part)
|
||||
|
||||
if complete_mpu:
|
||||
print("completing multipart upload, parts=%s" % parts)
|
||||
res = client.complete_multipart_upload(
|
||||
Bucket=bucket_name, Key=key, UploadId=mpu_id,
|
||||
MultipartUpload={'Parts': parts})
|
||||
else:
|
||||
print("aborting multipart upload, parts=%s" % parts)
|
||||
res = client.abort_multipart_upload(
|
||||
Bucket=bucket_name, Key=key, UploadId=mpu_id)
|
||||
|
||||
# clean up
|
||||
subprocess.run(["rm", "-f", part_path], check=True)
|
110
qa/workunits/rgw/test_rgw_s3_mp_reupload.sh
Executable file
110
qa/workunits/rgw/test_rgw_s3_mp_reupload.sh
Executable file
@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# INITIALIZATION
|
||||
|
||||
mydir=$(dirname $0)
|
||||
data_pool=default.rgw.buckets.data
|
||||
orphan_list_out=/tmp/orphan_list.$$
|
||||
radoslist_out=/tmp/radoslist.$$
|
||||
rados_ls_out=/tmp/rados_ls.$$
|
||||
diff_out=/tmp/diff.$$
|
||||
|
||||
rgw_host="$(hostname --fqdn)"
|
||||
echo "INFO: fully qualified domain name: $rgw_host"
|
||||
|
||||
export RGW_ACCESS_KEY="0555b35654ad1656d804"
|
||||
export RGW_SECRET_KEY="h7GhxuBLTrlhVUyxSPUKUV8r/2EI4ngqJxD7iBdBYLhwluN30JaT3Q=="
|
||||
export RGW_HOST="${RGW_HOST:-$rgw_host}"
|
||||
|
||||
# random argument determines if multipart is aborted or completed 50/50
|
||||
outcome=$((RANDOM % 2))
|
||||
if [ $outcome -eq 0 ] ;then
|
||||
echo "== TESTING *ABORTING* MULTIPART UPLOAD WITH RE-UPLOADS =="
|
||||
else
|
||||
echo "== TESTING *COMPLETING* MULTIPART UPLOAD WITH RE-UPLOADS =="
|
||||
fi
|
||||
|
||||
# random argument determines if multipart is aborted or completed 50/50
|
||||
versioning=$((RANDOM % 2))
|
||||
if [ $versioning -eq 0 ] ;then
|
||||
echo "== TESTING NON-VERSIONED BUCKET =="
|
||||
else
|
||||
echo "== TESTING VERSIONED BUCKET =="
|
||||
fi
|
||||
|
||||
# create a randomized bucket name
|
||||
bucket="reupload-bkt-$((RANDOM % 899999 + 100000))"
|
||||
|
||||
|
||||
# SET UP PYTHON VIRTUAL ENVIRONMENT
|
||||
|
||||
# install boto3
|
||||
python3 -m venv $mydir
|
||||
source $mydir/bin/activate
|
||||
pip install pip --upgrade
|
||||
pip install boto3
|
||||
|
||||
|
||||
# CREATE RGW USER IF NECESSARY
|
||||
|
||||
if radosgw-admin user info --access-key $RGW_ACCESS_KEY 2>/dev/null ;then
|
||||
echo INFO: user already exists
|
||||
else
|
||||
echo INFO: creating user
|
||||
radosgw-admin user create --uid testid \
|
||||
--access-key $RGW_ACCESS_KEY \
|
||||
--secret $RGW_SECRET_KEY \
|
||||
--display-name 'M. Tester' \
|
||||
--email tester@ceph.com 2>/dev/null
|
||||
fi
|
||||
|
||||
|
||||
# RUN REUPLOAD TEST
|
||||
|
||||
$mydir/bin/python3 ${mydir}/test_rgw_s3_mp_reupload.py $bucket $outcome $versioning
|
||||
|
||||
|
||||
# ANALYZE FOR ERRORS
|
||||
# (NOTE: for now we're choosing not to use the rgw-orphan-list tool)
|
||||
|
||||
# force garbage collection to remove extra parts
|
||||
radosgw-admin gc process --include-all 2>/dev/null
|
||||
|
||||
marker=$(radosgw-admin metadata get bucket:$bucket 2>/dev/null | grep bucket_id | sed 's/.*: "\(.*\)".*/\1/')
|
||||
|
||||
# determine expected rados objects
|
||||
radosgw-admin bucket radoslist --bucket=$bucket 2>/dev/null | sort >$radoslist_out
|
||||
echo "radosgw-admin bucket radoslist:"
|
||||
cat $radoslist_out
|
||||
|
||||
# determine found rados objects
|
||||
rados ls -p $data_pool 2>/dev/null | grep "^$marker" | sort >$rados_ls_out
|
||||
echo "rados ls:"
|
||||
cat $rados_ls_out
|
||||
|
||||
# compare expected and found
|
||||
diff $radoslist_out $rados_ls_out >$diff_out
|
||||
if [ $(cat $diff_out | wc -l) -ne 0 ] ;then
|
||||
error=1
|
||||
echo "ERROR: Found differences between expected and actual rados objects for test bucket."
|
||||
echo " note: indicators: '>' found but not expected; '<' expected but not found."
|
||||
cat $diff_out
|
||||
fi
|
||||
|
||||
|
||||
# CLEAN UP
|
||||
|
||||
deactivate
|
||||
|
||||
rm -f $orphan_list_out $radoslist_out $rados_ls_out $diff_out
|
||||
|
||||
|
||||
# PRODUCE FINAL RESULTS
|
||||
|
||||
if [ -n "$error" ] ;then
|
||||
echo "== FAILED =="
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "== PASSED =="
|
||||
exit 0
|
Loading…
Reference in New Issue
Block a user