Skip to content

Commit d277417

Browse files
authored
Unit tests for get_rules_to_fire in delayed_processing (#74615)
# Description - Smol tweaks to delayed processing's `get_rules_to_fire` for readability - Unit tested `get_rules_to_fire`
1 parent 5de2b79 commit d277417

File tree

2 files changed

+128
-10
lines changed

2 files changed

+128
-10
lines changed

src/sentry/rules/processing/delayed_processing.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -271,11 +271,8 @@ def get_rules_to_fire(
271271
if action_match == "any":
272272
rules_to_fire[alert_rule].add(group_id)
273273
break
274-
conditions_matched += 1
275-
else:
276-
if action_match == "all":
277-
# We failed to match all conditions for this group, skip
278-
break
274+
elif action_match == "all":
275+
conditions_matched += 1
279276
if action_match == "all" and conditions_matched == len(slow_conditions):
280277
rules_to_fire[alert_rule].add(group_id)
281278
return rules_to_fire

tests/sentry/rules/processing/test_delayed_processing.py

Lines changed: 126 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@
22
from collections.abc import Sequence
33
from copy import deepcopy
44
from datetime import datetime, timedelta
5-
from typing import cast
5+
from typing import DefaultDict, cast
66
from unittest.mock import Mock, patch
77
from uuid import uuid4
88

99
import pytest
1010

1111
from sentry import buffer
1212
from sentry.eventstore.models import GroupEvent
13+
from sentry.models.group import Group
1314
from sentry.models.project import Project
15+
from sentry.models.rule import Rule
1416
from sentry.models.rulefirehistory import RuleFireHistory
1517
from sentry.rules.conditions.event_frequency import (
1618
ComparisonType,
@@ -26,6 +28,7 @@
2628
get_condition_group_results,
2729
get_condition_query_groups,
2830
get_group_to_groupevent,
31+
get_rules_to_fire,
2932
get_rules_to_groups,
3033
get_rules_to_slow_conditions,
3134
get_slow_conditions,
@@ -43,8 +46,17 @@
4346
pytestmark = pytest.mark.sentry_metrics
4447

4548
FROZEN_TIME = before_now(days=1).replace(hour=1, minute=30, second=0, microsecond=0)
46-
TEST_RULE_SLOW_CONDITION = {"id": "sentry.rules.conditions.event_frequency.EventFrequencyCondition"}
47-
TEST_RULE_FAST_CONDITION = {"id": "sentry.rules.conditions.every_event.EveryEventCondition"}
49+
TEST_RULE_SLOW_CONDITION: EventFrequencyConditionData = {
50+
"id": "sentry.rules.conditions.event_frequency.EventFrequencyCondition",
51+
"value": 1,
52+
"interval": "1h",
53+
}
54+
55+
TEST_RULE_FAST_CONDITION: EventFrequencyConditionData = {
56+
"id": "sentry.rules.conditions.every_event.EveryEventCondition",
57+
"value": 1,
58+
"interval": "1h",
59+
}
4860

4961

5062
def test_bucket_num_groups():
@@ -366,8 +378,117 @@ def test_invalid_group_ids(self):
366378

367379

368380
class GetRulesToFireTest(TestCase):
369-
def test_get_rules_to_fire(self):
370-
pass
381+
def setUp(self):
382+
self.organization = self.create_organization()
383+
self.project = self.create_project()
384+
self.environment = self.create_environment()
385+
386+
self.rule1: Rule = self.create_project_rule(
387+
project=self.project,
388+
condition_match=[TEST_RULE_SLOW_CONDITION],
389+
environment_id=self.environment.id,
390+
)
391+
self.group1: Group = self.create_group(self.project)
392+
self.group2: Group = self.create_group(self.project)
393+
394+
self.condition_group_results: dict[UniqueConditionQuery, dict[int, int]] = {
395+
UniqueConditionQuery(
396+
cls_id=TEST_RULE_SLOW_CONDITION["id"],
397+
interval=TEST_RULE_SLOW_CONDITION["interval"],
398+
environment_id=self.environment.id,
399+
): {self.group1.id: 2, self.group2.id: 1}
400+
}
401+
402+
self.rules_to_slow_conditions: DefaultDict[
403+
Rule, list[EventFrequencyConditionData]
404+
] = defaultdict(list)
405+
self.rules_to_slow_conditions[self.rule1].append(TEST_RULE_SLOW_CONDITION)
406+
407+
self.rules_to_groups: DefaultDict[int, set[int]] = defaultdict(set)
408+
self.rules_to_groups[self.rule1.id].add(self.group1.id)
409+
self.rules_to_groups[self.rule1.id].add(self.group2.id)
410+
411+
# Mock _passes_comparison function
412+
self.patcher = patch("sentry.rules.processing.delayed_processing._passes_comparison")
413+
self.mock_passes_comparison = self.patcher.start()
414+
415+
def tearDown(self):
416+
self.patcher.stop()
417+
418+
def test_comparison(self):
419+
self.mock_passes_comparison.return_value = True
420+
421+
result = get_rules_to_fire(
422+
self.condition_group_results,
423+
self.rules_to_slow_conditions,
424+
self.rules_to_groups,
425+
self.project.id,
426+
)
427+
428+
assert result[self.rule1] == {self.group1.id, self.group2.id}
429+
430+
def test_comparison_fail_all(self):
431+
self.mock_passes_comparison.return_value = False
432+
433+
result = get_rules_to_fire(
434+
self.condition_group_results,
435+
self.rules_to_slow_conditions,
436+
self.rules_to_groups,
437+
self.project.id,
438+
)
439+
440+
assert self.rule1 not in result
441+
442+
def test_comparison_any(self):
443+
self.rule1.data["action_match"] = "any"
444+
self.mock_passes_comparison.return_value = True
445+
446+
result = get_rules_to_fire(
447+
self.condition_group_results,
448+
self.rules_to_slow_conditions,
449+
self.rules_to_groups,
450+
self.project.id,
451+
)
452+
453+
assert result[self.rule1] == {self.group1.id, self.group2.id}
454+
455+
def test_comparison_any_fail(self):
456+
self.rule1.data["action_match"] = "any"
457+
self.mock_passes_comparison.return_value = False
458+
459+
result = get_rules_to_fire(
460+
self.condition_group_results,
461+
self.rules_to_slow_conditions,
462+
self.rules_to_groups,
463+
self.project.id,
464+
)
465+
466+
assert self.rule1 not in result
467+
468+
def test_empty_input(self):
469+
result = get_rules_to_fire({}, defaultdict(list), defaultdict(set), self.project.id)
470+
assert len(result) == 0
471+
472+
@patch("sentry.rules.processing.delayed_processing._passes_comparison", return_value=True)
473+
def test_multiple_rules_and_groups(self, mock_passes):
474+
rule2 = self.create_project_rule(
475+
project=self.project,
476+
condition_match=[TEST_RULE_SLOW_CONDITION],
477+
environment_id=self.environment.id,
478+
)
479+
self.rules_to_slow_conditions[rule2].append(TEST_RULE_SLOW_CONDITION)
480+
self.rules_to_groups[rule2.id].add(self.group2.id)
481+
482+
result = get_rules_to_fire(
483+
self.condition_group_results,
484+
self.rules_to_slow_conditions,
485+
self.rules_to_groups,
486+
self.project.id,
487+
)
488+
489+
assert len(result) == 2
490+
assert result[self.rule1] == {self.group1.id, self.group2.id}
491+
assert result[rule2] == {self.group2.id}
371492

372493

373494
class GetRulesToGroupsTest(TestCase):

0 commit comments

Comments
 (0)