Skip to content

Commit

Permalink
Bug 1825705 - Alerts View - Add bug_due_date field to performance_ale…
Browse files Browse the repository at this point in the history
…rt_summary table (#7863)
  • Loading branch information
alexandru-io committed Nov 6, 2023
1 parent d9f78f2 commit 2b08e55
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 14 deletions.
102 changes: 95 additions & 7 deletions tests/model/test_time_to_triage.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
MON, TUE, WED, THU, FRI, SAT, SUN = range(1, 8)


def test_alert_summary_created_monday(test_perf_alert_summary):
def test_triage_due_alert_summary_created_monday(test_perf_alert_summary):
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-05-30')
test_perf_alert_summary.triage_due_date = None

Expand All @@ -15,7 +15,7 @@ def test_alert_summary_created_monday(test_perf_alert_summary):
assert test_perf_alert_summary.triage_due_date.isoweekday() == THU


def test_alert_summary_created_tuesday(test_perf_alert_summary):
def test_triage_due_alert_summary_created_tuesday(test_perf_alert_summary):
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-05-31')
test_perf_alert_summary.triage_due_date = None

Expand All @@ -27,7 +27,7 @@ def test_alert_summary_created_tuesday(test_perf_alert_summary):
assert test_perf_alert_summary.triage_due_date.isoweekday() == FRI


def test_alert_summary_created_wednesday(test_perf_alert_summary):
def test_triage_due_alert_summary_created_wednesday(test_perf_alert_summary):
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-06-01')
test_perf_alert_summary.triage_due_date = None

Expand All @@ -39,7 +39,7 @@ def test_alert_summary_created_wednesday(test_perf_alert_summary):
assert test_perf_alert_summary.triage_due_date.isoweekday() == MON


def test_alert_summary_created_thursday(test_perf_alert_summary):
def test_triage_due_alert_summary_created_thursday(test_perf_alert_summary):
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-06-02')
test_perf_alert_summary.triage_due_date = None

Expand All @@ -52,7 +52,7 @@ def test_alert_summary_created_thursday(test_perf_alert_summary):
assert test_perf_alert_summary.triage_due_date.isoweekday() == TUE


def test_alert_summary_created_friday(test_perf_alert_summary):
def test_triage_due_alert_summary_created_friday(test_perf_alert_summary):
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-06-03')
test_perf_alert_summary.triage_due_date = None

Expand All @@ -65,7 +65,7 @@ def test_alert_summary_created_friday(test_perf_alert_summary):
assert test_perf_alert_summary.triage_due_date.isoweekday() == WED


def test_alert_summary_created_saturday(test_perf_alert_summary):
def test_triage_due_alert_summary_created_saturday(test_perf_alert_summary):
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-06-04')
test_perf_alert_summary.triage_due_date = None

Expand All @@ -77,7 +77,7 @@ def test_alert_summary_created_saturday(test_perf_alert_summary):
assert test_perf_alert_summary.triage_due_date.isoweekday() == THU


def test_alert_summary_created_sunday(test_perf_alert_summary):
def test_triage_due_alert_summary_created_sunday(test_perf_alert_summary):
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-06-05')
test_perf_alert_summary.triage_due_date = None

Expand Down Expand Up @@ -107,3 +107,91 @@ def test_alert_summary_with_modified_created_date(test_perf_alert_summary):
# created friday = 5 + OKR = 3 => 8 => 1 (monday)
# 1 (monday) + 2 (2 days of OKR were weekend) = 3 (wednesday)
assert test_perf_alert_summary.triage_due_date.isoweekday() == WED


def test_bug_due_alert_summary_created_monday(test_perf_alert_summary):
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-05-30')
test_perf_alert_summary.bug_due_date = None

assert not test_perf_alert_summary.bug_due_date

test_perf_alert_summary.update_status()

# created monday isoweekday = 1 + OKR = 5 => 6 (saturday) => 1 (monday)
assert test_perf_alert_summary.bug_due_date.isoweekday() == MON


def test_bug_due_alert_summary_created_tuesday(test_perf_alert_summary):
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-05-31')
test_perf_alert_summary.bug_due_date = None

assert not test_perf_alert_summary.bug_due_date

test_perf_alert_summary.update_status()

# created tuesday isoweekday = 2 + OKR = 5 => 7 (saturday) => 1 (monday)
# 1 (monday) + 1 day (1 day of OKR was saturday) = 2 (tuesday)
assert test_perf_alert_summary.bug_due_date.isoweekday() == TUE


def test_bug_due_alert_summary_created_wednesday(test_perf_alert_summary):
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-06-01')
test_perf_alert_summary.bug_due_date = None

assert not test_perf_alert_summary.bug_due_date

test_perf_alert_summary.update_status()

# created wednesday = 3 + OKR = 5 => 1 (monday)
# 1 (monday) + 2 day (2 day of OKR was saturday) = 3 (wednesday)
assert test_perf_alert_summary.bug_due_date.isoweekday() == WED


def test_bug_due_alert_summary_created_thursday(test_perf_alert_summary):
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-06-02')
test_perf_alert_summary.bug_due_date = None

assert not test_perf_alert_summary.bug_due_date

test_perf_alert_summary.update_status()

# created thursday = 4 + OKR = 5 => 2 (tuesday)
# 2 (tuesday) + 2 day (2 day of OKR was saturday) = 4 (thursday)
assert test_perf_alert_summary.bug_due_date.isoweekday() == THU


def test_bug_due_alert_summary_created_friday(test_perf_alert_summary):
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-06-03')
test_perf_alert_summary.bug_due_date = None

assert not test_perf_alert_summary.bug_due_date

test_perf_alert_summary.update_status()

# created friday = 5 + OKR = 5 => 3 (wednesday)
# 3 (wednesday) + 2 (2 days of OKR were weekend) = 5 (friday)
assert test_perf_alert_summary.bug_due_date.isoweekday() == FRI


def test_bug_due_alert_summary_created_saturday(test_perf_alert_summary):
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-06-04')
test_perf_alert_summary.bug_due_date = None

assert not test_perf_alert_summary.bug_due_date

test_perf_alert_summary.update_status()

# created saturday = 6 => 1 (monday) + OKR = 5 => 6 (saturday) => 1 (monday)
assert test_perf_alert_summary.bug_due_date.isoweekday() == MON


def test_bug_due_alert_summary_created_sunday(test_perf_alert_summary):
test_perf_alert_summary.created = datetime.datetime.fromisoformat('2022-06-05')
test_perf_alert_summary.bug_due_date = None

assert not test_perf_alert_summary.bug_due_date

test_perf_alert_summary.update_status()

# created sunday = 7 => 1 (monday) + OKR = 5 => 6 (saturday) => 1 (monday)
assert test_perf_alert_summary.bug_due_date.isoweekday() == MON
5 changes: 3 additions & 2 deletions tests/perfalert/test_alerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
PerformanceDatum,
PerformanceSignature,
)
from treeherder.perf.utils import calculate_time_to_triage
from treeherder.perf.utils import calculate_time_to, TRIAGE_DAYS, BUG_DAYS


