1
1
from __future__ import annotations
2
2
3
3
import tempfile
4
- from datetime import datetime
4
+ from datetime import datetime , timedelta
5
5
from pathlib import Path
6
6
from typing import Type
7
+ from uuid import uuid4
7
8
8
9
from click .testing import CliRunner
9
10
from django .core .management import call_command
10
11
from django .utils import timezone
12
+ from sentry_relay .auth import generate_key_pair
11
13
12
14
from sentry .incidents .models import (
13
15
AlertRule ,
16
18
AlertRuleTrigger ,
17
19
AlertRuleTriggerAction ,
18
20
AlertRuleTriggerExclusion ,
21
+ PendingIncidentSnapshot ,
22
+ TimeSeriesSnapshot ,
19
23
)
24
+ from sentry .models .actor import ACTOR_TYPES , Actor
25
+ from sentry .models .counter import Counter
20
26
from sentry .models .dashboard import Dashboard , DashboardTombstone
21
27
from sentry .models .dashboard_widget import (
22
28
DashboardWidget ,
23
29
DashboardWidgetQuery ,
24
30
DashboardWidgetTypes ,
25
31
)
32
+ from sentry .models .email import Email
26
33
from sentry .models .environment import Environment , EnvironmentProject
34
+ from sentry .models .integrations .sentry_app import SentryApp
35
+ from sentry .models .integrations .sentry_app_component import SentryAppComponent
36
+ from sentry .models .integrations .sentry_app_installation import SentryAppInstallation
37
+ from sentry .models .notificationaction import NotificationAction , NotificationActionProject
38
+ from sentry .models .options .option import ControlOption , Option
39
+ from sentry .models .options .organization_option import OrganizationOption
27
40
from sentry .models .options .project_option import ProjectOption
28
41
from sentry .models .options .user_option import UserOption
29
42
from sentry .models .organization import Organization
30
43
from sentry .models .organizationaccessrequest import OrganizationAccessRequest
31
44
from sentry .models .organizationmapping import OrganizationMapping
32
45
from sentry .models .organizationmember import OrganizationMember
33
46
from sentry .models .organizationmemberteam import OrganizationMemberTeam
47
+ from sentry .models .orgauthtoken import OrgAuthToken
34
48
from sentry .models .project import Project
35
49
from sentry .models .projectbookmark import ProjectBookmark
36
50
from sentry .models .projectkey import ProjectKey
37
51
from sentry .models .projectownership import ProjectOwnership
38
52
from sentry .models .projectredirect import ProjectRedirect
39
53
from sentry .models .projectteam import ProjectTeam
54
+ from sentry .models .recentsearch import RecentSearch
55
+ from sentry .models .relay import Relay , RelayUsage
56
+ from sentry .models .repository import Repository
57
+ from sentry .models .rule import Rule , RuleActivity , RuleActivityType
58
+ from sentry .models .rulesnooze import RuleSnooze
59
+ from sentry .models .savedsearch import SavedSearch , Visibility
60
+ from sentry .models .search_common import SearchType
61
+ from sentry .models .servicehook import ServiceHook
40
62
from sentry .models .team import Team
41
63
from sentry .models .user import User
42
64
from sentry .models .useremail import UserEmail
43
65
from sentry .models .userip import UserIP
44
66
from sentry .models .userpermission import UserPermission
45
67
from sentry .models .userrole import UserRole , UserRoleUser
46
- from sentry .monitors .models import Monitor , MonitorEnvironment , MonitorType , ScheduleType
68
+ from sentry .monitors .models import (
69
+ CheckInStatus ,
70
+ Monitor ,
71
+ MonitorCheckIn ,
72
+ MonitorEnvironment ,
73
+ MonitorLocation ,
74
+ MonitorType ,
75
+ ScheduleType ,
76
+ )
47
77
from sentry .runner .commands .backup import import_ , validate
78
+ from sentry .sentry_apps .apps import SentryAppUpdater
48
79
from sentry .silo import unguarded_write
49
80
from sentry .snuba .models import QuerySubscription , SnubaQuery , SnubaQueryEventType
50
81
from sentry .testutils import TransactionTestCase
@@ -161,6 +192,17 @@ def test_alert_rule_trigger(self):
161
192
self .create_alert_rule_trigger_action (alert_rule_trigger = trigger )
162
193
return self .import_export_then_validate ()
163
194
195
+ @targets_models (ControlOption )
196
+ def test_control_option (self ):
197
+ ControlOption .objects .create (key = "foo" , value = "bar" )
198
+ return self .import_export_then_validate ()
199
+
200
+ @targets_models (Counter )
201
+ def test_counter (self ):
202
+ project = self .create_project ()
203
+ Counter .increment (project , 1 )
204
+ return self .import_export_then_validate ()
205
+
164
206
@targets_models (Dashboard )
165
207
def test_dashboard (self ):
166
208
self .create_dashboard ()
@@ -184,6 +226,11 @@ def test_dashboard_widget(self):
184
226
DashboardWidgetQuery .objects .create (widget = widget , order = 1 , name = "Test Query" )
185
227
return self .import_export_then_validate ()
186
228
229
+ @targets_models (Email )
230
+ def test_email (self ):
231
+ Email .
objects .
create (
email = "[email protected] " )
232
+ return self .import_export_then_validate ()
233
+
187
234
@targets_models (Environment )
188
235
def test_environment (self ):
189
236
self .create_environment ()
@@ -201,14 +248,46 @@ def test_monitor(self):
201
248
self .create_monitor ()
202
249
return self .import_export_then_validate ()
203
250
204
- @targets_models (MonitorEnvironment )
251
+ @targets_models (MonitorEnvironment , MonitorLocation )
205
252
def test_monitor_environment (self ):
206
253
monitor = self .create_monitor ()
207
254
env = Environment .objects .create (organization_id = monitor .organization_id , name = "test_env" )
208
- MonitorEnvironment .objects .create (
255
+ mon_env = MonitorEnvironment .objects .create (
209
256
monitor = monitor ,
210
257
environment = env ,
211
258
)
259
+ location = MonitorLocation .objects .create (guid = uuid4 (), name = "test_location" )
260
+ MonitorCheckIn .objects .create (
261
+ monitor = monitor ,
262
+ monitor_environment = mon_env ,
263
+ location = location ,
264
+ project_id = monitor .project_id ,
265
+ status = CheckInStatus .IN_PROGRESS ,
266
+ )
267
+ return self .import_export_then_validate ()
268
+
269
+ @targets_models (NotificationAction , NotificationActionProject )
270
+ def test_notification_action (self ):
271
+ self .create_notification_action (organization = self .organization , projects = [self .project ])
272
+ return self .import_export_then_validate ()
273
+
274
+ @targets_models (Option )
275
+ def test_option (self ):
276
+ Option .objects .create (key = "foo" , value = "bar" )
277
+ return self .import_export_then_validate ()
278
+
279
+ @targets_models (OrgAuthToken )
280
+ def test_org_auth_token (self ):
281
+ user = self .create_user ()
282
+ org = self .create_organization (owner = user )
283
+ OrgAuthToken .objects .create (
284
+ organization_id = org .id ,
285
+ name = "token 1" ,
286
+ token_hashed = "ABCDEF" ,
287
+ token_last_characters = "xyz1" ,
288
+ scope_list = ["org:ci" ],
289
+ date_last_used = None ,
290
+ )
212
291
return self .import_export_then_validate ()
213
292
214
293
@targets_models (Organization , OrganizationMapping )
@@ -228,6 +307,14 @@ def test_organization_membership(self):
228
307
OrganizationAccessRequest .objects .create (member = member , team = team )
229
308
return self .import_export_then_validate ()
230
309
310
+ @targets_models (OrganizationOption )
311
+ def test_organization_option (self ):
312
+ organization = self .create_organization (name = "test_org" , owner = self .user )
313
+ OrganizationOption .objects .create (
314
+ organization = organization , key = "sentry:account-rate-limit" , value = 0
315
+ )
316
+ return self .import_export_then_validate ()
317
+
231
318
@targets_models (Project , ProjectKey , ProjectOption , ProjectTeam )
232
319
def test_project (self ):
233
320
self .create_project ()
@@ -260,6 +347,87 @@ def test_project_redirect(self):
260
347
ProjectRedirect .record (project , "old_slug" )
261
348
return self .import_export_then_validate ()
262
349
350
+ @targets_models (Relay , RelayUsage )
351
+ def test_relay (self ):
352
+ _ , public_key = generate_key_pair ()
353
+ relay_id = str (uuid4 ())
354
+ Relay .objects .create (relay_id = relay_id , public_key = str (public_key ), is_internal = True )
355
+ RelayUsage .objects .create (relay_id = relay_id , version = "0.0.1" , public_key = public_key )
356
+ return self .import_export_then_validate ()
357
+
358
+ @targets_models (Repository )
359
+ def test_repository (self ):
360
+ Repository .objects .create (
361
+ name = "test_repo" ,
362
+ organization_id = self .organization .id ,
363
+ integration_id = self .integration .id ,
364
+ )
365
+ return self .import_export_then_validate ()
366
+
367
+ @targets_models (Rule , RuleActivity , RuleSnooze )
368
+ def test_rule (self ):
369
+ rule = self .create_project_rule (project = self .project )
370
+ RuleActivity .objects .create (rule = rule , type = RuleActivityType .CREATED .value )
371
+ self .snooze_rule (user_id = self .user .id , owner_id = self .user .id , rule = rule )
372
+ return self .import_export_then_validate ()
373
+
374
+ @targets_models (RecentSearch , SavedSearch )
375
+ def test_search (self ):
376
+ RecentSearch .objects .create (
377
+ organization = self .organization ,
378
+ user_id = self .user .id ,
379
+ type = SearchType .ISSUE .value ,
380
+ query = "some query" ,
381
+ )
382
+ SavedSearch .objects .create (
383
+ organization = self .organization ,
384
+ name = "Saved query" ,
385
+ query = "saved query" ,
386
+ visibility = Visibility .ORGANIZATION ,
387
+ )
388
+ return self .import_export_then_validate ()
389
+
390
+ @targets_models (SentryApp , SentryAppComponent , SentryAppInstallation )
391
+ def test_sentry_app (self ):
392
+ app = self .create_sentry_app (name = "test_app" , organization = self .organization )
393
+ self .create_sentry_app_installation (
394
+ slug = app .slug , organization = self .organization , user = self .user
395
+ )
396
+ updater = SentryAppUpdater (sentry_app = app )
397
+ updater .schema = {"elements" : [self .create_alert_rule_action_schema ()]}
398
+ updater .run (self .user )
399
+ return self .import_export_then_validate ()
400
+
401
+ @targets_models (PendingIncidentSnapshot , TimeSeriesSnapshot )
402
+ def test_snapshot (self ):
403
+ incident = self .create_incident ()
404
+ PendingIncidentSnapshot .objects .create (
405
+ incident = incident , target_run_date = datetime .utcnow () + timedelta (hours = 4 )
406
+ )
407
+ TimeSeriesSnapshot .objects .create (
408
+ start = datetime .utcnow () - timedelta (hours = 24 ),
409
+ end = datetime .utcnow (),
410
+ values = [[1.0 , 2.0 , 3.0 ], [1.5 , 2.5 , 3.5 ]],
411
+ period = 1 ,
412
+ )
413
+ return self .import_export_then_validate ()
414
+
415
+ @targets_models (ServiceHook )
416
+ def test_service_hook (self ):
417
+ app = self .create_sentry_app ()
418
+ actor = Actor .objects .create (type = ACTOR_TYPES ["team" ])
419
+ install = self .create_sentry_app_installation (organization = self .organization , slug = app .slug )
420
+ ServiceHook .objects .create (
421
+ application_id = app .id ,
422
+ actor_id = actor .id ,
423
+ project_id = self .project .id ,
424
+ organization_id = self .organization .id ,
425
+ events = [],
426
+ installation_id = install .id ,
427
+ url = "https://example.com" ,
428
+ )
429
+ return self .import_export_then_validate ()
430
+
263
431
@targets_models (User , UserEmail , UserOption , UserPermission )
264
432
def test_user (self ):
265
433
user = self .create_user ()
0 commit comments