Repository: getmoto/moto

Issue:
`MaximumMessageSize` not respected when creating a queue
moto version 1.3.14

Specifying the `MaximumMessageSize` attribute on a queue appears to have no impact on the size of the message that is permitted via `send_message`. I would have expected that the 10001 size message would have been rejected. 

```
import moto
mock_sqs = moto.mock_sqs()
mock_sqs.start()
import boto3
sqs = boto3.resource('sqs', region_name='us-east-1')
queue = sqs.create_queue(QueueName='foo', Attributes=dict(MaximumMessageSize='10000'))
queue.attributes['MaximumMessageSize']
> '10000'
queue.send_message(MessageBody='a' * 10000) # succeeds
queue.send_message(MessageBody='a' * 10001) # succeeds
queue.send_message(MessageBody='a' * 262144) # succeeds
queue.send_message(MessageBody='a' * 262145) # failure
```


Discussion:

Resolving patch:
diff --git a/moto/sqs/exceptions.py b/moto/sqs/exceptions.py
--- a/moto/sqs/exceptions.py
+++ b/moto/sqs/exceptions.py
@@ -103,6 +103,16 @@ def __init__(self, attribute_name):
         )
 
 
+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
 
diff --git a/moto/sqs/models.py b/moto/sqs/models.py
--- a/moto/sqs/models.py
+++ b/moto/sqs/models.py
@@ -35,6 +35,7 @@
     InvalidParameterValue,
     MissingParameter,
     OverLimit,
+    InvalidAttributeValue,
 )
 
 from moto.core import ACCOUNT_ID as DEFAULT_ACCOUNT_ID
@@ -43,6 +44,9 @@
 
 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 @@ def __init__(self, name, region, **kwargs):
             "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 @@ def __init__(self, name, region, **kwargs):
         # 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 @@ def send_message(
 
         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:


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
@@ -22,6 +22,11 @@
 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)
+    )