MT#55988 buildinfo: fix duration field

> [2022-12-16 06:07:01,563: ERROR/ForkPoolWorker-3] Task buildinfo.tasks.parse_buildinfo[bdf0ea9f-5b13-4d08-b23b-aa2ff3a61c40] raised unexpected: DataError('smallint out of range\n')

* define datetime field instead of timestamp, that would be filled
  with the processed value of timestamp

Change-Id: Id6c9dac31b5ad9e32890e399c16ff6d9bad06746
pull/9/head
Victor Seva 2 years ago
parent 73c4e2d3c2
commit a6b7a49f36

@ -0,0 +1,18 @@
# Generated by Django 3.2.15 on 2022-12-16 13:56
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("buildinfo", "0002_ldap_grp_perms"),
]
operations = [
migrations.AlterField(
model_name="buildinfo",
name="duration",
field=models.PositiveIntegerField(),
),
]

@ -0,0 +1,30 @@
# Generated by Django 3.2.15 on 2022-12-16 14:39
import django.utils.timezone
from django.db import migrations
from django.db import models
from buildinfo.utils import get_datetime
def migrate_timestamps(apps, schema_editor):
BuildInfo = apps.get_model("buildinfo", "BuildInfo")
for info in BuildInfo.objects.all():
info.datetime = get_datetime(info.timestamp)
class Migration(migrations.Migration):
dependencies = [
("buildinfo", "0003_duration_fix"),
]
operations = [
migrations.AddField(
model_name="buildinfo",
name="datetime",
field=models.DateTimeField(default=django.utils.timezone.now),
preserve_default=False,
),
migrations.RunPython(migrate_timestamps),
migrations.RemoveField(model_name="buildinfo", name="timestamp"),
]

@ -12,13 +12,27 @@
# #
# You should have received a copy of the GNU General Public License along # You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>. # with this program. If not, see <http://www.gnu.org/licenses/>.
from typing import Any
from django.db import models from django.db import models
from .utils import datetime
from .utils import get_datetime
class BuildInfoManager(models.Manager):
def create(self, **kwargs: Any) -> Any:
if "datetime" in kwargs:
val = kwargs.get("datetime")
if not isinstance(val, datetime):
kwargs["datetime"] = get_datetime(val)
return super().create(**kwargs)
class BuildInfo(models.Model): class BuildInfo(models.Model):
builton = models.CharField(max_length=50, null=False) builton = models.CharField(max_length=50, null=False)
timestamp = models.PositiveBigIntegerField(null=False) datetime = models.DateTimeField(null=False)
duration = models.PositiveSmallIntegerField(null=False) duration = models.PositiveIntegerField(null=False)
projectname = models.CharField(max_length=100, null=False) projectname = models.CharField(max_length=100, null=False)
buildnumber = models.IntegerField() buildnumber = models.IntegerField()
@ -29,6 +43,7 @@ class BuildInfo(models.Model):
param_release_uuid = models.CharField(max_length=64, null=True, blank=True) param_release_uuid = models.CharField(max_length=64, null=True, blank=True)
param_distribution = models.CharField(max_length=50, null=True, blank=True) param_distribution = models.CharField(max_length=50, null=True, blank=True)
param_ppa = models.CharField(max_length=50, null=True, blank=True) param_ppa = models.CharField(max_length=50, null=True, blank=True)
objects = BuildInfoManager()
def __str__(self): def __str__(self):
return ( return (

@ -28,7 +28,7 @@ class TestBuildInfo(BaseTest):
"param_distribution": "wheezy", "param_distribution": "wheezy",
"param_ppa": "gerrit_MT10339_review2054", "param_ppa": "gerrit_MT10339_review2054",
"builton": "fake-slave-1", "builton": "fake-slave-1",
"timestamp": 0, "datetime": 1668083617940,
"duration": 0, "duration": 0,
} }
return defaults return defaults

