Skip to content

Commit 5227ee3

Browse files
authored
chore: random slack code cleanup (#5307)
# What this PR does Related to #5287 Few random "clean-ups", type improvements, etc. Additionally, fixes a change made in #5292; we should wait to read from `slack_message.channel.slack_id`, until we've performed the data-migration mentioned in that PR (in the mean-time we should continue to use `slack_message._channel_id`). ## Checklist - [x] Unit, integration, and e2e (if applicable) tests updated - [x] Documentation added (or `pr:no public docs` PR label added if not required) - [x] Added the relevant release notes label (see labels prefixed w/ `release:`). These labels dictate how your PR will show up in the autogenerated release notes.
1 parent 417f978 commit 5227ee3

28 files changed

+315
-261
lines changed

engine/apps/alerts/models/alert_group.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ def acknowledge_by_user_or_backsync(
674674
organization_id = user.organization_id if user else self.channel.organization_id
675675
logger.debug(f"Started acknowledge_by_user_or_backsync for alert_group {self.pk}")
676676

677-
# if incident was silenced or resolved, unsilence/unresolve it without starting escalation
677+
# if alert group was silenced or resolved, unsilence/unresolve it without starting escalation
678678
if self.silenced:
679679
self.un_silence()
680680
self.log_records.create(
@@ -1990,6 +1990,13 @@ def slack_channel_id(self) -> str | None:
19901990

19911991
@property
19921992
def slack_message(self) -> typing.Optional["SlackMessage"]:
1993+
"""
1994+
`slack_message` property returns the first `SlackMessage` for the `AlertGroup`. This corresponds to the
1995+
Slack message representing the main message in Slack (ie. not a message in a thread).
1996+
1997+
This should not be confused with `slack_messages`, which is a `RelatedManager` that returns all `SlackMessage`
1998+
instances for the `AlertGroup`.
1999+
"""
19932000
try:
19942001
# prefetched_slack_messages could be set in apps.api.serializers.alert_group.AlertGroupListSerializer
19952002
return self.prefetched_slack_messages[0] if self.prefetched_slack_messages else None

engine/apps/alerts/models/alert_receive_channel.py

+15-15
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343

4444
from apps.alerts.models import AlertGroup, ChannelFilter
4545
from apps.labels.models import AlertReceiveChannelAssociatedLabel
46-
from apps.user_management.models import Organization, Team
46+
from apps.user_management.models import Organization, Team, User
4747

4848
logger = logging.getLogger(__name__)
4949

@@ -391,7 +391,7 @@ def save(self, *args, **kwargs):
391391

392392
return super().save(*args, **kwargs)
393393

394-
def change_team(self, team_id, user):
394+
def change_team(self, team_id: int, user: "User") -> None:
395395
if team_id == self.team_id:
396396
raise TeamCanNotBeChangedError("Integration is already in this team")
397397

@@ -409,34 +409,34 @@ def grafana_alerting_sync_manager(self):
409409
return GrafanaAlertingSyncManager(self)
410410

411411
@property
412-
def is_alerting_integration(self):
412+
def is_alerting_integration(self) -> bool:
413413
return self.integration in {
414414
AlertReceiveChannel.INTEGRATION_GRAFANA_ALERTING,
415415
AlertReceiveChannel.INTEGRATION_LEGACY_GRAFANA_ALERTING,
416416
}
417417

418418
@cached_property
419-
def team_name(self):
419+
def team_name(self) -> str:
420420
return self.team.name if self.team else "No team"
421421

422422
@cached_property
423-
def team_id_or_no_team(self):
423+
def team_id_or_no_team(self) -> str:
424424
return self.team_id if self.team else "no_team"
425425

426426
@cached_property
427-
def emojized_verbal_name(self):
427+
def emojized_verbal_name(self) -> str:
428428
return emoji.emojize(self.verbal_name, language="alias")
429429

430430
@property
431-
def new_incidents_web_link(self):
431+
def new_incidents_web_link(self) -> str:
432432
from apps.alerts.models import AlertGroup
433433

434434
return UIURLBuilder(self.organization).alert_groups(
435435
f"?integration={self.public_primary_key}&status={AlertGroup.NEW}",
436436
)
437437

438438
@property
439-
def is_rate_limited_in_slack(self):
439+
def is_rate_limited_in_slack(self) -> bool:
440440
return (
441441
self.rate_limited_in_slack_at is not None
442442
and self.rate_limited_in_slack_at + SLACK_RATE_LIMIT_TIMEOUT > timezone.now()
@@ -450,11 +450,11 @@ def start_send_rate_limit_message_task(self, delay=SLACK_RATE_LIMIT_DELAY):
450450
post_slack_rate_limit_message.apply_async((self.pk,), countdown=delay, task_id=task_id)
451451

452452
@property
453-
def alert_groups_count(self):
453+
def alert_groups_count(self) -> int:
454454
return self.alert_groups.count()
455455

456456
@property
457-
def alerts_count(self):
457+
def alerts_count(self) -> int:
458458
from apps.alerts.models import Alert
459459

460460
return Alert.objects.filter(group__channel=self).count()
@@ -464,7 +464,7 @@ def is_able_to_autoresolve(self) -> bool:
464464
return self.config.is_able_to_autoresolve
465465

466466
@property
467-
def is_demo_alert_enabled(self):
467+
def is_demo_alert_enabled(self) -> bool:
468468
return self.config.is_demo_alert_enabled
469469

470470
@property
@@ -513,7 +513,7 @@ def get_or_create_manual_integration(cls, defaults, **kwargs):
513513
return alert_receive_channel
514514

515515
@property
516-
def short_name(self):
516+
def short_name(self) -> str:
517517
if self.verbal_name is None:
518518
return self.created_name + "" if self.deleted_at is None else "(Deleted)"
519519
elif self.verbal_name == self.created_name:
@@ -548,14 +548,14 @@ def integration_url(self) -> str | None:
548548
return create_engine_url(f"integrations/v1/{slug}/{self.token}/")
549549

550550
@property
551-
def inbound_email(self):
551+
def inbound_email(self) -> typing.Optional[str]:
552552
if self.integration != AlertReceiveChannel.INTEGRATION_INBOUND_EMAIL:
553553
return None
554554

555555
return f"{self.token}@{live_settings.INBOUND_EMAIL_DOMAIN}"
556556

557557
@property
558-
def default_channel_filter(self):
558+
def default_channel_filter(self) -> typing.Optional["ChannelFilter"]:
559559
return self.channel_filters.filter(is_default=True).first()
560560

561561
# Templating
@@ -590,7 +590,7 @@ def templates(self):
590590
}
591591

592592
@property
593-
def is_available_for_custom_templates(self):
593+
def is_available_for_custom_templates(self) -> bool:
594594
return True
595595

596596
# Maintenance

engine/apps/alerts/tasks/compare_escalations.py

-4
This file was deleted.

engine/apps/alerts/tasks/escalate_alert_group.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
from common.custom_celery_tasks import shared_dedicated_queue_retry_task
88

9-
from .compare_escalations import compare_escalations
109
from .task_logger import task_logger
1110

1211

@@ -29,7 +28,7 @@ def escalate_alert_group(alert_group_pk):
2928
except IndexError:
3029
return f"Alert group with pk {alert_group_pk} doesn't exist"
3130

32-
if not compare_escalations(escalate_alert_group.request.id, alert_group.active_escalation_id):
31+
if escalate_alert_group.request.id != alert_group.active_escalation_id:
3332
return "Active escalation ID mismatch. Duplication or non-active escalation triggered. Active: {}".format(
3433
alert_group.active_escalation_id
3534
)

engine/apps/alerts/tasks/notify_user.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
from apps.phone_notifications.phone_backend import PhoneBackend
1818
from common.custom_celery_tasks import shared_dedicated_queue_retry_task
1919

20-
from .compare_escalations import compare_escalations
2120
from .task_logger import task_logger
2221

2322
if typing.TYPE_CHECKING:
@@ -618,7 +617,7 @@ def send_bundled_notification(user_notification_bundle_id: int):
618617
)
619618
return
620619

621-
if not compare_escalations(send_bundled_notification.request.id, user_notification_bundle.notification_task_id):
620+
if send_bundled_notification.request.id != user_notification_bundle.notification_task_id:
622621
task_logger.info(
623622
f"send_bundled_notification: notification_task_id mismatch. "
624623
f"Duplication or non-active notification triggered. "

engine/apps/alerts/tasks/unsilence.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
from common.custom_celery_tasks import shared_dedicated_queue_retry_task
77

8-
from .compare_escalations import compare_escalations
98
from .send_alert_group_signal import send_alert_group_signal
109
from .task_logger import task_logger
1110

@@ -17,17 +16,20 @@ def unsilence_task(alert_group_pk):
1716
from apps.alerts.models import AlertGroup, AlertGroupLogRecord
1817

1918
task_logger.info(f"Start unsilence_task for alert_group {alert_group_pk}")
19+
2020
with transaction.atomic():
2121
try:
2222
alert_group = AlertGroup.objects.filter(pk=alert_group_pk).select_for_update()[0] # Lock alert_group:
2323
except IndexError:
2424
task_logger.info(f"unsilence_task. alert_group {alert_group_pk} doesn't exist")
2525
return
26-
if not compare_escalations(unsilence_task.request.id, alert_group.unsilence_task_uuid):
26+
27+
if unsilence_task.request.id != alert_group.unsilence_task_uuid:
2728
task_logger.info(
2829
f"unsilence_task. alert_group {alert_group.pk}.ID mismatch.Active: {alert_group.unsilence_task_uuid}"
2930
)
3031
return
32+
3133
if alert_group.status == AlertGroup.SILENCED and alert_group.is_root_alert_group:
3234
initial_state = alert_group.state
3335
task_logger.info(f"unsilence alert_group {alert_group_pk} and start escalation if needed")

engine/apps/alerts/tests/test_alert_group.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,11 @@ def test_delete(
152152
# Check that appropriate Slack API calls are made
153153
assert mock_chat_delete.call_count == 2
154154
assert mock_chat_delete.call_args_list[0] == call(
155-
channel=resolution_note_1.slack_channel_id, ts=resolution_note_1.ts
155+
channel=resolution_note_1.slack_channel.slack_id, ts=resolution_note_1.ts
156156
)
157157
assert mock_chat_delete.call_args_list[1] == call(channel=slack_message.channel.slack_id, ts=slack_message.slack_id)
158158
mock_reactions_remove.assert_called_once_with(
159-
channel=resolution_note_2.slack_channel_id, name="memo", timestamp=resolution_note_2.ts
159+
channel=resolution_note_2.slack_channel.slack_id, name="memo", timestamp=resolution_note_2.ts
160160
)
161161

162162

engine/apps/alerts/tests/test_maintenance.py

+3-11
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@ def maintenance_test_setup(
1616

1717

1818
@pytest.mark.django_db
19-
def test_start_maintenance_integration(
20-
maintenance_test_setup, make_alert_receive_channel, mock_start_disable_maintenance_task
21-
):
19+
def test_start_maintenance_integration(maintenance_test_setup, make_alert_receive_channel):
2220
organization, user = maintenance_test_setup
2321

2422
alert_receive_channel = make_alert_receive_channel(
@@ -37,9 +35,7 @@ def test_start_maintenance_integration(
3735

3836

3937
@pytest.mark.django_db
40-
def test_start_maintenance_integration_multiple_previous_instances(
41-
maintenance_test_setup, make_alert_receive_channel, mock_start_disable_maintenance_task
42-
):
38+
def test_start_maintenance_integration_multiple_previous_instances(maintenance_test_setup, make_alert_receive_channel):
4339
organization, user = maintenance_test_setup
4440

4541
alert_receive_channel = make_alert_receive_channel(
@@ -64,9 +60,7 @@ def test_start_maintenance_integration_multiple_previous_instances(
6460

6561

6662
@pytest.mark.django_db
67-
def test_maintenance_integration_will_not_start_twice(
68-
maintenance_test_setup, make_alert_receive_channel, mock_start_disable_maintenance_task
69-
):
63+
def test_maintenance_integration_will_not_start_twice(maintenance_test_setup, make_alert_receive_channel):
7064
organization, user = maintenance_test_setup
7165

7266
alert_receive_channel = make_alert_receive_channel(
@@ -91,7 +85,6 @@ def test_alert_attached_to_maintenance_incident_integration(
9185
maintenance_test_setup,
9286
make_alert_receive_channel,
9387
make_alert_with_custom_create_method,
94-
mock_start_disable_maintenance_task,
9588
):
9689
organization, user = maintenance_test_setup
9790

@@ -122,7 +115,6 @@ def test_stop_maintenance(
122115
maintenance_test_setup,
123116
make_alert_receive_channel,
124117
make_alert_with_custom_create_method,
125-
mock_start_disable_maintenance_task,
126118
):
127119
organization, user = maintenance_test_setup
128120
alert_receive_channel = make_alert_receive_channel(

engine/apps/alerts/tests/test_notify_user.py

+60-34
Original file line numberDiff line numberDiff line change
@@ -530,47 +530,73 @@ def test_send_bundle_notification(
530530
alert_group_1 = make_alert_group(alert_receive_channel=alert_receive_channel)
531531
alert_group_2 = make_alert_group(alert_receive_channel=alert_receive_channel)
532532
alert_group_3 = make_alert_group(alert_receive_channel=alert_receive_channel)
533+
534+
task_id = "test_task_id"
533535
notification_bundle = make_user_notification_bundle(
534-
user, UserNotificationPolicy.NotificationChannel.SMS, notification_task_id="test_task_id", eta=timezone.now()
536+
user, UserNotificationPolicy.NotificationChannel.SMS, notification_task_id=task_id, eta=timezone.now()
535537
)
538+
536539
notification_bundle.append_notification(alert_group_1, notification_policy)
537540
notification_bundle.append_notification(alert_group_2, notification_policy)
538541
notification_bundle.append_notification(alert_group_3, notification_policy)
542+
539543
assert notification_bundle.notifications.filter(bundle_uuid__isnull=True).count() == 3
544+
540545
alert_group_3.resolve()
541-
with patch("apps.alerts.tasks.notify_user.compare_escalations", return_value=True):
542-
# send notification for 2 active alert groups
543-
send_bundled_notification(notification_bundle.id)
544-
assert f"alert_group {alert_group_3.id} is not active, skip notification" in caplog.text
545-
assert "perform bundled notification for alert groups with ids:" in caplog.text
546-
# check bundle_uuid was set, notification for resolved alert group was deleted
547-
assert notification_bundle.notifications.filter(bundle_uuid__isnull=True).count() == 0
548-
assert notification_bundle.notifications.all().count() == 2
549-
assert not notification_bundle.notifications.filter(alert_group=alert_group_3).exists()
550-
551-
# send notification for 1 active alert group
552-
notification_bundle.notifications.update(bundle_uuid=None)
553-
alert_group_2.resolve()
554-
send_bundled_notification(notification_bundle.id)
555-
assert f"alert_group {alert_group_2.id} is not active, skip notification" in caplog.text
556-
assert (
557-
f"there is only one alert group in bundled notification, perform regular notification. "
558-
f"alert_group {alert_group_1.id}"
559-
) in caplog.text
560-
# check bundle_uuid was set
561-
assert notification_bundle.notifications.filter(bundle_uuid__isnull=True).count() == 0
562-
assert notification_bundle.notifications.all().count() == 1
563-
# cleanup notifications
564-
notification_bundle.notifications.all().delete()
565-
566-
# send notification for 0 active alert group
567-
notification_bundle.append_notification(alert_group_1, notification_policy)
568-
alert_group_1.resolve()
569-
send_bundled_notification(notification_bundle.id)
570-
assert f"alert_group {alert_group_1.id} is not active, skip notification" in caplog.text
571-
assert f"no alert groups to notify about or notification is not allowed for user {user.id}" in caplog.text
572-
# check all notifications were deleted
573-
assert notification_bundle.notifications.all().count() == 0
546+
547+
# send notification for 2 active alert groups
548+
send_bundled_notification.apply((notification_bundle.id,), task_id=task_id)
549+
550+
assert f"alert_group {alert_group_3.id} is not active, skip notification" in caplog.text
551+
assert "perform bundled notification for alert groups with ids:" in caplog.text
552+
553+
# check bundle_uuid was set, notification for resolved alert group was deleted
554+
assert notification_bundle.notifications.filter(bundle_uuid__isnull=True).count() == 0
555+
assert notification_bundle.notifications.all().count() == 2
556+
assert not notification_bundle.notifications.filter(alert_group=alert_group_3).exists()
557+
558+
# send notification for 1 active alert group
559+
notification_bundle.notifications.update(bundle_uuid=None)
560+
561+
# since we're calling send_bundled_notification several times within this test, we need to reset task_id
562+
# because it gets set to None after the first call
563+
notification_bundle.notification_task_id = task_id
564+
notification_bundle.save()
565+
566+
alert_group_2.resolve()
567+
568+
send_bundled_notification.apply((notification_bundle.id,), task_id=task_id)
569+
570+
assert f"alert_group {alert_group_2.id} is not active, skip notification" in caplog.text
571+
assert (
572+
f"there is only one alert group in bundled notification, perform regular notification. "
573+
f"alert_group {alert_group_1.id}"
574+
) in caplog.text
575+
576+
# check bundle_uuid was set
577+
assert notification_bundle.notifications.filter(bundle_uuid__isnull=True).count() == 0
578+
assert notification_bundle.notifications.all().count() == 1
579+
580+
# cleanup notifications
581+
notification_bundle.notifications.all().delete()
582+
583+
# send notification for 0 active alert group
584+
notification_bundle.append_notification(alert_group_1, notification_policy)
585+
586+
# since we're calling send_bundled_notification several times within this test, we need to reset task_id
587+
# because it gets set to None after the first call
588+
notification_bundle.notification_task_id = task_id
589+
notification_bundle.save()
590+
591+
alert_group_1.resolve()
592+
593+
send_bundled_notification.apply((notification_bundle.id,), task_id=task_id)
594+
595+
assert f"alert_group {alert_group_1.id} is not active, skip notification" in caplog.text
596+
assert f"no alert groups to notify about or notification is not allowed for user {user.id}" in caplog.text
597+
598+
# check all notifications were deleted
599+
assert notification_bundle.notifications.all().count() == 0
574600

575601

576602
@pytest.mark.django_db

0 commit comments

Comments
 (0)