1
1
from unittest import mock
2
2
3
3
from sentry .incidents .grouptype import MetricAlertFire
4
+ from sentry .incidents .models .alert_rule import AlertRuleTriggerAction
5
+ from sentry .integrations .models .integration import Integration , OrganizationIntegration
4
6
from sentry .snuba .models import QuerySubscription
5
7
from sentry .testutils .cases import APITestCase
8
+ from sentry .testutils .silo import assume_test_silo_mode_of
6
9
from sentry .users .services .user .service import user_service
7
10
from sentry .workflow_engine .migration_helpers .alert_rule import (
8
11
create_data_condition_group ,
34
37
35
38
class AlertRuleMigrationHelpersTest (APITestCase ):
36
39
def setUp (self ):
40
+ METADATA = {
41
+ "api_key" : "1234-ABCD" ,
42
+ "base_url" : "https://api.opsgenie.com/" ,
43
+ "domain_name" : "test-app.app.opsgenie.com" ,
44
+ }
45
+ self .rpc_user = user_service .get_user (user_id = self .user .id )
46
+ self .og_team = {"id" : "123-id" , "team" : "cool-team" , "integration_key" : "1234-5678" }
47
+ self .integration = self .create_provider_integration (
48
+ provider = "opsgenie" , name = "hello-world" , external_id = "hello-world" , metadata = METADATA
49
+ )
50
+ self .sentry_app = self .create_sentry_app (
51
+ name = "foo" ,
52
+ organization = self .organization ,
53
+ is_alertable = True ,
54
+ verify_install = False ,
55
+ )
56
+ self .create_sentry_app_installation (
57
+ slug = self .sentry_app .slug , organization = self .organization , user = self .rpc_user
58
+ )
59
+ with assume_test_silo_mode_of (Integration , OrganizationIntegration ):
60
+ self .integration .add_organization (self .organization , self .user )
61
+ self .org_integration = OrganizationIntegration .objects .get (
62
+ organization_id = self .organization .id , integration_id = self .integration .id
63
+ )
64
+ self .org_integration .config = {"team_table" : [self .og_team ]}
65
+ self .org_integration .save ()
66
+
37
67
self .metric_alert = self .create_alert_rule ()
38
- self .alert_rule_trigger = self .create_alert_rule_trigger (alert_rule = self .metric_alert )
39
- self .alert_rule_trigger_action = self .create_alert_rule_trigger_action (
40
- alert_rule_trigger = self .alert_rule_trigger
68
+ self .alert_rule_trigger_warning = self .create_alert_rule_trigger (
69
+ alert_rule = self .metric_alert , label = "warning"
70
+ )
71
+ self .alert_rule_trigger_critical = self .create_alert_rule_trigger (
72
+ alert_rule = self .metric_alert , label = "critical"
73
+ )
74
+ self .alert_rule_trigger_action_email = self .create_alert_rule_trigger_action (
75
+ alert_rule_trigger = self .alert_rule_trigger_warning
76
+ )
77
+ self .alert_rule_trigger_action_integration = self .create_alert_rule_trigger_action (
78
+ target_identifier = self .og_team ["id" ],
79
+ type = AlertRuleTriggerAction .Type .OPSGENIE ,
80
+ target_type = AlertRuleTriggerAction .TargetType .SPECIFIC ,
81
+ integration = self .integration ,
82
+ alert_rule_trigger = self .alert_rule_trigger_critical ,
83
+ )
84
+
85
+ self .alert_rule_trigger_action_sentry_app = self .create_alert_rule_trigger_action (
86
+ target_identifier = self .sentry_app .id ,
87
+ type = AlertRuleTriggerAction .Type .SENTRY_APP ,
88
+ target_type = AlertRuleTriggerAction .TargetType .SENTRY_APP ,
89
+ sentry_app = self .sentry_app ,
90
+ alert_rule_trigger = self .alert_rule_trigger_critical ,
41
91
)
42
- self .rpc_user = user_service .get_user (user_id = self .user .id )
43
92
44
93
def test_create_metric_alert (self ):
45
94
"""
@@ -92,25 +141,37 @@ def test_create_metric_alert(self):
92
141
93
142
def test_create_metric_alert_trigger (self ):
94
143
"""
95
- Test that when we call the helper methods we create all the ACI models correctly for an alert rule trigger
144
+ Test that when we call the helper methods we create all the ACI models correctly for alert rule triggers
96
145
"""
97
146
migrate_alert_rule (self .metric_alert , self .rpc_user )
98
- migrate_metric_data_condition (self .alert_rule_trigger )
99
- alert_rule_trigger_data_condition = AlertRuleTriggerDataCondition .objects .get (
100
- alert_rule_trigger = self .alert_rule_trigger
101
- )
102
- data_condition_group_id = (
103
- alert_rule_trigger_data_condition .data_condition .condition_group .id
147
+ migrate_metric_data_condition (self .alert_rule_trigger_warning )
148
+ migrate_metric_data_condition (self .alert_rule_trigger_critical )
149
+
150
+ alert_rule_trigger_data_conditions = AlertRuleTriggerDataCondition .objects .filter (
151
+ alert_rule_trigger__in = [
152
+ self .alert_rule_trigger_critical ,
153
+ self .alert_rule_trigger_warning ,
154
+ ]
104
155
)
105
- data_condition = DataCondition .objects .get (condition_group = data_condition_group_id )
156
+ assert len (alert_rule_trigger_data_conditions ) == 2
157
+ data_condition_group_id = alert_rule_trigger_data_conditions [
158
+ 0
159
+ ].data_condition .condition_group .id
160
+ data_conditions = DataCondition .objects .filter (condition_group = data_condition_group_id )
161
+ assert len (data_conditions ) == 2
106
162
alert_rule_workflow = AlertRuleWorkflow .objects .get (alert_rule = self .metric_alert )
107
163
workflow = Workflow .objects .get (id = alert_rule_workflow .workflow .id )
108
164
data_condition_group = workflow .when_condition_group
109
165
110
- assert data_condition .condition == Condition .GREATER
111
- assert data_condition .comparison == self .alert_rule_trigger .alert_threshold
112
- assert data_condition .condition_result == DetectorPriorityLevel .HIGH
113
- assert data_condition .condition_group == data_condition_group
166
+ assert data_conditions [0 ].type == Condition .GREATER
167
+ assert data_conditions [0 ].comparison == self .alert_rule_trigger_warning .alert_threshold
168
+ assert data_conditions [0 ].condition_result == DetectorPriorityLevel .MEDIUM
169
+ assert data_conditions [0 ].condition_group == data_condition_group
170
+
171
+ assert data_conditions [1 ].type == Condition .GREATER
172
+ assert data_conditions [1 ].comparison == self .alert_rule_trigger_critical .alert_threshold
173
+ assert data_conditions [1 ].condition_result == DetectorPriorityLevel .HIGH
174
+ assert data_conditions [1 ].condition_group == data_condition_group
114
175
115
176
@mock .patch ("sentry.workflow_engine.migration_helpers.alert_rule.logger" )
116
177
def test_create_metric_alert_trigger_no_alert_rule_detector (self , mock_logger ):
@@ -121,45 +182,85 @@ def test_create_metric_alert_trigger_no_alert_rule_detector(self, mock_logger):
121
182
)
122
183
create_detector (self .metric_alert , self .project .id , data_condition_group , self .rpc_user )
123
184
# skip creating lookup tables
124
- migrate_metric_data_condition (self .alert_rule_trigger )
185
+ migrate_metric_data_condition (self .alert_rule_trigger_critical )
125
186
mock_logger .exception .assert_called_with (
126
187
"AlertRuleDetector does not exist" ,
127
188
extra = {
128
- "alert_rule_id" : self .alert_rule_trigger .alert_rule .id ,
189
+ "alert_rule_id" : self .alert_rule_trigger_critical .alert_rule .id ,
129
190
},
130
191
)
131
192
132
193
def test_create_metric_alert_trigger_action (self ):
133
194
"""
134
- Test that when we call the helper methods we create all the ACI models correctly for an alert rule trigger action
195
+ Test that when we call the helper methods we create all the ACI models correctly for alert rule trigger actions
135
196
"""
136
197
migrate_alert_rule (self .metric_alert , self .rpc_user )
137
- migrate_metric_data_condition (self .alert_rule_trigger )
138
- migrate_metric_action (self .alert_rule_trigger_action )
139
- alert_rule_trigger_data_condition = AlertRuleTriggerDataCondition .objects .get (
140
- alert_rule_trigger = self .alert_rule_trigger
141
- )
142
- data_condition_group_id = (
143
- alert_rule_trigger_data_condition .data_condition .condition_group .id
198
+
199
+ migrate_metric_data_condition (self .alert_rule_trigger_warning )
200
+ migrate_metric_data_condition (self .alert_rule_trigger_critical )
201
+
202
+ migrate_metric_action (self .alert_rule_trigger_action_email )
203
+ migrate_metric_action (self .alert_rule_trigger_action_integration )
204
+ migrate_metric_action (self .alert_rule_trigger_action_sentry_app )
205
+
206
+ alert_rule_trigger_data_condition = AlertRuleTriggerDataCondition .objects .filter (
207
+ alert_rule_trigger__in = [
208
+ self .alert_rule_trigger_warning ,
209
+ self .alert_rule_trigger_critical ,
210
+ ]
144
211
)
145
- data_condition_group_action = DataConditionGroupAction .objects .get (
212
+ data_condition_group_id = alert_rule_trigger_data_condition [
213
+ 0
214
+ ].data_condition .condition_group .id
215
+ data_condition_group_actions = DataConditionGroupAction .objects .filter (
146
216
condition_group_id = data_condition_group_id
147
217
)
148
- assert Action .objects .filter (id = data_condition_group_action .action .id ).exists ()
218
+ action = Action .objects .filter (
219
+ id__in = [item .action .id for item in data_condition_group_actions ]
220
+ )
221
+ assert len (action ) == 3
222
+
223
+ assert action [0 ].type .lower () == Action .Type .EMAIL
224
+ assert action [1 ].type .lower () == Action .Type .OPSGENIE
225
+ assert action [2 ].type .lower () == Action .Type .SENTRY_APP
149
226
150
227
@mock .patch ("sentry.workflow_engine.migration_helpers.alert_rule.logger" )
151
228
def test_create_metric_alert_trigger_action_no_alert_rule_trigger_data_condition (
152
229
self , mock_logger
153
230
):
231
+ """
232
+ Test that if the AlertRuleTriggerDataCondition doesn't exist we return None and log.
233
+ """
154
234
other_metric_alert = self .create_alert_rule ()
155
235
other_alert_rule_trigger = self .create_alert_rule_trigger (alert_rule = other_metric_alert )
156
236
157
237
migrate_alert_rule (other_metric_alert , self .rpc_user )
158
238
migrate_metric_data_condition (other_alert_rule_trigger )
159
- migrate_metric_action (self .alert_rule_trigger_action )
239
+ migrated_action = migrate_metric_action (self .alert_rule_trigger_action_email )
240
+ assert migrated_action is None
160
241
mock_logger .exception .assert_called_with (
161
242
"AlertRuleTriggerDataCondition does not exist" ,
162
243
extra = {
163
- "alert_rule_trigger_id" : self .alert_rule_trigger .id ,
244
+ "alert_rule_trigger_id" : self .alert_rule_trigger_warning .id ,
245
+ },
246
+ )
247
+
248
+ @mock .patch ("sentry.workflow_engine.migration_helpers.alert_rule.logger" )
249
+ def test_create_metric_alert_trigger_action_no_type (self , mock_logger ):
250
+ """
251
+ Test that if for some reason we don't find a match for Action.Type for the integratio provider we return None and log.
252
+ """
253
+ with assume_test_silo_mode_of (Integration , OrganizationIntegration ):
254
+ self .integration .update (provider = "hellboy" )
255
+ self .integration .save ()
256
+
257
+ migrate_alert_rule (self .metric_alert , self .rpc_user )
258
+ migrate_metric_data_condition (self .alert_rule_trigger_critical )
259
+ migrated = migrate_metric_action (self .alert_rule_trigger_action_integration )
260
+ assert migrated is None
261
+ mock_logger .warning .assert_called_with (
262
+ "Could not find a matching Action.Type for the trigger action" ,
263
+ extra = {
264
+ "alert_rule_trigger_action_id" : self .alert_rule_trigger_action_integration .id ,
164
265
},
165
266
)
0 commit comments