Add better support for SQS MaximumMessageSize attribute (#3374)

Closes #3205
This commit is contained in:
Brian Pandola 2020-10-10 09:54:36 -07:00 committed by GitHub
parent 1e8f87a55d
commit a2bd4515eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 77 additions and 1 deletions

View File

@ -103,6 +103,16 @@ class InvalidAttributeName(RESTError):
)
class InvalidAttributeValue(RESTError):
code = 400
def __init__(self, attribute_name):
super(InvalidAttributeValue, self).__init__(
"InvalidAttributeValue",
"Invalid value for the parameter {}.".format(attribute_name),
)
class InvalidParameterValue(RESTError):
code = 400

View File

@ -35,6 +35,7 @@ from .exceptions import (
InvalidParameterValue,
MissingParameter,
OverLimit,
InvalidAttributeValue,
)
from moto.core import ACCOUNT_ID as DEFAULT_ACCOUNT_ID
@ -43,6 +44,9 @@ DEFAULT_SENDER_ID = "AIDAIT2UOQQY3AUEKVGXU"
MAXIMUM_MESSAGE_LENGTH = 262144 # 256 KiB
MAXIMUM_MESSAGE_SIZE_ATTR_LOWER_BOUND = 1024
MAXIMUM_MESSAGE_SIZE_ATTR_UPPER_BOUND = MAXIMUM_MESSAGE_LENGTH
TRANSPORT_TYPE_ENCODINGS = {
"String": b"\x01",
"Binary": b"\x02",
@ -248,7 +252,7 @@ class Queue(CloudFormationModel):
"FifoQueue": "false",
"KmsDataKeyReusePeriodSeconds": 300, # five minutes
"KmsMasterKeyId": None,
"MaximumMessageSize": int(64 << 12),
"MaximumMessageSize": MAXIMUM_MESSAGE_LENGTH,
"MessageRetentionPeriod": 86400 * 4, # four days
"Policy": None,
"ReceiveMessageWaitTimeSeconds": 0,
@ -262,6 +266,11 @@ class Queue(CloudFormationModel):
# Check some conditions
if self.fifo_queue and not self.name.endswith(".fifo"):
raise InvalidParameterValue("Queue name must end in .fifo for FIFO queues")
if (
self.maximum_message_size < MAXIMUM_MESSAGE_SIZE_ATTR_LOWER_BOUND
or self.maximum_message_size > MAXIMUM_MESSAGE_SIZE_ATTR_UPPER_BOUND
):
raise InvalidAttributeValue("MaximumMessageSize")
@property
def pending_messages(self):
@ -649,6 +658,12 @@ class SQSBackend(BaseBackend):
queue = self.get_queue(queue_name)
if len(message_body) > queue.maximum_message_size:
msg = "One or more parameters are invalid. Reason: Message must be shorter than {} bytes.".format(
queue.maximum_message_size
)
raise InvalidParameterValue(msg)
if delay_seconds:
delay_seconds = int(delay_seconds)
else:

View File

@ -22,6 +22,11 @@ from nose.tools import assert_raises
from tests.helpers import requires_boto_gte
from tests.test_awslambda.test_lambda import get_test_zip_file1, get_role_name
from moto.core import ACCOUNT_ID
from moto.sqs.models import (
MAXIMUM_MESSAGE_SIZE_ATTR_LOWER_BOUND,
MAXIMUM_MESSAGE_SIZE_ATTR_UPPER_BOUND,
MAXIMUM_MESSAGE_LENGTH,
)
TEST_POLICY = """
{
@ -2157,3 +2162,49 @@ def test_invoke_function_from_sqs_exception():
time.sleep(1)
assert False, "Test Failed"
@mock_sqs
def test_maximum_message_size_attribute_default():
sqs = boto3.resource("sqs", region_name="eu-west-3")
queue = sqs.create_queue(QueueName="test-queue",)
int(queue.attributes["MaximumMessageSize"]).should.equal(MAXIMUM_MESSAGE_LENGTH)
with assert_raises(Exception) as e:
queue.send_message(MessageBody="a" * (MAXIMUM_MESSAGE_LENGTH + 1))
ex = e.exception
ex.response["Error"]["Code"].should.equal("InvalidParameterValue")
@mock_sqs
def test_maximum_message_size_attribute_fails_for_invalid_values():
sqs = boto3.resource("sqs", region_name="eu-west-3")
invalid_values = [
MAXIMUM_MESSAGE_SIZE_ATTR_LOWER_BOUND - 1,
MAXIMUM_MESSAGE_SIZE_ATTR_UPPER_BOUND + 1,
]
for message_size in invalid_values:
with assert_raises(ClientError) as e:
sqs.create_queue(
QueueName="test-queue",
Attributes={"MaximumMessageSize": str(message_size)},
)
ex = e.exception
ex.response["Error"]["Code"].should.equal("InvalidAttributeValue")
@mock_sqs
def test_send_message_fails_when_message_size_greater_than_max_message_size():
sqs = boto3.resource("sqs", region_name="eu-west-3")
message_size_limit = 12345
queue = sqs.create_queue(
QueueName="test-queue",
Attributes={"MaximumMessageSize": str(message_size_limit)},
)
int(queue.attributes["MaximumMessageSize"]).should.equal(message_size_limit)
with assert_raises(ClientError) as e:
queue.send_message(MessageBody="a" * (message_size_limit + 1))
ex = e.exception
ex.response["Error"]["Code"].should.equal("InvalidParameterValue")
ex.response["Error"]["Message"].should.contain(
"{} bytes".format(message_size_limit)
)