Skip to content

Commit

Permalink
Bug 1838836 - Add TaskclusterMetadata to the alert summary API endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Ionescu committed Aug 22, 2023
1 parent 962beae commit 1e45025
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 4 deletions.
73 changes: 73 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,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 @@ -666,6 +671,37 @@ def create_perf_signature(
last_updated=datetime.datetime.now(),
)

@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):
Expand Down Expand Up @@ -920,11 +956,48 @@ 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 = {
"current_push": test_taskcluster_metadata_2,
"prev_push": 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
24 changes: 23 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,14 @@
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_taskcluster_metadata,
test_taskcluster_metadata_2,
):
resp = client.get(reverse('performance-alerts-list'))
assert resp.status_code == 200

Expand All @@ -27,6 +34,7 @@ def test_alerts_get(client, test_repository, test_perf_alert):
'prev_value',
'related_summary_id',
'series_signature',
'taskcluster_metadata',
'summary_id',
'status',
't_value',
Expand All @@ -36,6 +44,20 @@ 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()) == {
'current_push',
'prev_push',
}
assert set(resp.json()['results'][0]['taskcluster_metadata']['current_push'].keys()) == {
'task_id',
'retry_id',
'result',
}
assert set(resp.json()['results'][0]['taskcluster_metadata']['prev_push'].keys()) == {
'task_id',
'retry_id',
'result',
}


def test_alerts_put(
Expand Down
44 changes: 42 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,14 @@ 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_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 +96,7 @@ def test_alert_summaries_get(client, test_perf_alert_summary, test_perf_alert):
'id',
'status',
'series_signature',
'taskcluster_metadata',
'is_regression',
'starred',
'manually_created',
Expand All @@ -105,12 +113,29 @@ 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()) == {
'current_push',
'prev_push',
}
assert set(resp.json()['results'][0]['alerts'][0]['taskcluster_metadata']['current_push'].keys()) == {
'task_id',
'retry_id',
'result',
}
assert set(resp.json()['results'][0]['alerts'][0]['taskcluster_metadata']['prev_push'].keys()) == {
'task_id',
'retry_id',
'result',
}


def test_alert_summaries_get_onhold(
client,
test_perf_alert_summary,
test_perf_alert,
test_perf_alert_with_tcmetadata,
test_perf_datum,
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 +175,7 @@ def test_alert_summaries_get_onhold(
'id',
'status',
'series_signature',
'taskcluster_metadata',
'is_regression',
'starred',
'manually_created',
Expand All @@ -166,6 +192,20 @@ 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()) == {
'current_push',
'prev_push',
}
assert set(resp.json()['results'][0]['alerts'][0]['taskcluster_metadata']['current_push'].keys()) == {
'task_id',
'retry_id',
'result',
}
assert set(resp.json()['results'][0]['alerts'][0]['taskcluster_metadata']['prev_push'].keys()) == {
'task_id',
'retry_id',
'result',
}


def test_alert_summaries_put(
Expand Down
53 changes: 52 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, Job
from treeherder.perf.models import (
BackfillRecord,
IssueTracker,
Expand All @@ -17,6 +17,7 @@
PerformanceSignature,
PerformanceTag,
)
from treeherder.webapp.api.serializers import TaskclusterMetadataSerializer
from treeherder.webapp.api.utils import to_timestamp


Expand Down Expand Up @@ -116,8 +117,53 @@ class Meta:
]


class AlertTaskclusterMetadataSerializer(serializers.ModelSerializer):
current_push = serializers.SerializerMethodField()
prev_push = serializers.SerializerMethodField()

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

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

class Meta:
model = Job
fields = [
# 'task_id',
# 'retry_id',
'current_push',
'prev_push',
]


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

return super().update(instance, validated_data)

def get_taskcluster_metadata(self, alert):
serializer = AlertTaskclusterMetadataSerializer(alert)
return serializer.data

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

Expand All @@ -192,6 +242,7 @@ class Meta:
'id',
'status',
'series_signature',
'taskcluster_metadata',
'is_regression',
'prev_value',
'new_value',
Expand Down
1 change: 1 addition & 0 deletions ui/perfherder/alerts/AlertActionPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ export default class AlertActionPanel extends React.Component {
} else {
fetchAlertSummaries(alertSummary.id);
}

this.clearSelectedAlerts();
};

Expand Down

0 comments on commit 1e45025

Please sign in to comment.