Skip to content

Commit a63b3b6

Browse files
authored
test(aci milestone 3): metric issue integration tests (#94730)
Building off of Colleen's existing metric issue integration tests.
1 parent 6c3a730 commit a63b3b6

File tree

3 files changed

+333
-214
lines changed

3 files changed

+333
-214
lines changed

tests/sentry/incidents/test_metric_issue_detector_handler.py

Lines changed: 43 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,15 @@
1-
from datetime import UTC, datetime, timedelta
2-
31
from sentry.incidents.grouptype import MetricIssueDetectorHandler
4-
from sentry.incidents.utils.constants import INCIDENTS_SNUBA_SUBSCRIPTION_TYPE
5-
from sentry.incidents.utils.types import QuerySubscriptionUpdate
62
from sentry.issues.issue_occurrence import IssueOccurrence
7-
from sentry.snuba.dataset import Dataset
8-
from sentry.snuba.models import SnubaQuery, SnubaQueryEventType
9-
from sentry.snuba.subscriptions import create_snuba_query, create_snuba_subscription
103
from sentry.testutils.helpers.datetime import freeze_time
11-
from sentry.workflow_engine.models import DataCondition, DataPacket
4+
from sentry.workflow_engine.models import DataCondition
125
from sentry.workflow_engine.models.data_condition import Condition
13-
from sentry.workflow_engine.types import (
14-
DetectorEvaluationResult,
15-
DetectorGroupKey,
16-
DetectorPriorityLevel,
17-
)
18-
from tests.sentry.workflow_engine.handlers.detector.test_base import BaseDetectorHandlerTest
6+
from tests.sentry.incidents.utils.test_metric_issue_base import BaseMetricIssueTest
197

208

219
@freeze_time()
22-
class TestEvaluateMetricDetector(BaseDetectorHandlerTest):
10+
class TestEvaluateMetricDetector(BaseMetricIssueTest):
2311
def setUp(self):
2412
super().setUp()
25-
self.detector_group_key = None
26-
self.detector = self.create_detector(
27-
project=self.project,
28-
workflow_condition_group=self.create_data_condition_group(),
29-
type="handler_with_state",
30-
created_by_id=self.user.id,
31-
)
32-
self.critical_detector_trigger = self.create_data_condition(
33-
type=Condition.GREATER,
34-
comparison=5,
35-
condition_result=DetectorPriorityLevel.HIGH,
36-
condition_group=self.detector.workflow_condition_group,
37-
)
38-
self.warning_detector_trigger = self.create_data_condition(
39-
comparison=3,
40-
type=Condition.GREATER,
41-
condition_result=DetectorPriorityLevel.MEDIUM,
42-
condition_group=self.detector.workflow_condition_group,
43-
)
44-
with self.tasks():
45-
self.snuba_query = create_snuba_query(
46-
query_type=SnubaQuery.Type.ERROR,
47-
dataset=Dataset.Events,
48-
query="hello",
49-
aggregate="count()",
50-
time_window=timedelta(minutes=1),
51-
resolution=timedelta(minutes=1),
52-
environment=self.environment,
53-
event_types=[SnubaQueryEventType.EventType.ERROR],
54-
)
55-
self.query_subscription = create_snuba_subscription(
56-
project=self.detector.project,
57-
subscription_type=INCIDENTS_SNUBA_SUBSCRIPTION_TYPE,
58-
snuba_query=self.snuba_query,
59-
)
60-
self.alert_rule = self.create_alert_rule()
61-
self.create_alert_rule_detector(alert_rule_id=self.alert_rule.id, detector=self.detector)
62-
6313
self.handler = MetricIssueDetectorHandler(self.detector)
6414

6515
def generate_evidence_data(
@@ -93,100 +43,68 @@ def generate_evidence_data(
9343
)
9444
return evidence_data
9545

96-
def test_metric_issue_occurrence(self):
97-
value = self.critical_detector_trigger.comparison + 1
98-
packet = QuerySubscriptionUpdate(
99-
entity="entity",
100-
subscription_id=str(self.query_subscription.id),
101-
values={"value": value},
102-
timestamp=datetime.now(UTC),
103-
)
104-
data_packet = DataPacket[QuerySubscriptionUpdate](
105-
source_id=str(self.query_subscription.id), packet=packet
106-
)
107-
evidence_data = self.generate_evidence_data(
108-
value, self.critical_detector_trigger, self.warning_detector_trigger
109-
)
110-
111-
result: dict[DetectorGroupKey, DetectorEvaluationResult] = self.handler.evaluate(
112-
data_packet
113-
)
114-
evaluation_result: DetectorEvaluationResult = result[self.detector_group_key]
115-
assert isinstance(evaluation_result.result, IssueOccurrence)
116-
occurrence: IssueOccurrence = evaluation_result.result
117-
46+
def verify_issue_occurrence(
47+
self, occurrence: IssueOccurrence, evidence_data: dict, detector_trigger: DataCondition
48+
) -> None:
11849
assert occurrence is not None
11950
assert occurrence.issue_title == self.detector.name
12051
assert occurrence.subtitle == self.handler.construct_title(
12152
snuba_query=self.snuba_query,
122-
detector_trigger=self.critical_detector_trigger,
123-
priority=self.critical_detector_trigger.condition_result,
53+
detector_trigger=detector_trigger,
54+
priority=detector_trigger.condition_result,
12455
)
12556
assert occurrence.evidence_data == evidence_data
12657
assert occurrence.level == "error"
127-
assert occurrence.priority == self.critical_detector_trigger.condition_result
58+
assert occurrence.priority == detector_trigger.condition_result
12859
assert occurrence.assignee
12960
assert occurrence.assignee.id == self.detector.created_by_id
13061

62+
def test_metric_issue_occurrence(self):
63+
value = self.critical_detector_trigger.comparison + 1
64+
data_packet = self.create_subscription_packet(value)
65+
evidence_data = self.generate_evidence_data(
66+
value, self.critical_detector_trigger, self.warning_detector_trigger
67+
)
68+
69+
occurrence = self.process_packet_and_return_result(data_packet)
70+
assert isinstance(occurrence, IssueOccurrence)
71+
72+
self.verify_issue_occurrence(occurrence, evidence_data, self.critical_detector_trigger)
73+
13174
def test_warning_level(self):
13275
value = self.warning_detector_trigger.comparison + 1
133-
packet = QuerySubscriptionUpdate(
134-
entity="entity",
135-
subscription_id=str(self.query_subscription.id),
136-
values={"value": value},
137-
timestamp=datetime.now(UTC),
138-
)
139-
data_packet = DataPacket[QuerySubscriptionUpdate](
140-
source_id=str(self.query_subscription.id), packet=packet
141-
)
76+
data_packet = self.create_subscription_packet(value)
14277
evidence_data = self.generate_evidence_data(value, self.warning_detector_trigger)
14378

144-
result: dict[DetectorGroupKey, DetectorEvaluationResult] = self.handler.evaluate(
145-
data_packet
146-
)
147-
evaluation_result: DetectorEvaluationResult = result[self.detector_group_key]
148-
assert isinstance(evaluation_result.result, IssueOccurrence)
149-
occurrence: IssueOccurrence = evaluation_result.result
79+
occurrence = self.process_packet_and_return_result(data_packet)
80+
assert isinstance(occurrence, IssueOccurrence)
15081

151-
assert occurrence is not None
152-
assert occurrence.issue_title == self.detector.name
153-
assert occurrence.subtitle == self.handler.construct_title(
154-
snuba_query=self.snuba_query,
155-
detector_trigger=self.warning_detector_trigger,
156-
priority=self.warning_detector_trigger.condition_result,
157-
)
158-
assert occurrence.evidence_data == evidence_data
159-
assert occurrence.level == "error"
160-
assert occurrence.priority == self.warning_detector_trigger.condition_result
82+
self.verify_issue_occurrence(occurrence, evidence_data, self.warning_detector_trigger)
16183

16284
def test_does_not_trigger(self):
16385
value = self.warning_detector_trigger.comparison - 1
164-
packet = QuerySubscriptionUpdate(
165-
entity="entity",
166-
subscription_id=str(self.query_subscription.id),
167-
values={"value": value},
168-
timestamp=datetime.now(UTC),
169-
)
170-
data_packet = DataPacket[QuerySubscriptionUpdate](
171-
source_id=str(self.query_subscription.id), packet=packet
172-
)
173-
result = self.handler.evaluate(data_packet)
174-
assert result == {}
86+
data_packet = self.create_subscription_packet(value)
87+
result = self.process_packet_and_return_result(data_packet)
88+
assert result is None
17589

17690
def test_missing_detector_trigger(self):
17791
value = self.critical_detector_trigger.comparison + 1
178-
packet = QuerySubscriptionUpdate(
179-
entity="entity",
180-
subscription_id=str(self.query_subscription.id),
181-
values={"value": value},
182-
timestamp=datetime.now(UTC),
183-
)
184-
data_packet = DataPacket[QuerySubscriptionUpdate](
185-
source_id=str(self.query_subscription.id), packet=packet
186-
)
92+
data_packet = self.create_subscription_packet(value)
18793
DataCondition.objects.all().delete()
188-
result = self.handler.evaluate(data_packet)
189-
assert result == {}
94+
result = self.process_packet_and_return_result(data_packet)
95+
assert result is None
96+
97+
def test_flipped_detector_trigger(self):
98+
self.warning_detector_trigger.delete()
99+
self.critical_detector_trigger.update(type=Condition.LESS)
100+
value = self.critical_detector_trigger.comparison - 1
101+
data_packet = self.create_subscription_packet(value)
102+
evidence_data = self.generate_evidence_data(value, self.critical_detector_trigger)
103+
104+
occurrence = self.process_packet_and_return_result(data_packet)
105+
assert isinstance(occurrence, IssueOccurrence)
106+
107+
self.verify_issue_occurrence(occurrence, evidence_data, self.critical_detector_trigger)
190108

191109

192110
class TestConstructTitle(TestEvaluateMetricDetector):

0 commit comments

Comments
 (0)