Improve SQS Compatibility with AWS (#1520)

* Return correct error code when fetching a queue that does not exist

* Improve SQS Queue get and set attributes

* Queue creation and set_attributes uses the same code path
    - ensure bool/int values are cast correctly
* RedrivePolicy is handled properly with set_attributes
    - _setup_dlq is called
    - is json decoded, so that returned RedrivePolicy is not json
      encoded twice
* As per AWS not all attributes are returned when they are not set, for
  example RedrivePolicy, FifoQueue, Policy, Kms*
* WaitTimeSeconds is not a queue attribute switch to
  ReceiveMessageWaitTimeSeconds
This commit is contained in:
Iain Bullard 2018-03-21 15:48:08 +00:00 committed by Jack Danger
commit 6dce7dcb18
3 changed files with 170 additions and 60 deletions

View file

@ -72,6 +72,24 @@ def test_create_queue():
queue.attributes.get('VisibilityTimeout').should.equal('30')
@mock_sqs
def test_create_queue_kms():
sqs = boto3.resource('sqs', region_name='us-east-1')
new_queue = sqs.create_queue(
QueueName='test-queue',
Attributes={
'KmsMasterKeyId': 'master-key-id',
'KmsDataKeyReusePeriodSeconds': '600'
})
new_queue.should_not.be.none
queue = sqs.get_queue_by_name(QueueName='test-queue')
queue.attributes.get('KmsMasterKeyId').should.equal('master-key-id')
queue.attributes.get('KmsDataKeyReusePeriodSeconds').should.equal('600')
@mock_sqs
def test_get_nonexistent_queue():
sqs = boto3.resource('sqs', region_name='us-east-1')
@ -79,13 +97,15 @@ def test_get_nonexistent_queue():
sqs.get_queue_by_name(QueueName='nonexisting-queue')
ex = err.exception
ex.operation_name.should.equal('GetQueueUrl')
ex.response['Error']['Code'].should.equal('QueueDoesNotExist')
ex.response['Error']['Code'].should.equal(
'AWS.SimpleQueueService.NonExistentQueue')
with assert_raises(ClientError) as err:
sqs.Queue('http://whatever-incorrect-queue-address').load()
ex = err.exception
ex.operation_name.should.equal('GetQueueAttributes')
ex.response['Error']['Code'].should.equal('QueueDoesNotExist')
ex.response['Error']['Code'].should.equal(
'AWS.SimpleQueueService.NonExistentQueue')
@mock_sqs
@ -890,7 +910,7 @@ def test_create_fifo_queue_with_dlq():
def test_queue_with_dlq():
if os.environ.get('TEST_SERVER_MODE', 'false').lower() == 'true':
raise SkipTest('Cant manipulate time in server mode')
sqs = boto3.client('sqs', region_name='us-east-1')
with freeze_time("2015-01-01 12:00:00"):
@ -933,6 +953,7 @@ def test_queue_with_dlq():
resp = sqs.list_dead_letter_source_queues(QueueUrl=queue_url1)
resp['queueUrls'][0].should.equal(queue_url2)
@mock_sqs
def test_redrive_policy_available():
sqs = boto3.client('sqs', region_name='us-east-1')
@ -956,3 +977,51 @@ def test_redrive_policy_available():
attributes = sqs.get_queue_attributes(QueueUrl=queue_url2)['Attributes']
assert 'RedrivePolicy' in attributes
assert json.loads(attributes['RedrivePolicy']) == redrive_policy
# Cant have redrive policy without maxReceiveCount
with assert_raises(ClientError):
sqs.create_queue(
QueueName='test-queue2',
Attributes={
'FifoQueue': 'true',
'RedrivePolicy': json.dumps({'deadLetterTargetArn': queue_arn1})
}
)
@mock_sqs
def test_redrive_policy_non_existent_queue():
sqs = boto3.client('sqs', region_name='us-east-1')
redrive_policy = {
'deadLetterTargetArn': 'arn:aws:sqs:us-east-1:123456789012:no-queue',
'maxReceiveCount': 1,
}
with assert_raises(ClientError):
sqs.create_queue(
QueueName='test-queue',
Attributes={
'RedrivePolicy': json.dumps(redrive_policy)
}
)
@mock_sqs
def test_redrive_policy_set_attributes():
sqs = boto3.resource('sqs', region_name='us-east-1')
queue = sqs.create_queue(QueueName='test-queue')
deadletter_queue = sqs.create_queue(QueueName='test-deadletter')
redrive_policy = {
'deadLetterTargetArn': deadletter_queue.attributes['QueueArn'],
'maxReceiveCount': 1,
}
queue.set_attributes(Attributes={
'RedrivePolicy': json.dumps(redrive_policy)})
copy = sqs.get_queue_by_name(QueueName='test-queue')
assert 'RedrivePolicy' in copy.attributes
copy_policy = json.loads(copy.attributes['RedrivePolicy'])
assert copy_policy == redrive_policy