Skip to content

Commit

Permalink
fixes for most tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mwheeler-ep committed Dec 18, 2024
1 parent b3914b8 commit cea470f
Show file tree
Hide file tree
Showing 14 changed files with 218 additions and 117 deletions.
23 changes: 11 additions & 12 deletions engine/apps/alerts/models/alert.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,18 +145,17 @@ def create(
group.log_records.create(type=AlertGroupLogRecord.TYPE_REGISTERED)
group.log_records.create(type=AlertGroupLogRecord.TYPE_ROUTE_ASSIGNED)

if group_created and alert_receive_channel.team:
# add the team from the integration if its available
group.teams.set([alert_receive_channel.team])
elif (
group_created
and channel_filter
and channel_filter.escalation_chain
and channel_filter.escalation_chain.team
and channel_filter.update_team
):
# set the team to the one defined in the escalation_chain if defined.
group.teams.set([channel_filter.escalation_chain.team])
if alert_receive_channel.team:
# add the team from the integration if its available
group.teams.set([alert_receive_channel.team])
elif (
channel_filter
and channel_filter.escalation_chain
and channel_filter.escalation_chain.team
and channel_filter.update_team
):
# set the team to the one defined in the escalation_chain if defined.
group.teams.set([channel_filter.escalation_chain.team])

if group_created or alert.group.pause_escalation:
# Build escalation snapshot if needed and start escalation
Expand Down
2 changes: 1 addition & 1 deletion engine/apps/alerts/models/alert_receive_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -792,4 +792,4 @@ def listen_for_alertreceivechannel_model_save(

metrics_remove_deleted_integration_from_cache(instance, instance.organization)
else:
metrics_update_integration_cache(instance, instance.organization)
metrics_update_integration_cache(instance)
39 changes: 31 additions & 8 deletions engine/apps/api/tests/test_alert_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from apps.alerts.constants import ActionSource
from apps.alerts.models import (
Alert,
AlertGroup,
AlertGroupExternalID,
AlertGroupLogRecord,
Expand Down Expand Up @@ -887,14 +888,35 @@ def test_get_filter_by_teams(
alert_receive_channel_1 = make_alert_receive_channel(organization, team=team1)
alert_receive_channel_2 = make_alert_receive_channel(organization, team=team2)

alert_group_0 = make_alert_group(alert_receive_channel_0)
make_alert(alert_group=alert_group_0, raw_request_data=alert_raw_request_data)

alert_group_1 = make_alert_group(alert_receive_channel_1)
make_alert(alert_group=alert_group_1, raw_request_data=alert_raw_request_data)

alert_group_2 = make_alert_group(alert_receive_channel_2)
make_alert(alert_group=alert_group_2, raw_request_data=alert_raw_request_data)
alert_group_0 = Alert.create(
title="the title",
message="the message",
alert_receive_channel=alert_receive_channel_0,
raw_request_data={},
integration_unique_data={},
image_url=None,
link_to_upstream_details=None,
).group

alert_group_1 = Alert.create(
title="the title",
message="the message",
alert_receive_channel=alert_receive_channel_1,
raw_request_data={},
integration_unique_data={},
image_url=None,
link_to_upstream_details=None,
).group

alert_group_2 = Alert.create(
title="the title",
message="the message",
alert_receive_channel=alert_receive_channel_2,
raw_request_data={},
integration_unique_data={},
image_url=None,
link_to_upstream_details=None,
).group

url = reverse("api-internal:alertgroup-list")

Expand All @@ -911,6 +933,7 @@ def test_get_filter_by_teams(
# check the "No team" case
response = client.get(url + "?team=null", **make_user_auth_headers(user, token))
assert response.status_code == status.HTTP_200_OK
print()
assert len(response.data["results"]) == 1
assert {ag["pk"] for ag in response.data["results"]} == {alert_group_0.public_primary_key}

Expand Down
22 changes: 19 additions & 3 deletions engine/apps/api/tests/test_team.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from rest_framework import status
from rest_framework.test import APIClient

from apps.alerts.models import AlertReceiveChannel
from apps.alerts.models import AlertReceiveChannel, Alert
from apps.api.permissions import LegacyAccessControlRole
from apps.api.serializers.user import UserHiddenFieldsSerializer
from apps.schedules.models import CustomOnCallShift, OnCallScheduleCalendar, OnCallScheduleWeb
Expand Down Expand Up @@ -356,7 +356,15 @@ def test_team_permissions_wrong_team(
user.teams.add(team_with_user)

alert_receive_channel = make_alert_receive_channel(organization, team=team_without_user)
alert_group = make_alert_group(alert_receive_channel)
alert_group = Alert.create(
title="the title",
message="the message",
alert_receive_channel=alert_receive_channel,
raw_request_data={},
integration_unique_data={},
image_url=None,
link_to_upstream_details=None,
).group

escalation_chain = make_escalation_chain(organization, team=team_without_user)
schedule = make_schedule(organization, schedule_class=OnCallScheduleCalendar, team=team_without_user)
Expand Down Expand Up @@ -402,7 +410,15 @@ def test_team_permissions_not_in_team(
another_user.save(update_fields=["current_team"])

alert_receive_channel = make_alert_receive_channel(organization, team=team)
alert_group = make_alert_group(alert_receive_channel)
alert_group = Alert.create(
title="the title",
message="the message",
alert_receive_channel=alert_receive_channel,
raw_request_data={},
integration_unique_data={},
image_url=None,
link_to_upstream_details=None,
).group

escalation_chain = make_escalation_chain(organization, team=team)
schedule = make_schedule(organization, schedule_class=OnCallScheduleCalendar, team=team)
Expand Down
10 changes: 6 additions & 4 deletions engine/apps/api/views/alert_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,9 @@ def filter_with_resolution_note(self, queryset, name, value):
).distinct()
return queryset


# TODO need to probably rework this to ensure it works correctly with both paradigms
class AlertGroupTeamFilteringMixin(TeamFilteringMixin):
TEAM_LOOKUP = "team"
TEAM_LOOKUP = "teams"

def retrieve(self, request, *args, **kwargs):
try:
Expand Down Expand Up @@ -293,6 +293,8 @@ class AlertGroupView(
filter_backends = [AlertGroupSearchFilter, filters.DjangoFilterBackend]
filterset_class = AlertGroupFilter

TEAM_LOOKUP="teams"

def get_serializer_class(self):
if self.action == "list":
return AlertGroupListSerializer
Expand All @@ -304,19 +306,19 @@ def get_queryset(self, ignore_filtering_by_available_teams=False):

team_values = self.request.query_params.getlist("team", [])
if team_values:
null_team_lookup = Q(teams__isnull=True) if NO_TEAM_VALUE in team_values else None
null_team_lookup = (Q(teams__isnull=True) | Q(teams=None)) if NO_TEAM_VALUE in team_values else None
teams_lookup = Q(teams__public_primary_key__in=[ppk for ppk in team_values if ppk != NO_TEAM_VALUE])
if null_team_lookup:
teams_lookup = teams_lookup | null_team_lookup

# TODO also need to filter on integration as well.
if not ignore_filtering_by_available_teams:
queryset = AlertGroup.objects.filter(*self.available_teams_lookup_args)
else:
queryset = AlertGroup.objects

if team_values:
queryset = queryset.filter(teams_lookup)


if self.action in ("list", "stats") and not self.request.query_params.get("started_at"):
queryset = queryset.filter(started_at__gte=timezone.now() - timezone.timedelta(days=30))
Expand Down
94 changes: 53 additions & 41 deletions engine/apps/metrics_exporter/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
from apps.alerts.models import AlertReceiveChannel
from apps.user_management.models import Organization

def _get_teams_for_cache(organization):
teams = list(organization.teams.all())
class NoTeam():
team_id = "no_team"
name = "No team"
teams.append(NoTeam())
return teams

def get_organization_ids_from_db():
from apps.alerts.models import AlertReceiveChannel
Expand Down Expand Up @@ -141,19 +148,26 @@ def get_default_states_dict() -> AlertGroupStateDict:
}


def metrics_update_integration_cache(integration: "AlertReceiveChannel", organization: "Organization") -> None:
def metrics_update_integration_cache(integration: "AlertReceiveChannel") -> None:
"""Update integration data in metrics cache"""
metrics_cache_timeout = get_metrics_cache_timeout(integration.organization_id)
metric_alert_groups_total_key = get_metric_alert_groups_total_key(integration.organization_id)
metric_alert_groups_response_time_key = get_metric_alert_groups_response_time_key(integration.organization_id)

for team in organization.teams.all():
metrics_cache_timeout = get_metrics_cache_timeout(integration.organization.id)
metric_alert_groups_total_key = get_metric_alert_groups_total_key(integration.organization.id)
metric_alert_groups_response_time_key = get_metric_alert_groups_response_time_key(integration.organization.id)
print(integration.organization.id)
print("cccc")
for team in _get_teams_for_cache(integration.organization):
print(team)
for metric_key in [metric_alert_groups_total_key, metric_alert_groups_response_time_key]:
print(metric_key)
metric_cache = cache.get(metric_key, {})
print(metric_cache)
integration_metric_cache = metric_cache.get((integration.id,team.team_id))
print(integration_metric_cache)
if integration_metric_cache:
cache_updated = False
print("eeee")
if integration_metric_cache["integration_name"] != integration.emojized_verbal_name:
print("dddd")
integration_metric_cache["integration_name"] = integration.emojized_verbal_name
cache_updated = True
if cache_updated:
Expand All @@ -163,10 +177,10 @@ def metrics_update_integration_cache(integration: "AlertReceiveChannel", organiz
def metrics_remove_deleted_integration_from_cache(integration: "AlertReceiveChannel", organization: "Organization"):
"""Remove data related to deleted integration from metrics cache"""
metrics_cache_timeout = get_metrics_cache_timeout(integration.organization_id)
metric_alert_groups_total_key = get_metric_alert_groups_total_key(integration.organization_id)
metric_alert_groups_total_key = get_metric_alert_groups_total_key(integration.organization.id)
metric_alert_groups_response_time_key = get_metric_alert_groups_response_time_key(integration.organization_id)

for team in organization.teams.all():
for team in _get_teams_for_cache(organization):
for metric_key in [metric_alert_groups_total_key, metric_alert_groups_response_time_key]:
metric_cache = cache.get(metric_key)
if metric_cache:
Expand All @@ -178,16 +192,16 @@ def metrics_add_integrations_to_cache(integrations: list["AlertReceiveChannel"],
"""
Bulk add new integration data to metrics cache. This method is safe to call multiple times on the same integrations.
"""
metrics_cache_timeout = get_metrics_cache_timeout(organization.org_id)
metric_alert_groups_total_key = get_metric_alert_groups_total_key(organization.org_id)
metrics_cache_timeout = get_metrics_cache_timeout(organization.id)
metric_alert_groups_total_key = get_metric_alert_groups_total_key(organization.id)

instance_slug = organization.stack_slug
instance_id = organization.stack_id
grafana_org_id = organization.org_id
metric_alert_groups_total: typing.Dict[int, AlertGroupsTotalMetricsDict] = cache.get(
metric_alert_groups_total_key, {}
)
for team in organization.teams.all():
for team in _get_teams_for_cache(organization):
for integration in integrations:
metric_alert_groups_total.setdefault(
(integration.id,team.team_id),
Expand All @@ -203,12 +217,12 @@ def metrics_add_integrations_to_cache(integrations: list["AlertReceiveChannel"],
)
cache.set(metric_alert_groups_total_key, metric_alert_groups_total, timeout=metrics_cache_timeout)

metric_alert_groups_response_time_key = get_metric_alert_groups_response_time_key(organization.org_id)
metric_alert_groups_response_time_key = get_metric_alert_groups_response_time_key(organization.id)
metric_alert_groups_response_time: typing.Dict[int, AlertGroupsResponseTimeMetricsDict] = cache.get(
metric_alert_groups_response_time_key, {}
)

for team in organization.teams.all():
for team in _get_teams_for_cache(organization):
for integration in integrations:
metric_alert_groups_response_time.setdefault(
(integration.id, team.team_id),
Expand Down Expand Up @@ -239,17 +253,17 @@ def metrics_bulk_update_team_label_cache(teams_updated_data: dict, organization_
# TODO need to work out how to handle team changes... or if we need to.

for team_id, team_data in teams_updated_data.items():
for integration_id, team_id in metric_alert_groups_total:
if metric_alert_groups_total[(integration_id, team_id)]["team_id"] == team_id:
integration_response_time_metrics = metric_alert_groups_response_time.get(integration_id)
for index in metric_alert_groups_total:
if metric_alert_groups_total[index]["team_id"] == team_id:
integration_response_time_metrics = metric_alert_groups_response_time.get(index)
if team_data["deleted"]:
metric_alert_groups_total[(integration_id, team_id)]["team_id"] = "no_team"
metric_alert_groups_total[(integration_id, team_id)]["team_name"] = "No team"
metric_alert_groups_total[index]["team_id"] = "no_team"
metric_alert_groups_total[index]["team_name"] = "No team"
if integration_response_time_metrics:
integration_response_time_metrics["team_id"] = "no_team"
integration_response_time_metrics["team_name"] = "No team"
else:
metric_alert_groups_total[(integration_id, team_id)]["team_name"] = team_data["team_name"]
metric_alert_groups_total[index]["team_name"] = team_data["team_name"]
if integration_response_time_metrics:
integration_response_time_metrics["team_name"] = team_data["team_name"]

Expand Down Expand Up @@ -283,32 +297,31 @@ def metrics_update_alert_groups_state_cache(states_diff: dict, organization: "Or
if not states_diff:
return

metrics_cache_timeout = get_metrics_cache_timeout(organization.org_id)
metric_alert_groups_total_key = get_metric_alert_groups_total_key(organization.org_id)
metrics_cache_timeout = get_metrics_cache_timeout(organization.id)
metric_alert_groups_total_key = get_metric_alert_groups_total_key(organization.id)
metric_alert_groups_total = cache.get(metric_alert_groups_total_key, {})


if not metric_alert_groups_total:
return
for integration_id, service_data in states_diff.items():
for team in organization.teams.all():
integration_alert_groups = metric_alert_groups_total.get((int(integration_id), team.team_id))
if not integration_alert_groups:
continue
for service_name, service_state_diff in service_data.items():
states_to_update = integration_alert_groups["services"].setdefault(service_name, get_default_states_dict())
for previous_state, counter in service_state_diff["previous_states"].items():
if states_to_update[previous_state] - counter > 0:
states_to_update[previous_state] -= counter
else:
states_to_update[previous_state] = 0
for new_state, counter in service_state_diff["new_states"].items():
states_to_update[new_state] += counter
for index, service_data in states_diff.items():
integration_alert_groups = metric_alert_groups_total.get(index)
if not integration_alert_groups:
continue
for service_name, service_state_diff in service_data.items():
states_to_update = integration_alert_groups["services"].setdefault(service_name, get_default_states_dict())
for previous_state, counter in service_state_diff["previous_states"].items():
if states_to_update[previous_state] - counter > 0:
states_to_update[previous_state] -= counter
else:
states_to_update[previous_state] = 0
for new_state, counter in service_state_diff["new_states"].items():
states_to_update[new_state] += counter

cache.set(metric_alert_groups_total_key, metric_alert_groups_total, timeout=metrics_cache_timeout)


def metrics_update_alert_groups_response_time_cache(integrations_response_time: dict, organization_id: int):
def metrics_update_alert_groups_response_time_cache(integrations_response_time: dict, organization):
"""
Update alert groups response time metric cache for each integration in `integrations_response_time` dict.
integrations_response_time dict example:
Expand All @@ -320,14 +333,13 @@ def metrics_update_alert_groups_response_time_cache(integrations_response_time:
"""
if not integrations_response_time:
return

metrics_cache_timeout = get_metrics_cache_timeout(organization_id)
metric_alert_groups_response_time_key = get_metric_alert_groups_response_time_key(organization_id)
metrics_cache_timeout = get_metrics_cache_timeout(organization.id)
metric_alert_groups_response_time_key = get_metric_alert_groups_response_time_key(organization.id)
metric_alert_groups_response_time = cache.get(metric_alert_groups_response_time_key, {})
if not metric_alert_groups_response_time:
return
for integration_id, service_data in integrations_response_time.items():
integration_response_time_metrics = metric_alert_groups_response_time.get(int(integration_id))
for index, service_data in integrations_response_time.items():
integration_response_time_metrics = metric_alert_groups_response_time.get(index)
if not integration_response_time_metrics:
continue
for service_name, response_time_values in service_data.items():
Expand Down
Loading

0 comments on commit cea470f

Please sign in to comment.