Skip to content

Commit 503b00a

Browse files
committed
Address comments
1 parent 501ebf6 commit 503b00a

File tree

5 files changed

+139
-39
lines changed

5 files changed

+139
-39
lines changed

localstack-core/localstack/services/sqs/provider.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1241,7 +1241,7 @@ def receive_message(
12411241
poll_empty_queue = True
12421242
elif wait_time_seconds is None:
12431243
wait_time_seconds = queue.wait_time_seconds
1244-
elif wait_time_seconds < 1 or wait_time_seconds > 20:
1244+
elif wait_time_seconds < 0 or wait_time_seconds > 20:
12451245
raise InvalidParameterValueException(
12461246
f"Value {wait_time_seconds} for parameter WaitTimeSeconds is invalid. "
12471247
f"Reason: Must be >= 0 and <= 20, if provided."

tests/aws/services/sqs/test_sqs.py

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,6 @@ def test_receive_empty_queue(self, sqs_queue, snapshot, aws_sqs_client):
256256
empty_short_poll_resp = aws_sqs_client.receive_message(
257257
QueueUrl=queue_url, MaxNumberOfMessages=1
258258
)
259-
260259
snapshot.match("empty_short_poll_resp", empty_short_poll_resp)
261260

262261
empty_long_poll_resp = aws_sqs_client.receive_message(
@@ -268,16 +267,32 @@ def test_receive_empty_queue(self, sqs_queue, snapshot, aws_sqs_client):
268267
@markers.snapshot.skip_snapshot_verify(paths=["$..Error.Detail"])
269268
def test_send_receive_wait_time_seconds(self, sqs_queue, snapshot, aws_sqs_client):
270269
queue_url = sqs_queue
271-
send_result = aws_sqs_client.send_message(QueueUrl=queue_url, MessageBody="message")
272-
assert send_result["MessageId"]
270+
send_result_1 = aws_sqs_client.send_message(QueueUrl=queue_url, MessageBody="message")
271+
assert send_result_1["MessageId"]
272+
273+
send_result_2 = aws_sqs_client.send_message(QueueUrl=queue_url, MessageBody="message")
274+
assert send_result_2["MessageId"]
273275

274276
MAX_WAIT_TIME_SECONDS = 20
275277
with pytest.raises(ClientError) as e:
276278
aws_sqs_client.receive_message(
277279
QueueUrl=queue_url, WaitTimeSeconds=MAX_WAIT_TIME_SECONDS + 1
278280
)
281+
snapshot.match("recieve_message_error_too_large", e.value.response)
282+
283+
with pytest.raises(ClientError) as e:
284+
aws_sqs_client.receive_message(QueueUrl=queue_url, WaitTimeSeconds=-1)
285+
snapshot.match("recieve_message_error_too_small", e.value.response)
279286

280-
snapshot.match("recieve_message_error", e.value.response)
287+
empty_short_poll_by_default_resp = aws_sqs_client.receive_message(
288+
QueueUrl=queue_url, MaxNumberOfMessages=1
289+
)
290+
snapshot.match("empty_short_poll_by_default_resp", empty_short_poll_by_default_resp)
291+
292+
empty_short_poll_explicit_resp = aws_sqs_client.receive_message(
293+
QueueUrl=queue_url, MaxNumberOfMessages=1, WaitTimeSeconds=0
294+
)
295+
snapshot.match("empty_short_poll_explicit_resp", empty_short_poll_explicit_resp)
281296

282297
@markers.aws.validated
283298
def test_receive_message_attributes_timestamp_types(self, sqs_queue, aws_sqs_client):

tests/aws/services/sqs/test_sqs.snapshot.json

Lines changed: 98 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3648,9 +3648,9 @@
36483648
"recorded-content": {}
36493649
},
36503650
"tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_wait_time_seconds[sqs]": {
3651-
"recorded-date": "23-01-2025, 12:43:53",
3651+
"recorded-date": "10-02-2025, 13:22:29",
36523652
"recorded-content": {
3653-
"recieve_message_error": {
3653+
"recieve_message_error_too_large": {
36543654
"Error": {
36553655
"Code": "InvalidParameterValue",
36563656
"Message": "Value 21 for parameter WaitTimeSeconds is invalid. Reason: Must be >= 0 and <= 20, if provided.",
@@ -3660,15 +3660,54 @@
36603660
"ResponseMetadata": {
36613661
"HTTPHeaders": {},
36623662
"HTTPStatusCode": 400
3663-
3663+
}
3664+
},
3665+
"recieve_message_error_too_small": {
3666+
"Error": {
3667+
"Code": "InvalidParameterValue",
3668+
"Message": "Value -1 for parameter WaitTimeSeconds is invalid. Reason: Must be >= 0 and <= 20, if provided.",
3669+
"QueryErrorCode": "InvalidParameterValueException",
3670+
"Type": "Sender"
3671+
},
3672+
"ResponseMetadata": {
3673+
"HTTPHeaders": {},
3674+
"HTTPStatusCode": 400
3675+
}
3676+
},
3677+
"empty_short_poll_by_default_resp": {
3678+
"Messages": [
3679+
{
3680+
"Body": "message",
3681+
"MD5OfBody": "78e731027d8fd50ed642340b7c9a63b3",
3682+
"MessageId": "<uuid:1>",
3683+
"ReceiptHandle": "<receipt-handle:1>"
3684+
}
3685+
],
3686+
"ResponseMetadata": {
3687+
"HTTPHeaders": {},
3688+
"HTTPStatusCode": 200
3689+
}
3690+
},
3691+
"empty_short_poll_explicit_resp": {
3692+
"Messages": [
3693+
{
3694+
"Body": "message",
3695+
"MD5OfBody": "78e731027d8fd50ed642340b7c9a63b3",
3696+
"MessageId": "<uuid:2>",
3697+
"ReceiptHandle": "<receipt-handle:2>"
3698+
}
3699+
],
3700+
"ResponseMetadata": {
3701+
"HTTPHeaders": {},
3702+
"HTTPStatusCode": 200
36643703
}
36653704
}
36663705
}
36673706
},
36683707
"tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_wait_time_seconds[sqs_query]": {
3669-
"recorded-date": "23-01-2025, 12:43:54",
3708+
"recorded-date": "10-02-2025, 13:22:32",
36703709
"recorded-content": {
3671-
"recieve_message_error": {
3710+
"recieve_message_error_too_large": {
36723711
"Error": {
36733712
"Code": "InvalidParameterValue",
36743713
"Detail": null,
@@ -3679,12 +3718,58 @@
36793718
"HTTPHeaders": {},
36803719
"HTTPStatusCode": 400
36813720
}
3721+
},
3722+
"recieve_message_error_too_small": {
3723+
"Error": {
3724+
"Code": "InvalidParameterValue",
3725+
"Detail": null,
3726+
"Message": "Value -1 for parameter WaitTimeSeconds is invalid. Reason: Must be >= 0 and <= 20, if provided.",
3727+
"Type": "Sender"
3728+
},
3729+
"ResponseMetadata": {
3730+
"HTTPHeaders": {},
3731+
"HTTPStatusCode": 400
3732+
}
3733+
},
3734+
"empty_short_poll_by_default_resp": {
3735+
"Messages": [
3736+
{
3737+
"Body": "message",
3738+
"MD5OfBody": "78e731027d8fd50ed642340b7c9a63b3",
3739+
"MessageId": "<uuid:1>",
3740+
"ReceiptHandle": "<receipt-handle:1>"
3741+
}
3742+
],
3743+
"ResponseMetadata": {
3744+
"HTTPHeaders": {},
3745+
"HTTPStatusCode": 200
3746+
}
3747+
},
3748+
"empty_short_poll_explicit_resp": {
3749+
"Messages": [
3750+
{
3751+
"Body": "message",
3752+
"MD5OfBody": "78e731027d8fd50ed642340b7c9a63b3",
3753+
"MessageId": "<uuid:2>",
3754+
"ReceiptHandle": "<receipt-handle:2>"
3755+
}
3756+
],
3757+
"ResponseMetadata": {
3758+
"HTTPHeaders": {},
3759+
"HTTPStatusCode": 200
3760+
}
36823761
}
36833762
}
36843763
},
36853764
"tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_empty_queue[sqs]": {
3686-
"recorded-date": "30-01-2025, 22:32:45",
3765+
"recorded-date": "10-02-2025, 13:18:17",
36873766
"recorded-content": {
3767+
"empty_short_poll_resp_no_param": {
3768+
"ResponseMetadata": {
3769+
"HTTPHeaders": {},
3770+
"HTTPStatusCode": 200
3771+
}
3772+
},
36883773
"empty_short_poll_resp": {
36893774
"ResponseMetadata": {
36903775
"HTTPHeaders": {},
@@ -3700,8 +3785,14 @@
37003785
}
37013786
},
37023787
"tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_empty_queue[sqs_query]": {
3703-
"recorded-date": "30-01-2025, 22:32:48",
3788+
"recorded-date": "10-02-2025, 13:18:20",
37043789
"recorded-content": {
3790+
"empty_short_poll_resp_no_param": {
3791+
"ResponseMetadata": {
3792+
"HTTPHeaders": {},
3793+
"HTTPStatusCode": 200
3794+
}
3795+
},
37053796
"empty_short_poll_resp": {
37063797
"ResponseMetadata": {
37073798
"HTTPHeaders": {},

tests/aws/services/sqs/test_sqs.validation.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,10 +204,10 @@
204204
"last_validated_date": "2024-04-30T13:34:22+00:00"
205205
},
206206
"tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_empty_queue[sqs]": {
207-
"last_validated_date": "2025-01-30T22:32:45+00:00"
207+
"last_validated_date": "2025-02-10T13:18:17+00:00"
208208
},
209209
"tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_empty_queue[sqs_query]": {
210-
"last_validated_date": "2025-01-30T22:32:48+00:00"
210+
"last_validated_date": "2025-02-10T13:18:20+00:00"
211211
},
212212
"tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_receive_message_attribute_names_filters[sqs]": {
213213
"last_validated_date": "2024-06-04T11:54:31+00:00"
@@ -330,10 +330,10 @@
330330
"last_validated_date": "2024-04-30T13:40:05+00:00"
331331
},
332332
"tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_wait_time_seconds[sqs]": {
333-
"last_validated_date": "2025-01-23T12:43:53+00:00"
333+
"last_validated_date": "2025-02-10T13:22:29+00:00"
334334
},
335335
"tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_send_receive_wait_time_seconds[sqs_query]": {
336-
"last_validated_date": "2025-01-23T12:43:54+00:00"
336+
"last_validated_date": "2025-02-10T13:22:32+00:00"
337337
},
338338
"tests/aws/services/sqs/test_sqs.py::TestSqsProvider::test_set_empty_redrive_policy[sqs]": {
339339
"last_validated_date": "2024-08-20T14:14:08+00:00"

tests/aws/services/sqs/test_sqs_backdoor.py

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
from botocore.exceptions import ClientError
88

99
from localstack import config
10+
from localstack.services.sqs.constants import (
11+
HEADER_LOCALSTACK_SQS_OVERRIDE_MESSAGE_COUNT,
12+
HEADER_LOCALSTACK_SQS_OVERRIDE_WAIT_TIME_SECONDS,
13+
)
14+
from localstack.services.sqs.provider import MAX_NUMBER_OF_MESSAGES
1015
from localstack.services.sqs.utils import parse_queue_url
1116
from localstack.testing.pytest import markers
1217
from localstack.utils.strings import short_uid
@@ -373,20 +378,16 @@ def test_receive_message_override_max_number_of_messages(
373378
):
374379
# Create standalone boto3 client since registering hooks to the session-wide
375380
# aws_client (from the fixture) will have side-effects.
376-
aws_client = aws_client_factory().sqs
381+
sqs_client = aws_client_factory().sqs
377382

378383
override_max_number_of_messages = 20
379-
380-
from localstack.services.sqs.constants import HEADER_LOCALSTACK_SQS_OVERRIDE_MESSAGE_COUNT
381-
from localstack.services.sqs.provider import MAX_NUMBER_OF_MESSAGES
382-
383384
queue_url = sqs_create_queue()
384385

385386
for i in range(override_max_number_of_messages):
386-
aws_client.send_message(QueueUrl=queue_url, MessageBody=f"message-{i}")
387+
sqs_client.send_message(QueueUrl=queue_url, MessageBody=f"message-{i}")
387388

388389
with pytest.raises(ClientError):
389-
aws_client.receive_message(
390+
sqs_client.receive_message(
390391
QueueUrl=queue_url,
391392
VisibilityTimeout=0,
392393
MaxNumberOfMessages=override_max_number_of_messages,
@@ -407,13 +408,13 @@ def _handler_inject_header(params, context, **kwargs):
407408
override_message_count
408409
)
409410

410-
aws_client.meta.events.register(
411+
sqs_client.meta.events.register(
411412
"provide-client-params.sqs.ReceiveMessage", _handle_receive_message_override
412413
)
413414

414-
aws_client.meta.events.register("before-call.sqs.ReceiveMessage", _handler_inject_header)
415+
sqs_client.meta.events.register("before-call.sqs.ReceiveMessage", _handler_inject_header)
415416

416-
response = aws_client.receive_message(
417+
response = sqs_client.receive_message(
417418
QueueUrl=queue_url,
418419
VisibilityTimeout=30,
419420
MaxNumberOfMessages=override_max_number_of_messages,
@@ -427,19 +428,12 @@ def _handler_inject_header(params, context, **kwargs):
427428
def test_receive_message_override_message_wait_time_seconds(
428429
self, sqs_create_queue, aws_client_factory
429430
):
430-
aws_client = aws_client_factory().sqs
431-
431+
sqs_client = aws_client_factory().sqs
432432
override_message_wait_time_seconds = 30
433-
434-
from localstack.services.sqs.constants import (
435-
HEADER_LOCALSTACK_SQS_OVERRIDE_WAIT_TIME_SECONDS,
436-
)
437-
from localstack.services.sqs.provider import MAX_NUMBER_OF_MESSAGES
438-
439433
queue_url = sqs_create_queue()
440434

441435
with pytest.raises(ClientError):
442-
aws_client.receive_message(
436+
sqs_client.receive_message(
443437
QueueUrl=queue_url,
444438
VisibilityTimeout=0,
445439
MaxNumberOfMessages=MAX_NUMBER_OF_MESSAGES,
@@ -461,14 +455,14 @@ def _handler_inject_header(params, context, **kwargs):
461455
override_wait_time
462456
)
463457

464-
aws_client.meta.events.register(
458+
sqs_client.meta.events.register(
465459
"provide-client-params.sqs.ReceiveMessage", _handle_receive_message_override
466460
)
467461

468-
aws_client.meta.events.register("before-call.sqs.ReceiveMessage", _handler_inject_header)
462+
sqs_client.meta.events.register("before-call.sqs.ReceiveMessage", _handler_inject_header)
469463

470464
def _send_message():
471-
aws_client.send_message(QueueUrl=queue_url, MessageBody=f"message-{short_uid()}")
465+
sqs_client.send_message(QueueUrl=queue_url, MessageBody=f"message-{short_uid()}")
472466

473467
# Populate with 9 messages (1 below the MaxNumberOfMessages threshold).
474468
# This should cause long-polling to exit since MaxNumberOfMessages is met.
@@ -478,7 +472,7 @@ def _send_message():
478472
Timer(25, _send_message).start() # send message asynchronously after 1 second
479473

480474
start_t = time.time()
481-
response = aws_client.receive_message(
475+
response = sqs_client.receive_message(
482476
QueueUrl=queue_url,
483477
VisibilityTimeout=30,
484478
MaxNumberOfMessages=MAX_NUMBER_OF_MESSAGES,

0 commit comments

Comments
 (0)