diff --git a/moto/sqs/models.py b/moto/sqs/models.py index 447c0f01d..61dbfcb8e 100644 --- a/moto/sqs/models.py +++ b/moto/sqs/models.py @@ -6,21 +6,14 @@ import re from moto.core import BaseBackend from moto.core.utils import camelcase_to_underscores, get_random_message_id from .utils import generate_receipt_handle, unix_time_millis - +from .exceptions import ( + ReceiptHandleIsInvalid, + MessageNotInflight +) DEFAULT_ACCOUNT_ID = 123456789012 -class MessageNotInflight(Exception): - description = "The message referred to is not in flight." - status_code = 400 - - -class ReceiptHandleIsInvalid(Exception): - description = "The receipt handle provided is not valid." - status_code = 400 - - class Message(object): def __init__(self, message_id, body): self.id = message_id diff --git a/moto/sqs/responses.py b/moto/sqs/responses.py index 53acc3264..1b7ff62fc 100644 --- a/moto/sqs/responses.py +++ b/moto/sqs/responses.py @@ -3,6 +3,10 @@ from jinja2 import Template from moto.core.responses import BaseResponse from moto.core.utils import camelcase_to_underscores from .models import sqs_backend +from .exceptions import ( + MessageNotInflight, + ReceiptHandleIsInvalid +) MAXIMUM_VISIBILTY_TIMEOUT = 43200 @@ -46,11 +50,14 @@ class QueueResponse(BaseResponse): MAXIMUM_VISIBILTY_TIMEOUT ), dict(status=400) - sqs_backend.change_message_visibility( - queue_name=queue_name, - receipt_handle=receipt_handle, - visibility_timeout=visibility_timeout - ) + try: + sqs_backend.change_message_visibility( + queue_name=queue_name, + receipt_handle=receipt_handle, + visibility_timeout=visibility_timeout + ) + except (ReceiptHandleIsInvalid, MessageNotInflight) as e: + return "Invalid request: {}".format(e.description), dict(status=e.status_code) template = Template(CHANGE_MESSAGE_VISIBILITY_RESPONSE) return template.render() diff --git a/tests/test_sqs/test_sqs.py b/tests/test_sqs/test_sqs.py index 9b8380885..5b2767ef2 100644 --- a/tests/test_sqs/test_sqs.py +++ b/tests/test_sqs/test_sqs.py @@ -1,6 +1,7 @@ import boto from boto.exception import SQSError from boto.sqs.message import RawMessage + import requests import sure # noqa import time @@ -283,3 +284,51 @@ def test_queue_attributes(): attribute_names.should.contain('VisibilityTimeout') attribute_names.should.contain('LastModifiedTimestamp') attribute_names.should.contain('QueueArn') + + +@mock_sqs +def test_change_message_visibility_on_invalid_receipt(): + conn = boto.connect_sqs('the_key', 'the_secret') + queue = conn.create_queue("test-queue", visibility_timeout=1) + + conn.send_message(queue, 'this is another test message') + queue.count().should.equal(1) + messages = conn.receive_message(queue, number_messages=1) + + assert len(messages) == 1 + + original_message = messages[0] + + queue.count().should.equal(0) + + time.sleep(2) + + queue.count().should.equal(1) + + messages = conn.receive_message(queue, number_messages=1) + + assert len(messages) == 1 + + original_message.change_visibility.when.called_with(100).should.throw(SQSError) + + +@mock_sqs +def test_change_message_visibility_on_visible_message(): + conn = boto.connect_sqs('the_key', 'the_secret') + queue = conn.create_queue("test-queue", visibility_timeout=1) + + conn.send_message(queue, 'this is another test message') + queue.count().should.equal(1) + messages = conn.receive_message(queue, number_messages=1) + + assert len(messages) == 1 + + original_message = messages[0] + + queue.count().should.equal(0) + + time.sleep(2) + + queue.count().should.equal(1) + + original_message.change_visibility.when.called_with(100).should.throw(SQSError)