Run black on moto & test directories.

This commit is contained in:
Asher Foa 2019-10-31 08:44:26 -07:00
commit 96e5b1993d
507 changed files with 52541 additions and 47814 deletions

File diff suppressed because it is too large Load diff

View file

@ -19,14 +19,14 @@ def test_lifecycle_create():
bucket = conn.create_bucket("foobar")
lifecycle = Lifecycle()
lifecycle.add_rule('myid', '', 'Enabled', 30)
lifecycle.add_rule("myid", "", "Enabled", 30)
bucket.configure_lifecycle(lifecycle)
response = bucket.get_lifecycle_config()
len(response).should.equal(1)
lifecycle = response[0]
lifecycle.id.should.equal('myid')
lifecycle.prefix.should.equal('')
lifecycle.status.should.equal('Enabled')
lifecycle.id.should.equal("myid")
lifecycle.prefix.should.equal("")
lifecycle.status.should.equal("Enabled")
list(lifecycle.transition).should.equal([])
@ -39,21 +39,19 @@ def test_lifecycle_with_filters():
lfc = {
"Rules": [
{
"Expiration": {
"Days": 7
},
"Expiration": {"Days": 7},
"ID": "wholebucket",
"Filter": {
"Prefix": ""
},
"Status": "Enabled"
"Filter": {"Prefix": ""},
"Status": "Enabled",
}
]
}
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
assert len(result["Rules"]) == 1
assert result["Rules"][0]["Filter"]["Prefix"] == ''
assert result["Rules"][0]["Filter"]["Prefix"] == ""
assert not result["Rules"][0]["Filter"].get("And")
assert not result["Rules"][0]["Filter"].get("Tag")
with assert_raises(KeyError):
@ -63,39 +61,38 @@ def test_lifecycle_with_filters():
lfc = {
"Rules": [
{
"Expiration": {
"Days": 7
},
"Expiration": {"Days": 7},
"ID": "wholebucket",
"Filter": {},
"Status": "Enabled"
"Status": "Enabled",
}
]
}
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
assert len(result["Rules"]) == 1
with assert_raises(KeyError):
assert result["Rules"][0]["Prefix"]
# If we remove the filter -- and don't specify a Prefix, then this is bad:
lfc['Rules'][0].pop('Filter')
lfc["Rules"][0].pop("Filter")
with assert_raises(ClientError) as err:
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
assert err.exception.response["Error"]["Code"] == "MalformedXML"
# With a tag:
lfc["Rules"][0]["Filter"] = {
'Tag': {
"Key": "mytag",
"Value": "mytagvalue"
}
}
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
lfc["Rules"][0]["Filter"] = {"Tag": {"Key": "mytag", "Value": "mytagvalue"}}
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
assert len(result["Rules"]) == 1
with assert_raises(KeyError):
assert result["Rules"][0]["Filter"]['Prefix']
assert result["Rules"][0]["Filter"]["Prefix"]
assert not result["Rules"][0]["Filter"].get("And")
assert result["Rules"][0]["Filter"]["Tag"]["Key"] == "mytag"
assert result["Rules"][0]["Filter"]["Tag"]["Value"] == "mytagvalue"
@ -106,15 +103,12 @@ def test_lifecycle_with_filters():
lfc["Rules"][0]["Filter"] = {
"And": {
"Prefix": "some/prefix",
"Tags": [
{
"Key": "mytag",
"Value": "mytagvalue"
}
]
"Tags": [{"Key": "mytag", "Value": "mytagvalue"}],
}
}
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
assert len(result["Rules"]) == 1
assert not result["Rules"][0]["Filter"].get("Prefix")
@ -129,17 +123,13 @@ def test_lifecycle_with_filters():
lfc["Rules"][0]["Filter"]["And"] = {
"Prefix": "some/prefix",
"Tags": [
{
"Key": "mytag",
"Value": "mytagvalue"
},
{
"Key": "mytag2",
"Value": "mytagvalue2"
}
]
{"Key": "mytag", "Value": "mytagvalue"},
{"Key": "mytag2", "Value": "mytagvalue2"},
],
}
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
assert len(result["Rules"]) == 1
assert not result["Rules"][0]["Filter"].get("Prefix")
@ -155,17 +145,13 @@ def test_lifecycle_with_filters():
# And filter without Prefix but multiple Tags:
lfc["Rules"][0]["Filter"]["And"] = {
"Tags": [
{
"Key": "mytag",
"Value": "mytagvalue"
},
{
"Key": "mytag2",
"Value": "mytagvalue2"
}
{"Key": "mytag", "Value": "mytagvalue"},
{"Key": "mytag2", "Value": "mytagvalue2"},
]
}
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
assert len(result["Rules"]) == 1
with assert_raises(KeyError):
@ -179,89 +165,81 @@ def test_lifecycle_with_filters():
assert result["Rules"][0]["Prefix"]
# Can't have both filter and prefix:
lfc["Rules"][0]["Prefix"] = ''
lfc["Rules"][0]["Prefix"] = ""
with assert_raises(ClientError) as err:
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
assert err.exception.response["Error"]["Code"] == "MalformedXML"
lfc["Rules"][0]["Prefix"] = 'some/path'
lfc["Rules"][0]["Prefix"] = "some/path"
with assert_raises(ClientError) as err:
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
assert err.exception.response["Error"]["Code"] == "MalformedXML"
# No filters -- just a prefix:
del lfc["Rules"][0]["Filter"]
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
assert not result["Rules"][0].get("Filter")
assert result["Rules"][0]["Prefix"] == "some/path"
# Can't have Tag, Prefix, and And in a filter:
del lfc['Rules'][0]['Prefix']
del lfc["Rules"][0]["Prefix"]
lfc["Rules"][0]["Filter"] = {
"Prefix": "some/prefix",
"Tag": {
"Key": "mytag",
"Value": "mytagvalue"
}
"Tag": {"Key": "mytag", "Value": "mytagvalue"},
}
with assert_raises(ClientError) as err:
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
assert err.exception.response["Error"]["Code"] == "MalformedXML"
lfc["Rules"][0]["Filter"] = {
"Tag": {
"Key": "mytag",
"Value": "mytagvalue"
},
"Tag": {"Key": "mytag", "Value": "mytagvalue"},
"And": {
"Prefix": "some/prefix",
"Tags": [
{
"Key": "mytag",
"Value": "mytagvalue"
},
{
"Key": "mytag2",
"Value": "mytagvalue2"
}
]
}
{"Key": "mytag", "Value": "mytagvalue"},
{"Key": "mytag2", "Value": "mytagvalue2"},
],
},
}
with assert_raises(ClientError) as err:
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
assert err.exception.response["Error"]["Code"] == "MalformedXML"
# Make sure multiple rules work:
lfc = {
"Rules": [
{
"Expiration": {
"Days": 7
},
"Expiration": {"Days": 7},
"ID": "wholebucket",
"Filter": {
"Prefix": ""
},
"Status": "Enabled"
"Filter": {"Prefix": ""},
"Status": "Enabled",
},
{
"Expiration": {
"Days": 10
},
"Expiration": {"Days": 10},
"ID": "Tags",
"Filter": {
"Tag": {'Key': 'somekey', 'Value': 'somevalue'}
},
"Status": "Enabled"
}
"Filter": {"Tag": {"Key": "somekey", "Value": "somevalue"}},
"Status": "Enabled",
},
]
}
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")['Rules']
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")["Rules"]
assert len(result) == 2
assert result[0]['ID'] == 'wholebucket'
assert result[1]['ID'] == 'Tags'
assert result[0]["ID"] == "wholebucket"
assert result[1]["ID"] == "Tags"
@mock_s3
@ -272,25 +250,25 @@ def test_lifecycle_with_eodm():
lfc = {
"Rules": [
{
"Expiration": {
"ExpiredObjectDeleteMarker": True
},
"Expiration": {"ExpiredObjectDeleteMarker": True},
"ID": "wholebucket",
"Filter": {
"Prefix": ""
},
"Status": "Enabled"
"Filter": {"Prefix": ""},
"Status": "Enabled",
}
]
}
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
assert len(result["Rules"]) == 1
assert result["Rules"][0]["Expiration"]["ExpiredObjectDeleteMarker"]
# Set to False:
lfc["Rules"][0]["Expiration"]["ExpiredObjectDeleteMarker"] = False
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
assert len(result["Rules"]) == 1
assert not result["Rules"][0]["Expiration"]["ExpiredObjectDeleteMarker"]
@ -298,13 +276,17 @@ def test_lifecycle_with_eodm():
# With failure:
lfc["Rules"][0]["Expiration"]["Days"] = 7
with assert_raises(ClientError) as err:
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
assert err.exception.response["Error"]["Code"] == "MalformedXML"
del lfc["Rules"][0]["Expiration"]["Days"]
lfc["Rules"][0]["Expiration"]["Date"] = datetime(2015, 1, 1)
with assert_raises(ClientError) as err:
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
assert err.exception.response["Error"]["Code"] == "MalformedXML"
@ -316,25 +298,25 @@ def test_lifecycle_with_nve():
lfc = {
"Rules": [
{
"NoncurrentVersionExpiration": {
"NoncurrentDays": 30
},
"NoncurrentVersionExpiration": {"NoncurrentDays": 30},
"ID": "wholebucket",
"Filter": {
"Prefix": ""
},
"Status": "Enabled"
"Filter": {"Prefix": ""},
"Status": "Enabled",
}
]
}
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
assert len(result["Rules"]) == 1
assert result["Rules"][0]["NoncurrentVersionExpiration"]["NoncurrentDays"] == 30
# Change NoncurrentDays:
lfc["Rules"][0]["NoncurrentVersionExpiration"]["NoncurrentDays"] = 10
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
assert len(result["Rules"]) == 1
assert result["Rules"][0]["NoncurrentVersionExpiration"]["NoncurrentDays"] == 10
@ -350,48 +332,61 @@ def test_lifecycle_with_nvt():
lfc = {
"Rules": [
{
"NoncurrentVersionTransitions": [{
"NoncurrentDays": 30,
"StorageClass": "ONEZONE_IA"
}],
"NoncurrentVersionTransitions": [
{"NoncurrentDays": 30, "StorageClass": "ONEZONE_IA"}
],
"ID": "wholebucket",
"Filter": {
"Prefix": ""
},
"Status": "Enabled"
"Filter": {"Prefix": ""},
"Status": "Enabled",
}
]
}
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
assert len(result["Rules"]) == 1
assert result["Rules"][0]["NoncurrentVersionTransitions"][0]["NoncurrentDays"] == 30
assert result["Rules"][0]["NoncurrentVersionTransitions"][0]["StorageClass"] == "ONEZONE_IA"
assert (
result["Rules"][0]["NoncurrentVersionTransitions"][0]["StorageClass"]
== "ONEZONE_IA"
)
# Change NoncurrentDays:
lfc["Rules"][0]["NoncurrentVersionTransitions"][0]["NoncurrentDays"] = 10
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
assert len(result["Rules"]) == 1
assert result["Rules"][0]["NoncurrentVersionTransitions"][0]["NoncurrentDays"] == 10
# Change StorageClass:
lfc["Rules"][0]["NoncurrentVersionTransitions"][0]["StorageClass"] = "GLACIER"
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
assert len(result["Rules"]) == 1
assert result["Rules"][0]["NoncurrentVersionTransitions"][0]["StorageClass"] == "GLACIER"
assert (
result["Rules"][0]["NoncurrentVersionTransitions"][0]["StorageClass"]
== "GLACIER"
)
# With failures for missing children:
del lfc["Rules"][0]["NoncurrentVersionTransitions"][0]["NoncurrentDays"]
with assert_raises(ClientError) as err:
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
assert err.exception.response["Error"]["Code"] == "MalformedXML"
lfc["Rules"][0]["NoncurrentVersionTransitions"][0]["NoncurrentDays"] = 30
del lfc["Rules"][0]["NoncurrentVersionTransitions"][0]["StorageClass"]
with assert_raises(ClientError) as err:
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
assert err.exception.response["Error"]["Code"] == "MalformedXML"
@ -403,28 +398,33 @@ def test_lifecycle_with_aimu():
lfc = {
"Rules": [
{
"AbortIncompleteMultipartUpload": {
"DaysAfterInitiation": 7
},
"AbortIncompleteMultipartUpload": {"DaysAfterInitiation": 7},
"ID": "wholebucket",
"Filter": {
"Prefix": ""
},
"Status": "Enabled"
"Filter": {"Prefix": ""},
"Status": "Enabled",
}
]
}
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
assert len(result["Rules"]) == 1
assert result["Rules"][0]["AbortIncompleteMultipartUpload"]["DaysAfterInitiation"] == 7
assert (
result["Rules"][0]["AbortIncompleteMultipartUpload"]["DaysAfterInitiation"] == 7
)
# Change DaysAfterInitiation:
lfc["Rules"][0]["AbortIncompleteMultipartUpload"]["DaysAfterInitiation"] = 30
client.put_bucket_lifecycle_configuration(Bucket="bucket", LifecycleConfiguration=lfc)
client.put_bucket_lifecycle_configuration(
Bucket="bucket", LifecycleConfiguration=lfc
)
result = client.get_bucket_lifecycle_configuration(Bucket="bucket")
assert len(result["Rules"]) == 1
assert result["Rules"][0]["AbortIncompleteMultipartUpload"]["DaysAfterInitiation"] == 30
assert (
result["Rules"][0]["AbortIncompleteMultipartUpload"]["DaysAfterInitiation"]
== 30
)
# TODO: Add test for failures due to missing children
@ -435,15 +435,16 @@ def test_lifecycle_with_glacier_transition():
bucket = conn.create_bucket("foobar")
lifecycle = Lifecycle()
transition = Transition(days=30, storage_class='GLACIER')
rule = Rule('myid', prefix='', status='Enabled', expiration=None,
transition=transition)
transition = Transition(days=30, storage_class="GLACIER")
rule = Rule(
"myid", prefix="", status="Enabled", expiration=None, transition=transition
)
lifecycle.append(rule)
bucket.configure_lifecycle(lifecycle)
response = bucket.get_lifecycle_config()
transition = response[0].transition
transition.days.should.equal(30)
transition.storage_class.should.equal('GLACIER')
transition.storage_class.should.equal("GLACIER")
transition.date.should.equal(None)
@ -452,16 +453,16 @@ def test_lifecycle_multi():
conn = boto.s3.connect_to_region("us-west-1")
bucket = conn.create_bucket("foobar")
date = '2022-10-12T00:00:00.000Z'
sc = 'GLACIER'
date = "2022-10-12T00:00:00.000Z"
sc = "GLACIER"
lifecycle = Lifecycle()
lifecycle.add_rule("1", "1/", "Enabled", 1)
lifecycle.add_rule("2", "2/", "Enabled", Expiration(days=2))
lifecycle.add_rule("3", "3/", "Enabled", Expiration(date=date))
lifecycle.add_rule("4", "4/", "Enabled", None,
Transition(days=4, storage_class=sc))
lifecycle.add_rule("5", "5/", "Enabled", None,
Transition(date=date, storage_class=sc))
lifecycle.add_rule("4", "4/", "Enabled", None, Transition(days=4, storage_class=sc))
lifecycle.add_rule(
"5", "5/", "Enabled", None, Transition(date=date, storage_class=sc)
)
bucket.configure_lifecycle(lifecycle)
# read the lifecycle back

View file

@ -11,30 +11,35 @@ from moto import mock_s3
@mock_s3
def test_s3_storage_class_standard():
s3 = boto3.client("s3")
s3.create_bucket(Bucket="Bucket")
s3 = boto3.client("s3")
s3.create_bucket(Bucket="Bucket")
# add an object to the bucket with standard storage
# add an object to the bucket with standard storage
s3.put_object(Bucket="Bucket", Key="my_key", Body="my_value")
s3.put_object(Bucket="Bucket", Key="my_key", Body="my_value")
list_of_objects = s3.list_objects(Bucket="Bucket")
list_of_objects = s3.list_objects(Bucket="Bucket")
list_of_objects['Contents'][0]["StorageClass"].should.equal("STANDARD")
list_of_objects["Contents"][0]["StorageClass"].should.equal("STANDARD")
@mock_s3
def test_s3_storage_class_infrequent_access():
s3 = boto3.client("s3")
s3.create_bucket(Bucket="Bucket")
s3 = boto3.client("s3")
s3.create_bucket(Bucket="Bucket")
# add an object to the bucket with standard storage
# add an object to the bucket with standard storage
s3.put_object(Bucket="Bucket", Key="my_key_infrequent", Body="my_value_infrequent", StorageClass="STANDARD_IA")
s3.put_object(
Bucket="Bucket",
Key="my_key_infrequent",
Body="my_value_infrequent",
StorageClass="STANDARD_IA",
)
D = s3.list_objects(Bucket="Bucket")
D = s3.list_objects(Bucket="Bucket")
D['Contents'][0]["StorageClass"].should.equal("STANDARD_IA")
D["Contents"][0]["StorageClass"].should.equal("STANDARD_IA")
@mock_s3
@ -42,74 +47,104 @@ def test_s3_storage_class_intelligent_tiering():
s3 = boto3.client("s3")
s3.create_bucket(Bucket="Bucket")
s3.put_object(Bucket="Bucket", Key="my_key_infrequent", Body="my_value_infrequent", StorageClass="INTELLIGENT_TIERING")
s3.put_object(
Bucket="Bucket",
Key="my_key_infrequent",
Body="my_value_infrequent",
StorageClass="INTELLIGENT_TIERING",
)
objects = s3.list_objects(Bucket="Bucket")
objects['Contents'][0]["StorageClass"].should.equal("INTELLIGENT_TIERING")
objects["Contents"][0]["StorageClass"].should.equal("INTELLIGENT_TIERING")
@mock_s3
def test_s3_storage_class_copy():
s3 = boto3.client("s3")
s3.create_bucket(Bucket="Bucket")
s3.put_object(Bucket="Bucket", Key="First_Object", Body="Body", StorageClass="STANDARD")
s3 = boto3.client("s3")
s3.create_bucket(Bucket="Bucket")
s3.put_object(
Bucket="Bucket", Key="First_Object", Body="Body", StorageClass="STANDARD"
)
s3.create_bucket(Bucket="Bucket2")
# second object is originally of storage class REDUCED_REDUNDANCY
s3.put_object(Bucket="Bucket2", Key="Second_Object", Body="Body2")
s3.create_bucket(Bucket="Bucket2")
# second object is originally of storage class REDUCED_REDUNDANCY
s3.put_object(Bucket="Bucket2", Key="Second_Object", Body="Body2")
s3.copy_object(CopySource = {"Bucket": "Bucket", "Key": "First_Object"}, Bucket="Bucket2", Key="Second_Object", StorageClass="ONEZONE_IA")
s3.copy_object(
CopySource={"Bucket": "Bucket", "Key": "First_Object"},
Bucket="Bucket2",
Key="Second_Object",
StorageClass="ONEZONE_IA",
)
list_of_copied_objects = s3.list_objects(Bucket="Bucket2")
list_of_copied_objects = s3.list_objects(Bucket="Bucket2")
# checks that a copied object can be properly copied
list_of_copied_objects["Contents"][0]["StorageClass"].should.equal("ONEZONE_IA")
# checks that a copied object can be properly copied
list_of_copied_objects["Contents"][0]["StorageClass"].should.equal("ONEZONE_IA")
@mock_s3
def test_s3_invalid_copied_storage_class():
s3 = boto3.client("s3")
s3.create_bucket(Bucket="Bucket")
s3.put_object(Bucket="Bucket", Key="First_Object", Body="Body", StorageClass="STANDARD")
s3 = boto3.client("s3")
s3.create_bucket(Bucket="Bucket")
s3.put_object(
Bucket="Bucket", Key="First_Object", Body="Body", StorageClass="STANDARD"
)
s3.create_bucket(Bucket="Bucket2")
s3.put_object(Bucket="Bucket2", Key="Second_Object", Body="Body2", StorageClass="REDUCED_REDUNDANCY")
s3.create_bucket(Bucket="Bucket2")
s3.put_object(
Bucket="Bucket2",
Key="Second_Object",
Body="Body2",
StorageClass="REDUCED_REDUNDANCY",
)
# Try to copy an object with an invalid storage class
with assert_raises(ClientError) as err:
s3.copy_object(CopySource = {"Bucket": "Bucket", "Key": "First_Object"}, Bucket="Bucket2", Key="Second_Object", StorageClass="STANDARD2")
# Try to copy an object with an invalid storage class
with assert_raises(ClientError) as err:
s3.copy_object(
CopySource={"Bucket": "Bucket", "Key": "First_Object"},
Bucket="Bucket2",
Key="Second_Object",
StorageClass="STANDARD2",
)
e = err.exception
e.response["Error"]["Code"].should.equal("InvalidStorageClass")
e.response["Error"]["Message"].should.equal("The storage class you specified is not valid")
e = err.exception
e.response["Error"]["Code"].should.equal("InvalidStorageClass")
e.response["Error"]["Message"].should.equal(
"The storage class you specified is not valid"
)
@mock_s3
def test_s3_invalid_storage_class():
s3 = boto3.client("s3")
s3.create_bucket(Bucket="Bucket")
s3 = boto3.client("s3")
s3.create_bucket(Bucket="Bucket")
# Try to add an object with an invalid storage class
with assert_raises(ClientError) as err:
s3.put_object(Bucket="Bucket", Key="First_Object", Body="Body", StorageClass="STANDARDD")
# Try to add an object with an invalid storage class
with assert_raises(ClientError) as err:
s3.put_object(
Bucket="Bucket", Key="First_Object", Body="Body", StorageClass="STANDARDD"
)
e = err.exception
e.response["Error"]["Code"].should.equal("InvalidStorageClass")
e.response["Error"]["Message"].should.equal("The storage class you specified is not valid")
e = err.exception
e.response["Error"]["Code"].should.equal("InvalidStorageClass")
e.response["Error"]["Message"].should.equal(
"The storage class you specified is not valid"
)
@mock_s3
def test_s3_default_storage_class():
s3 = boto3.client("s3")
s3.create_bucket(Bucket="Bucket")
s3 = boto3.client("s3")
s3.create_bucket(Bucket="Bucket")
s3.put_object(Bucket="Bucket", Key="First_Object", Body="Body")
s3.put_object(Bucket="Bucket", Key="First_Object", Body="Body")
list_of_objects = s3.list_objects(Bucket="Bucket")
list_of_objects = s3.list_objects(Bucket="Bucket")
# tests that the default storage class is still STANDARD
list_of_objects["Contents"][0]["StorageClass"].should.equal("STANDARD")
# tests that the default storage class is still STANDARD
list_of_objects["Contents"][0]["StorageClass"].should.equal("STANDARD")
@mock_s3
@ -117,10 +152,16 @@ def test_s3_copy_object_error_for_glacier_storage_class():
s3 = boto3.client("s3")
s3.create_bucket(Bucket="Bucket")
s3.put_object(Bucket="Bucket", Key="First_Object", Body="Body", StorageClass="GLACIER")
s3.put_object(
Bucket="Bucket", Key="First_Object", Body="Body", StorageClass="GLACIER"
)
with assert_raises(ClientError) as exc:
s3.copy_object(CopySource={"Bucket": "Bucket", "Key": "First_Object"}, Bucket="Bucket", Key="Second_Object")
s3.copy_object(
CopySource={"Bucket": "Bucket", "Key": "First_Object"},
Bucket="Bucket",
Key="Second_Object",
)
exc.exception.response["Error"]["Code"].should.equal("ObjectNotInActiveTierError")
@ -130,9 +171,15 @@ def test_s3_copy_object_error_for_deep_archive_storage_class():
s3 = boto3.client("s3")
s3.create_bucket(Bucket="Bucket")
s3.put_object(Bucket="Bucket", Key="First_Object", Body="Body", StorageClass="DEEP_ARCHIVE")
s3.put_object(
Bucket="Bucket", Key="First_Object", Body="Body", StorageClass="DEEP_ARCHIVE"
)
with assert_raises(ClientError) as exc:
s3.copy_object(CopySource={"Bucket": "Bucket", "Key": "First_Object"}, Bucket="Bucket", Key="Second_Object")
s3.copy_object(
CopySource={"Bucket": "Bucket", "Key": "First_Object"},
Bucket="Bucket",
Key="Second_Object",
)
exc.exception.response["Error"]["Code"].should.equal("ObjectNotInActiveTierError")

