Repository navigation
Commit b73b480
fix(tests): Fix outstanding flaky tests (#128264)
Fixes the root causes of backend tests that still fail on master, based
on the per-attempt failure events in the `sentry-tests` project over the
last 30 days. There is one commit per cause.
All fixes are test-only except one: the uptime alert index now orders
its pagination by `id`. The customer-domain `(?!new)` bug was moved to
its own PRs, #128274 (backend) and #128275 (frontend).
### Production change: unordered pagination in the uptime alert index
(`test_owner_filter` 11, `test` 2)
`OrganizationUptimeAlertIndexEndpoint` paginates with `OffsetPaginator`
and no `order_by`, so offset and limit are applied to an unordered
queryset. The order within a page, and which rows land on which page,
follows Postgres row order. That is a real correctness bug: rows can be
duplicated or skipped across pages. It now orders by `id`.
`test_paginates_in_id_order` is a new regression test. It creates five
detectors, deletes and reinserts their rows newest first so the physical
order is the reverse of id order, then walks three pages with
`per_page=2` and the cursor. It checks that each page has the expected
ids in ascending order, with no gaps or duplicates. Without the fix it
gets the rows in reverse.
Refs #108890
Refs #108884
### Test-only fixes
**Unordered queries in the deploy notification:
`SlackDeployNotificationTest::test_deploy_block` (12).** The buttons
come from `release.projects.all()` and the footer from
`release.projects.all()[0]`. These are two unordered queries, and the
`LIMIT 1` one can use a different join plan, so the footer can name a
project other than the first button. The production code does not
promise any order between them. The test still checks every button's
slug, URL, and value, and now checks that the footer names one of the
release's projects instead of the first button's.
Refs #108927
**Postgres row order:
`test_redirect_for_logged_in_user_with_different_active_org` (19).** The
session had no active org, so the channel login view fell back to the
first of the user's orgs from an unordered query. When Postgres returned
the second org first, the user counted as already logged in to the
target org. The test now sets `activeorg` in the session, which is the
state its comment describes.
Refs #108900
Refs #108881
**Snuba rows left over from an earlier test: feedback categories (17),
label query (13 + 3), `EventTest::test_snuba_data` (3).** These classes
write to and read from Snuba but never reset it. Snowflake ids are built
from the wall-clock second plus a Redis sequence, and Redis is flushed
and Postgres rolled back after every test. So two tests that start in
the same second get the same org and project ids, and the second one
reads the first one's rows. The classes now use the `reset_snuba`
fixture through `@pytest.mark.usefixtures`, not `SnubaTestCase`.
`SnubaTestCase` also overrides `create_project()` and `store_event()`,
which would change the fixtures and ingestion these tests run against,
and none of them needs that.
Snowflake id reuse across tests is broader than these classes. Any test
that reads Snuba data without resetting it can hit it. This PR fixes
only the tests that fail.
Refs #108654
Refs #109451
Refs #109450
Refs #109445
Refs #109435
Refs #109433
Refs #109432
Refs #108888
Refs #108770
Refs #108935
Refs #108873
Refs #109056
Refs #108982
Refs #108930
Refs #108902
Refs #108838
**Global `time.sleep` patches: `StreamDemoDataTest` (12).**
`patch("sentry.conduit.tasks.time.sleep")` replaces `time.sleep` for
every thread in the process, so any background thread that sleeps adds
to the count (CI saw 451 to 5332 calls instead of 100). Both stream
tests now patch the module-local `time` references instead:
`sentry.conduit.tasks.time`, and in the retry test also
`sentry.utils.retries.time`, where the retry policy sleeps. The real
`time.time()` stays in place. The retry test now also checks both sleep
counts. No other test in the file patches `time.sleep`.
Refs #108842
**Batch deadline:
`TestBatchedOccurrenceConsumer::test_issue_multiple_status_changes`
(4).** Arroyo starts the batch deadline when the strategy is built, so
with `max_batch_time=1` a slow run flushed the batch before all six
messages arrived. The test now uses `sys.maxsize`, like its sibling
tests since #88955.
Refs #108997
**1 second rate limit windows:
`test_impersonation_enforces_rate_limits_when_disabled` (1).**
Impersonation limits use 1 second windows, so three calls that straddle
a second boundary are counted in different windows. The calls now run
under `freeze_time`, like the other tests in the file.
`test_impersonation_with_custom_endpoint_config` has the same pattern
and gets the same fix.
Refs #109043
**Random collision: `test_ttl_jitter` (1).** Two random TTLs round to
the same second about once in 1800 runs, and the test asserted they
differ. It now checks the bounds with real draws and the spread with
fixed draws.
Refs #108952
### Reproductions
Each fix was checked with a deterministic reproduction, run against the
parent commit (fails) and against the fix (passes). The uptime
pagination test and the TTL jitter draws are committed. The others are
not, because they force the failure by rewriting physical row order,
pinning the snowflake clock, or adding a sleeping background thread.
Those depend on planner behavior or test order, or test the test harness
rather than the product.
| Fix | Reproduction | Parent | Fixed |
|---|---|---|---|
| Uptime pagination | `test_paginates_in_id_order` | fail | pass |
| Deploy footer | release_project rows in the opposite physical order to
project rows | fail | pass |
| Channel login | first org's mapping row rewritten to the end of the
heap | fail | pass |
| Snuba reset (3 classes) | snowflake clock pinned to one second,
preceded by a test that writes feedback or events | fail | pass |
| Conduit sleeps | background thread calling `time.sleep` during the
test | fail | pass |
| Batch deadline | arroyo clock advanced 2s after the strategy is built
| fail | pass |
| Impersonation windows | wall clock advanced 1s per rate limit check |
fail | pass |
| TTL jitter | `random.seed(1095)` | fail | pass |
The ten changed test files (139 tests) also passed 20 consecutive runs
with `-n 2 --dist=loadfile`, per-worker Snuba, and `PYTHONHASHSEED=0`,
as in CI.
<!-- junior-request-attribution:start -->
via @joshuarli.
<!-- junior-request-attribution:end -->
<!-- junior-session-footer:start -->
<!-- junior-conversation-id:agent%3A3f29e2341c39dfa3441598ed78b058a7 -->
--
[View Junior
Session](https://junior-prod.sentry.dev/conversations/agent%3A3f29e2341c39dfa3441598ed78b058a7)
[[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3A3f29e2341c39dfa3441598ed78b058a7/?project=4510944073809921)
<!-- junior-session-footer:end -->
---------
Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
Co-authored-by: Joshua Li <14209781+joshuarli@users.noreply.github.com>1 parent e669d6f commit b73b480
11 files changed
Lines changed: 97 additions & 27 deletions
File tree
- src/sentry/uptime/endpoints
- tests/sentry
- conduit
- feedback
- endpoints
- lib
- integrations/slack/notifications
- issues
- middleware
- sentry_metrics
- services/eventstore
- uptime/endpoints
- web/frontend
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
141 | 141 | | |
142 | 142 | | |
143 | 143 | | |
| 144 | + | |
144 | 145 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
| |||
256 | 257 | | |
257 | 258 | | |
258 | 259 | | |
259 | | - | |
260 | | - | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
261 | 264 | | |
| 265 | + | |
262 | 266 | | |
263 | 267 | | |
264 | 268 | | |
| |||
271 | 275 | | |
272 | 276 | | |
273 | 277 | | |
274 | | - | |
| 278 | + | |
275 | 279 | | |
276 | 280 | | |
277 | 281 | | |
| |||
280 | 284 | | |
281 | 285 | | |
282 | 286 | | |
283 | | - | |
284 | | - | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
285 | 292 | | |
| 293 | + | |
286 | 294 | | |
287 | 295 | | |
288 | 296 | | |
| |||
305 | 313 | | |
306 | 314 | | |
307 | 315 | | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| |||
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
16 | 20 | | |
17 | 21 | | |
18 | 22 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
23 | 26 | | |
24 | 27 | | |
25 | 28 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
58 | 57 | | |
59 | | - | |
| 58 | + | |
60 | 59 | | |
61 | 60 | | |
62 | 61 | | |
63 | | - | |
64 | | - | |
| 62 | + | |
65 | 63 | | |
66 | | - | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
67 | 68 | | |
68 | | - | |
69 | | - | |
| 69 | + | |
| 70 | + | |
70 | 71 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
465 | 465 | | |
466 | 466 | | |
467 | 467 | | |
468 | | - | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
469 | 471 | | |
470 | 472 | | |
471 | 473 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
235 | 235 | | |
236 | 236 | | |
237 | 237 | | |
238 | | - | |
239 | | - | |
240 | | - | |
241 | | - | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
242 | 246 | | |
243 | 247 | | |
244 | 248 | | |
| |||
289 | 293 | | |
290 | 294 | | |
291 | 295 | | |
292 | | - | |
293 | | - | |
294 | | - | |
295 | | - | |
| 296 | + | |
| 297 | + | |
| 298 | + | |
| 299 | + | |
| 300 | + | |
| 301 | + | |
296 | 302 | | |
297 | 303 | | |
298 | 304 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
2 | 3 | | |
3 | 4 | | |
4 | 5 | | |
| |||
216 | 217 | | |
217 | 218 | | |
218 | 219 | | |
219 | | - | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
220 | 228 | | |
221 | 229 | | |
222 | 230 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
44 | 44 | | |
45 | 45 | | |
46 | 46 | | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
47 | 50 | | |
48 | 51 | | |
49 | 52 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
1 | 3 | | |
2 | 4 | | |
3 | 5 | | |
| 6 | + | |
4 | 7 | | |
5 | 8 | | |
6 | 9 | | |
| |||
23 | 26 | | |
24 | 27 | | |
25 | 28 | | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
26 | 53 | | |
27 | 54 | | |
28 | 55 | | |
| |||
0 commit comments