Skip to content

Commit 08df935

Browse files
authored
Merge pull request #591 from cbodley/wip-68292
s3: test GetObject with PartNumber and SSE-C encryption
2 parents cba8047 + acc8ef4 commit 08df935

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

s3tests_boto3/functional/test_s3.py

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6460,6 +6460,61 @@ def test_multipart_get_part():
64606460
assert status == 400
64616461
assert error_code == 'InvalidPart'
64626462

6463+
@pytest.mark.encryption
6464+
@pytest.mark.fails_on_dbstore
6465+
def test_multipart_sse_c_get_part():
6466+
bucket_name = get_new_bucket()
6467+
client = get_client()
6468+
key = "mymultipart"
6469+
6470+
part_size = 5*1024*1024
6471+
part_sizes = 3 * [part_size] + [1*1024*1024]
6472+
part_count = len(part_sizes)
6473+
total_size = sum(part_sizes)
6474+
6475+
enc_headers = {
6476+
'x-amz-server-side-encryption-customer-algorithm': 'AES256',
6477+
'x-amz-server-side-encryption-customer-key': 'pO3upElrwuEXSoFwCfnZPdSsmt/xWeFa0N9KgDijwVs=',
6478+
'x-amz-server-side-encryption-customer-key-md5': 'DWygnHRtgiJ77HCm+1rvHw==',
6479+
}
6480+
get_args = {
6481+
'SSECustomerAlgorithm': 'AES256',
6482+
'SSECustomerKey': 'pO3upElrwuEXSoFwCfnZPdSsmt/xWeFa0N9KgDijwVs=',
6483+
'SSECustomerKeyMD5': 'DWygnHRtgiJ77HCm+1rvHw==',
6484+
}
6485+
6486+
(upload_id, data, parts) = _multipart_upload_enc(client, bucket_name, key, total_size,
6487+
part_size, init_headers=enc_headers, part_headers=enc_headers, metadata=None, resend_parts=[2])
6488+
6489+
# request part before complete
6490+
e = assert_raises(ClientError, client.get_object, Bucket=bucket_name, Key=key, PartNumber=1)
6491+
status, error_code = _get_status_and_error_code(e.response)
6492+
assert status == 404
6493+
assert error_code == 'NoSuchKey'
6494+
6495+
client.complete_multipart_upload(Bucket=bucket_name, Key=key, UploadId=upload_id, MultipartUpload={'Parts': parts})
6496+
assert len(parts) == part_count
6497+
6498+
for part, size in zip(parts, part_sizes):
6499+
response = client.head_object(Bucket=bucket_name, Key=key, PartNumber=part['PartNumber'], **get_args)
6500+
assert response['PartsCount'] == part_count
6501+
assert response['ETag'] == '"{}"'.format(part['ETag'])
6502+
6503+
response = client.get_object(Bucket=bucket_name, Key=key, PartNumber=part['PartNumber'], **get_args)
6504+
assert response['PartsCount'] == part_count
6505+
assert response['ETag'] == '"{}"'.format(part['ETag'])
6506+
assert response['ContentLength'] == size
6507+
# compare contents
6508+
for chunk in response['Body'].iter_chunks():
6509+
assert chunk.decode() == data[0:len(chunk)]
6510+
data = data[len(chunk):]
6511+
6512+
# request PartNumber out of range
6513+
e = assert_raises(ClientError, client.get_object, Bucket=bucket_name, Key=key, PartNumber=5)
6514+
status, error_code = _get_status_and_error_code(e.response)
6515+
assert status == 400
6516+
assert error_code == 'InvalidPart'
6517+
64636518
@pytest.mark.fails_on_dbstore
64646519
def test_multipart_single_get_part():
64656520
bucket_name = get_new_bucket()
@@ -6522,6 +6577,33 @@ def test_non_multipart_get_part():
65226577
assert response['ETag'] == etag
65236578
assert _get_body(response) == 'body'
65246579

6580+
@pytest.mark.encryption
6581+
@pytest.mark.fails_on_dbstore
6582+
def test_non_multipart_sse_c_get_part():
6583+
bucket_name = get_new_bucket()
6584+
client = get_client()
6585+
key = "singlepart"
6586+
6587+
sse_args = {
6588+
'SSECustomerAlgorithm': 'AES256',
6589+
'SSECustomerKey': 'pO3upElrwuEXSoFwCfnZPdSsmt/xWeFa0N9KgDijwVs=',
6590+
'SSECustomerKeyMD5': 'DWygnHRtgiJ77HCm+1rvHw=='
6591+
}
6592+
6593+
response = client.put_object(Bucket=bucket_name, Key=key, Body='body', **sse_args)
6594+
etag = response['ETag']
6595+
6596+
# request for PartNumber > 1 results in InvalidPart
6597+
e = assert_raises(ClientError, client.get_object, Bucket=bucket_name, Key=key, PartNumber=2, **sse_args)
6598+
status, error_code = _get_status_and_error_code(e.response)
6599+
assert status == 400
6600+
assert error_code == 'InvalidPart'
6601+
6602+
# request for PartNumber = 1 gives back the entire object
6603+
response = client.get_object(Bucket=bucket_name, Key=key, PartNumber=1, **sse_args)
6604+
assert response['ETag'] == etag
6605+
assert _get_body(response) == 'body'
6606+
65256607

65266608
def _simple_http_req_100_cont(host, port, is_secure, method, resource):
65276609
"""

0 commit comments

Comments
 (0)