@ -12,9 +12,12 @@
# #
# You should have received a copy of the GNU General Public License along # You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>. # with this program. If not, see <http://www.gnu.org/licenses/>.
from datetime import datetime
from unittest.mock import mock_open from unittest.mock import mock_open
from unittest.mock import patch from unittest.mock import patch
from django.utils import timezone
from buildinfo import models from buildinfo import models
from buildinfo import utils from buildinfo import utils
from repoapi.models import JenkinsBuildInfo from repoapi.models import JenkinsBuildInfo
@ -45,6 +48,17 @@ build_info = """{
class TestBuildInfo(BaseTest): class TestBuildInfo(BaseTest):
dt = datetime(
2022,
11,
10,
12,
33,
37,
940000,
tzinfo=timezone.get_current_timezone(),
)
def get_defaults(self, info=False): def get_defaults(self, info=False):
defaults = { defaults = {
"projectname": "fake", "projectname": "fake",
@ -66,7 +80,7 @@ class TestBuildInfo(BaseTest):
defaults.update( defaults.update(
{ {
"builton": "fake-slave-1", "builton": "fake-slave-1",
"timestamp": 0, "datetime": 1668083617940,
"duration": 0, "duration": 0,
} }
) )
@ -74,6 +88,9 @@ class TestBuildInfo(BaseTest):
defaults.update(jbi_defaults) defaults.update(jbi_defaults)
return defaults return defaults
def test_get_datetime(self):
self.assertEqual(utils.get_datetime(1668083617940), self.dt)
@patch("builtins.open", mock_open(read_data=build_info)) @patch("builtins.open", mock_open(read_data=build_info))
@patch("repoapi.utils.dlfile") @patch("repoapi.utils.dlfile")
def test_process_buildinfo(self, dlfile): def test_process_buildinfo(self, dlfile):
@ -84,3 +101,4 @@ class TestBuildInfo(BaseTest):
utils.process_buildinfo(jbi.pk, "/tmp/fake.txt") utils.process_buildinfo(jbi.pk, "/tmp/fake.txt")
qs = models.BuildInfo.objects.filter(builton="jenkins-slave13") qs = models.BuildInfo.objects.filter(builton="jenkins-slave13")
self.assertEqual(qs.count(), 1) self.assertEqual(qs.count(), 1)
self.assertEqual(qs.first().datetime, self.dt)

@ -13,23 +13,30 @@
# You should have received a copy of the GNU General Public License along # You should have received a copy of the GNU General Public License along
# with this program. If not, see <http://www.gnu.org/licenses/>. # with this program. If not, see <http://www.gnu.org/licenses/>.
import json import json
from datetime import datetime
import structlog import structlog
from django.apps import apps from django.apps import apps
from django.utils import timezone
from .models import BuildInfo
logger = structlog.get_logger(__name__) logger = structlog.get_logger(__name__)
def get_datetime(timestamp: float) -> datetime:
return datetime.fromtimestamp(
timestamp / 1000, tz=timezone.get_current_timezone()
)
def process_buildinfo(jbi_id: int, path: str): def process_buildinfo(jbi_id: int, path: str):
JenkinsBuildInfo = apps.get_model("repoapi", "JenkinsBuildInfo") JenkinsBuildInfo = apps.get_model("repoapi", "JenkinsBuildInfo")
jbi = JenkinsBuildInfo.objects.get(pk=jbi_id) jbi = JenkinsBuildInfo.objects.get(pk=jbi_id)
BuildInfo = apps.get_model("buildinfo", "BuildInfo")
with open(path, "r") as file: with open(path, "r") as file:
info = json.load(file) info = json.load(file)
BuildInfo.objects.create( BuildInfo.objects.create(
builton=info["builtOn"], builton=info["builtOn"],
timestamp=info["timestamp"], datetime=info["timestamp"],
duration=info["duration"], duration=info["duration"],
projectname=jbi.projectname, projectname=jbi.projectname,
jobname=jbi.jobname, jobname=jbi.jobname,

Loading…
Cancel
Save