test(appsec): bound the django test app flush and fix its suitespec gap DD_U55XLN - #19700
test(appsec): bound the django test app flush and fix its suitespec gap DD_U55XLN#19700christophe-papazian wants to merge 3 commits into
Conversation
The /shutdown endpoints called tracer.shutdown() with no timeout (django) or with the same 10s the client uses (flask). Under a gunicorn gevent worker the flush can block the hub the writer needs, so the request read-timed-out and the test failed with the server still alive and the port still bound. Bound both flushes to 5s, below the client's 10s timeout. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Codeowners resolved asResolved from the full PR diff against |
Circular import analysis
|
Dependency direction analysis
|
tests/appsec/app.py matched only the threats suites, none of which run the integration tests that actually serve it, so the shutdown change in the previous commit shipped without any of them running. Same gap that #19674 closed for appsec_utils.py. 15 -> 19 matched suites. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Could you explain how it fixes the flaky test ? |
|
Maybe unrelated (and with some shameless self-promotion 😁): if this is a gevent deadlock issue, could it have been fixed upstream by this PR? It’s included in the latest gevent release, 26.8.0. Maybe we could try regenerating the Riot requirements against that version. |
Reverts the flask app.py timeout change: its 10s already matched the caller's, and cutting it to 5s reduced the flush budget for suites that do assert on test-agent payloads, with no evidence it helped anything. Keeps the django bound, rejustified. It is not the fix for the flake -- gevent 26.8.0 is, via gevent/gevent#2199 -- but an unbounded wait in a fixture teardown holds the job to the suite timeout instead of failing one test, and a lost gevent notification can only park an untimed wait forever. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
You're right on both counts, thanks — I've narrowed the PR. On "fail early, not a fix": agreed, and the flask half is reverted. To answer the "shouldn't it fail for missing signals?" part specifically: What I've kept is only the django side, and only as hygiene: On gevent#2199 — I think you've found the actual root cause, and the shameless self-promotion is fully earned. It lines up unusually well:
And our pins are behind: every appsec django + gunicorn + gevent lockfile is on I've regenerated them via
So: this PR stays as teardown hygiene plus the suitespec gap, and the gevent refresh follows separately with |
APPSEC-69623
Two independent changes, neither claiming to be the fix for the flake.
Bounds the django test app's trace flush.
/shutdowncalledtracer.shutdown()with no timeout, documented as "block until flushing has successfully completed". An unbounded wait in a fixture teardown holds the job to the suite timeout rather than failing one test, and a lost gevent notification can only park an untimed wait forever — a timed one still wakes on its hub timer.tests/appsec/app.pyalready passed a timeout, so django was the outlier.Adds
tests/appsec/app.pyto the four suites that serve it. It matched only the threats suites, so changes to it ran none of the integration tests. Same gap #19674 closed forappsec_utils.py.The actual fix for
U55XLNis upstream: gevent 26.8.0 ships gevent/gevent#2199, and our appsec django venvs are pinned to 25.9.1. A lockfile refresh is coming separately. Thanks @florentinl for both catches — the flask10 → 5change is reverted, since it only reduced the flush budget for suites that do assert on test-agent payloads.DD_U55XLN