From 6b627c03e6619281498166d549036dd237e23b50 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Nov 02 2018 08:11:12 +0000 Subject: Add Event.dry_run and Event.requester fields to database. The `dry_run` field is needed to have better way to distinguish between real events and dry_run mode events. The `requester` field is needed for Botas to not create advisories for builds requested by release-driver. It is also useful to see who requester the manaual rebuild generally. --- diff --git a/freshmaker/migrations/versions/8eeddff9a4f3_add_dry_run_and_requester.py b/freshmaker/migrations/versions/8eeddff9a4f3_add_dry_run_and_requester.py new file mode 100644 index 0000000..9f371f2 --- /dev/null +++ b/freshmaker/migrations/versions/8eeddff9a4f3_add_dry_run_and_requester.py @@ -0,0 +1,24 @@ +"""Add dry_run and requester to events table. + +Revision ID: 8eeddff9a4f3 +Revises: 807ea37dcf0e +Create Date: 2018-11-02 09:07:26.898276 + +""" + +# revision identifiers, used by Alembic. +revision = '8eeddff9a4f3' +down_revision = '807ea37dcf0e' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + op.add_column('events', sa.Column('dry_run', sa.Boolean(), nullable=True)) + op.add_column('events', sa.Column('requester', sa.String(), nullable=True)) + + +def downgrade(): + op.drop_column('events', 'requester') + op.drop_column('events', 'dry_run') diff --git a/freshmaker/models.py b/freshmaker/models.py index 419dbcc..eeefe3e 100644 --- a/freshmaker/models.py +++ b/freshmaker/models.py @@ -147,6 +147,10 @@ class Event(FreshmakerBase): time_created = db.Column(db.DateTime, nullable=True) # List of builds associated with this Event. builds = relationship("ArtifactBuild", back_populates="event") + # True if the even should be handled in dry run mode. + dry_run = db.Column(db.Boolean, default=False) + # For manual rebuilds, set to user requesting the rebuild. Otherwise null. + requester = db.Column(db.String, nullable=True) manual_triggered = db.Column( db.Boolean, @@ -155,7 +159,7 @@ class Event(FreshmakerBase): @classmethod def create(cls, session, message_id, search_key, event_type, released=True, - state=None, manual=False): + state=None, manual=False, dry_run=False, requester=None): if event_type in EVENT_TYPES: event_type = EVENT_TYPES[event_type] now = datetime.utcnow() @@ -167,6 +171,8 @@ class Event(FreshmakerBase): state=state or EventState.INITIALIZED.value, time_created=now, manual_triggered=manual, + dry_run=dry_run, + requester=requester, ) session.add(event) return event @@ -187,18 +193,19 @@ class Event(FreshmakerBase): @classmethod def get_or_create(cls, session, message_id, search_key, event_type, - released=True, manual=False): + released=True, manual=False, dry_run=False): instance = cls.get(session, message_id) if instance: return instance return cls.create(session, message_id, search_key, event_type, - released=released, manual=manual) + released=released, manual=manual, dry_run=dry_run) @classmethod def get_or_create_from_event(cls, session, event, released=True): return cls.get_or_create(session, event.msg_id, event.search_key, event.__class__, - released=released, manual=event.manual) + released=released, manual=event.manual, + dry_run=event.dry_run) @classmethod def get_unreleased(cls, session, states=None): @@ -329,6 +336,8 @@ class Event(FreshmakerBase): "state_name": EventState(self.state).name, "state_reason": self.state_reason, "url": event_url, + "dry_run": self.dry_run, + "requester": self.requester, "builds": [b.json() for b in self.builds], } diff --git a/freshmaker/views.py b/freshmaker/views.py index 7721ec8..35759c2 100644 --- a/freshmaker/views.py +++ b/freshmaker/views.py @@ -24,6 +24,7 @@ import six from flask import request, jsonify from flask.views import MethodView +from flask import g from freshmaker import app from freshmaker import messaging @@ -262,6 +263,7 @@ class BuildAPI(MethodView): # to client sending this POST request. The client can then use the ID # to check for the event status. db_event = models.Event.get_or_create_from_event(db.session, event) + db_event.requester = g.user.username db.session.commit() # Forward the POST data (including the msg_id of the database event we diff --git a/tests/test_views.py b/tests/test_views.py index 24a73e5..43d2275 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -479,11 +479,33 @@ class TestManualTriggerRebuild(helpers.ModelsTestCase): u'state': 0, u'state_name': u'INITIALIZED', u'state_reason': None, - u'url': u'/api/1/events/1'}) + u'url': u'/api/1/events/1', + u'dry_run': False, + u'requester': 'tester1'}) publish.assert_called_once_with( 'manual.rebuild', {'msg_id': 'manual_rebuild_123', u'errata_id': 1}) + @patch('freshmaker.messaging.publish') + @patch('freshmaker.parsers.internal.manual_rebuild.ErrataAdvisory.' + 'from_advisory_id') + @patch('freshmaker.parsers.internal.manual_rebuild.time.time') + def test_manual_rebuild_dry_run(self, time, from_advisory_id, publish): + 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, 'dry_run': True}), + content_type='application/json') + data = json.loads(resp.get_data(as_text=True)) + + # Other fields are predictible. + self.assertEqual(data['dry_run'], True) + publish.assert_called_once_with( + 'manual.rebuild', + {'msg_id': 'manual_rebuild_123', u'errata_id': 1, 'dry_run': True}) + @patch('freshmaker.parsers.internal.manual_rebuild.ErrataAdvisory.' 'from_advisory_id') def test_not_rebuild_nonrpm_advisory(self, from_advisory_id):