Skip to content

Commit

Permalink
Publish UpdateReadyForTesting whenever an update is created
Browse files Browse the repository at this point in the history
See https://pagure.io/fedora-ci/general/issue/436 . This is the
behaviour test systems want, based on real-world experience.
We do not want test systems to wait for updates to reach the
updates-testing repo before they test; we want them to test as
soon as the update is created. All the test systems that exist
pull the builds to be tested from Koji, they do not rely on them
being present in updates-testing.

Waiting for the update to reach updates-testing before tests run
can mean a wait of up to 24 hours, which is obviously not ideal
when people want test results fast. It also means we can't gate
push to updates-testing on tests that trigger on this message.

openQA currently listens out for other messages to use as a
proxy for 'update was created' in order to mitigate this problem,
but Fedora CI does not do so, and consequently its tests often
trigger late. This change, along with the earlier change to
publish this message when an update's builds are changed, will
allow us to simplify openQA's logic considerably (it can just
trigger any time it sees this message) and improve CI's
scheduling considerably without any need to make changes to the
trigger logic on the CI side.

Signed-off-by: Adam Williamson <awilliam@redhat.com>
(cherry picked from commit d3765ed)
  • Loading branch information
AdamWill authored and mergify[bot] committed Dec 3, 2023
1 parent 5f7f63e commit 65bb0a7
Show file tree
Hide file tree
Showing 10 changed files with 337 additions and 235 deletions.
9 changes: 9 additions & 0 deletions bodhi-messages/bodhi/messages/schemas/update.py
Original file line number Diff line number Diff line change
Expand Up @@ -1034,6 +1034,15 @@ class UpdateReadyForTestingV3(UpdateMessage):
"""
Sent when an update is ready to be tested. Simplified version.
Specifically, this message is sent:
* When an update is created
* When an update is edited and its builds change
* When a "re-trigger tests" request is made via the web UI or API
These are the points where we expect that automated systems will
test the update.
Inherits from UpdateMessage and only contains as much extra
information (in the 'artifact' dict) as the Fedora CI schedulers
actually need.
Expand Down
4 changes: 3 additions & 1 deletion bodhi-server/bodhi/server/buildsys.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,9 @@ def getBuild(self, build='TurboGears-1.0.2.2-2.fc17', other=False, testing=False
'package_name': 'gnome-backgrounds',
'release': '1.fc17',
'tag_name': 'f17-build-side-7777',
'version': '3.0'}
'version': '3.0',
'id': 16061,
'task_id': 15051}

theid = 16058
if other and not testing:
Expand Down
41 changes: 15 additions & 26 deletions bodhi-server/bodhi/server/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2009,13 +2009,14 @@ def __init__(self, *args, **kwargs):
alias = '%s-%s-%s' % (prefix, year, id)
self.alias = alias
self.release_id = kwargs['release'].id
# we need this to be set for message publishing to work
self.status = kwargs.get('status', UpdateStatus.pending)

super(Update, self).__init__(*args, **kwargs)

log.debug('Set alias for %s to %s' % (self.get_title(), alias))

if self.status == UpdateStatus.testing:
self._ready_for_testing(self, self.status, None, None)
self._ready_for_testing(self, None)

@property
def version_hash(self):
Expand Down Expand Up @@ -4215,10 +4216,10 @@ def _build_group_test_message(self, agent="bodhi", retrigger=False):
"""
Build the dictionary sent when an update is ready to be tested.
This is used in bodhi.server.models.Update._ready_for_testing and in
bodhi.server.services.updates.trigger_tests which are the two places
where we send notifications about an update being ready to be tested
by any CI system.
This is used when we send notifications about an update being
ready to be tested by any CI system - on update creation, any
time the update is edited and its builds change, and if someone
sends a Re-Trigger Tests request via the web UI or API.
Args:
agent (str): For the case where the message is sent as a test
Expand Down Expand Up @@ -4250,23 +4251,19 @@ def _build_group_test_message(self, agent="bodhi", retrigger=False):
}

