Skip to content

Commit cf13b1f

Browse files
snigdhasceorourke
authored andcommitted
Switch to using detector_id for the lookups
1 parent dcd5c36 commit cf13b1f

File tree

4 files changed

+65
-41
lines changed

4 files changed

+65
-41
lines changed

src/sentry/models/groupopenperiod.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ def get_open_periods_for_group(
243243
return open_periods
244244

245245

246-
def create_open_period(group: Group, start_time: datetime) -> None:
246+
def create_open_period(group: Group, start_time: datetime) -> GroupOpenPeriod:
247247
if not features.has("organizations:issue-open-periods", group.project.organization):
248248
return
249249

@@ -254,7 +254,7 @@ def create_open_period(group: Group, start_time: datetime) -> None:
254254

255255
# There are some historical cases where we log multiple regressions for the same group,
256256
# but we only want to create a new open period for the first regression
257-
GroupOpenPeriod.objects.create(
257+
return GroupOpenPeriod.objects.create(
258258
group=group,
259259
project=group.project,
260260
date_started=start_time,

src/sentry/workflow_engine/models/incident_groupopenperiod.py

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
FlexibleForeignKey,
1111
region_silo_model,
1212
)
13+
from sentry.incidents.models.alert_rule import AlertRule
1314
from sentry.incidents.models.incident import Incident
1415
from sentry.models.groupopenperiod import GroupOpenPeriod
16+
from sentry.workflow_engine.models.alertrule_detector import AlertRuleDetector
1517

1618
logger = logging.getLogger(__name__)
1719

@@ -51,21 +53,14 @@ def create_from_occurrence(self, occurrence, group, open_period):
5153
open_period: The GroupOpenPeriod for the group
5254
"""
5355
try:
54-
# Extract alert_id from evidence_data
55-
alert_id = occurrence.evidence_data.get("alert_id")
56-
if not alert_id:
57-
logger.warning(
58-
"No alert_id found in evidence_data for metric issue",
59-
extra={
60-
"group_id": group.id,
61-
"occurrence_id": occurrence.id,
62-
},
63-
)
64-
return None
56+
# Extract alert_id from evidence_data using the detector_id
57+
detector_id = occurrence.evidence_data.get("detector_id")
58+
if detector_id:
59+
alert_id = AlertRuleDetector.objects.get(detector_id=detector_id).alert_rule_id
60+
else:
61+
raise Exception("No detector_id found in evidence_data for metric issue")
6562

6663
# Try to find the active incident for this alert rule and project
67-
from sentry.incidents.models.alert_rule import AlertRule
68-
6964
try:
7065
alert_rule = AlertRule.objects.get(id=alert_id)
7166
incident = Incident.objects.get_active_incident(
@@ -88,7 +83,7 @@ def create_from_occurrence(self, occurrence, group, open_period):
8883
else:
8984
# Incident doesn't exist yet, create a placeholder relationship
9085
# that will be updated when the incident is created
91-
return self.create_placeholder_relationship(alert_id, open_period, group.project)
86+
return self.create_placeholder_relationship(detector_id, open_period, group.project)
9287

9388
except Exception as e:
9489
logger.exception(
@@ -133,20 +128,20 @@ def create_relationship(self, incident, open_period):
133128
return None
134129

135130
@classmethod
136-
def create_placeholder_relationship(self, alert_id, open_period, project):
131+
def create_placeholder_relationship(self, detector_id, open_period, project):
137132
"""
138133
Creates a placeholder relationship when the incident doesn't exist yet.
139134
This will be updated when the incident is created.
140135
141136
Args:
142-
alert_id: The alert rule ID
137+
detector_id: The detector ID
143138
open_period: The GroupOpenPeriod to link
144139
project: The project for the group
145140
"""
146141
try:
147142
# Store the alert_id in the open_period data for later lookup
148143
data = open_period.data or {}
149-
data["pending_incident_alert_id"] = alert_id
144+
data["pending_incident_detector_id"] = detector_id
150145
open_period.update(data=data)
151146

152147
return None
@@ -155,7 +150,7 @@ def create_placeholder_relationship(self, alert_id, open_period, project):
155150
logger.exception(
156151
"Failed to create placeholder IncidentGroupOpenPeriod relationship",
157152
extra={
158-
"alert_id": alert_id,
153+
"detector_id": detector_id,
159154
"open_period_id": open_period.id,
160155
"error": str(e),
161156
},
@@ -174,9 +169,10 @@ def create_pending_relationships_for_incident(self, incident, alert_rule):
174169
alert_rule: The AlertRule that triggered the incident
175170
"""
176171
try:
177-
# Find all open periods that have a pending incident alert_id for this alert rule
172+
# Find all open periods that have a pending incident detector_id for this alert rule
173+
detector_id = AlertRuleDetector.objects.get(alert_rule_id=alert_rule.id).detector_id
178174
pending_open_periods = GroupOpenPeriod.objects.filter(
179-
data__pending_incident_alert_id=alert_rule.id,
175+
data__pending_incident_detector_id=detector_id,
180176
group__project__in=incident.projects.all(),
181177
)
182178

@@ -186,7 +182,7 @@ def create_pending_relationships_for_incident(self, incident, alert_rule):
186182
if relationship:
187183
# Remove the pending flag from the open_period data
188184
data = open_period.data or {}
189-
data.pop("pending_incident_alert_id", None)
185+
data.pop("pending_incident_detector_id", None)
190186
open_period.update(data=data)
191187

192188
except Exception as e:

tests/sentry/issues/test_ingest_incident_integration.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ def setUp(self) -> None:
2424
projects=[self.project],
2525
name="Test Alert Rule",
2626
)
27+
self.detector = self.create_detector(
28+
project=self.project,
29+
name="Test Detector",
30+
)
31+
self.alert_rule_detector = self.create_alert_rule_detector(
32+
alert_rule_id=self.alert_rule.id,
33+
detector=self.detector,
34+
)
2735

2836
def save_issue_occurrence(
2937
self, group_type: int = MetricIssue.type_id
@@ -40,7 +48,7 @@ def save_issue_occurrence(
4048
"issue_title": "Test Issue",
4149
"subtitle": "Test Subtitle",
4250
"resource_id": None,
43-
"evidence_data": {"alert_id": self.alert_rule.id},
51+
"evidence_data": {"detector_id": self.detector.id},
4452
"evidence_display": [
4553
{"name": "Test Evidence", "value": "Test Value", "important": True}
4654
],
@@ -84,7 +92,7 @@ def test_save_issue_occurrence_creates_placeholder_when_incident_doesnt_exist(se
8492
assert group is not None
8593

8694
open_period = GroupOpenPeriod.objects.get(group=group)
87-
assert open_period.data["pending_incident_alert_id"] == self.alert_rule.id
95+
assert open_period.data["pending_incident_detector_id"] == self.detector.id
8896

8997
assert not IncidentGroupOpenPeriod.objects.filter(group_open_period=open_period).exists()
9098

tests/sentry/workflow_engine/models/test_incident_groupopenperiod.py

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
import uuid
12
from typing import Any
23
from unittest.mock import patch
34

45
from django.utils import timezone
56

67
from sentry.incidents.grouptype import MetricIssue
8+
from sentry.incidents.models.incident import IncidentStatus
79
from sentry.issues.ingest import save_issue_occurrence
810
from sentry.issues.issue_occurrence import IssueOccurrenceData
9-
from sentry.models.groupopenperiod import GroupOpenPeriod
11+
from sentry.models.group import GroupStatus
12+
from sentry.models.groupopenperiod import GroupOpenPeriod, create_open_period
1013
from sentry.testutils.cases import TestCase
1114
from sentry.testutils.helpers.features import with_feature
1215
from sentry.workflow_engine.models import IncidentGroupOpenPeriod
@@ -22,6 +25,14 @@ def setUp(self) -> None:
2225
projects=[self.project],
2326
name="Test Alert Rule",
2427
)
28+
self.detector = self.create_detector(
29+
project=self.project,
30+
name="Test Detector",
31+
)
32+
self.alert_rule_detector = self.create_alert_rule_detector(
33+
alert_rule_id=self.alert_rule.id,
34+
detector=self.detector,
35+
)
2536
self.group = self.create_group(project=self.project)
2637
self.group.type = MetricIssue.type_id
2738
self.group.save()
@@ -32,14 +43,14 @@ def save_issue_occurrence(self, include_alert_id: bool = True) -> tuple[Any, Gro
3243
)
3344

3445
occurrence_data: IssueOccurrenceData = {
35-
"id": "1",
46+
"id": str(uuid.uuid4()),
3647
"project_id": self.project.id,
3748
"event_id": event.event_id,
3849
"fingerprint": ["test-fingerprint"],
3950
"issue_title": "Test Issue",
4051
"subtitle": "Test Subtitle",
4152
"resource_id": None,
42-
"evidence_data": {"alert_id": self.alert_rule.id} if include_alert_id else {},
53+
"evidence_data": {"detector_id": self.detector.id} if include_alert_id else {},
4354
"evidence_display": [
4455
{"name": "Test Evidence", "value": "Test Value", "important": True}
4556
],
@@ -55,7 +66,9 @@ def save_issue_occurrence(self, include_alert_id: bool = True) -> tuple[Any, Gro
5566
assert group_info is not None
5667
assert group_info.group.type == MetricIssue.type_id
5768

58-
open_period = GroupOpenPeriod.objects.get(group=group_info.group)
69+
open_period = (
70+
GroupOpenPeriod.objects.filter(group=group_info.group).order_by("-date_started").first()
71+
)
5972
assert open_period is not None
6073
assert open_period.date_ended is None
6174
return occurrence, open_period
@@ -88,7 +101,7 @@ def test_create_from_occurrence_without_incident(self) -> None:
88101

89102
assert result is None
90103
open_period.refresh_from_db()
91-
assert open_period.data["pending_incident_alert_id"] == self.alert_rule.id
104+
assert open_period.data["pending_incident_detector_id"] == self.detector.id
92105

93106
@with_feature("organizations:issue-open-periods")
94107
def test_create_from_occurrence_no_alert_id(self) -> None:
@@ -125,9 +138,9 @@ def test_create_relationship_new(self) -> None:
125138
assert result.group_open_period == open_period
126139

127140
@with_feature("organizations:issue-open-periods")
128-
def test_create_relationship_existing(self) -> None:
129-
"""Test updating an existing relationship"""
130-
occurrence, open_period = self.save_issue_occurrence()
141+
def test_create_second_relationship(self) -> None:
142+
"""Test creating a second relationship for a new incident"""
143+
_, open_period = self.save_issue_occurrence()
131144

132145
incident1 = self.create_incident(
133146
organization=self.organization,
@@ -139,42 +152,49 @@ def test_create_relationship_existing(self) -> None:
139152
# Create initial relationship
140153
relationship = IncidentGroupOpenPeriod.create_relationship(incident1, open_period)
141154
assert relationship.incident_id == incident1.id
155+
assert relationship.group_open_period == open_period
142156

143-
# Create new incident and update relationship
157+
incident1.status = IncidentStatus.CLOSED.value
158+
incident1.save()
159+
160+
open_period.group.update(status=GroupStatus.RESOLVED)
161+
open_period.update(date_ended=timezone.now())
162+
open_period_2 = create_open_period(open_period.group, timezone.now())
163+
164+
# Create new incident and new relationship
144165
incident2 = self.create_incident(
145166
organization=self.organization,
146167
title="Test Incident 2",
147168
date_started=timezone.now(),
148169
alert_rule=self.alert_rule,
149170
)
150171

151-
result = IncidentGroupOpenPeriod.create_relationship(incident2, open_period)
152-
172+
result = IncidentGroupOpenPeriod.create_relationship(incident2, open_period_2)
153173
assert result is not None
154174
assert result.incident_id == incident2.id
155175
assert result.incident_identifier == incident2.identifier
156-
assert result.group_open_period == open_period
176+
assert result.group_open_period == open_period_2
157177

158178
@with_feature("organizations:issue-open-periods")
159179
def test_create_placeholder_relationship(self) -> None:
160180
"""Test creating a placeholder relationship"""
161181
occurrence, open_period = self.save_issue_occurrence()
162182

163183
result = IncidentGroupOpenPeriod.create_placeholder_relationship(
164-
self.alert_rule.id, open_period, self.project
184+
self.detector.id, open_period, self.project
165185
)
166186

167187
assert result is None
168188
open_period.refresh_from_db()
169-
assert open_period.data["pending_incident_alert_id"] == self.alert_rule.id
189+
assert open_period.data["pending_incident_detector_id"] == self.detector.id
170190

171191
@with_feature("organizations:issue-open-periods")
172192
def test_create_pending_relationships_for_incident(self) -> None:
173193
"""Test creating relationships for pending open periods"""
174194
occurrence, open_period = self.save_issue_occurrence()
175195

176196
# Create a placeholder relationship
177-
open_period.data = {"pending_incident_alert_id": self.alert_rule.id}
197+
open_period.data = {"pending_incident_detector_id": self.detector.id}
178198
open_period.save()
179199

180200
incident = self.create_incident(
@@ -193,7 +213,7 @@ def test_create_pending_relationships_for_incident(self) -> None:
193213

194214
# Check that placeholder was cleaned up
195215
open_period.refresh_from_db()
196-
assert "pending_incident_alert_id" not in open_period.data
216+
assert "pending_incident_detector_id" not in open_period.data
197217

198218
@with_feature("organizations:issue-open-periods")
199219
def test_create_pending_relationships_for_incident_no_pending(self) -> None:

0 commit comments

Comments
 (0)