Skip to content

SQS: Raise PurgeQueueInProgress on repeated purge within 60 seconds - #10234

Merged
bpandola merged 1 commit into
getmoto:masterfrom
haeganm:fix/sqs-purge-queue-in-progress
Sep 7, 2026
Merged

bpandola merged 1 commit into
getmoto:masterfrom
haeganm:fix/sqs-purge-queue-in-progress

Conversation

@haeganm

@haeganm haeganm commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Fixes #10233

SQS allows only one PurgeQueue operation per queue every 60 seconds; a second call inside the window fails with AWS.SimpleQueueService.PurgeQueueInProgress. Moto allowed unlimited consecutive purges. The 60 second rule is documented in the PurgeQueue API reference and the PurgeQueueInProgress error shape is declared on the operation in the botocore service model.

Changes:

  • Queue now records last_purged_at, and purge_queue raises the new PurgeQueueInProgress exception when called again within 60 seconds, following the existing SQS exception conventions (legacy query-compat error code, same shape as QueueDoesNotExist).
  • Two tests: a plain double-purge test asserting the error code and message (runs in server mode too), and a freezegun test asserting the purge succeeds again once 60 seconds have passed (skipped in server mode like the other time-manipulation tests in the file).

Checked that nothing else in moto or its test suite purges a queue twice within a window, so no existing behavior breaks. Note this makes moto stricter in a way that matches AWS: a user suite that purges the same queue repeatedly in under 60 seconds of real time will now get the same error AWS would give (freezegun sidesteps it). If you would rather gate this behind a setting, happy to rework.

Testing: pytest tests/test_sqs/ passes (the two test_sqs_integration.py Lambda-in-Docker tests fail identically on unmodified master in my environment, no Docker); the new tests fail before the fix and pass after; ruff check and ruff format --check clean with the pinned ruff 0.14.10.

SQS allows only one PurgeQueue operation per queue every 60 seconds;
a second call inside the window fails with
AWS.SimpleQueueService.PurgeQueueInProgress. Moto allowed unlimited
consecutive purges. Track the last purge time on the queue and raise
the documented error inside the window.
@codecov

codecov Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.32%. Comparing base (289555e) to head (ffd3883).

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #10234      +/-   ##
==========================================
- Coverage   93.32%   93.32%   -0.01%     
==========================================
  Files        1342     1342              
  Lines      122702   122710       +8     
==========================================
+ Hits       114508   114515       +7     
- Misses       8194     8195       +1     
Flag Coverage Δ
servertests 27.93% <37.50%> (+<0.01%) ⬆️
unittests 93.29% <100.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Ashishkosana Ashishkosana left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, focused fidelity fix — matches the documented SQS rule that only one PurgeQueue is allowed per queue every 60 seconds, and the error code/shape lines up with the botocore model (AWS.SimpleQueueService.PurgeQueueInProgress) the same way QueueDoesNotExist does.

What looks good:

  • Recording last_purged_at on the operation itself (not on whether messages existed) is the right AWS-shaped behavior.
  • Exception subclass follows existing SQS conventions.
  • Tests cover both the in-window failure (including the message string) and the after-60s success path, with the server-mode skip consistent with other freezegun tests in this file.
  • Calling out the “moto gets stricter / suites that double-purge fast will now fail like AWS” tradeoff in the PR body is exactly the right note for maintainers.

One optional nit (non-blocking): purge_queue still clears _messages / _pending_messages without taking _messages_lock, while receive paths wait on that Condition. That predates this PR, but if you touch this area again it might be worth aligning the purge write with the lock so a concurrent receive can’t observe a half-cleared queue. Not required for this change.

CI looks green from here. LGTM.

@bpandola bpandola added this to the 5.2.4 milestone Sep 7, 2026
@bpandola
bpandola merged commit e1e1dbe into getmoto:master Sep 7, 2026
133 of 134 checks passed
JackDanger added a commit to robotocore/robotocore that referenced this pull request Oct 26, 2026
Ports moto 5.2.4's purge_queue (getmoto/moto#10234): Queue records
last_purged_at and a second purge inside the 60-second window raises
PurgeQueueInProgress — error code AWS.SimpleQueueService.PurgeQueueInProgress,
message "Only one PurgeQueue operation on {queue} is allowed every 60
seconds.", HTTP 403 (the status botocore's SQS model declares). The
throttle is per queue and per timestamp, so every client is blocked in
the window, not just the caller of the first purge; a rejected purge
leaves stored messages and the bridge pending buffer untouched.

Generated-by: termag
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SQS: purge_queue never raises PurgeQueueInProgress within the 60 second window

3 participants