def test_copy_object(stub_and_patch, make_unique_name, make_bucket): """Test that copying an object from one bucket to another works as expected.""" stubber = stub_and_patch(bucket_wrapper, 'get_s3') src_bucket = make_bucket(stubber, bucket_wrapper.get_s3()) dest_bucket = make_bucket(stubber, bucket_wrapper.get_s3()) src_object_key = make_unique_name('src-object') dest_object_key = make_unique_name('dest-object') data = b"Some test data!" stubber.stub_put_object(src_bucket.name, src_object_key) stubber.stub_head_object(src_bucket.name, src_object_key) stubber.stub_copy_object(src_bucket.name, src_object_key, dest_bucket.name, dest_object_key) stubber.stub_head_object(dest_bucket.name, dest_object_key) stubber.stub_get_object(dest_bucket.name, dest_object_key, data) stubber.stub_list_objects(dest_bucket.name, [dest_object_key]) stubber.stub_delete_objects(dest_bucket.name, [dest_object_key]) stubber.stub_list_objects(src_bucket.name, [src_object_key]) stubber.stub_delete_objects(src_bucket.name, [src_object_key]) object_wrapper.put_object(src_bucket, src_object_key, data) copied_obj = object_wrapper.copy_object(src_bucket, src_object_key, dest_bucket, dest_object_key) assert data == copied_obj.get()['Body'].read() object_wrapper.empty_bucket(dest_bucket) object_wrapper.empty_bucket(src_bucket)
def test_put_get_delete_cors(stub_and_patch, make_unique_name, make_bucket): """Test that put, get, and delete of CORS on a bucket works as expected.""" stubber = stub_and_patch(bucket_wrapper, 'get_s3') bucket = make_bucket(stubber, bucket_wrapper.get_s3()) cors_rules = [{ 'AllowedOrigins': ['http://www.example.com'], 'AllowedMethods': ['PUT', 'POST', 'DELETE'], 'AllowedHeaders': ['*'] }] stubber.stub_put_bucket_cors(bucket.name, cors_rules) stubber.stub_get_bucket_cors(bucket.name, cors_rules) stubber.stub_delete_bucket_cors(bucket.name) stubber.stub_get_bucket_cors(bucket.name, error_code='NoSuchCORSConfiguration') bucket_wrapper.put_cors(bucket.name, cors_rules) cors = bucket_wrapper.get_cors(bucket.name) assert cors.cors_rules == cors_rules bucket_wrapper.delete_cors(bucket.name) with pytest.raises(ClientError) as exc_info: _ = bucket_wrapper.get_cors(bucket.name) assert exc_info.value.response['Error']['Code'] == 'NoSuchCORSConfiguration'
def test_list_objects_empty_bucket(stub_and_patch, make_unique_name, make_bucket, object_count): """Test that listing the objects in a test bucket returns the expected list and that the bucket can be emptied of objects.""" stubber = stub_and_patch(bucket_wrapper, 'get_s3') bucket = make_bucket(stubber, bucket_wrapper.get_s3()) object_key = make_unique_name('object') put_keys = [] for obj_suffix in range(0, object_count): key = f"{object_key}-{obj_suffix}" data = bytes(f"Test data-{obj_suffix}", 'utf-8') stubber.stub_put_object(bucket.name, key) stubber.stub_head_object(bucket.name, key) object_wrapper.put_object(bucket, key, data) put_keys.append(key) stubber.stub_list_objects(bucket.name, put_keys) stubber.stub_list_objects(bucket.name, put_keys, "object") stubber.stub_list_objects(bucket.name, put_keys) if put_keys: stubber.stub_delete_objects(bucket.name, put_keys) stubber.stub_list_objects(bucket.name) all_objects = object_wrapper.list_objects(bucket) assert set(put_keys).issubset([o.key for o in all_objects]) filtered_objects = object_wrapper.list_objects(bucket, "object") assert put_keys == [o.key for o in filtered_objects] object_wrapper.empty_bucket(bucket) assert [] == object_wrapper.list_objects(bucket)
def test_put_get_delete_object(stub_and_patch, make_unique_name, make_bucket, object_data): """Test that put, get, delete of an object into a test bucket works as expected.""" stubber = stub_and_patch(bucket_wrapper, 'get_s3') bucket = make_bucket(stubber, bucket_wrapper.get_s3()) object_key = make_unique_name('object') stubber.stub_put_object(bucket.name, object_key) stubber.stub_head_object(bucket.name, object_key) stubber.stub_get_object(bucket.name, object_key, object_data) stubber.stub_delete_object(bucket.name, object_key) stubber.stub_head_object(bucket.name, object_key, 404) stubber.stub_get_object(bucket.name, object_key, error_code='NoSuchKey') object_wrapper.put_object(bucket, object_key, object_data) data = object_wrapper.get_object(bucket, object_key) if isinstance(object_data, bytes): assert data == object_data else: with open(object_data, 'rb') as file: assert file.read() == data object_wrapper.delete_object(bucket, object_key) with pytest.raises(ClientError) as exc_info: object_wrapper.get_object(bucket, object_key) assert exc_info.value.response['Error']['Code'] == 'NoSuchKey'
def test_grant_log_delivery_access(stub_and_patch, make_unique_name, make_bucket): """Test that using an ACL to grant access to the log delivery group succeeds.""" stubber = stub_and_patch(bucket_wrapper, 'get_s3') bucket = make_bucket(stubber, bucket_wrapper.get_s3()) stubber.stub_get_bucket_acl(bucket.name) stubber.stub_put_bucket_acl(bucket.name) stubber.stub_get_bucket_acl(bucket.name, ['owner', 'log_delivery']) bucket_wrapper.grant_log_delivery_access(bucket.name) acl = bucket_wrapper.get_acl(bucket.name) log_delivery_grantee = { 'Grantee': { 'Type': 'Group', 'URI': 'http://acs.amazonaws.com/groups/s3/LogDelivery' }, 'Permission': 'WRITE' } assert log_delivery_grantee in acl.grants owner_grantee = { 'Grantee': { 'Type': 'CanonicalUser', 'ID': acl.owner['ID'], 'DisplayName': acl.owner['DisplayName'] }, 'Permission': 'FULL_CONTROL' } assert owner_grantee in acl.grants
def test_delete_objects(stub_and_patch, make_unique_name, make_bucket): """Test that deleting objects from a bucket works as expected.""" stubber = stub_and_patch(bucket_wrapper, 'get_s3') bucket = make_bucket(stubber, bucket_wrapper.get_s3()) object_key = make_unique_name('object') put_keys = [] for suffix in range(0, 5): put_key = f"{object_key}-{suffix}" stubber.stub_put_object(bucket.name, put_key) stubber.stub_head_object(bucket.name, put_key) object_wrapper.put_object(bucket, put_key, b"Test data!") put_keys.append(put_key) delete_keys = put_keys[3:] keep_keys = put_keys[:3] stubber.stub_delete_objects(bucket.name, delete_keys) stubber.stub_list_objects(bucket.name, keep_keys) stubber.stub_list_objects(bucket.name) response = object_wrapper.delete_objects(bucket, delete_keys) assert set(delete_keys) == set(obj['Key'] for obj in response['Deleted']) assert set(keep_keys) == set( obj.key for obj in object_wrapper.list_objects(bucket)) object_wrapper.empty_bucket(bucket)
def test_bucket_exists(stub_and_patch, make_unique_name, make_bucket): """Test that bucket existence is correctly determined.""" stubber = stub_and_patch(bucket_wrapper, 'get_s3') bucket = make_bucket(stubber, bucket_wrapper.get_s3()) stubber.stub_head_bucket(bucket.name) assert bucket_wrapper.bucket_exists(bucket.name)
def test_get_cors_expect_none(stub_and_patch, make_unique_name, make_bucket): """Test that getting CORS for a new bucket raises an error.""" stubber = stub_and_patch(bucket_wrapper, 'get_s3') bucket = make_bucket(stubber, bucket_wrapper.get_s3()) stubber.stub_get_bucket_cors(bucket.name, error_code='NoSuchCORSConfiguration') with pytest.raises(ClientError) as exc_info: _ = bucket_wrapper.get_cors(bucket.name) assert exc_info.value.response['Error']['Code'] == 'NoSuchCORSConfiguration'
def test_create_existing_bucket(stub_and_patch, make_unique_name, make_bucket): """Test that creating an existing bucket raises an error.""" stubber = stub_and_patch(bucket_wrapper, 'get_s3') bucket = make_bucket(stubber, bucket_wrapper.get_s3()) stubber.stub_create_bucket(bucket.name, stubber.region_name, error_code='BucketAlreadyOwnedByYou') with pytest.raises(stubber.client.exceptions.BucketAlreadyOwnedByYou): bucket_wrapper.create_bucket(bucket.name, stubber.region_name)
def test_put_not_file_expect_error(stub_and_patch, make_unique_name, make_bucket): """Test that putting an object using a string that is not a file name raises an error.""" stubber = stub_and_patch(bucket_wrapper, 'get_s3') bucket = make_bucket(stubber, bucket_wrapper.get_s3()) object_key = make_unique_name('object') with pytest.raises(IOError): object_wrapper.put_object(bucket, object_key, "neither-file-nor-binary")
def test_get_acl(stub_and_patch, make_unique_name, make_bucket): """Test that getting a bucket ACL returns the expected values.""" stubber = stub_and_patch(bucket_wrapper, 'get_s3') bucket = make_bucket(stubber, bucket_wrapper.get_s3()) stubber.stub_get_bucket_acl(bucket.name, ['owner']) acl = bucket_wrapper.get_acl(bucket.name) assert len(acl.grants) == 1 assert acl.owner['ID'] == acl.grants[0]['Grantee']['ID'] assert acl.grants[0]['Permission'] == 'FULL_CONTROL'
def test_get_bucket_lifecycle_configuration(stub_and_patch, make_unique_name, make_bucket): """Test that getting the lifecycle configuration of a new bucket raises an error.""" stubber = stub_and_patch(bucket_wrapper, 'get_s3') bucket = make_bucket(stubber, bucket_wrapper.get_s3()) stubber.stub_get_bucket_lifecycle_configuration( bucket.name, error_code='NoSuchLifecycleConfiguration' ) with pytest.raises(ClientError) as exc_info: _ = bucket_wrapper.get_lifecycle_configuration(bucket.name) assert exc_info.value.response['Error']['Code'] == 'NoSuchLifecycleConfiguration'
def test_get_buckets(stub_and_patch, make_unique_name, make_bucket): """Test getting a list of buckets.""" stubber = stub_and_patch(bucket_wrapper, 'get_s3') created_buckets = [ make_bucket(stubber, bucket_wrapper.get_s3()) for ind in range(0, 5) ] stubber.stub_list_buckets(created_buckets) gotten_buckets = bucket_wrapper.get_buckets() intersection = [b for b in gotten_buckets if b in created_buckets] assert created_buckets == intersection
def test_delete_full_bucket(stub_and_patch, make_unique_name, make_bucket): """Test that deleting a bucket that contains objects raises an error.""" stubber = stub_and_patch(bucket_wrapper, 'get_s3') bucket = make_bucket(stubber, bucket_wrapper.get_s3()) object_key = 'test_bucket_wrapper.py' stubber.stub_put_object(bucket.name, object_key) stubber.stub_delete_bucket(bucket.name, error_code='BucketNotEmpty') obj = bucket.Object(object_key) obj.upload_fileobj(io.BytesIO(b"Test data.")) with pytest.raises(ClientError): bucket_wrapper.delete_bucket(bucket) if not stubber.use_stubs: obj.delete()
def test_put_get_delete_bucket_lifecycle_configuration( stub_and_patch, make_unique_name, make_bucket): """ Test that put, get, delete of lifecycle configuration on a bucket works as expected. """ stubber = stub_and_patch(bucket_wrapper, 'get_s3') bucket = make_bucket(stubber, bucket_wrapper.get_s3()) put_rules = [{ 'ID': str(uuid.uuid1()), 'Filter': { 'And': { 'Prefix': 'monsters/', 'Tags': [{'Key': 'type', 'Value': 'zombie'}] } }, 'Status': 'Enabled', 'Expiration': {'Days': 28} }, { 'ID': str(uuid.uuid1()), 'Filter': { 'And': { 'Prefix': 'monsters/', 'Tags': [{'Key': 'type', 'Value': 'frankenstein'}] } }, 'Status': 'Enabled', 'Transitions': [{'Days': 365, 'StorageClass': 'GLACIER'}] }] stubber.stub_put_bucket_lifecycle_configuration(bucket.name, put_rules) stubber.stub_get_bucket_lifecycle_configuration(bucket.name, put_rules) stubber.stub_delete_bucket_lifecycle_configuration(bucket.name) stubber.stub_get_bucket_lifecycle_configuration( bucket.name, error_code='NoSuchLifecycleConfiguration' ) bucket_wrapper.put_lifecycle_configuration(bucket.name, put_rules) rules = bucket_wrapper.get_lifecycle_configuration(bucket.name) assert rules == put_rules bucket_wrapper.delete_lifecycle_configuration(bucket.name) with pytest.raises(ClientError) as exc_info: _ = bucket_wrapper.get_lifecycle_configuration(bucket.name) assert exc_info.value.response['Error']['Code'] == 'NoSuchLifecycleConfiguration'
def test_put_bucket_policy_bad_version(stub_and_patch, make_unique_name, make_bucket): """ Test that a policy version other than 2012-10-17 or 2008-10-17 fails. This is because the version is the version of the policy format and so must be a recognized version string. """ stubber = stub_and_patch(bucket_wrapper, 'get_s3') bucket = make_bucket(stubber, bucket_wrapper.get_s3()) put_policy = { 'Version': '2020-03-17' } stubber.stub_put_bucket_policy(bucket.name, put_policy, error_code='MalformedPolicy') with pytest.raises(ClientError) as exc_info: bucket_wrapper.put_policy(bucket.name, put_policy) assert exc_info.value.response['Error']['Code'] == 'MalformedPolicy'
def test_put_get_acl(stub_and_patch, make_unique_name, make_bucket): """ Test that put and get of an object ACL works as expected. To run this test against the non-stubbed AWS service, you must replace the email and canonical_user values with an existing AWS user or the test will fail. """ stubber = stub_and_patch(bucket_wrapper, 'get_s3') bucket = make_bucket(stubber, bucket_wrapper.get_s3()) object_key = make_unique_name('object') email = '*****@*****.**' canonical_user = '******' stubber.stub_put_object(bucket.name, object_key) stubber.stub_head_object(bucket.name, object_key) stubber.stub_get_object_acl(bucket.name, object_key) stubber.stub_put_object_acl(bucket.name, object_key, email) stubber.stub_get_object_acl(bucket.name, object_key, email) stubber.stub_list_objects(bucket.name) object_wrapper.put_object(bucket, object_key, b"Test data") object_wrapper.put_acl(bucket, object_key, email) acl = object_wrapper.get_acl(bucket, object_key) email_grantee = { 'Grantee': { 'Type': 'CanonicalUser', 'DisplayName': canonical_user, 'ID': ANY }, 'Permission': 'READ' } assert email_grantee in acl.grants owner_grantee = { 'Grantee': { 'Type': 'CanonicalUser', 'ID': acl.owner['ID'], 'DisplayName': acl.owner['DisplayName'] }, 'Permission': 'FULL_CONTROL' } assert owner_grantee in acl.grants object_wrapper.empty_bucket(bucket)
def test_put_get_delete_bucket_policy(stub_and_patch, make_unique_name, make_bucket): """ Test that put, get, delete on a bucket policy works as expected. To run this test with the non-stubbed AWS service, you must update the principal ARN to an existing AWS user, or the test will fail. """ stubber = stub_and_patch(bucket_wrapper, 'get_s3') bucket = make_bucket(stubber, bucket_wrapper.get_s3()) policy_id = uuid.uuid1() put_policy = { 'Version': '2012-10-17', 'Id': str(policy_id), 'Statement': [{ 'Effect': 'Allow', 'Principal': {'AWS': 'arn:aws:iam::111122223333:user/Martha'}, 'Action': [ 's3:GetObject', 's3:ListBucket' ], 'Resource': [ f'arn:aws:s3:::{bucket.name}/*', f'arn:aws:s3:::{bucket.name}' ] }] } stubber.stub_put_bucket_policy(bucket.name, put_policy) stubber.stub_get_bucket_policy(bucket.name, put_policy) stubber.stub_delete_bucket_policy(bucket.name) stubber.stub_get_bucket_policy(bucket.name, error_code='NoSuchBucketPolicy') bucket_wrapper.put_policy(bucket.name, put_policy) policy = bucket_wrapper.get_policy(bucket.name) assert put_policy == policy bucket_wrapper.delete_policy(bucket.name) with pytest.raises(ClientError) as exc_info: _ = bucket_wrapper.get_policy(bucket.name) assert exc_info.value.response['Error']['Code'] == 'NoSuchBucketPolicy'