diff --git a/moto/sqs/models.py b/moto/sqs/models.py index 1d0e86106..6ec47f2ab 100644 --- a/moto/sqs/models.py +++ b/moto/sqs/models.py @@ -887,6 +887,17 @@ class SQSBackend(BaseBackend): if message.receipt_handle == receipt_handle: if message.visible: raise MessageNotInflight + + visibility_timeout_msec = int(visibility_timeout) * 1000 + given_visibility_timeout = unix_time_millis() + visibility_timeout_msec + if given_visibility_timeout - message.sent_timestamp > 43200 * 1000: + raise InvalidParameterValue( + "Value {0} for parameter VisibilityTimeout is invalid. Reason: Total " + "VisibilityTimeout for the message is beyond the limit [43200 seconds]".format( + visibility_timeout + ) + ) + message.change_visibility(visibility_timeout) if message.visible: # If the message is visible again, remove it from pending diff --git a/tests/test_sqs/test_sqs.py b/tests/test_sqs/test_sqs.py index 2288cec77..3fe2e025c 100644 --- a/tests/test_sqs/test_sqs.py +++ b/tests/test_sqs/test_sqs.py @@ -800,6 +800,41 @@ def test_send_receive_message_with_attributes_with_labels(): ) +@mock_sqs +def test_change_message_visibility_than_permitted(): + if settings.TEST_SERVER_MODE: + raise SkipTest("Cant manipulate time in server mode") + + sqs = boto3.resource("sqs", region_name="us-east-1") + conn = boto3.client("sqs", region_name="us-east-1") + + with freeze_time("2015-01-01 12:00:00"): + conn.create_queue(QueueName="test-queue-visibility") + queue = sqs.Queue("test-queue-visibility") + queue.send_message(MessageBody="derp") + messages = conn.receive_message(QueueUrl=queue.url) + messages.get("Messages").should.have.length_of(1) + + conn.change_message_visibility( + QueueUrl=queue.url, + ReceiptHandle=messages.get("Messages")[0].get("ReceiptHandle"), + VisibilityTimeout=360, + ) + + with freeze_time("2015-01-01 12:05:00"): + + with pytest.raises(ClientError) as err: + conn.change_message_visibility( + QueueUrl=queue.url, + ReceiptHandle=messages.get("Messages")[0].get("ReceiptHandle"), + VisibilityTimeout=43200, + ) + + ex = err.value + ex.operation_name.should.equal("ChangeMessageVisibility") + ex.response["Error"]["Code"].should.equal("InvalidParameterValue") + + @mock_sqs def test_send_receive_message_timestamps(): sqs = boto3.resource("sqs", region_name="us-east-1") @@ -1869,7 +1904,7 @@ def test_batch_change_message_visibility(): { "Id": str(uuid.uuid4()), "ReceiptHandle": handle, - "VisibilityTimeout": 43200, + "VisibilityTimeout": 43000, } for handle in handles ]