Add better support for SQS MaximumMessageSize
attribute (#3374)
Closes #3205
This commit is contained in:
parent
1e8f87a55d
commit
a2bd4515eb
@ -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):
|
class InvalidParameterValue(RESTError):
|
||||||
code = 400
|
code = 400
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ from .exceptions import (
|
|||||||
InvalidParameterValue,
|
InvalidParameterValue,
|
||||||
MissingParameter,
|
MissingParameter,
|
||||||
OverLimit,
|
OverLimit,
|
||||||
|
InvalidAttributeValue,
|
||||||
)
|
)
|
||||||
|
|
||||||
from moto.core import ACCOUNT_ID as DEFAULT_ACCOUNT_ID
|
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_LENGTH = 262144 # 256 KiB
|
||||||
|
|
||||||
|
MAXIMUM_MESSAGE_SIZE_ATTR_LOWER_BOUND = 1024
|
||||||
|
MAXIMUM_MESSAGE_SIZE_ATTR_UPPER_BOUND = MAXIMUM_MESSAGE_LENGTH
|
||||||
|
|
||||||
TRANSPORT_TYPE_ENCODINGS = {
|
TRANSPORT_TYPE_ENCODINGS = {
|
||||||
"String": b"\x01",
|
"String": b"\x01",
|
||||||
"Binary": b"\x02",
|
"Binary": b"\x02",
|
||||||
@ -248,7 +252,7 @@ class Queue(CloudFormationModel):
|
|||||||
"FifoQueue": "false",
|
"FifoQueue": "false",
|
||||||
"KmsDataKeyReusePeriodSeconds": 300, # five minutes
|
"KmsDataKeyReusePeriodSeconds": 300, # five minutes
|
||||||
"KmsMasterKeyId": None,
|
"KmsMasterKeyId": None,
|
||||||
"MaximumMessageSize": int(64 << 12),
|
"MaximumMessageSize": MAXIMUM_MESSAGE_LENGTH,
|
||||||
"MessageRetentionPeriod": 86400 * 4, # four days
|
"MessageRetentionPeriod": 86400 * 4, # four days
|
||||||
"Policy": None,
|
"Policy": None,
|
||||||
"ReceiveMessageWaitTimeSeconds": 0,
|
"ReceiveMessageWaitTimeSeconds": 0,
|
||||||
@ -262,6 +266,11 @@ class Queue(CloudFormationModel):
|
|||||||
# Check some conditions
|
# Check some conditions
|
||||||
if self.fifo_queue and not self.name.endswith(".fifo"):
|
if self.fifo_queue and not self.name.endswith(".fifo"):
|
||||||
raise InvalidParameterValue("Queue name must end in .fifo for FIFO queues")
|
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
|
@property
|
||||||
def pending_messages(self):
|
def pending_messages(self):
|
||||||
@ -649,6 +658,12 @@ class SQSBackend(BaseBackend):
|
|||||||
|
|
||||||
queue = self.get_queue(queue_name)
|
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:
|
if delay_seconds:
|
||||||
delay_seconds = int(delay_seconds)
|
delay_seconds = int(delay_seconds)
|
||||||
else:
|
else:
|
||||||
|
@ -22,6 +22,11 @@ from nose.tools import assert_raises
|
|||||||
from tests.helpers import requires_boto_gte
|
from tests.helpers import requires_boto_gte
|
||||||
from tests.test_awslambda.test_lambda import get_test_zip_file1, get_role_name
|
from tests.test_awslambda.test_lambda import get_test_zip_file1, get_role_name
|
||||||
from moto.core import ACCOUNT_ID
|
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 = """
|
TEST_POLICY = """
|
||||||
{
|
{
|
||||||
@ -2157,3 +2162,49 @@ def test_invoke_function_from_sqs_exception():
|
|||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
assert False, "Test Failed"
|
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)
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user