@@ -4311,78 +4311,55 @@ def assert_deleted_groups(self, groups: Sequence[Group]) -> None:
4311
4311
assert not Group .objects .filter (id = group .id ).exists ()
4312
4312
assert not GroupHash .objects .filter (group_id = group .id ).exists ()
4313
4313
4314
- @patch ("sentry.eventstream.backend" )
4315
- def test_delete_by_id (self , mock_eventstream : MagicMock ) -> None :
4316
- eventstream_state = {"event_stream_state" : str (uuid4 ())}
4317
- mock_eventstream .start_delete_groups = Mock (return_value = eventstream_state )
4314
+ @patch ("sentry.eventstream.snuba.SnubaEventStream._send" )
4315
+ @patch ("sentry.eventstream.snuba.datetime" )
4316
+ def test_delete_by_id (self , mock_datetime : MagicMock , mock_send : MagicMock ) -> None :
4317
+ fixed_datetime = datetime .now ()
4318
+ mock_datetime .now .return_value = fixed_datetime
4318
4319
4319
- group1 = self .create_group (status = GroupStatus .RESOLVED )
4320
- group2 = self .create_group (status = GroupStatus .UNRESOLVED )
4321
- group3 = self .create_group (status = GroupStatus .IGNORED )
4322
- group4 = self .create_group (
4323
- project = self .create_project (slug = "foo" ),
4324
- status = GroupStatus .UNRESOLVED ,
4325
- )
4326
-
4327
- hashes = []
4328
- for g in group1 , group2 , group3 , group4 :
4329
- hash = uuid4 ().hex
4330
- hashes .append (hash )
4331
- GroupHash .objects .create (project = g .project , hash = hash , group = g )
4320
+ groups = self .create_n_groups_with_hashes (2 , project = self .project )
4321
+ group_ids = [group .id for group in groups ]
4332
4322
4333
4323
self .login_as (user = self .user )
4334
- with self .feature ("organizations:global-views" ):
4335
- response = self .get_response (
4336
- qs_params = {"id" : [group1 .id , group2 .id ], "group4" : group4 .id }
4337
- )
4338
-
4339
- mock_eventstream .start_delete_groups .assert_called_once_with (
4340
- group1 .project_id , [group1 .id , group2 .id ]
4341
- )
4342
-
4343
- assert response .status_code == 204
4344
-
4345
- assert Group .objects .get (id = group1 .id ).status == GroupStatus .PENDING_DELETION
4346
- assert not GroupHash .objects .filter (group_id = group1 .id ).exists ()
4347
-
4348
- assert Group .objects .get (id = group2 .id ).status == GroupStatus .PENDING_DELETION
4349
- assert not GroupHash .objects .filter (group_id = group2 .id ).exists ()
4350
-
4351
- assert Group .objects .get (id = group3 .id ).status != GroupStatus .PENDING_DELETION
4352
- assert GroupHash .objects .filter (group_id = group3 .id ).exists ()
4353
-
4354
- assert Group .objects .get (id = group4 .id ).status != GroupStatus .PENDING_DELETION
4355
- assert GroupHash .objects .filter (group_id = group4 .id ).exists ()
4356
-
4357
- Group .objects .filter (id__in = (group1 .id , group2 .id )).update (status = GroupStatus .UNRESOLVED )
4358
-
4359
- with self .tasks ():
4360
- with self .feature ("organizations:global-views" ):
4361
- response = self .get_response (
4362
- qs_params = {"id" : [group1 .id , group2 .id ], "group4" : group4 .id }
4363
- )
4324
+ with self .tasks (), self .feature ("organizations:global-views" ):
4325
+ response = self .get_response (qs_params = {"id" : group_ids })
4326
+ assert response .status_code == 204
4364
4327
4365
- # XXX(markus): Something is sending duplicated replacements to snuba --
4366
- # once from within tasks.deletions.groups and another time from
4367
- # sentry.deletions.defaults.groups
4368
- assert mock_eventstream .end_delete_groups .call_args_list == [
4369
- call (eventstream_state ),
4370
- call (eventstream_state ),
4328
+ # Extract transaction_id from the first call
4329
+ transaction_id = mock_send .call_args_list [0 ][1 ]["extra_data" ][0 ]["transaction_id" ]
4330
+
4331
+ assert mock_send .call_args_list == [
4332
+ call (
4333
+ self .project .id ,
4334
+ "start_delete_groups" ,
4335
+ extra_data = (
4336
+ {
4337
+ "transaction_id" : transaction_id ,
4338
+ "project_id" : self .project .id ,
4339
+ "group_ids" : group_ids ,
4340
+ "datetime" : json .datetime_to_str (fixed_datetime ),
4341
+ },
4342
+ ),
4343
+ asynchronous = False ,
4344
+ ),
4345
+ call (
4346
+ self .project .id ,
4347
+ "end_delete_groups" ,
4348
+ extra_data = (
4349
+ {
4350
+ "transaction_id" : transaction_id ,
4351
+ "project_id" : self .project .id ,
4352
+ "group_ids" : group_ids ,
4353
+ "datetime" : json .datetime_to_str (fixed_datetime ),
4354
+ },
4355
+ ),
4356
+ asynchronous = False ,
4357
+ ),
4371
4358
]
4372
4359
4373
- assert response .status_code == 204
4374
-
4375
- assert not Group .objects .filter (id = group1 .id ).exists ()
4376
- assert not GroupHash .objects .filter (group_id = group1 .id ).exists ()
4377
-
4378
- assert not Group .objects .filter (id = group2 .id ).exists ()
4379
- assert not GroupHash .objects .filter (group_id = group2 .id ).exists ()
4380
-
4381
- assert Group .objects .filter (id = group3 .id ).exists ()
4382
- assert GroupHash .objects .filter (group_id = group3 .id ).exists ()
4383
-
4384
- assert Group .objects .filter (id = group4 .id ).exists ()
4385
- assert GroupHash .objects .filter (group_id = group4 .id ).exists ()
4360
+ for group in groups :
4361
+ assert not Group .objects .filter (id = group .id ).exists ()
4362
+ assert not GroupHash .objects .filter (group_id = group .id ).exists ()
4386
4363
4387
4364
@patch ("sentry.eventstream.backend" )
4388
4365
def test_delete_performance_issue_by_id (self , mock_eventstream : MagicMock ) -> None :
@@ -4417,85 +4394,6 @@ def test_bulk_delete_for_many_projects_without_option(self) -> None:
4417
4394
groups_1 = self .create_n_groups_with_hashes (2 , project = self .project )
4418
4395
groups_2 = self .create_n_groups_with_hashes (5 , project = project_2 )
4419
4396
4420
- with (
4421
- self .tasks (),
4422
- patch ("sentry.deletions.tasks.groups.GROUP_CHUNK_SIZE" , NEW_CHUNK_SIZE ),
4423
- patch ("sentry.deletions.tasks.groups.logger" ) as mock_logger ,
4424
- patch (
4425
- "sentry.api.helpers.group_index.delete.uuid4" ,
4426
- side_effect = [self .get_mock_uuid ("foo" ), self .get_mock_uuid ("bar" )],
4427
- ),
4428
- ):
4429
- self .login_as (user = self .user )
4430
- response = self .get_success_response (qs_params = {"query" : "" })
4431
- assert response .status_code == 204
4432
- batch_1 = [g .id for g in groups_2 [0 :2 ]]
4433
- batch_2 = [g .id for g in groups_2 [2 :4 ]]
4434
- batch_3 = [g .id for g in groups_2 [4 :]]
4435
- assert batch_1 + batch_2 + batch_3 == [g .id for g in groups_2 ]
4436
-
4437
- calls_by_project : dict [int , list [tuple [str , dict [str , Any ]]]] = defaultdict (list )
4438
- for log_call in mock_logger .info .call_args_list :
4439
- calls_by_project [log_call [1 ]["extra" ]["project_id" ]].append (log_call )
4440
-
4441
- assert len (calls_by_project ) == 2
4442
- assert calls_by_project [self .project .id ] == [
4443
- call (
4444
- "delete_groups.started" ,
4445
- extra = {
4446
- "object_ids_count" : len (groups_1 ),
4447
- "object_ids_current_batch" : [g .id for g in groups_1 ],
4448
- "first_id" : groups_1 [0 ].id ,
4449
- "project_id" : self .project .id ,
4450
- "transaction_id" : "bar" ,
4451
- },
4452
- ),
4453
- ]
4454
- assert calls_by_project [project_2 .id ] == [
4455
- call (
4456
- "delete_groups.started" ,
4457
- extra = {
4458
- "object_ids_count" : 5 ,
4459
- "object_ids_current_batch" : batch_1 ,
4460
- "first_id" : batch_1 [0 ],
4461
- "project_id" : project_2 .id ,
4462
- "transaction_id" : "foo" ,
4463
- },
4464
- ),
4465
- call (
4466
- "delete_groups.started" ,
4467
- extra = {
4468
- "object_ids_count" : 3 ,
4469
- "object_ids_current_batch" : batch_2 ,
4470
- "first_id" : batch_2 [0 ],
4471
- "project_id" : project_2 .id ,
4472
- "transaction_id" : "foo" ,
4473
- },
4474
- ),
4475
- call (
4476
- "delete_groups.started" ,
4477
- extra = {
4478
- "object_ids_count" : 1 ,
4479
- "object_ids_current_batch" : batch_3 ,
4480
- "first_id" : batch_3 [0 ],
4481
- "project_id" : project_2 .id ,
4482
- "transaction_id" : "foo" ,
4483
- },
4484
- ),
4485
- ]
4486
-
4487
- self .assert_deleted_groups (groups_1 + groups_2 )
4488
-
4489
- def test_bulk_delete_for_many_projects_with_option (self ) -> None :
4490
- NEW_CHUNK_SIZE = 2
4491
- with (
4492
- self .options ({"deletions.groups.use-new-task" : True }),
4493
- self .feature ("organizations:global-views" ),
4494
- ):
4495
- project_2 = self .create_project (slug = "baz" , organization = self .organization )
4496
- groups_1 = self .create_n_groups_with_hashes (2 , project = self .project )
4497
- groups_2 = self .create_n_groups_with_hashes (5 , project = project_2 )
4498
-
4499
4397
with (
4500
4398
self .tasks (),
4501
4399
patch ("sentry.api.helpers.group_index.delete.GROUP_CHUNK_SIZE" , NEW_CHUNK_SIZE ),
0 commit comments