|
1 | 1 | import os |
2 | 2 | import random |
3 | 3 | from datetime import datetime, timedelta |
4 | | -from time import time |
| 4 | +from time import sleep, time |
5 | 5 | from typing import Any |
6 | 6 | from unittest import mock |
7 | 7 | from uuid import uuid4 |
@@ -383,6 +383,32 @@ def select_rows( |
383 | 383 | def tenant_ids(self) -> dict[str, str]: |
384 | 384 | return {"referrer": self.referrer, "organization_id": self.organization.id} |
385 | 385 |
|
| 386 | + def poll_for_deletion( |
| 387 | + self, |
| 388 | + project_id: int, |
| 389 | + expected_none: bool = True, |
| 390 | + max_attempts: int = 10, |
| 391 | + delay: float = 0.1, |
| 392 | + ) -> None: |
| 393 | + """ |
| 394 | + Poll Snuba until issue platform events are deleted or present. |
| 395 | +
|
| 396 | + ClickHouse light deletes are eventually consistent, so we need to poll |
| 397 | + until the deletion becomes visible in queries. |
| 398 | + """ |
| 399 | + for attempt in range(max_attempts): |
| 400 | + result = self.select_issue_platform_events(project_id) |
| 401 | + if (expected_none and result is None) or (not expected_none and result is not None): |
| 402 | + return |
| 403 | + if attempt < max_attempts - 1: |
| 404 | + sleep(delay) |
| 405 | + |
| 406 | + # Final check - let the assertion fail with proper error message |
| 407 | + if expected_none: |
| 408 | + assert self.select_issue_platform_events(project_id) is None |
| 409 | + else: |
| 410 | + assert self.select_issue_platform_events(project_id) is not None |
| 411 | + |
386 | 412 | def test_simple_issue_platform(self) -> None: |
387 | 413 | # Adding this query here to make sure that the cache is not being used |
388 | 414 | assert self.select_error_events(self.project.id) is None |
@@ -436,7 +462,8 @@ def test_simple_issue_platform(self) -> None: |
436 | 462 | # The Issue Platform group and occurrence have been deleted |
437 | 463 | assert not Group.objects.filter(id=issue_platform_group.id).exists() |
438 | 464 | # assert not nodestore.backend.get(occurrence_node_id) |
439 | | - assert self.select_issue_platform_events(self.project.id) is None |
| 465 | + # Poll for eventual consistency - ClickHouse light deletes are not immediately visible |
| 466 | + self.poll_for_deletion(self.project.id, expected_none=True) |
440 | 467 |
|
441 | 468 | @mock.patch("sentry.deletions.tasks.nodestore.bulk_snuba_queries") |
442 | 469 | def test_issue_platform_batching(self, mock_bulk_snuba_queries: mock.Mock) -> None: |
|
0 commit comments