def _verify_alert(
Expand Down Expand Up @@ -41,7 +41,8 @@ def _verify_alert(
assert summary.push_id == expected_push_id
assert summary.prev_push_id == expected_prev_push_id
assert summary.status == expected_summary_status
assert summary.triage_due_date == calculate_time_to_triage(summary.created)
assert summary.triage_due_date == calculate_time_to(summary.created, TRIAGE_DAYS)
assert summary.bug_due_date == calculate_time_to(summary.created, BUG_DAYS)


def _generate_performance_data(
Expand Down
4 changes: 4 additions & 0 deletions tests/webapp/api/test_performance_alertsummary_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,15 @@ def test_alert_summaries_get(
'alerts',
'bug_number',
'bug_updated',
'bug_due_date',
'issue_tracker',
'notes',
'assignee_username',
'assignee_email',
'framework',
'id',
'created',
'first_triaged',
'triage_due_date',
'prev_push_id',
'related_alerts',
Expand Down Expand Up @@ -149,13 +151,15 @@ def test_alert_summaries_get_onhold(
'alerts',
'bug_number',
'bug_updated',
'bug_due_date',
'issue_tracker',
'notes',
'assignee_username',
'assignee_email',
'framework',
'id',
'created',
'first_triaged',
'triage_due_date',
'prev_push_id',
'related_alerts',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Generated by Django 3.2.13 on 2022-05-30 11:02
from django.db import migrations, models

from treeherder.perf.utils import calculate_time_to_triage
from treeherder.perf.utils import calculate_time_to, TRIAGE_DAYS


def update_summary_triage_due_date(apps, schema_editor):
PerformanceAlertSummary = apps.get_model('perf', 'PerformanceAlertSummary')

for row in PerformanceAlertSummary.objects.all():
row.triage_due_date = calculate_time_to_triage(row.created)
row.triage_due_date = calculate_time_to(row.created, due_days=TRIAGE_DAYS)
row.save()


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Generated by Django 4.0.8 on 2023-03-28 09:33

from django.db import migrations, models

from treeherder.perf.utils import calculate_time_to, BUG_DAYS


def update_summary_bug_due_date(apps, schema_editor):
PerformanceAlertSummary = apps.get_model('perf', 'PerformanceAlertSummary')

for row in PerformanceAlertSummary.objects.all():
row.bug_due_date = calculate_time_to(row.created, due_days=BUG_DAYS)
row.save()


class Migration(migrations.Migration):
dependencies = [
('perf', '0050_cascade_perf_datum_deletion_replicate'),
]

operations = [
migrations.AddField(
model_name='performancealertsummary',
name='bug_due_date',
field=models.DateTimeField(default=None, null=True),
),
migrations.RunPython(
update_summary_bug_due_date,
reverse_code=migrations.RunPython.noop,
),
]
8 changes: 6 additions & 2 deletions treeherder/perf/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
JobType,
JobGroup,
)
from treeherder.perf.utils import calculate_time_to_triage
from treeherder.perf.utils import calculate_time_to, TRIAGE_DAYS, BUG_DAYS
from treeherder.utils import default_serializer

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -311,6 +311,7 @@ class PerformanceAlertSummary(models.Model):
status = models.IntegerField(choices=STATUSES, default=UNTRIAGED)

bug_number = models.PositiveIntegerField(null=True)
bug_due_date = models.DateTimeField(null=True, default=None)
bug_updated = models.DateTimeField(null=True)

issue_tracker = models.ForeignKey(IssueTracker, on_delete=models.PROTECT, default=1) # Bugzilla
Expand All @@ -324,11 +325,14 @@ def __init__(self, *args, **kwargs):
def save(self, *args, **kwargs):
if self.bug_number is not None and self.bug_number != self.__prev_bug_number:
self.bug_updated = datetime.now()
triage_due = calculate_time_to_triage(self.created)
triage_due = calculate_time_to(self.created, TRIAGE_DAYS)
bug_due = calculate_time_to(self.created, BUG_DAYS)
# created is initially PerformanceDatum.push_timestamp and due to a potential race condition
# triage_due_date is not always calculated after the real created date
if self.triage_due_date != triage_due:
self.triage_due_date = triage_due
if self.bug_due_date != bug_due:
self.bug_due_date = bug_due
super(PerformanceAlertSummary, self).save(*args, **kwargs)
self.__prev_bug_number = self.bug_number

Expand Down
4 changes: 3 additions & 1 deletion treeherder/perf/utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import datetime

MON, TUE, WED, THU, FRI, SAT, SUN = range(1, 8)
TRIAGE_DAYS = 3
BUG_DAYS = 5


def calculate_time_to_triage(created, due_days=3):
def calculate_time_to(created, due_days=3):
due_date = created

# if the alert was created in weekend, move the date to Monday
Expand Down
4 changes: 4 additions & 0 deletions treeherder/webapp/api/performance_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,9 @@ class PerformanceAlertSummarySerializer(serializers.ModelSerializer):
prev_push_id = serializers.ReadOnlyField()
push_id = serializers.ReadOnlyField()
created = serializers.ReadOnlyField()
first_triaged = serializers.ReadOnlyField()
triage_due_date = serializers.ReadOnlyField()
bug_due_date = serializers.ReadOnlyField()

def update(self, instance, validated_data):
instance.timestamp_first_triage()
Expand All @@ -300,13 +302,15 @@ class Meta:
'push_id',
'prev_push_id',
'created',
'first_triaged',
'triage_due_date',
'repository',
'framework',
'alerts',
'related_alerts',
'status',
'bug_number',
'bug_due_date',
'bug_updated',
'issue_tracker',
'notes',
Expand Down

0 comments on commit 2b08e55

Please sign in to comment.