Repository: getmoto/moto

Issue:
Error in handling maxReceiveCount in SQS dead letter queues
When creating a queue with a deadletter queue redrive policy, the "maxReceiveCount" is not being converted to an integer before being tested against.

The AWS guidance for setting up the redrive policy is a JSON string with string keys and values:
https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-dead-letter-queue.html

```
            final SetQueueAttributesRequest request = new SetQueueAttributesRequest()
                    .withQueueUrl(sourceQueueUrl)
                    .addAttributesEntry(QueueAttributeName.RedrivePolicy.toString(),
                            "{\"maxReceiveCount\":\"5\", \"deadLetterTargetArn\":\""
                                    + deadLetterQueueArn + "\"}");
```

When this is used against moto, there is an error in the comparison here:
```
TypeError: '>=' not supported between instances of 'int' and 'str'
172.18.0.3 - - [22/Aug/2019 16:05:19] "POST /123456789012/local_AccountEvent HTTP/1.1" 500 -
Error on request:
Traceback (most recent call last):
...
  File "/usr/local/lib/python3.6/dist-packages/moto/sqs/responses.py", line 357, in receive_message
    queue_name, message_count, wait_time, visibility_timeout)
  File "/usr/local/lib/python3.6/dist-packages/moto/sqs/models.py", line 515, in receive_messages
    if queue.dead_letter_queue is not None and message.approximate_receive_count >= queue.redrive_policy['maxReceiveCount']:
```

Since using string values is what is in Amazon's guidance, the SQS module should attempt to turn this property into an integer (if not already) when pulling it out.



Discussion:

Resolving patch:
diff --git a/moto/sqs/models.py b/moto/sqs/models.py
--- a/moto/sqs/models.py
+++ b/moto/sqs/models.py
@@ -263,6 +263,9 @@ def _setup_dlq(self, policy):
         if 'maxReceiveCount' not in self.redrive_policy:
             raise RESTError('InvalidParameterValue', 'Redrive policy does not contain maxReceiveCount')
 
+        # 'maxReceiveCount' is stored as int
+        self.redrive_policy['maxReceiveCount'] = int(self.redrive_policy['maxReceiveCount'])
+
         for queue in sqs_backends[self.region].queues.values():
             if queue.queue_arn == self.redrive_policy['deadLetterTargetArn']:
                 self.dead_letter_queue = queue


Test patch:
diff --git a/tests/test_sqs/test_sqs.py b/tests/test_sqs/test_sqs.py
--- a/tests/test_sqs/test_sqs.py
+++ b/tests/test_sqs/test_sqs.py
@@ -1117,6 +1117,28 @@ def test_redrive_policy_set_attributes():
     assert copy_policy == redrive_policy
 
 
+@mock_sqs
+def test_redrive_policy_set_attributes_with_string_value():
+    sqs = boto3.resource('sqs', region_name='us-east-1')
+
+    queue = sqs.create_queue(QueueName='test-queue')
+    deadletter_queue = sqs.create_queue(QueueName='test-deadletter')
+
+    queue.set_attributes(Attributes={
+        'RedrivePolicy': json.dumps({
+            'deadLetterTargetArn': deadletter_queue.attributes['QueueArn'],
+            'maxReceiveCount': '1',
+        })})
+
+    copy = sqs.get_queue_by_name(QueueName='test-queue')
+    assert 'RedrivePolicy' in copy.attributes
+    copy_policy = json.loads(copy.attributes['RedrivePolicy'])
+    assert copy_policy == {
+        'deadLetterTargetArn': deadletter_queue.attributes['QueueArn'],
+        'maxReceiveCount': 1,
+    }
+
+
 @mock_sqs
 def test_receive_messages_with_message_group_id():
     sqs = boto3.resource('sqs', region_name='us-east-1')