@staticmethod
def _ready_for_testing(target, value, old, initiator):
def _ready_for_testing(target, old):
"""
Signal that the update has been moved to testing.
Signal that the update is ready for testing.
This happens in the following cases:
- for stable releases: the update lands in the testing repository
- for rawhide: all packages in an update have been built by koji
This happens when the update is created. The same message is
also published when the update is edited and its builds change
and when a "re-trigger tests" request is sent, but not by this
method.
Args:
target (Update): The update that has had a change to its status attribute.
value (EnumSymbol): The new value of Update.status.
old (EnumSymbol): The old value of the Update.status
initiator (sqlalchemy.orm.attributes.Event): The event object that is initiating this
transition.
target (Update): The update that has been created.
old (EnumSymbol): The old value of the Update.status.
"""
if value != UpdateStatus.testing or value == old:
return
if old == NEVER_SET:
# This is the object initialization phase. This instance is not ready, don't create
# the message now. This method will be called again at the end of __init__
Expand All @@ -4289,14 +4286,6 @@ def _ready_for_testing(target, value, old, initiator):
)


event.listen(
Update.status,
'set',
Update._ready_for_testing,
active_history=True,
)


class Compose(Base):
"""
Express the status of an in-progress compose job.
Expand Down
17 changes: 10 additions & 7 deletions bodhi-server/tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,12 @@ def create_update(session, build_nvrs, release_name='F17'):
expiration_date=expiration_date)
session.add(override)

update = models.Update(
builds=builds, user=user, request=models.UpdateRequest.testing,
notes='Useful details!', type=models.UpdateType.bugfix,
date_submitted=datetime(1984, 11, 2),
requirements='rpmlint', stable_karma=3, unstable_karma=-3, release=release)
with mock.patch('bodhi.server.models.notifications'):
update = models.Update(
builds=builds, user=user, request=models.UpdateRequest.testing,
notes='Useful details!', type=models.UpdateType.bugfix,
date_submitted=datetime(1984, 11, 2),
requirements='rpmlint', stable_karma=3, unstable_karma=-3, release=release)
session.add(update)
return update

Expand Down Expand Up @@ -185,7 +186,8 @@ def populate(db):
db.flush()
# This mock will help us generate a consistent update alias.
with mock.patch(target='uuid.uuid4', return_value='wat'):
update = create_update(db, ['bodhi-2.0-1.fc17'])
with mock.patch('bodhi.server.models.notifications'):
update = create_update(db, ['bodhi-2.0-1.fc17'])
update.type = models.UpdateType.bugfix
update.severity = models.UpdateSeverity.medium
bug = models.Bug(bug_id=12345)
Expand Down Expand Up @@ -247,11 +249,12 @@ def _setup_method(self):
self.db = Session()
self.db.begin_nested()

buildsys.setup_buildsystem({'buildsystem': 'dev'})

if self._populate_db:
populate(self.db)

bugs.set_bugtracker()
buildsys.setup_buildsystem({'buildsystem': 'dev'})

self._request_sesh = mock.patch('bodhi.server.webapp._complete_database_session',
webapp._rollback_or_commit)
Expand Down
1 change: 1 addition & 0 deletions bodhi-server/tests/consumers/test_automatic_updates.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@


@mock.patch('bodhi.server.consumers.automatic_updates.work_on_bugs_task', mock.Mock())
@mock.patch('bodhi.server.models.notifications', mock.Mock())
class TestAutomaticUpdateHandler(base.BasePyTestCase):
"""Test the automatic update handler."""

Expand Down
6 changes: 2 additions & 4 deletions bodhi-server/tests/consumers/test_signed.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,8 +232,7 @@ def test_consume_from_tag_not_signed(self, mock_build_model):
def test_consume_from_tag(self):
"""
Assert that update created from tag is handled correctly when message
is received.
Update status is changed to testing and corresponding message is sent.
is received: update status is changed to testing.
"""
self.handler.db_factory = base.TransactionalSessionMaker(self.Session)
update = self.db.query(Update).join(Build).filter(Build.nvr == 'bodhi-2.0-1.fc17').one()
Expand Down Expand Up @@ -265,8 +264,7 @@ def test_consume_from_tag(self):
'unsatisfied_requirements': []
}
mock_greenwave.return_value = greenwave_response
with fml_testing.mock_sends(update_schemas.UpdateReadyForTestingV3):
self.handler(self.sample_side_tag_message)
self.handler(self.sample_side_tag_message)

assert update.builds[0].signed is True
assert update.builds[0].update.request is None
Expand Down
Loading

0 comments on commit 65bb0a7

Please sign in to comment.