Merge branch 'master' into add-iam-virtual-mfa-device
This commit is contained in:
commit
00045ae480
21 changed files with 745 additions and 230 deletions
|
|
@ -1,8 +1,8 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIEUDCCAjgCCQDfXZHMio+6oDANBgkqhkiG9w0BAQ0FADBjMQswCQYDVQQGEwJH
|
||||
MIIEUDCCAjgCCQDfXZHMio+6oDANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJH
|
||||
QjESMBAGA1UECAwJQmVya3NoaXJlMQ8wDQYDVQQHDAZTbG91Z2gxEzARBgNVBAoM
|
||||
Ck1vdG9TZXJ2ZXIxCzAJBgNVBAsMAlFBMQ0wCwYDVQQDDARNb3RvMB4XDTE3MDky
|
||||
MTIxMjQ1MFoXDTI3MDkxOTIxMjQ1MFowcTELMAkGA1UEBhMCR0IxEjAQBgNVBAgM
|
||||
Ck1vdG9TZXJ2ZXIxCzAJBgNVBAsMAlFBMQ0wCwYDVQQDDARNb3RvMB4XDTE5MTAy
|
||||
MTEzMjczMVoXDTQ5MTIzMTEzMjczNFowcTELMAkGA1UEBhMCR0IxEjAQBgNVBAgM
|
||||
CUJlcmtzaGlyZTEPMA0GA1UEBwwGU2xvdWdoMRMwEQYDVQQKDApNb3RvU2VydmVy
|
||||
MRMwEQYDVQQLDApPcGVyYXRpb25zMRMwEQYDVQQDDAoqLm1vdG8uY29tMIIBIjAN
|
||||
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzC/oBkzwiIBEceSC/tSD7hkqs8AW
|
||||
|
|
@ -11,16 +11,16 @@ niDXbMgAQE9oxUxtkFESxiNa+EbAMLBFtBkPRvc3iKXh/cfLo7yP8VdqEIDmJCB/
|
|||
vpjJvf6HnrNJ7keQR+oGJNf7jVaCgOVdJ4lt7+98YDVde7jLx1DN+QbvViJQl60n
|
||||
K3bmfuLiiw8154Eyi9DOcJE8AB+W7KpPdrmbPisR1EiqY0i0L62ZixN0rPi5hHF+
|
||||
ozwURL1axcmLjlhIFi8YhBCNcY6ThE7jrqgLIq1n6d8ezRxjDKmqfH1spQIDAQAB
|
||||
MA0GCSqGSIb3DQEBDQUAA4ICAQCgl/EfjE0Jh3cqQgoOlaFq6L1iJVgy5sYKCC4r
|
||||
OU4dHgifZ6/grqCJesGiS1Vh4L8XklN++C2aSL73lVtxXoCSopP8Yj0rOGeA6b+7
|
||||
Fetm4ZQYF61QtahC0L2fkvKXR+uz1I85ndSoMJPT8lbm7sYJuL81Si32NOo6kC6y
|
||||
4eKzV4KznxdAf6XaQMKtMIyXO3PWTrjm5ayzS6UsmnBvULGDCaAQznFlVFdGNSHx
|
||||
CaENICR0CBcB+vbL7FPC683a4afceM+aMcMVElWG5q8fxtgbL/aPhzfonhDGWOM4
|
||||
Rdg8x+yDdi7swxmWlcW5wlP8LpLxN/S3GR9j9IyelxUGmb20yTph3i1K6RM/Fm2W
|
||||
PI8xdneA6qycUAJo93NfaCuNK7yBfK3uDLqmWlGh3xCG+I1JETLRbxYBWiqeVTb3
|
||||
qjHMrsgqTqjcaCiKR/5H2eVkdcr8mLxrV5niyBItDl1xGxj4LF8hDLormhaCjiBb
|
||||
N1cMq5saj/BpoIanlqOWby6uRMYlZvuhwKQGPVWgfuRWKFzGbMWyPCxATbiU89Wb
|
||||
IykNkT1zTCE/eZwH12T4A7jrBiWq8WNfIST0Z7MReE6Oz+M9Pxx7DyDzSb2Y1RmU
|
||||
xNYd8CavZLCfns00xZSo+10deMoKVS9GgxSHcS4ELaVaBQwu35emiMJSLcK7iNGE
|
||||
I4WVSA==
|
||||
MA0GCSqGSIb3DQEBCwUAA4ICAQAOwvJjY1cLIBVGCDPkkxH4xCP6+QRdm7bqF7X5
|
||||
DNZ70YcJ27GldrEPmKX8C1RvkC4oCsaytl8Hlw3ZcS1GvwBxTVlnYIE6nLPPi1ix
|
||||
LvYYgoq+Mjk/2XPCnU/6cqJhb5INskg9s0o15jv27cUIgWVMnj+d5lvSiy1HhdYM
|
||||
wvuQzXELjhe/rHw1/BFGaBV2vd7einUQwla50UZLcsj6FwWSIsv7EB4GaY/G0XqC
|
||||
Mai2PltBgBPFqsZo27uBeVfxqMZtwAQlr4iWwWZm1haDy6D4GFCSR8E/gtlyhiN4
|
||||
MOk1cmr9PSOMB3CWqKjkx7lPMOQT/f+gxlCnupNHsHcZGvQV4mCPiU+lLwp+8z/s
|
||||
bupQwRvu1SwSUD2rIsVeUuSP3hbMcfhiZA50lenQNApimgrThdPUoFXi07FUdL+F
|
||||
1QCk6cvA48KzGRo+bPSfZQusj51k/2+hl4sHHZdWg6mGAIY9InMKmPDE4VzM8hro
|
||||
fr2fJLqKQ4h+xKbEYnvPEPttUdJbvUgr9TKKVw+m3lmW9SktzE5KtvWvN6daTj9Z
|
||||
oHDJkOyko3uyTzk+HwWDC/pQ2cC+iF1MjIHi72U9ibObSODg/d9cMH3XJTnZ9W3+
|
||||
He9iuH4dJpKnVjnJ5NKt7IOrPHID77160hpwF1dim22ZRp508eYapRzgawPMpCcd
|
||||
a6YipQ==
|
||||
-----END CERTIFICATE-----
|
||||
|
|
|
|||
59
tests/test_athena/test_athena.py
Normal file
59
tests/test_athena/test_athena.py
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import datetime
|
||||
|
||||
from botocore.exceptions import ClientError
|
||||
import boto3
|
||||
import sure # noqa
|
||||
|
||||
from moto import mock_athena
|
||||
|
||||
|
||||
@mock_athena
|
||||
def test_create_work_group():
|
||||
client = boto3.client('athena', region_name='us-east-1')
|
||||
|
||||
response = client.create_work_group(
|
||||
Name='athena_workgroup',
|
||||
Description='Test work group',
|
||||
Configuration={
|
||||
'ResultConfiguration': {
|
||||
'OutputLocation': 's3://bucket-name/prefix/',
|
||||
'EncryptionConfiguration': {
|
||||
'EncryptionOption': 'SSE_KMS',
|
||||
'KmsKey': 'aws:arn:kms:1233456789:us-east-1:key/number-1',
|
||||
},
|
||||
},
|
||||
},
|
||||
Tags=[],
|
||||
)
|
||||
|
||||
try:
|
||||
# The second time should throw an error
|
||||
response = client.create_work_group(
|
||||
Name='athena_workgroup',
|
||||
Description='duplicate',
|
||||
Configuration={
|
||||
'ResultConfiguration': {
|
||||
'OutputLocation': 's3://bucket-name/prefix/',
|
||||
'EncryptionConfiguration': {
|
||||
'EncryptionOption': 'SSE_KMS',
|
||||
'KmsKey': 'aws:arn:kms:1233456789:us-east-1:key/number-1',
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
except ClientError as err:
|
||||
err.response['Error']['Code'].should.equal('InvalidRequestException')
|
||||
err.response['Error']['Message'].should.equal('WorkGroup already exists')
|
||||
else:
|
||||
raise RuntimeError('Should have raised ResourceNotFoundException')
|
||||
|
||||
# Then test the work group appears in the work group list
|
||||
response = client.list_work_groups()
|
||||
|
||||
response['WorkGroups'].should.have.length_of(1)
|
||||
work_group = response['WorkGroups'][0]
|
||||
work_group['Name'].should.equal('athena_workgroup')
|
||||
work_group['Description'].should.equal('Test work group')
|
||||
work_group['State'].should.equal('ENABLED')
|
||||
|
|
@ -769,10 +769,10 @@ def test_get_function_created_with_zipfile():
|
|||
|
||||
|
||||
@mock_lambda
|
||||
def add_function_permission():
|
||||
def test_add_function_permission():
|
||||
conn = boto3.client('lambda', 'us-west-2')
|
||||
zip_content = get_test_zip_file1()
|
||||
result = conn.create_function(
|
||||
conn.create_function(
|
||||
FunctionName='testFunction',
|
||||
Runtime='python2.7',
|
||||
Role='test-iam-role',
|
||||
|
|
@ -796,16 +796,16 @@ def add_function_permission():
|
|||
EventSourceToken='blah',
|
||||
Qualifier='2'
|
||||
)
|
||||
assert 'Statement' in response
|
||||
res = json.loads(response['Statement'])
|
||||
assert res['Action'] == "lambda:InvokeFunction"
|
||||
assert u'Statement' in response
|
||||
res = json.loads(response[u'Statement'])
|
||||
assert res[u'Action'] == u'lambda:InvokeFunction'
|
||||
|
||||
|
||||
@mock_lambda
|
||||
def get_function_policy():
|
||||
def test_get_function_policy():
|
||||
conn = boto3.client('lambda', 'us-west-2')
|
||||
zip_content = get_test_zip_file1()
|
||||
result = conn.create_function(
|
||||
conn.create_function(
|
||||
FunctionName='testFunction',
|
||||
Runtime='python2.7',
|
||||
Role='test-iam-role',
|
||||
|
|
@ -834,10 +834,9 @@ def get_function_policy():
|
|||
FunctionName='testFunction'
|
||||
)
|
||||
|
||||
assert 'Policy' in response
|
||||
assert isinstance(response['Policy'], str)
|
||||
res = json.loads(response['Policy'])
|
||||
assert res['Statement'][0]['Action'] == 'lambda:InvokeFunction'
|
||||
assert u'Policy' in response
|
||||
res = json.loads(response[u'Policy'])
|
||||
assert res[u'Statement'][0][u'Action'] == u'lambda:InvokeFunction'
|
||||
|
||||
|
||||
@mock_lambda
|
||||
|
|
|
|||
|
|
@ -2161,20 +2161,11 @@ def test_condition_expression__attr_doesnt_exist():
|
|||
client.create_table(
|
||||
TableName='test',
|
||||
KeySchema=[{'AttributeName': 'forum_name', 'KeyType': 'HASH'}],
|
||||
AttributeDefinitions=[
|
||||
{'AttributeName': 'forum_name', 'AttributeType': 'S'},
|
||||
],
|
||||
ProvisionedThroughput={'ReadCapacityUnits': 1, 'WriteCapacityUnits': 1},
|
||||
)
|
||||
|
||||
client.put_item(
|
||||
TableName='test',
|
||||
Item={
|
||||
'forum_name': {'S': 'foo'},
|
||||
'ttl': {'N': 'bar'},
|
||||
}
|
||||
)
|
||||
AttributeDefinitions=[{'AttributeName': 'forum_name', 'AttributeType': 'S'}],
|
||||
ProvisionedThroughput={'ReadCapacityUnits': 1, 'WriteCapacityUnits': 1})
|
||||
|
||||
client.put_item(TableName='test',
|
||||
Item={'forum_name': {'S': 'foo'}, 'ttl': {'N': 'bar'}})
|
||||
|
||||
def update_if_attr_doesnt_exist():
|
||||
# Test nonexistent top-level attribute.
|
||||
|
|
@ -2261,6 +2252,7 @@ def test_condition_expression__and_order():
|
|||
}
|
||||
)
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
def test_query_gsi_with_range_key():
|
||||
dynamodb = boto3.client('dynamodb', region_name='us-east-1')
|
||||
|
|
@ -2510,13 +2502,15 @@ def test_index_with_unknown_attributes_should_fail():
|
|||
def test_update_list_index__set_existing_index():
|
||||
table_name = 'test_list_index_access'
|
||||
client = create_table_with_list(table_name)
|
||||
client.put_item(TableName=table_name,
|
||||
Item={'id': {'S': 'foo'}, 'itemlist': {'L': [{'S': 'bar1'}, {'S': 'bar2'}, {'S': 'bar3'}]}})
|
||||
client.update_item(TableName=table_name, Key={'id': {'S': 'foo'}},
|
||||
UpdateExpression='set itemlist[1]=:Item',
|
||||
ExpressionAttributeValues={':Item': {'S': 'bar2_update'}})
|
||||
#
|
||||
result = client.get_item(TableName=table_name, Key={'id': {'S': 'foo'}})['Item']
|
||||
assert result['id'] == {'S': 'foo'}
|
||||
assert result['itemlist'] == {'L': [{'S': 'bar1'}, {'S': 'bar2_update'}, {'S': 'bar3'}]}
|
||||
result['id'].should.equal({'S': 'foo'})
|
||||
result['itemlist'].should.equal({'L': [{'S': 'bar1'}, {'S': 'bar2_update'}, {'S': 'bar3'}]})
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
|
|
@ -2530,14 +2524,16 @@ def test_update_list_index__set_existing_nested_index():
|
|||
ExpressionAttributeValues={':Item': {'S': 'bar2_update'}})
|
||||
#
|
||||
result = client.get_item(TableName=table_name, Key={'id': {'S': 'foo2'}})['Item']
|
||||
assert result['id'] == {'S': 'foo2'}
|
||||
assert result['itemmap']['M']['itemlist']['L'] == [{'S': 'bar1'}, {'S': 'bar2_update'}, {'S': 'bar3'}]
|
||||
result['id'].should.equal({'S': 'foo2'})
|
||||
result['itemmap']['M']['itemlist']['L'].should.equal([{'S': 'bar1'}, {'S': 'bar2_update'}, {'S': 'bar3'}])
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
def test_update_list_index__set_index_out_of_range():
|
||||
table_name = 'test_list_index_access'
|
||||
client = create_table_with_list(table_name)
|
||||
client.put_item(TableName=table_name,
|
||||
Item={'id': {'S': 'foo'}, 'itemlist': {'L': [{'S': 'bar1'}, {'S': 'bar2'}, {'S': 'bar3'}]}})
|
||||
client.update_item(TableName=table_name, Key={'id': {'S': 'foo'}},
|
||||
UpdateExpression='set itemlist[10]=:Item',
|
||||
ExpressionAttributeValues={':Item': {'S': 'bar10'}})
|
||||
|
|
@ -2562,6 +2558,25 @@ def test_update_list_index__set_nested_index_out_of_range():
|
|||
assert result['itemmap']['M']['itemlist']['L'] == [{'S': 'bar1'}, {'S': 'bar2'}, {'S': 'bar3'}, {'S': 'bar10'}]
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
def test_update_list_index__set_double_nested_index():
|
||||
table_name = 'test_list_index_access'
|
||||
client = create_table_with_list(table_name)
|
||||
client.put_item(TableName=table_name,
|
||||
Item={'id': {'S': 'foo2'},
|
||||
'itemmap': {'M': {'itemlist': {'L': [{'M': {'foo': {'S': 'bar11'}, 'foos': {'S': 'bar12'}}},
|
||||
{'M': {'foo': {'S': 'bar21'}, 'foos': {'S': 'bar21'}}}]}}}})
|
||||
client.update_item(TableName=table_name, Key={'id': {'S': 'foo2'}},
|
||||
UpdateExpression='set itemmap.itemlist[1].foos=:Item',
|
||||
ExpressionAttributeValues={':Item': {'S': 'bar22'}})
|
||||
#
|
||||
result = client.get_item(TableName=table_name, Key={'id': {'S': 'foo2'}})['Item']
|
||||
assert result['id'] == {'S': 'foo2'}
|
||||
len(result['itemmap']['M']['itemlist']['L']).should.equal(2)
|
||||
result['itemmap']['M']['itemlist']['L'][0].should.equal({'M': {'foo': {'S': 'bar11'}, 'foos': {'S': 'bar12'}}}) # unchanged
|
||||
result['itemmap']['M']['itemlist']['L'][1].should.equal({'M': {'foo': {'S': 'bar21'}, 'foos': {'S': 'bar22'}}}) # updated
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
def test_update_list_index__set_index_of_a_string():
|
||||
table_name = 'test_list_index_access'
|
||||
|
|
@ -2578,15 +2593,29 @@ def test_update_list_index__set_index_of_a_string():
|
|||
'The document path provided in the update expression is invalid for update')
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
def test_remove_top_level_attribute():
|
||||
table_name = 'test_remove'
|
||||
client = create_table_with_list(table_name)
|
||||
client.put_item(TableName=table_name,
|
||||
Item={'id': {'S': 'foo'}, 'item': {'S': 'bar'}})
|
||||
client.update_item(TableName=table_name, Key={'id': {'S': 'foo'}}, UpdateExpression='REMOVE item')
|
||||
#
|
||||
result = client.get_item(TableName=table_name, Key={'id': {'S': 'foo'}})['Item']
|
||||
result.should.equal({'id': {'S': 'foo'}})
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
def test_remove_list_index__remove_existing_index():
|
||||
table_name = 'test_list_index_access'
|
||||
client = create_table_with_list(table_name)
|
||||
client.put_item(TableName=table_name,
|
||||
Item={'id': {'S': 'foo'}, 'itemlist': {'L': [{'S': 'bar1'}, {'S': 'bar2'}, {'S': 'bar3'}]}})
|
||||
client.update_item(TableName=table_name, Key={'id': {'S': 'foo'}}, UpdateExpression='REMOVE itemlist[1]')
|
||||
#
|
||||
result = client.get_item(TableName=table_name, Key={'id': {'S': 'foo'}})['Item']
|
||||
assert result['id'] == {'S': 'foo'}
|
||||
assert result['itemlist'] == {'L': [{'S': 'bar1'}, {'S': 'bar3'}]}
|
||||
result['id'].should.equal({'S': 'foo'})
|
||||
result['itemlist'].should.equal({'L': [{'S': 'bar1'}, {'S': 'bar3'}]})
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
|
|
@ -2598,8 +2627,8 @@ def test_remove_list_index__remove_existing_nested_index():
|
|||
client.update_item(TableName=table_name, Key={'id': {'S': 'foo2'}}, UpdateExpression='REMOVE itemmap.itemlist[1]')
|
||||
#
|
||||
result = client.get_item(TableName=table_name, Key={'id': {'S': 'foo2'}})['Item']
|
||||
assert result['id'] == {'S': 'foo2'}
|
||||
assert result['itemmap']['M']['itemlist']['L'] == [{'S': 'bar1'}]
|
||||
result['id'].should.equal({'S': 'foo2'})
|
||||
result['itemmap']['M']['itemlist']['L'].should.equal([{'S': 'bar1'}])
|
||||
|
||||
|
||||
@mock_dynamodb2
|
||||
|
|
@ -2626,6 +2655,8 @@ def test_remove_list_index__remove_existing_double_nested_index():
|
|||
def test_remove_list_index__remove_index_out_of_range():
|
||||
table_name = 'test_list_index_access'
|
||||
client = create_table_with_list(table_name)
|
||||
client.put_item(TableName=table_name,
|
||||
Item={'id': {'S': 'foo'}, 'itemlist': {'L': [{'S': 'bar1'}, {'S': 'bar2'}, {'S': 'bar3'}]}})
|
||||
client.update_item(TableName=table_name, Key={'id': {'S': 'foo'}}, UpdateExpression='REMOVE itemlist[10]')
|
||||
#
|
||||
result = client.get_item(TableName=table_name, Key={'id': {'S': 'foo'}})['Item']
|
||||
|
|
@ -2639,8 +2670,6 @@ def create_table_with_list(table_name):
|
|||
KeySchema=[{'AttributeName': 'id', 'KeyType': 'HASH'}],
|
||||
AttributeDefinitions=[{'AttributeName': 'id', 'AttributeType': 'S'}],
|
||||
BillingMode='PAY_PER_REQUEST')
|
||||
client.put_item(TableName=table_name,
|
||||
Item={'id': {'S': 'foo'}, 'itemlist': {'L': [{'S': 'bar1'}, {'S': 'bar2'}, {'S': 'bar3'}]}})
|
||||
return client
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -214,16 +214,46 @@ def test_update_login_profile():
|
|||
def test_delete_role():
|
||||
conn = boto3.client('iam', region_name='us-east-1')
|
||||
|
||||
with assert_raises(ClientError):
|
||||
with assert_raises(conn.exceptions.NoSuchEntityException):
|
||||
conn.delete_role(RoleName="my-role")
|
||||
|
||||
# Test deletion failure with a managed policy
|
||||
conn.create_role(RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="/my-path/")
|
||||
role = conn.get_role(RoleName="my-role")
|
||||
role.get('Role').get('Arn').should.equal('arn:aws:iam::123456789012:role/my-path/my-role')
|
||||
|
||||
response = conn.create_policy(PolicyName="my-managed-policy", PolicyDocument=MOCK_POLICY)
|
||||
conn.attach_role_policy(PolicyArn=response['Policy']['Arn'], RoleName="my-role")
|
||||
with assert_raises(conn.exceptions.DeleteConflictException):
|
||||
conn.delete_role(RoleName="my-role")
|
||||
conn.detach_role_policy(PolicyArn=response['Policy']['Arn'], RoleName="my-role")
|
||||
conn.delete_policy(PolicyArn=response['Policy']['Arn'])
|
||||
conn.delete_role(RoleName="my-role")
|
||||
with assert_raises(conn.exceptions.NoSuchEntityException):
|
||||
conn.get_role(RoleName="my-role")
|
||||
|
||||
with assert_raises(ClientError):
|
||||
# Test deletion failure with an inline policy
|
||||
conn.create_role(RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="/my-path/")
|
||||
conn.put_role_policy(RoleName="my-role", PolicyName="my-role-policy", PolicyDocument=MOCK_POLICY)
|
||||
with assert_raises(conn.exceptions.DeleteConflictException):
|
||||
conn.delete_role(RoleName="my-role")
|
||||
conn.delete_role_policy(RoleName="my-role", PolicyName="my-role-policy")
|
||||
conn.delete_role(RoleName="my-role")
|
||||
with assert_raises(conn.exceptions.NoSuchEntityException):
|
||||
conn.get_role(RoleName="my-role")
|
||||
|
||||
# Test deletion failure with attachment to an instance profile
|
||||
conn.create_role(RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="/my-path/")
|
||||
conn.create_instance_profile(InstanceProfileName="my-profile")
|
||||
conn.add_role_to_instance_profile(InstanceProfileName="my-profile", RoleName="my-role")
|
||||
with assert_raises(conn.exceptions.DeleteConflictException):
|
||||
conn.delete_role(RoleName="my-role")
|
||||
conn.remove_role_from_instance_profile(InstanceProfileName="my-profile", RoleName="my-role")
|
||||
conn.delete_role(RoleName="my-role")
|
||||
with assert_raises(conn.exceptions.NoSuchEntityException):
|
||||
conn.get_role(RoleName="my-role")
|
||||
|
||||
# Test deletion with no conflicts
|
||||
conn.create_role(RoleName="my-role", AssumeRolePolicyDocument="some policy", Path="/my-path/")
|
||||
conn.delete_role(RoleName="my-role")
|
||||
with assert_raises(conn.exceptions.NoSuchEntityException):
|
||||
conn.get_role(RoleName="my-role")
|
||||
|
||||
|
||||
|
|
@ -992,12 +1022,40 @@ def test_delete_user_deprecated():
|
|||
@mock_iam()
|
||||
def test_delete_user():
|
||||
conn = boto3.client('iam', region_name='us-east-1')
|
||||
with assert_raises(ClientError):
|
||||
with assert_raises(conn.exceptions.NoSuchEntityException):
|
||||
conn.delete_user(UserName='my-user')
|
||||
|
||||
# Test deletion failure with a managed policy
|
||||
conn.create_user(UserName='my-user')
|
||||
[user['UserName'] for user in conn.list_users()['Users']].should.equal(['my-user'])
|
||||
response = conn.create_policy(PolicyName="my-managed-policy", PolicyDocument=MOCK_POLICY)
|
||||
conn.attach_user_policy(PolicyArn=response['Policy']['Arn'], UserName="my-user")
|
||||
with assert_raises(conn.exceptions.DeleteConflictException):
|
||||
conn.delete_user(UserName='my-user')
|
||||
conn.detach_user_policy(PolicyArn=response['Policy']['Arn'], UserName="my-user")
|
||||
conn.delete_policy(PolicyArn=response['Policy']['Arn'])
|
||||
conn.delete_user(UserName='my-user')
|
||||
assert conn.list_users()['Users'].should.be.empty
|
||||
with assert_raises(conn.exceptions.NoSuchEntityException):
|
||||
conn.get_user(UserName='my-user')
|
||||
|
||||
# Test deletion failure with an inline policy
|
||||
conn.create_user(UserName='my-user')
|
||||
conn.put_user_policy(
|
||||
UserName='my-user',
|
||||
PolicyName='my-user-policy',
|
||||
PolicyDocument=MOCK_POLICY
|
||||
)
|
||||
with assert_raises(conn.exceptions.DeleteConflictException):
|
||||
conn.delete_user(UserName='my-user')
|
||||
conn.delete_user_policy(UserName='my-user', PolicyName='my-user-policy')
|
||||
conn.delete_user(UserName='my-user')
|
||||
with assert_raises(conn.exceptions.NoSuchEntityException):
|
||||
conn.get_user(UserName='my-user')
|
||||
|
||||
# Test deletion with no conflicts
|
||||
conn.create_user(UserName='my-user')
|
||||
conn.delete_user(UserName='my-user')
|
||||
with assert_raises(conn.exceptions.NoSuchEntityException):
|
||||
conn.get_user(UserName='my-user')
|
||||
|
||||
|
||||
@mock_iam_deprecated()
|
||||
|
|
|
|||
|
|
@ -1247,6 +1247,54 @@ def test_website_redirect_location():
|
|||
resp['WebsiteRedirectLocation'].should.equal(url)
|
||||
|
||||
|
||||
@mock_s3
|
||||
def test_boto3_list_objects_truncated_response():
|
||||
s3 = boto3.client('s3', region_name='us-east-1')
|
||||
s3.create_bucket(Bucket='mybucket')
|
||||
s3.put_object(Bucket='mybucket', Key='one', Body=b'1')
|
||||
s3.put_object(Bucket='mybucket', Key='two', Body=b'22')
|
||||
s3.put_object(Bucket='mybucket', Key='three', Body=b'333')
|
||||
|
||||
# First list
|
||||
resp = s3.list_objects(Bucket='mybucket', MaxKeys=1)
|
||||
listed_object = resp['Contents'][0]
|
||||
|
||||
assert listed_object['Key'] == 'one'
|
||||
assert resp['MaxKeys'] == 1
|
||||
assert resp['IsTruncated'] == True
|
||||
assert resp['Prefix'] == 'None'
|
||||
assert resp['Delimiter'] == 'None'
|
||||
assert 'NextMarker' in resp
|
||||
|
||||
next_marker = resp["NextMarker"]
|
||||
|
||||
# Second list
|
||||
resp = s3.list_objects(
|
||||
Bucket='mybucket', MaxKeys=1, Marker=next_marker)
|
||||
listed_object = resp['Contents'][0]
|
||||
|
||||
assert listed_object['Key'] == 'three'
|
||||
assert resp['MaxKeys'] == 1
|
||||
assert resp['IsTruncated'] == True
|
||||
assert resp['Prefix'] == 'None'
|
||||
assert resp['Delimiter'] == 'None'
|
||||
assert 'NextMarker' in resp
|
||||
|
||||
next_marker = resp["NextMarker"]
|
||||
|
||||
# Third list
|
||||
resp = s3.list_objects(
|
||||
Bucket='mybucket', MaxKeys=1, Marker=next_marker)
|
||||
listed_object = resp['Contents'][0]
|
||||
|
||||
assert listed_object['Key'] == 'two'
|
||||
assert resp['MaxKeys'] == 1
|
||||
assert resp['IsTruncated'] == False
|
||||
assert resp['Prefix'] == 'None'
|
||||
assert resp['Delimiter'] == 'None'
|
||||
assert 'NextMarker' not in resp
|
||||
|
||||
|
||||
@mock_s3
|
||||
def test_boto3_list_keys_xml_escaped():
|
||||
s3 = boto3.client('s3', region_name='us-east-1')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue