Skip to content

Commit

Permalink
feat: create testruns model in timeseries app
Browse files Browse the repository at this point in the history
  • Loading branch information
joseph-sentry committed Feb 11, 2025
1 parent f7dae7d commit 0d177e8
Showing 7 changed files with 369 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Generated by Django 4.2.16 on 2025-02-06 15:02

import django.contrib.postgres.fields
import django_prometheus.models
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
(
"timeseries",
"0014_remove_measurement_timeseries_measurement_flag_unique_and_more",
),
]

operations = [
migrations.CreateModel(
name="Testrun",
fields=[
("timestamp", models.DateTimeField(primary_key=True, serialize=False)),
("repo_id", models.BigIntegerField()),
("test_id", models.BinaryField()),
("flags_hash", models.BinaryField(null=True)),
("testsuite", models.TextField(null=True)),
("classname", models.TextField(null=True)),
("name", models.TextField(null=True)),
("computed_name", models.TextField(null=True)),
("outcome", models.TextField()),
("duration_seconds", models.FloatField(null=True)),
("failure_message", models.TextField(null=True)),
("framework", models.TextField(null=True)),
("filename", models.TextField(null=True)),
("commit_sha", models.TextField(null=True)),
("branch", models.TextField(null=True)),
(
"flags",
django.contrib.postgres.fields.ArrayField(
base_field=models.TextField(), null=True, size=None
),
),
("upload_id", models.BigIntegerField(null=True)),
],
bases=(
django_prometheus.models.ExportModelOperationsMixin(
"timeseries.testrun"
),
models.Model,
),
),
migrations.RunSQL(
"ALTER TABLE timeseries_testrun DROP CONSTRAINT timeseries_testrun_pkey;",
reverse_sql="",
),
migrations.RunSQL(
"SELECT create_hypertable('timeseries_testrun', 'timestamp');",
reverse_sql="",
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Generated by Django 4.2.16 on 2025-02-06 15:13

from django.db import migrations


class Migration(migrations.Migration):
# cant create this views in a transaction
atomic = False

dependencies = [
("timeseries", "0015_testrun_testrun_flags_hash_test_id_unique"),
]

operations = [
migrations.RunSQL(
"""
create materialized view timeseries_testrun_branch_summary_1day
with (timescaledb.continuous) as
select
repo_id,
branch,
testsuite,
classname,
name,
min(computed_name) as computed_name,
COUNT(DISTINCT CASE WHEN outcome = 'failure' OR outcome = 'flaky_fail' THEN commit_sha ELSE NULL END) AS cwf,
time_bucket(interval '1 days', timestamp) as timestamp_bin,
last(duration_seconds, timestamp) as last_duration_seconds,
avg(duration_seconds) as avg_duration_seconds,
COUNT(*) FILTER (WHERE outcome = 'pass') AS pass_count,
COUNT(*) FILTER (WHERE outcome = 'failure') AS fail_count,
COUNT(*) FILTER (WHERE outcome = 'skip') AS skip_count,
COUNT(*) FILTER (WHERE outcome = 'flaky_fail') AS flaky_fail_count,
MAX(timestamp) AS updated_at,
array_agg(DISTINCT flags) filter(where flags <> '{}') as flags
from timeseries_testrun
group by
repo_id, test_id, branch, timestamp_bin;
""",
reverse_sql="drop materialized view timeseries_testrun_branch_summary_1day;",
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Generated by Django 4.2.16 on 2025-02-06 16:56

from django.db import migrations


class Migration(migrations.Migration):
# cant create this views in a transaction
atomic = False

dependencies = [
("timeseries", "0016_auto_20250206_1513"),
]

operations = [
migrations.RunSQL(
"""
create materialized view timeseries_testrun_summary_1day
with (timescaledb.continuous) as
select
repo_id,
testsuite,
classname,
name,
min(computed_name) as computed_name,
COUNT(DISTINCT CASE WHEN outcome = 'failure' OR outcome = 'flaky_fail' THEN commit_sha ELSE NULL END) AS cwf,
time_bucket(interval '1 days', timestamp) as timestamp_bin,
last(duration_seconds, timestamp) as last_duration_seconds,
avg(duration_seconds) as avg_duration_seconds,
COUNT(*) FILTER (WHERE outcome = 'pass') AS pass_count,
COUNT(*) FILTER (WHERE outcome = 'failure') AS fail_count,
COUNT(*) FILTER (WHERE outcome = 'skip') AS skip_count,
COUNT(*) FILTER (WHERE outcome = 'flaky_fail') AS flaky_fail_count,
MAX(timestamp) AS updated_at,
array_agg(DISTINCT flags) filter(where flags <> '{}') as flags
from timeseries_testrun
group by
repo_id, test_id, timestamp_bin;
""",
reverse_sql="drop materialized view timeseries_testrun_summary_1day;",
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.2.16 on 2025-02-06 16:57

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("timeseries", "0017_auto_20250206_1656"),
]

operations = [
migrations.RunSQL(
"""
select add_continuous_aggregate_policy(
'timeseries_testrun_branch_summary_1day',
start_offset => '7 days',
end_offset => '1 days',
schedule_interval => INTERVAL '1 days'
);
""",
reverse_sql="select remove_continuous_aggregate_policy('timeseries_testrun_branch_summary_1day');",
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.2.16 on 2025-02-06 16:57

from django.db import migrations


class Migration(migrations.Migration):
dependencies = [
("timeseries", "0018_auto_20250206_1657"),
]

operations = [
migrations.RunSQL(
"""
select add_continuous_aggregate_policy(
'timeseries_testrun_summary_1day',
start_offset => '7 days',
end_offset => '1 days',
schedule_interval => INTERVAL '1 days'
);
""",
reverse_sql="select remove_continuous_aggregate_policy('timeseries_testrun_summary_1day');",
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Generated by Django 4.2.16 on 2025-02-06 16:57
import django.contrib.postgres.fields
import django_prometheus.models
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("timeseries", "0019_auto_20250206_1657"),
]

operations = [
migrations.CreateModel(
name="TestrunBranchSummary",
fields=[
(
"timestamp_bin",
models.DateTimeField(primary_key=True, serialize=False),
),
("repo_id", models.IntegerField()),
("branch", models.TextField()),
("name", models.TextField()),
("classname", models.TextField()),
("testsuite", models.TextField()),
("computed_name", models.TextField()),
("cwf", models.IntegerField()),
("avg_duration_seconds", models.FloatField()),
("last_duration_seconds", models.FloatField()),
("pass_count", models.IntegerField()),
("fail_count", models.IntegerField()),
("skip_count", models.IntegerField()),
("flaky_fail_count", models.IntegerField()),
("updated_at", models.DateTimeField()),
(
"flags",
django.contrib.postgres.fields.ArrayField(
base_field=models.TextField(), null=True, size=None
),
),
],
options={
"db_table": "timeseries_testrun_branch_summary_1day",
"managed": False,
},
bases=(
django_prometheus.models.ExportModelOperationsMixin(
"timeseries.testrun_continuous_aggregate"
),
models.Model,
),
),
migrations.CreateModel(
name="TestrunSummary",
fields=[
(
"timestamp_bin",
models.DateTimeField(primary_key=True, serialize=False),
),
("repo_id", models.IntegerField()),
("name", models.TextField()),
("classname", models.TextField()),
("testsuite", models.TextField()),
("computed_name", models.TextField()),
("cwf", models.IntegerField()),
("avg_duration_seconds", models.FloatField()),
("last_duration_seconds", models.FloatField()),
("pass_count", models.IntegerField()),
("fail_count", models.IntegerField()),
("skip_count", models.IntegerField()),
("flaky_fail_count", models.IntegerField()),
("updated_at", models.DateTimeField()),
(
"flags",
django.contrib.postgres.fields.ArrayField(
base_field=models.TextField(), null=True, size=None
),
),
],
options={
"db_table": "timeseries_testrun_summary_1day",
"managed": False,
},
bases=(
django_prometheus.models.ExportModelOperationsMixin(
"timeseries.testrun_continuous_aggregate"
),
models.Model,
),
),
]
92 changes: 92 additions & 0 deletions shared/django_apps/timeseries/models.py
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
from enum import Enum

import django.db.models as models
from django.contrib.postgres.fields import ArrayField
from django.utils import timezone
from django_prometheus.models import ExportModelOperationsMixin

@@ -184,3 +185,94 @@ def is_backfilled(self) -> bool:
if not self.created_at:
return False
return datetime.now() > self.created_at + timedelta(hours=1)


class Testrun(ExportModelOperationsMixin("timeseries.testrun"), models.Model):
timestamp = models.DateTimeField(null=False, primary_key=True)

test_id = models.BinaryField(null=False)
flags_hash = models.BinaryField(null=True)

name = models.TextField(null=True)
classname = models.TextField(null=True)
testsuite = models.TextField(null=True)
computed_name = models.TextField(null=True)

outcome = models.TextField(null=False)

duration_seconds = models.FloatField(null=True)
failure_message = models.TextField(null=True)
framework = models.TextField(null=True)
filename = models.TextField(null=True)

repo_id = models.BigIntegerField(null=True)
commit_sha = models.TextField(null=True)
branch = models.TextField(null=True)

flags = ArrayField(models.TextField(), null=True)
upload_id = models.BigIntegerField(null=True)

class Meta:
app_label = TIMESERIES_APP_LABEL
indexes = [
models.Index(
fields=["repo_id", "test_id", "flags_hash"],
),
]
constraints = [
models.UniqueConstraint(
fields=["repo_id", "test_id", "flags_hash"],
name="flags_hash_test_id_unique",
),
]


class TestrunBranchSummary(
ExportModelOperationsMixin("timeseries.testrun_continuous_aggregate"), models.Model
):
timestamp_bin = models.DateTimeField(primary_key=True)
repo_id = models.IntegerField()
branch = models.TextField()
name = models.TextField()
classname = models.TextField()
testsuite = models.TextField()
computed_name = models.TextField()
cwf = models.IntegerField()
avg_duration_seconds = models.FloatField()
last_duration_seconds = models.FloatField()
pass_count = models.IntegerField()
fail_count = models.IntegerField()
skip_count = models.IntegerField()
flaky_fail_count = models.IntegerField()
updated_at = models.DateTimeField()
flags = ArrayField(models.TextField(), null=True)

class Meta:
app_label = TIMESERIES_APP_LABEL
db_table = "timeseries_testrun_branch_summary_1day"
managed = False


class TestrunSummary(
ExportModelOperationsMixin("timeseries.testrun_continuous_aggregate"), models.Model
):
timestamp_bin = models.DateTimeField(primary_key=True)
repo_id = models.IntegerField()
name = models.TextField()
classname = models.TextField()
testsuite = models.TextField()
computed_name = models.TextField()
cwf = models.IntegerField()
avg_duration_seconds = models.FloatField()
last_duration_seconds = models.FloatField()
pass_count = models.IntegerField()
fail_count = models.IntegerField()
skip_count = models.IntegerField()
flaky_fail_count = models.IntegerField()
updated_at = models.DateTimeField()
flags = ArrayField(models.TextField(), null=True)

class Meta:
app_label = TIMESERIES_APP_LABEL
db_table = "timeseries_testrun_summary_1day"
managed = False

0 comments on commit 0d177e8

Please sign in to comment.