Skip to content

Commit bf0cc37

Browse files
committed
tests
1 parent f4450cf commit bf0cc37

File tree

2 files changed

+85
-5
lines changed

2 files changed

+85
-5
lines changed

src/sentry/workflow_engine/migrations/0060_backfill_metric_alert_resolution_action_filters.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,18 @@ def backfill_resolution_action_filters(apps: Apps, schema_editor: BaseDatabaseSc
3838
workflow_dcgs = DataConditionGroup.objects.filter(
3939
workflowdataconditiongroup__workflow__id=workflow_id
4040
)
41-
if DataCondition.objects.filter(
42-
condition_group__in=workflow_dcgs, type="issue_priority_deescalating"
43-
).exists():
44-
# the resolution action filters have already been created, either via dual write or a previous migration
45-
continue
4641

4742
with transaction.atomic(router.db_for_write(DataCondition)):
4843
for dcg in workflow_dcgs:
44+
if DataCondition.objects.filter(
45+
condition_group=dcg, type="issue_priority_deescalating"
46+
).exists():
47+
# the resolution action filter has already been created, either via dual write or a previous migration
48+
# I have this inside the loop because it's possible someone added a new condition after we turned
49+
# on dual write of resolution action filters, so one of the conditions is correct and the other
50+
# needs to be backfilled
51+
continue
52+
4953
action_filter = DataCondition.objects.get(
5054
condition_group=dcg,
5155
)
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
from sentry.testutils.cases import TestMigrations
2+
from sentry.workflow_engine.models import Condition, DataCondition, DataConditionGroup
3+
from sentry.workflow_engine.types import DetectorPriorityLevel
4+
5+
6+
class TestBackfillMetricAlertResolutionActionFilters(TestMigrations):
7+
app = "workflow_engine"
8+
migrate_from = "0059_fix_high_priority_condition_triggers"
9+
migrate_to = "0060_backfill_metric_alert_resolution_action_filters"
10+
11+
def mock_aci_objects(self) -> tuple[DataConditionGroup, DataConditionGroup]:
12+
alert_rule = self.create_alert_rule(organization=self.organization)
13+
workflow = self.create_workflow(organization=self.organization)
14+
self.create_alert_rule_workflow(alert_rule=alert_rule, workflow=workflow)
15+
16+
critical_dcg = self.create_data_condition_group(organization=self.organization)
17+
self.create_workflow_data_condition_group(workflow=workflow, condition_group=critical_dcg)
18+
self.create_data_condition(
19+
comparison=DetectorPriorityLevel.HIGH,
20+
condition_result=True,
21+
type=Condition.ISSUE_PRIORITY_GREATER_OR_EQUAL,
22+
condition_group=critical_dcg,
23+
)
24+
25+
warning_dcg = self.create_data_condition_group(organization=self.organization)
26+
self.create_workflow_data_condition_group(workflow=workflow, condition_group=warning_dcg)
27+
self.create_data_condition(
28+
comparison=DetectorPriorityLevel.MEDIUM,
29+
condition_result=True,
30+
type=Condition.ISSUE_PRIORITY_GREATER_OR_EQUAL,
31+
condition_group=warning_dcg,
32+
)
33+
34+
return critical_dcg, warning_dcg
35+
36+
def create_resolve_action_filter(self, dcg: DataConditionGroup) -> None:
37+
self.create_data_condition(
38+
comparison=DetectorPriorityLevel.HIGH,
39+
condition_result=True,
40+
type=Condition.ISSUE_PRIORITY_DEESCALATING,
41+
condition_group=dcg,
42+
)
43+
44+
def assert_resolve_action_filter_exists(
45+
self, dcg: DataConditionGroup, comparison: DetectorPriorityLevel
46+
) -> None:
47+
queryset = DataCondition.objects.filter(
48+
comparison=comparison, type=Condition.ISSUE_PRIORITY_DEESCALATING, condition_group=dcg
49+
)
50+
assert queryset.exists()
51+
assert queryset.count() == 1
52+
53+
def setup_initial_state(self):
54+
# vanilla
55+
self.critical_dcg_1, self.warning_dcg_1 = self.mock_aci_objects()
56+
57+
# both dcgs have a resolution action filter
58+
self.critical_dcg_2, self.warning_dcg_2 = self.mock_aci_objects()
59+
self.create_resolve_action_filter(self.critical_dcg_2)
60+
self.create_resolve_action_filter(self.warning_dcg_2)
61+
62+
# only one dcg has a resolution action filter
63+
self.critical_dcg_3, self.warning_dcg_3 = self.mock_aci_objects()
64+
self.create_resolve_action_filter(self.warning_dcg_3)
65+
66+
def test_simple(self):
67+
self.assert_resolve_action_filter_exists(self.critical_dcg_1, DetectorPriorityLevel.HIGH)
68+
self.assert_resolve_action_filter_exists(self.warning_dcg_1, DetectorPriorityLevel.MEDIUM)
69+
70+
def test_both_migrated(self):
71+
self.assert_resolve_action_filter_exists(self.critical_dcg_2, DetectorPriorityLevel.HIGH)
72+
self.assert_resolve_action_filter_exists(self.warning_dcg_2, DetectorPriorityLevel.MEDIUM)
73+
74+
def test_one_migrated(self):
75+
self.assert_resolve_action_filter_exists(self.critical_dcg_3, DetectorPriorityLevel.HIGH)
76+
self.assert_resolve_action_filter_exists(self.warning_dcg_3, DetectorPriorityLevel.MEDIUM)

0 commit comments

Comments
 (0)