#385 Include Freshmaker event start and completion times in the REST API
Merged 4 years ago by jkaluza. Opened 4 years ago by srieger.
srieger/freshmaker master  into  master

@@ -0,0 +1,21 @@ 

+ """Add time done for Freshmaker events

+ 

+ Revision ID: 2358b6f55f24

+ Revises: fbc2eac9bfa5

+ Create Date: 2019-06-20 10:00:31.190304

+ 

+ """

+ 

+ revision = '2358b6f55f24'

+ down_revision = 'fbc2eac9bfa5'

+ 

+ from alembic import op

+ import sqlalchemy as sa

+ 

+ 

+ def upgrade():

+     op.add_column('events', sa.Column('time_done', sa.DateTime(), nullable=True))

+ 

+ 

+ def downgrade():

+     op.drop_column('events', 'time_done')

file modified
+8 -1
@@ -146,6 +146,7 @@ 

      state = db.Column(db.Integer, nullable=False)

      state_reason = db.Column(db.String, nullable=True)

      time_created = db.Column(db.DateTime, nullable=True)

+     time_done = db.Column(db.DateTime, nullable=True)

      # AppenderQuery for getting builds associated with this Event.

      builds = relationship("ArtifactBuild", back_populates="event",

                            lazy="dynamic", cascade="all, delete-orphan",
@@ -311,13 +312,17 @@ 

  

      def transition(self, state, state_reason=None):

          """

-         Sets the state and state_reason of this Event.

+         Sets the time_done, state, and state_reason of this Event.

  

          :param state: EventState value

          :param state_reason: Reason why this state has been set.

          :return: True/False, whether state was changed

          """

  

+         # Log the time done

+         if state == EventState.FAILED.value or state == EventState.COMPLETE.value:

+             self.time_done = datetime.utcnow()

+ 

          # Log the state and state_reason

          if state == EventState.FAILED.value:

              log_fnc = log.error
@@ -384,6 +389,8 @@ 

              "state": self.state,

              "state_name": EventState(self.state).name,

              "state_reason": self.state_reason,

+             "time_created": _utc_datetime_to_iso(self.time_created),

+             "time_done": _utc_datetime_to_iso(self.time_done),

              "url": event_url,

              "dry_run": self.dry_run,

              "requester": self.requester,

file modified
+9 -1
@@ -20,6 +20,9 @@ 

  #

  # Written by Jan Kaluza <jkaluza@redhat.com>

  

+ import datetime

+ from mock import patch

+ 

  from freshmaker import db, events

  from freshmaker.models import ArtifactBuild, ArtifactType

  from freshmaker.models import Event, EventState, EVENT_TYPES, EventDependency
@@ -170,7 +173,10 @@ 

              str(event), "<UnknownEventType 1024, search_key=test>")

  

      def test_event_json_min(self):

-         event = Event.create(db.session, "test_msg_id5", "RHSA-2017-289", events.TestingEvent)

+         with patch('freshmaker.models.datetime') as datetime_patch:

+             datetime_patch.utcnow.return_value = datetime.datetime(2017, 8, 21, 13, 42, 20)

+             event = Event.create(db.session, "test_msg_id5", "RHSA-2017-289", events.TestingEvent)

+ 

          build = ArtifactBuild.create(db.session, event, "ed", "module", 1234)

          build.state = ArtifactBuildState.FAILED

          ArtifactBuild.create(db.session, event, "mksh", "module", 1235, build)
@@ -186,6 +192,8 @@ 

              'state': 0,

              'state_name': 'INITIALIZED',

              'state_reason': None,

+             'time_created': '2017-08-21T13:42:20Z',

+             'time_done': None,

              'url': 'http://localhost:5001/api/1/events/1',

              'requested_rebuilds': [],

              'requester_metadata': {},

file modified
+21 -7
@@ -21,6 +21,7 @@ 

  

  import unittest

  import json

+ import datetime

  import six

  import contextlib

  import flask
@@ -321,6 +322,15 @@ 

          evs = json.loads(resp.get_data(as_text=True))['items']

          self.assertEqual(len(evs), 2)

  

+     def test_query_event_complete(self):

+         event = db.session.query(models.Event).get(1)

+         with patch('freshmaker.models.datetime') as datetime_patch:

+             datetime_patch.utcnow.return_value = datetime.datetime(2099, 8, 21, 13, 42, 20)

+             event.transition(models.EventState.COMPLETE.value)

+         resp = self.client.get('/api/1/events/1')

+         data = json.loads(resp.get_data(as_text=True))

+         self.assertEqual(data['time_done'], '2099-08-21T13:42:20Z')

+ 

      def test_query_event_by_message_id(self):

          resp = self.client.get('/api/1/events/?message_id=2017-00000000-0000-0000-0000-000000000001')

          evs = json.loads(resp.get_data(as_text=True))['items']
@@ -451,10 +461,11 @@ 

          self.assertEqual(data['message'], 'No such build state found.')

  

      def test_about_api(self):

-         resp = self.client.get('/api/1/about/')

+         # Since the version is always changing, let's just mock it to be consistent

+         with patch('freshmaker.views.version', '1.0.0'):

+             resp = self.client.get('/api/1/about/')

          data = json.loads(resp.get_data(as_text=True))

-         # version is 'unknown' in case of skip_install=True in tox.ini

-         self.assertEqual(data['version'], 'unknown')

+         self.assertEqual(data['version'], '1.0.0')

  

      @patch("freshmaker.views.ImageVerifier")

      def test_verify_image(self, verifier):
@@ -531,10 +542,11 @@ 

          time.return_value = 123

          from_advisory_id.return_value = ErrataAdvisory(

              123, 'name', 'REL_PREP', ['rpm'])

- 

-         resp = self.client.post('/api/1/builds/',

-                                 data=json.dumps({'errata_id': 1}),

-                                 content_type='application/json')

+         with patch('freshmaker.models.datetime') as datetime_patch:

+             datetime_patch.utcnow.return_value = datetime.datetime(2017, 8, 21, 13, 42, 20)

+             resp = self.client.post('/api/1/builds/',

+                                     data=json.dumps({'errata_id': 1}),

+                                     content_type='application/json')

          data = json.loads(resp.get_data(as_text=True))

  

          # Other fields are predictible.
@@ -547,6 +559,8 @@ 

              u'state': 0,

              u'state_name': u'INITIALIZED',

              u'state_reason': None,

+             u'time_created': u'2017-08-21T13:42:20Z',

+             u'time_done': None,

              u'url': u'/api/1/events/1',

              u'dry_run': False,

              u'requester': 'tester1',

no initial comment

rebased onto 69a8ed7870664fb827533c398b466e82461e2ffe

4 years ago

Once you have all the changes to models.py done, you also need to run ./manager createdb. This will generate new file in the ./freshmaker/migrations/versions to introduce the changes you did in models.py in the database during ODCS upgrade.

rebased onto f0041d6749c8c425f815ebd599610ad334e45b16

4 years ago

rebased onto d77b754370ce1a9df060c1770c27225420b4e7e3

4 years ago

rebased onto 7286347807e8e432cecb4548a5b0c5e0456ec9e9

4 years ago

1 new commit added

  • `Mock the version returned intest_about_api```
4 years ago

Please remove these comments. They are generated automatically just to remind you to verify what Alembic generated. We remove them in our projects usually :).

@srieger: Good job here ;). I have only one minor change request. Once this is done, we can merge it :).

1 new commit added

  • fixup! Include Freshmaker event start and completion times in the REST API
4 years ago

rebased onto ed18262

4 years ago

Pull-Request has been merged by jkaluza

4 years ago