Skip to content

Commit

Permalink
Add TaskclusterMetadata to the alert summary API endpoint (#7740)
Browse files Browse the repository at this point in the history
Bug 1838836 - Add TaskclusterMetadata to the alert summary API endpoint
  • Loading branch information
alexandru-io authored Sep 20, 2023
1 parent 1e0edda commit 983aeb1
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 4 deletions.
70 changes: 70 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,11 @@ def test_job_2(eleven_job_blobs, create_jobs):
return create_jobs(eleven_job_blobs[0:2])[1]


@pytest.fixture
def test_job_3(eleven_job_blobs, create_jobs):
return create_jobs(eleven_job_blobs[0:3])[2]


@pytest.fixture
def mock_log_parser(monkeypatch):
from celery import shared_task
Expand Down Expand Up @@ -669,6 +674,32 @@ def create_perf_signature(
)


@pytest.fixture
def test_taskcluster_metadata(test_job_2) -> th_models.TaskclusterMetadata:
return create_taskcluster_metadata(test_job_2)


@pytest.fixture
def test_taskcluster_metadata_2(test_job_3) -> th_models.TaskclusterMetadata:
return create_taskcluster_metadata_2(test_job_3)


def create_taskcluster_metadata(test_job_2) -> th_models.TaskclusterMetadata:
return th_models.TaskclusterMetadata.objects.create(
job=test_job_2,
task_id='V3SVuxO8TFy37En_6HcXLp',
retry_id='0',
)


def create_taskcluster_metadata_2(test_job_3) -> th_models.TaskclusterMetadata:
return th_models.TaskclusterMetadata.objects.create(
job=test_job_3,
task_id='V3SVuxO8TFy37En_6HcXLq',
retry_id='0',
)


@pytest.fixture
def test_perf_signature_2(test_perf_signature):
return perf_models.PerformanceSignature.objects.create(
Expand Down Expand Up @@ -922,11 +953,50 @@ def test_perf_alert_summary_with_bug(
)


@pytest.fixture
def test_perf_datum(test_repository, test_perf_signature, test_job_2):
push = th_models.Push.objects.get(id=1)
perf_models.PerformanceDatum.objects.create(
repository=test_repository,
job=test_job_2,
push_id=1,
signature=test_perf_signature,
value=1,
push_timestamp=push.time,
)


@pytest.fixture
def test_perf_datum_2(test_repository, test_perf_signature, test_job_3):
push = th_models.Push.objects.get(id=2)
perf_models.PerformanceDatum.objects.create(
repository=test_repository,
job=test_job_3,
push_id=2,
signature=test_perf_signature,
value=1,
push_timestamp=push.time,
)


@pytest.fixture
def test_perf_alert(test_perf_signature, test_perf_alert_summary) -> perf_models.PerformanceAlert:
return create_perf_alert(summary=test_perf_alert_summary, series_signature=test_perf_signature)


@pytest.fixture
def test_perf_alert_with_tcmetadata(
test_perf_signature, test_perf_alert_summary
) -> perf_models.PerformanceAlert:
perf_alert = create_perf_alert(
summary=test_perf_alert_summary, series_signature=test_perf_signature
)
perf_alert.taskcluster_metadata = test_taskcluster_metadata_2
perf_alert.prev_taskcluster_metadata = test_taskcluster_metadata
perf_alert.save()
return perf_alert


def create_perf_alert(**alert_properties) -> perf_models.PerformanceAlert:
defaults = dict(
amount_abs=50.0,
Expand Down
20 changes: 19 additions & 1 deletion tests/webapp/api/test_performance_alerts_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,15 @@
from treeherder.perf.models import PerformanceAlert, PerformanceAlertSummary, PerformanceFramework


def test_alerts_get(client, test_repository, test_perf_alert):
def test_alerts_get(
client,
test_repository,
test_perf_alert_with_tcmetadata,
test_perf_datum,
test_perf_datum_2,
test_taskcluster_metadata,
test_taskcluster_metadata_2,
):
resp = client.get(reverse('performance-alerts-list'))
assert resp.status_code == 200

Expand All @@ -27,6 +35,8 @@ def test_alerts_get(client, test_repository, test_perf_alert):
'prev_value',
'related_summary_id',
'series_signature',
'taskcluster_metadata',
'prev_taskcluster_metadata',
'summary_id',
'status',
't_value',
Expand All @@ -36,6 +46,14 @@ def test_alerts_get(client, test_repository, test_perf_alert):
'noise_profile',
}
assert resp.json()['results'][0]['related_summary_id'] is None
assert set(resp.json()['results'][0]['taskcluster_metadata'].keys()) == {
'task_id',
'retry_id',
}
assert set(resp.json()['results'][0]['prev_taskcluster_metadata'].keys()) == {
'task_id',
'retry_id',
}


def test_alerts_put(
Expand Down
36 changes: 34 additions & 2 deletions tests/webapp/api/test_performance_alertsummary_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,15 @@ def test_perf_alert_onhold(test_perf_signature, test_perf_alert_summary_onhold)
)


def test_alert_summaries_get(client, test_perf_alert_summary, test_perf_alert):
def test_alert_summaries_get(
client,
test_perf_alert_summary,
test_perf_alert_with_tcmetadata,
test_perf_datum,
test_perf_datum_2,
test_taskcluster_metadata,
test_taskcluster_metadata_2,
):
# verify that we get the performance summary + alert on GET
resp = client.get(reverse('performance-alert-summaries-list'))
assert resp.status_code == 200
Expand Down Expand Up @@ -89,6 +97,8 @@ def test_alert_summaries_get(client, test_perf_alert_summary, test_perf_alert):
'id',
'status',
'series_signature',
'taskcluster_metadata',
'prev_taskcluster_metadata',
'is_regression',
'starred',
'manually_created',
Expand All @@ -105,12 +115,24 @@ def test_alert_summaries_get(client, test_perf_alert_summary, test_perf_alert):
'noise_profile',
}
assert resp.json()['results'][0]['related_alerts'] == []
assert set(resp.json()['results'][0]['alerts'][0]['taskcluster_metadata'].keys()) == {
'task_id',
'retry_id',
}
assert set(resp.json()['results'][0]['alerts'][0]['prev_taskcluster_metadata'].keys()) == {
'task_id',
'retry_id',
}


def test_alert_summaries_get_onhold(
client,
test_perf_alert_summary,
test_perf_alert,
test_perf_alert_with_tcmetadata,
test_perf_datum,
test_perf_datum_2,
test_taskcluster_metadata,
test_taskcluster_metadata_2,
test_perf_alert_summary_onhold,
test_perf_alert_onhold,
test_repository_onhold,
Expand Down Expand Up @@ -150,6 +172,8 @@ def test_alert_summaries_get_onhold(
'id',
'status',
'series_signature',
'taskcluster_metadata',
'prev_taskcluster_metadata',
'is_regression',
'starred',
'manually_created',
Expand All @@ -166,6 +190,14 @@ def test_alert_summaries_get_onhold(
'noise_profile',
}
assert resp.json()['results'][0]['related_alerts'] == []
assert set(resp.json()['results'][0]['alerts'][0]['taskcluster_metadata'].keys()) == {
'task_id',
'retry_id',
}
assert set(resp.json()['results'][0]['alerts'][0]['prev_taskcluster_metadata'].keys()) == {
'task_id',
'retry_id',
}


def test_alert_summaries_put(
Expand Down
42 changes: 41 additions & 1 deletion treeherder/webapp/api/performance_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from django.db import transaction
from rest_framework import exceptions, serializers

from treeherder.model.models import Repository
from treeherder.model.models import Repository, TaskclusterMetadata
from treeherder.perf.models import (
BackfillRecord,
IssueTracker,
Expand Down Expand Up @@ -118,6 +118,8 @@ class Meta:

class PerformanceAlertSerializer(serializers.ModelSerializer):
series_signature = PerformanceSignatureSerializer(read_only=True)
taskcluster_metadata = serializers.SerializerMethodField()
prev_taskcluster_metadata = serializers.SerializerMethodField()
summary_id = serializers.SlugRelatedField(
slug_field="id",
source="summary",
Expand Down Expand Up @@ -183,6 +185,42 @@ def update(self, instance, validated_data):

return super().update(instance, validated_data)

def get_taskcluster_metadata(self, alert):
datum = PerformanceDatum.objects.filter(
signature=alert.series_signature,
repository=alert.series_signature.repository,
push=alert.summary.push,
).first()
if datum:
try:
metadata = TaskclusterMetadata.objects.get(job=datum.job)
return {
'task_id': metadata.task_id,
'retry_id': metadata.retry_id,
}
except ObjectDoesNotExist:
return {}
else:
return {}

def get_prev_taskcluster_metadata(self, alert):
datum = PerformanceDatum.objects.filter(
signature=alert.series_signature,
repository=alert.series_signature.repository,
push=alert.summary.prev_push,
).first()
if datum:
try:
metadata = TaskclusterMetadata.objects.get(job=datum.job)
return {
'task_id': metadata.task_id,
'retry_id': metadata.retry_id,
}
except ObjectDoesNotExist:
return {}
else:
return {}

def get_classifier_email(self, performance_alert):
return getattr(performance_alert.classifier, 'email', None)

Expand All @@ -192,6 +230,8 @@ class Meta:
'id',
'status',
'series_signature',
'taskcluster_metadata',
'prev_taskcluster_metadata',
'is_regression',
'prev_value',
'new_value',
Expand Down

0 comments on commit 983aeb1

Please sign in to comment.