View file

@ -1,28 +1,36 @@
from __future__ import unicode_literals
import os
from sure import expect
from moto.s3.utils import bucket_name_from_url, _VersionedKeyStore, parse_region_from_url, clean_key_name, undo_clean_key_name
from moto.s3.utils import (
bucket_name_from_url,
_VersionedKeyStore,
parse_region_from_url,
clean_key_name,
undo_clean_key_name,
)
from parameterized import parameterized
def test_base_url():
expect(bucket_name_from_url('https://s3.amazonaws.com/')).should.equal(None)
expect(bucket_name_from_url("https://s3.amazonaws.com/")).should.equal(None)
def test_localhost_bucket():
expect(bucket_name_from_url('https://wfoobar.localhost:5000/abc')
).should.equal("wfoobar")
expect(bucket_name_from_url("https://wfoobar.localhost:5000/abc")).should.equal(
"wfoobar"
)
def test_localhost_without_bucket():
expect(bucket_name_from_url(
'https://www.localhost:5000/def')).should.equal(None)
expect(bucket_name_from_url("https://www.localhost:5000/def")).should.equal(None)
def test_force_ignore_subdomain_for_bucketnames():
os.environ['S3_IGNORE_SUBDOMAIN_BUCKETNAME'] = '1'
expect(bucket_name_from_url('https://subdomain.localhost:5000/abc/resource')).should.equal(None)
del(os.environ['S3_IGNORE_SUBDOMAIN_BUCKETNAME'])
os.environ["S3_IGNORE_SUBDOMAIN_BUCKETNAME"] = "1"
expect(
bucket_name_from_url("https://subdomain.localhost:5000/abc/resource")
).should.equal(None)
del os.environ["S3_IGNORE_SUBDOMAIN_BUCKETNAME"]
def test_versioned_key_store():
@ -30,78 +38,84 @@ def test_versioned_key_store():
d.should.have.length_of(0)
d['key'] = [1]
d["key"] = [1]
d.should.have.length_of(1)
d['key'] = 2
d["key"] = 2
d.should.have.length_of(1)
d.should.have.key('key').being.equal(2)
d.should.have.key("key").being.equal(2)
d.get.when.called_with('key').should.return_value(2)
d.get.when.called_with('badkey').should.return_value(None)
d.get.when.called_with('badkey', 'HELLO').should.return_value('HELLO')
d.get.when.called_with("key").should.return_value(2)
d.get.when.called_with("badkey").should.return_value(None)
d.get.when.called_with("badkey", "HELLO").should.return_value("HELLO")
# Tests key[
d.shouldnt.have.key('badkey')
d.__getitem__.when.called_with('badkey').should.throw(KeyError)
d.shouldnt.have.key("badkey")
d.__getitem__.when.called_with("badkey").should.throw(KeyError)
d.getlist('key').should.have.length_of(2)
d.getlist('key').should.be.equal([[1], 2])
d.getlist('badkey').should.be.none
d.getlist("key").should.have.length_of(2)
d.getlist("key").should.be.equal([[1], 2])
d.getlist("badkey").should.be.none
d.setlist('key', 1)
d.getlist('key').should.be.equal([1])
d.setlist("key", 1)
d.getlist("key").should.be.equal([1])
d.setlist('key', (1, 2))
d.getlist('key').shouldnt.be.equal((1, 2))
d.getlist('key').should.be.equal([1, 2])
d.setlist("key", (1, 2))
d.getlist("key").shouldnt.be.equal((1, 2))
d.getlist("key").should.be.equal([1, 2])
d.setlist('key', [[1], [2]])
d['key'].should.have.length_of(1)
d.getlist('key').should.be.equal([[1], [2]])
d.setlist("key", [[1], [2]])
d["key"].should.have.length_of(1)
d.getlist("key").should.be.equal([[1], [2]])
def test_parse_region_from_url():
expected = 'us-west-2'
for url in ['http://s3-us-west-2.amazonaws.com/bucket',
'http://s3.us-west-2.amazonaws.com/bucket',
'http://bucket.s3-us-west-2.amazonaws.com',
'https://s3-us-west-2.amazonaws.com/bucket',
'https://s3.us-west-2.amazonaws.com/bucket',
'https://bucket.s3-us-west-2.amazonaws.com']:
expected = "us-west-2"
for url in [
"http://s3-us-west-2.amazonaws.com/bucket",
"http://s3.us-west-2.amazonaws.com/bucket",
"http://bucket.s3-us-west-2.amazonaws.com",
"https://s3-us-west-2.amazonaws.com/bucket",
"https://s3.us-west-2.amazonaws.com/bucket",
"https://bucket.s3-us-west-2.amazonaws.com",
]:
parse_region_from_url(url).should.equal(expected)
expected = 'us-east-1'
for url in ['http://s3.amazonaws.com/bucket',
'http://bucket.s3.amazonaws.com',
'https://s3.amazonaws.com/bucket',
'https://bucket.s3.amazonaws.com']:
expected = "us-east-1"
for url in [
"http://s3.amazonaws.com/bucket",
"http://bucket.s3.amazonaws.com",
"https://s3.amazonaws.com/bucket",
"https://bucket.s3.amazonaws.com",
]:
parse_region_from_url(url).should.equal(expected)
@parameterized([
('foo/bar/baz',
'foo/bar/baz'),
('foo',
'foo'),
('foo/run_dt%3D2019-01-01%252012%253A30%253A00',
'foo/run_dt=2019-01-01%2012%3A30%3A00'),
])
@parameterized(
[
("foo/bar/baz", "foo/bar/baz"),
("foo", "foo"),
(
"foo/run_dt%3D2019-01-01%252012%253A30%253A00",
"foo/run_dt=2019-01-01%2012%3A30%3A00",
),
]
)
def test_clean_key_name(key, expected):
clean_key_name(key).should.equal(expected)
@parameterized([
('foo/bar/baz',
'foo/bar/baz'),
('foo',
'foo'),
('foo/run_dt%3D2019-01-01%252012%253A30%253A00',
'foo/run_dt%253D2019-01-01%25252012%25253A30%25253A00'),
])
@parameterized(
[
("foo/bar/baz", "foo/bar/baz"),
("foo", "foo"),
(
"foo/run_dt%3D2019-01-01%252012%253A30%253A00",
"foo/run_dt%253D2019-01-01%25252012%25253A30%25253A00",
),
]
)
def test_undo_clean_key_name(key, expected):
undo_clean_key_name(key).should.equal(expected)

