diff --git a/bodhi/server/models/models.py b/bodhi/server/models/models.py index 806c362f51..3a4f0256cd 100644 --- a/bodhi/server/models/models.py +++ b/bodhi/server/models/models.py @@ -1400,6 +1400,18 @@ def get_pushed_color(self): color = '#00ff00' # green return color + def obsolete_if_unstable(self, db): + """ + If an update with pending status(autopush enabled) reaches unstable karma + threshold, make sure it gets obsoleted. + """ + if self.autokarma and self.status is UpdateStatus.pending and self.request is UpdateRequest.testing \ + and self.unstable_karma not in (0, None) and self.karma <= self.unstable_karma: + log.info("%s has reached unstable karma thresholds" % self.title) + self.obsolete(db) + flash_log("%s has been obsoleted." % self.title) + return + def comment(self, session, text, karma=0, author=None, anonymous=False, karma_critpath=0, bug_feedback=None, testcase_feedback=None, check_karma=True): @@ -1465,6 +1477,9 @@ def comment(self, session, text, karma=0, author=None, anonymous=False, caveats.append({ 'name': 'karma', 'description': str(e), }) + + # Obsolete pending update if it reaches unstable karma threshold + self.obsolete_if_unstable(session) else: log.debug('Ignoring duplicate %d karma from %s on %s' % (karma, author, self.title)) diff --git a/bodhi/tests/server/functional/test_updates.py b/bodhi/tests/server/functional/test_updates.py index c51410e2d6..2aee226605 100644 --- a/bodhi/tests/server/functional/test_updates.py +++ b/bodhi/tests/server/functional/test_updates.py @@ -1956,6 +1956,108 @@ def test_revoke_action_for_testing_request(self, publish, *args): publish.assert_called_with( topic='update.request.revoke', msg=mock.ANY) + @mock.patch(**mock_valid_requirements) + @mock.patch('bodhi.server.notifications.publish') + def test_obsolete_if_unstable_with_autopush_enabled_when_pending(self, publish, *args): + """ + Send update to obsolete state if it reaches unstable karma on + pending state where request is testing when Autopush is enabled. Make sure that it + does not go to update-testing state. + """ + nvr = u'bodhi-2.0.0-2.fc17' + args = self.get_update(nvr) + args['autokarma'] = True + args['stable_karma'] = 1 + args['unstable_karma'] = -1 + + resp = self.app.post_json('/updates/', args) + up = Update.get(nvr, self.db) + up.status = UpdateStatus.pending + up.request = UpdateRequest.testing + up.comment(self.db, u'Failed to work', author=u'ralph', karma=-1) + self.db.flush() + + up = self.db.query(Update).filter_by(title=nvr).one() + self.assertEquals(up.karma, -1) + self.assertEquals(up.status, UpdateStatus.obsolete) + self.assertEquals(up.request, None) + + @mock.patch(**mock_valid_requirements) + @mock.patch('bodhi.server.notifications.publish') + def test_obsolete_if_unstable_with_autopush_disabled_when_pending(self, publish, *args): + """ + Don't automatically send update to obsolete state if it reaches unstable karma on + pending state when Autopush is disabled. + """ + nvr = u'bodhi-2.0.0-2.fc17' + args = self.get_update(nvr) + args['autokarma'] = False + args['stable_karma'] = 1 + args['unstable_karma'] = -1 + + resp = self.app.post_json('/updates/', args) + up = Update.get(nvr, self.db) + up.status = UpdateStatus.pending + up.request = UpdateRequest.testing + up.comment(self.db, u'Failed to work', author=u'ralph', karma=-1) + self.db.flush() + + up = self.db.query(Update).filter_by(title=nvr).one() + self.assertEquals(up.karma, -1) + self.assertEquals(up.status, UpdateStatus.pending) + self.assertEquals(up.request, UpdateRequest.testing) + + @mock.patch(**mock_valid_requirements) + @mock.patch('bodhi.server.notifications.publish') + def test_obsolete_if_unstable_karma_not_reached_with_autopush_enabled_when_pending(self, publish, *args): + """ + Don't send update to obsolete state if it does not reach unstable karma threshold + on pending state when Autopush is enabled. + """ + nvr = u'bodhi-2.0.0-2.fc17' + args = self.get_update(nvr) + args['autokarma'] = True + args['stable_karma'] = 2 + args['unstable_karma'] = -2 + + resp = self.app.post_json('/updates/', args) + up = Update.get(nvr, self.db) + up.status = UpdateStatus.pending + up.request = UpdateRequest.testing + up.comment(self.db, u'Failed to work', author=u'ralph', karma=-1) + self.db.flush() + + up = self.db.query(Update).filter_by(title=nvr).one() + self.assertEquals(up.karma, -1) + self.assertEquals(up.status, UpdateStatus.pending) + self.assertEquals(up.request, UpdateRequest.testing) + + @mock.patch(**mock_valid_requirements) + @mock.patch('bodhi.server.notifications.publish') + def test_obsolete_if_unstable_with_autopush_enabled_when_testing(self, publish, *args): + """ + Send update to obsolete state if it reaches unstable karma threshold on + testing state where request is stable when Autopush is enabled. Make sure that it + does not go to stable state. + """ + nvr = u'bodhi-2.0.0-2.fc17' + args = self.get_update(nvr) + args['autokarma'] = True + args['stable_karma'] = 1 + args['unstable_karma'] = -1 + + resp = self.app.post_json('/updates/', args) + up = Update.get(nvr, self.db) + up.status = UpdateStatus.testing + up.request = UpdateRequest.stable + up.comment(self.db, u'Failed to work', author=u'ralph', karma=-1) + self.db.flush() + + up = self.db.query(Update).filter_by(title=nvr).one() + self.assertEquals(up.karma, -1) + self.assertEquals(up.status, UpdateStatus.obsolete) + self.assertEquals(up.request, None) + @mock.patch(**mock_taskotron_results) @mock.patch(**mock_valid_requirements) @mock.patch('bodhi.server.notifications.publish')