View file

@ -6,16 +6,16 @@ import sure # noqa
from flask.testing import FlaskClient
import moto.server as server
'''
"""
Test the different server responses
'''
"""
class AuthenticatedClient(FlaskClient):
def open(self, *args, **kwargs):
kwargs['headers'] = kwargs.get('headers', {})
kwargs['headers']['Authorization'] = "Any authorization header"
kwargs['content_length'] = 0 # Fixes content-length complaints.
kwargs["headers"] = kwargs.get("headers", {})
kwargs["headers"]["Authorization"] = "Any authorization header"
kwargs["content_length"] = 0 # Fixes content-length complaints.
return super(AuthenticatedClient, self).open(*args, **kwargs)
@ -27,30 +27,29 @@ def authenticated_client():
def test_s3_server_get():
test_client = authenticated_client()
res = test_client.get('/')
res = test_client.get("/")
res.data.should.contain(b'ListAllMyBucketsResult')
res.data.should.contain(b"ListAllMyBucketsResult")
def test_s3_server_bucket_create():
test_client = authenticated_client()
res = test_client.put('/', 'http://foobaz.localhost:5000/')
res = test_client.put("/", "http://foobaz.localhost:5000/")
res.status_code.should.equal(200)
res = test_client.get('/')
res.data.should.contain(b'<Name>foobaz</Name>')
res = test_client.get("/")
res.data.should.contain(b"<Name>foobaz</Name>")
res = test_client.get('/', 'http://foobaz.localhost:5000/')
res = test_client.get("/", "http://foobaz.localhost:5000/")
res.status_code.should.equal(200)
res.data.should.contain(b"ListBucketResult")
res = test_client.put(
'/bar', 'http://foobaz.localhost:5000/', data='test value')
res = test_client.put("/bar", "http://foobaz.localhost:5000/", data="test value")
res.status_code.should.equal(200)
assert 'ETag' in dict(res.headers)
assert "ETag" in dict(res.headers)
res = test_client.get('/bar', 'http://foobaz.localhost:5000/')
res = test_client.get("/bar", "http://foobaz.localhost:5000/")
res.status_code.should.equal(200)
res.data.should.equal(b"test value")
@ -59,24 +58,24 @@ def test_s3_server_bucket_versioning():
test_client = authenticated_client()
# Just enough XML to enable versioning
body = '<Status>Enabled</Status>'
res = test_client.put(
'/?versioning', 'http://foobaz.localhost:5000', data=body)
body = "<Status>Enabled</Status>"
res = test_client.put("/?versioning", "http://foobaz.localhost:5000", data=body)
res.status_code.should.equal(200)
def test_s3_server_post_to_bucket():
test_client = authenticated_client()
res = test_client.put('/', 'http://tester.localhost:5000/')
res = test_client.put("/", "http://tester.localhost:5000/")
res.status_code.should.equal(200)
test_client.post('/', "https://tester.localhost:5000/", data={
'key': 'the-key',
'file': 'nothing'
})
test_client.post(
"/",
"https://tester.localhost:5000/",
data={"key": "the-key", "file": "nothing"},
)
res = test_client.get('/the-key', 'http://tester.localhost:5000/')
res = test_client.get("/the-key", "http://tester.localhost:5000/")
res.status_code.should.equal(200)
res.data.should.equal(b"nothing")
@ -84,23 +83,28 @@ def test_s3_server_post_to_bucket():
def test_s3_server_post_without_content_length():
test_client = authenticated_client()
res = test_client.put('/', 'http://tester.localhost:5000/', environ_overrides={'CONTENT_LENGTH': ''})
res = test_client.put(
"/", "http://tester.localhost:5000/", environ_overrides={"CONTENT_LENGTH": ""}
)
res.status_code.should.equal(411)
res = test_client.post('/', "https://tester.localhost:5000/", environ_overrides={'CONTENT_LENGTH': ''})
res = test_client.post(
"/", "https://tester.localhost:5000/", environ_overrides={"CONTENT_LENGTH": ""}
)
res.status_code.should.equal(411)
def test_s3_server_post_unicode_bucket_key():
# Make sure that we can deal with non-ascii characters in request URLs (e.g., S3 object names)
dispatcher = server.DomainDispatcherApplication(server.create_backend_app)
backend_app = dispatcher.get_application({
'HTTP_HOST': 's3.amazonaws.com',
'PATH_INFO': '/test-bucket/test-object-てすと'
})
backend_app = dispatcher.get_application(
{"HTTP_HOST": "s3.amazonaws.com", "PATH_INFO": "/test-bucket/test-object-てすと"}
)
assert backend_app
backend_app = dispatcher.get_application({
'HTTP_HOST': 's3.amazonaws.com',
'PATH_INFO': '/test-bucket/test-object-てすと'.encode('utf-8')
})
backend_app = dispatcher.get_application(
{
"HTTP_HOST": "s3.amazonaws.com",
"PATH_INFO": "/test-bucket/test-object-てすと".encode("utf-8"),
}
)
assert backend_app