Exemple #1
0
    def test_gating_required_false(self):
        """Assert that test_gating_status is not updated if test_gating is not enabled."""
        update = models.Update.query.filter_by(title=u'bodhi-2.0-1.fc17').one()
        update.test_gating_status = None
        hub = mock.MagicMock()
        hub.config = {'environment': 'environment',
                      'topic_prefix': 'topic_prefix'}
        h = updates.UpdatesHandler(hub)
        h.db_factory = base.TransactionalSessionMaker(self.Session)
        # Throw a bogus bug id in there to ensure it doesn't raise AssertionError.
        message = {
            'topic': 'bodhi.update.request.testing',
            'body': {'msg': {'update': {'alias': u'bodhi-2.0-1.fc17'},
                             'new_bugs': []}}}

        with mock.patch('bodhi.server.models.util.greenwave_api_post') as mock_greenwave:
            greenwave_response = {
                'policies_satisfied': False,
                'summary': u'what have you done‽',
                'applicable_policies': ['taskotron_release_critical_tasks'],
                'unsatisfied_requirements': ['some arbitrary test you disagree with']
            }
            mock_greenwave.return_value = greenwave_response

            h.consume(message)

        update = models.Update.query.filter_by(title=u'bodhi-2.0-1.fc17').one()
        self.assertIsNone(update.test_gating_status)
        self.assertIsNone(update.greenwave_summary_string)
Exemple #2
0
    def test_edited_update_bugs_in_update(self, work_on_bugs, fetch_test_cases):
        """
        Test with a message that indicates that the update is being edited, and the list of bugs
        matches what UpdatesHandler finds in the database.
        """
        hub = mock.MagicMock()
        hub.config = {'environment': 'environment',
                      'topic_prefix': 'topic_prefix'}
        h = updates.UpdatesHandler(hub)
        h.db_factory = base.TransactionalSessionMaker(self.Session)
        message = {
            'topic': 'bodhi.update.edit',
            'body': {'msg': {'update': {'alias': u'bodhi-2.0-1.fc17'},
                             'new_bugs': ['12345']}}}

        h.consume(message)

        self.assertEqual(work_on_bugs.call_count, 1)
        self.assertTrue(isinstance(work_on_bugs.mock_calls[0][1][1],
                                   sqlalchemy.orm.session.Session))
        self.assertEqual(work_on_bugs.mock_calls[0][1][2].title, u'bodhi-2.0-1.fc17')
        self.assertEqual([b.bug_id for b in work_on_bugs.mock_calls[0][1][3]], [12345])
        self.assertEqual(fetch_test_cases.call_count, 1)
        self.assertTrue(isinstance(fetch_test_cases.mock_calls[0][1][1],
                                   sqlalchemy.orm.session.Session))
Exemple #3
0
    def test_edited_update_bug_not_in_update(self, work_on_bugs,
                                             fetch_test_cases):
        """
        Test with a message that indicates that the update is being edited, and the list of bugs
        contains one that UpdatesHandler does not find in the database.
        """
        hub = mock.MagicMock()
        hub.config = {
            'environment': 'environment',
            'topic_prefix': 'topic_prefix'
        }
        h = updates.UpdatesHandler(hub)
        h.db_factory = base.TransactionalSessionMaker(self.Session)
        message = {
            'topic': 'bodhi.update.edit',
            'body': {
                'msg': {
                    'update': {
                        'alias': u'bodhi-2.0-1.fc17'
                    },
                    'new_bugs': ['12345', '123456']
                }
            }
        }

        self.assertRaises(AssertionError, h.consume, message)

        self.assertEqual(work_on_bugs.call_count, 0)
        self.assertEqual(fetch_test_cases.call_count, 0)
Exemple #4
0
    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.
        """
        self.handler.db_factory = base.TransactionalSessionMaker(self.Session)
        update = self.db.query(Update).filter(
            Build.nvr == 'bodhi-2.0-1.fc17').one()
        update.from_tag = "f30-side-tag"
        update.status = UpdateStatus.pending
        update.release.composed_by_bodhi = False
        update.builds[0].signed = False
        update.pushed = False

        self.db.commit()
        with mock.patch('bodhi.server.models.util.greenwave_api_post'
                        ) as mock_greenwave:
            greenwave_response = {
                'policies_satisfied': True,
                'summary': "all tests have passed"
            }
            mock_greenwave.return_value = greenwave_response
            with fml_testing.mock_sends(
                    update_schemas.UpdateReadyForTestingV1):
                self.handler(self.sample_side_tag_message)

        assert update.builds[0].signed is True
        assert update.builds[0].update.request is None
        assert update.status == UpdateStatus.testing
        assert update.pushed is True
        assert update.test_gating_status == TestGatingStatus.passed
Exemple #5
0
    def test_resume_empty_compose(self, publish):
        """
        Test correct operation when the --resume flag is given but one of the Composes has no
        updates.
        """
        cli = CliRunner()
        # Let's mark ejabberd as locked and already in a push. Since we are resuming and since we
        # will decline pushing the first time we are asked, it should be the only package that gets
        # included.
        ejabberd = self.create_update([u'ejabberd-16.09-4.fc17'])
        ejabberd.builds[0].signed = True
        ejabberd.locked = True
        compose = models.Compose(release=ejabberd.release,
                                 request=ejabberd.request)
        self.db.add(compose)
        # This compose has no updates, so bodhi-push should delete it.
        compose = models.Compose(release=ejabberd.release,
                                 request=models.UpdateRequest.stable)
        self.db.add(compose)
        self.db.commit()

        with mock.patch('bodhi.server.push.transactional_session_maker',
                        return_value=base.TransactionalSessionMaker(
                            self.Session)):
            result = cli.invoke(push.push,
                                ['--username', 'bowlofeggs', '--resume'],
                                input='y\ny')

        self.assertEqual(result.exit_code, 0)
        self.assertEqual(result.output, TEST_RESUME_EMPTY_COMPOSE)
        ejabberd = self.db.query(
            models.Update).filter_by(title=u'ejabberd-16.09-4.fc17').one()
        python_nose = self.db.query(
            models.Update).filter_by(title=u'python-nose-1.3.7-11.fc17').one()
        python_paste_deploy = self.db.query(models.Update).filter_by(
            title=u'python-paste-deploy-1.5.2-8.fc17').one()
        publish.assert_called_once_with(
            topic='masher.start',
            msg={
                'composes': [ejabberd.compose.__json__(composer=True)],
                'resume': True,
                'agent': 'bowlofeggs',
                'api_version': 2
            },
            force=True)
        # ejabberd should still be locked.
        self.assertTrue(ejabberd.locked)
        self.assertTrue(ejabberd.date_locked <= datetime.utcnow())
        self.assertEqual(ejabberd.compose.release, ejabberd.release)
        self.assertEqual(ejabberd.compose.request, ejabberd.request)
        # These should be left alone.
        for u in [python_nose, python_paste_deploy]:
            self.assertFalse(u.locked)
            self.assertIsNone(u.date_locked)
            self.assertIsNone(u.compose)
        # The empty compose should have been deleted.
        self.assertEqual(
            self.db.query(models.Compose).filter_by(
                release_id=ejabberd.release.id,
                request=models.UpdateRequest.stable).count(), 0)
Exemple #6
0
    def test_edited_update_bugs_in_update(self, work_on_bugs, fetch_test_cases,
                                          sleep):
        """
        Test with a message that indicates that the update is being edited, and the list of bugs
        matches what UpdatesHandler finds in the database.
        """
        h = updates.UpdatesHandler()
        h.db_factory = base.TransactionalSessionMaker(self.Session)
        update = models.Build.query.filter_by(
            nvr='bodhi-2.0-1.fc17').one().update
        message = Message(topic='bodhi.update.edit',
                          body={
                              'msg': {
                                  'update': {
                                      'alias': update.alias
                                  },
                                  'new_bugs': ['12345']
                              }
                          })
        h(message)

        self.assertEqual(work_on_bugs.call_count, 1)
        self.assertTrue(
            isinstance(work_on_bugs.mock_calls[0][1][1],
                       sqlalchemy.orm.session.Session))
        self.assertEqual(work_on_bugs.mock_calls[0][1][2].title,
                         u'bodhi-2.0-1.fc17')
        self.assertEqual([b.bug_id for b in work_on_bugs.mock_calls[0][1][3]],
                         [12345])
        self.assertEqual(fetch_test_cases.call_count, 1)
        self.assertTrue(
            isinstance(fetch_test_cases.mock_calls[0][1][1],
                       sqlalchemy.orm.session.Session))
        sleep.assert_called_once_with(1)
Exemple #7
0
    def test_request_testing(self, work_on_bugs, fetch_test_cases):
        """
        Assert correct behavior when the message tells us that the update is requested for testing.
        """
        hub = mock.MagicMock()
        hub.config = {'environment': 'environment',
                      'topic_prefix': 'topic_prefix'}
        h = updates.UpdatesHandler(hub)
        h.db_factory = base.TransactionalSessionMaker(self.Session)
        # Throw a bogus bug id in there to ensure it doesn't raise AssertionError.
        message = {
            'topic': 'bodhi.update.request.testing',
            'body': {'msg': {'update': {'alias': u'bodhi-2.0-1.fc17'},
                             'new_bugs': ['this isnt a real bug lol']}}}

        h.consume(message)

        self.assertEqual(work_on_bugs.call_count, 1)
        self.assertTrue(isinstance(work_on_bugs.mock_calls[0][1][1],
                                   sqlalchemy.orm.session.Session))
        self.assertEqual(work_on_bugs.mock_calls[0][1][2].title, u'bodhi-2.0-1.fc17')
        # Despite our weird bogus bug id, the update's bug list should have been used.
        self.assertEqual([b.bug_id for b in work_on_bugs.mock_calls[0][1][3]], [12345])
        self.assertEqual(fetch_test_cases.call_count, 1)
        self.assertTrue(isinstance(fetch_test_cases.mock_calls[0][1][1],
                                   sqlalchemy.orm.session.Session))
Exemple #8
0
    def test_update_not_found(self, work_on_bugs, fetch_test_cases):
        """
        If the message references an update that isn't found, assert that an Exception is raised.
        """
        hub = mock.MagicMock()
        hub.config = {
            'environment': 'environment',
            'topic_prefix': 'topic_prefix'
        }
        h = updates.UpdatesHandler(hub)
        h.db_factory = base.TransactionalSessionMaker(self.Session)
        # Use a bogus topic to trigger the NotImplementedError.
        message = {
            'topic': 'bodhi.update.request.testing',
            'body': {
                'msg': {
                    'update': {
                        'alias': u'hurd-1.0-1.fc26'
                    }
                }
            }
        }

        with self.assertRaises(exceptions.BodhiException) as exc:
            h.consume(message)

        self.assertEqual(str(exc.exception),
                         "Couldn't find alias u'hurd-1.0-1.fc26' in DB")
        self.assertEqual(work_on_bugs.call_count, 0)
        self.assertEqual(fetch_test_cases.call_count, 0)
Exemple #9
0
    def test_without_alias(self, work_on_bugs, fetch_test_cases, error):
        """
        An error should get logged and the function should return if the message has no alias.
        """
        hub = mock.MagicMock()
        hub.config = {
            'environment': 'environment',
            'topic_prefix': 'topic_prefix'
        }
        h = updates.UpdatesHandler(hub)
        h.db_factory = base.TransactionalSessionMaker(self.Session)
        message = {
            'topic': 'bodhi.update.edit',
            'body': {
                'msg': {
                    'update': {},
                    'new_bugs': ['12345']
                }
            }
        }

        h.consume(message)

        self.assertEqual(work_on_bugs.call_count, 0)
        self.assertEqual(fetch_test_cases.call_count, 0)
        error.assert_called_once_with(
            "Update Handler got update with no alias {'new_bugs': ['12345'], 'update': {}}."
        )
Exemple #10
0
    def test_edited_update_bug_not_in_update(self, work_on_bugs, fetch_test_cases, sleep):
        """
        Test with a message that indicates that the update is being edited, and the list of bugs
        contains one that UpdatesHandler does not find in the update.
        """
        bug = models.Bug(bug_id=123456)
        self.db.add(bug)
        self.db.commit()

        h = updates.UpdatesHandler()
        h.db_factory = base.TransactionalSessionMaker(self.Session)
        update = models.Build.query.filter_by(nvr='bodhi-2.0-1.fc17').one().update
        message = Message(
            topic='bodhi.update.edit',
            body={'msg': {'update': {'alias': update.alias},
                          'new_bugs': ['12345', '123456']}}
        )

        h(message)

        self.assertEqual(work_on_bugs.call_count, 1)
        self.assertTrue(isinstance(work_on_bugs.mock_calls[0][1][0],
                                   sqlalchemy.orm.session.Session))
        self.assertEqual(work_on_bugs.mock_calls[0][1][1].title, 'bodhi-2.0-1.fc17')
        self.assertEqual([b.bug_id for b in work_on_bugs.mock_calls[0][1][2]], [12345, 123456])
        self.assertEqual(fetch_test_cases.call_count, 1)
        self.assertTrue(isinstance(fetch_test_cases.mock_calls[0][1][0],
                                   sqlalchemy.orm.session.Session))
        sleep.assert_called_once_with(1)

        # Bug with id '123456' should be attached to update
        bug = models.Bug.query.filter_by(bug_id=123456).one()
        update = models.Build.query.filter_by(nvr='bodhi-2.0-1.fc17').one().update
        self.assertIn(bug, update.bugs)
Exemple #11
0
    def test_unknown_topic(self, work_on_bugs, fetch_test_cases):
        """
        Assert that NotImplementedError gets raised when an unknown topic is received.
        """
        hub = mock.MagicMock()
        hub.config = {
            'environment': 'environment',
            'topic_prefix': 'topic_prefix'
        }
        h = updates.UpdatesHandler(hub)
        h.db_factory = base.TransactionalSessionMaker(self.Session)
        # Use a bogus topic to trigger the NotImplementedError.
        message = {
            'topic': 'bodhi.update.nawjustkiddin',
            'body': {
                'msg': {
                    'update': {
                        'alias': u'bodhi-2.0-1.fc17'
                    },
                    'new_bugs': ['12345']
                }
            }
        }

        self.assertRaises(NotImplementedError, h.consume, message)

        self.assertEqual(work_on_bugs.call_count, 0)
        self.assertEqual(fetch_test_cases.call_count, 0)
Exemple #12
0
    def test_request_testing(self, work_on_bugs, fetch_test_cases, sleep):
        """
        Assert correct behavior when the message tells us that the update is requested for testing.
        """
        h = updates.UpdatesHandler()
        h.db_factory = base.TransactionalSessionMaker(self.Session)
        update = models.Build.query.filter_by(nvr='bodhi-2.0-1.fc17').one().update
        # Throw a bogus bug id in there to ensure it doesn't raise AssertionError.
        message = Message(
            topic='bodhi.update.request.testing',
            body={'msg': {'update': {'alias': update.alias},
                          'new_bugs': ['this isnt a real bug lol']}}
        )
        h(message)

        self.assertEqual(work_on_bugs.call_count, 1)
        self.assertTrue(isinstance(work_on_bugs.mock_calls[0][1][1],
                                   sqlalchemy.orm.session.Session))
        self.assertEqual(work_on_bugs.mock_calls[0][1][2].title, 'bodhi-2.0-1.fc17')
        # Despite our weird bogus bug id, the update's bug list should have been used.
        self.assertEqual([b.bug_id for b in work_on_bugs.mock_calls[0][1][3]], [12345])
        self.assertEqual(fetch_test_cases.call_count, 1)
        self.assertTrue(isinstance(fetch_test_cases.mock_calls[0][1][1],
                                   sqlalchemy.orm.session.Session))
        sleep.assert_called_once_with(1)
Exemple #13
0
    def test_gating_required_true(self, sleep):
        """Assert that test_gating_status is updated when test_gating is enabled."""
        update = models.Build.query.filter_by(nvr='bodhi-2.0-1.fc17').one().update
        update.test_gating_status = None

        h = updates.UpdatesHandler()
        h.db_factory = base.TransactionalSessionMaker(self.Session)
        # Throw a bogus bug id in there to ensure it doesn't raise AssertionError.
        message = Message(
            topic='bodhi.update.request.testing',
            body={'msg': {'update': {'alias': update.alias},
                          'new_bugs': []}}
        )
        with mock.patch('bodhi.server.models.util.greenwave_api_post') as mock_greenwave:
            greenwave_response = {
                'policies_satisfied': False,
                'summary': 'what have you done‽',
                'applicable_policies': ['taskotron_release_critical_tasks'],
                'unsatisfied_requirements': [
                    {'testcase': 'dist.rpmdeplint',
                     'item': {'item': 'bodhi-2.0-1.fc17', 'type': 'koji_build'},
                     'type': 'test-result-missing', 'scenario': None},
                    {'testcase': 'dist.rpmdeplint',
                     'item': {'original_spec_nvr': 'bodhi-2.0-1.fc17'},
                     'type': 'test-result-missing', 'scenario': None},
                    {'testcase': 'dist.rpmdeplint',
                     'item': {'item': update.alias, 'type': 'bodhi_update'},
                     'type': 'test-result-missing', 'scenario': None}]}
            mock_greenwave.return_value = greenwave_response

            h(message)

        update = models.Build.query.filter_by(nvr='bodhi-2.0-1.fc17').one().update
        self.assertEqual(update.test_gating_status, models.TestGatingStatus.failed)
        sleep.assert_called_once_with(1)
Exemple #14
0
    def test_unsigned_updates_skipped(self, publish, mock_init):
        """
        Unsigned updates should get skipped.
        """
        cli = CliRunner()
        # Let's mark nose unsigned so it gets skipped.
        python_nose = self.db.query(models.Update).filter_by(
            title=u'python-nose-1.3.7-11.fc17').one()
        python_nose.builds[0].signed = False
        self.db.commit()

        with mock.patch('bodhi.server.push.transactional_session_maker',
                        return_value=base.TransactionalSessionMaker(self.Session)):
            result = cli.invoke(push.push, ['--username', 'bowlofeggs'], input='y')

        mock_init.assert_called_once_with(active=True, cert_prefix=u'shell')
        self.assertEqual(result.exit_code, 0)
        self.assertEqual(result.output, TEST_UNSIGNED_UPDATES_SKIPPED_EXPECTED_OUTPUT)
        python_nose = self.db.query(models.Update).filter_by(
            title=u'python-nose-1.3.7-11.fc17').one()
        python_paste_deploy = self.db.query(models.Update).filter_by(
            title=u'python-paste-deploy-1.5.2-8.fc17').one()
        publish.assert_called_once_with(
            topic='masher.start',
            msg={'composes': [python_paste_deploy.compose.__json__()],
                 'resume': False, 'agent': 'bowlofeggs', 'api_version': 2},
            force=True)
        self.assertFalse(python_nose.locked)
        self.assertIsNone(python_nose.date_locked)
        self.assertTrue(python_paste_deploy.locked)
        self.assertTrue(python_paste_deploy.date_locked <= datetime.utcnow())
        self.assertEqual(python_paste_deploy.compose.release, python_paste_deploy.release)
        self.assertEqual(python_paste_deploy.compose.request, python_paste_deploy.request)
Exemple #15
0
    def test_update_not_found(self, work_on_bugs, fetch_test_cases, sleep):
        """
        If the message references an update that isn't found, assert that an Exception is raised.
        """
        h = updates.UpdatesHandler()
        h.db_factory = base.TransactionalSessionMaker(self.Session)
        with pytest.raises(exceptions.BodhiException) as exc:
            h.run(api_version=1,
                  data={
                      'action': 'testing',
                      'update': {
                          'alias': 'does not exist',
                          'builds': [{
                              'nvr': 'bodhi-2.0-1.fc17'
                          }],
                          'user': {
                              'name': 'brodhi'
                          },
                          'status': 'pending',
                          'request': 'testing'
                      }
                  })

        assert str(exc.value) == "Couldn't find alias 'does not exist' in DB"
        assert work_on_bugs.call_count == 0
        assert fetch_test_cases.call_count == 0
        sleep.assert_called_once_with(1)
Exemple #16
0
    def test_cert_prefix_flag(self, publish, init):
        """
        Test correct operation when the --cert-prefix flag is used.
        """
        cli = CliRunner()
        self.db.commit()

        with mock.patch('bodhi.server.push.transactional_session_maker',
                        return_value=base.TransactionalSessionMaker(
                            self.Session)):
            result = cli.invoke(
                push.push,
                ['--username', 'bowlofeggs', '--cert-prefix', 'some_prefix'],
                input='y')

        self.assertEqual(result.exit_code, 0)
        self.assertEqual(result.output, TEST_CERT_PREFIX_FLAG_EXPECTED_OUTPUT)
        init.assert_called_once_with(active=True, cert_prefix='some_prefix')
        publish.assert_called_once_with(topic='masher.start',
                                        msg={
                                            'composes': [{
                                                'security': False,
                                                'release_id': 1,
                                                'request': u'testing',
                                                'content_type': u'rpm'
                                            }],
                                            'resume':
                                            False,
                                            'agent':
                                            'bowlofeggs',
                                            'api_version':
                                            2
                                        },
                                        force=True)
Exemple #17
0
    def test_request_testing(self, work_on_bugs, fetch_test_cases, sleep):
        """
        Assert correct behavior when the message tells us that the update is requested for testing.
        """
        h = updates.UpdatesHandler()
        h.db_factory = base.TransactionalSessionMaker(self.Session)
        update = models.Build.query.filter_by(
            nvr='bodhi-2.0-1.fc17').one().update
        h.run(api_version=1,
              data={
                  'action': 'testing',
                  'update': {
                      'alias': update.alias,
                      'builds': [{
                          'nvr': 'bodhi-2.0-1.fc17'
                      }],
                      'user': {
                          'name': 'brodhi'
                      },
                      'status': str(update.status),
                      'request': str(update.request)
                  }
              })

        assert work_on_bugs.call_count == 1
        assert isinstance(work_on_bugs.mock_calls[0][1][1],
                          sqlalchemy.orm.session.Session)
        assert work_on_bugs.mock_calls[0][1][2].title == 'bodhi-2.0-1.fc17'
        # The update's bug list should have been used.
        assert [b.bug_id for b in work_on_bugs.mock_calls[0][1][3]] == [12345]
        assert fetch_test_cases.call_count == 1
        assert isinstance(fetch_test_cases.mock_calls[0][1][1],
                          sqlalchemy.orm.session.Session)
        sleep.assert_called_once_with(1)
Exemple #18
0
    def test_consume_from_tag_composed_by_bodhi(self, add_tag):
        """
        Assert that update created from tag for a release composed by bodhi
        is handled correctly when message is received.
        The update request should be set to 'testing' so that the next composer run
        will change the update status.
        """
        self.handler.db_factory = base.TransactionalSessionMaker(self.Session)
        update = self.db.query(Update).filter(
            Build.nvr == 'bodhi-2.0-1.fc17').one()
        update.from_tag = "f30-side-tag"
        update.status = UpdateStatus.pending
        update.request = None
        update.release.composed_by_bodhi = True
        update.release.pending_testing_tag = "f30-testing-pending"
        update.builds[0].signed = False
        update.pushed = False

        self.db.commit()
        with mock.patch('bodhi.server.models.util.greenwave_api_post'
                        ) as mock_greenwave:
            greenwave_response = {
                'policies_satisfied': True,
                'summary': "all tests have passed"
            }
            mock_greenwave.return_value = greenwave_response
            with fml_testing.mock_sends(update_schemas.UpdateRequestTestingV1):
                self.handler(self.sample_side_tag_message_2)

        assert update.builds[0].signed is True
        assert update.builds[0].update.request == UpdateRequest.testing
        assert update.status == UpdateStatus.pending
        assert update.pushed is False
        assert update.test_gating_status == TestGatingStatus.passed
        assert add_tag.not_called()
    def setup_method(self, method):
        """Set up environment for each test."""
        super().setup_method(method)

        self.release = self.db.query(Release).filter_by(name='F17').first()
        if self.release:
            self.release.create_automatic_updates = True
            self.db.flush()
        else:
            self.release = self.create_release('17',
                                               create_automatic_updates=True)

        body = {
            'build_id': 442562,
            'name': 'colord',
            'tag_id': 214,
            'instance': 's390',
            'tag': 'f17-updates-candidate',
            'user': '******',
            'version': '1.3.4',
            'owner': 'sharkcz',
            'release': '1.fc26',
        }

        self.sample_message = Message(topic='', body=body)
        self.sample_nvr = f"{body['name']}-{body['version']}-{body['release']}"

        self.db_factory = base.TransactionalSessionMaker(self.Session)
        self.handler = AutomaticUpdateHandler(self.db_factory)
Exemple #20
0
    def test_abort_push(self, publish):
        """
        Ensure that the push gets aborted if the user types 'n' when asked if they want to push.
        """
        cli = CliRunner()
        self.db.commit()

        with mock.patch('bodhi.server.push.transactional_session_maker',
                        return_value=base.TransactionalSessionMaker(self.Session)):
            result = cli.invoke(push.push, ['--username', 'bowlofeggs'], input='n')

        # The exit code is 1 when the push is aborted.
        self.assertEqual(result.exit_code, 1)

        # This is a terribly dirty hack that strips an SQLAlchemy warning about calling configure
        # on a scoped session with existing sessions. This should ultimately be fixed by making
        # sure there are no sessions when the CLI is invoked (since it calls configure)
        if 'scoped session' in result.output:
            doctored_output = result.output.split('\n', 2)[2]
        else:
            doctored_output = result.output
        self.assertEqual(doctored_output, TEST_ABORT_PUSH_EXPECTED_OUTPUT)
        self.assertEqual(publish.call_count, 0)
        # The updates should not be locked
        for u in [u'bodhi-2.0-1.fc17', u'python-nose-1.3.7-11.fc17',
                  u'python-paste-deploy-1.5.2-8.fc17']:
            u = self.db.query(models.Update).filter_by(title=u).one()
            self.assertFalse(u.locked)
            self.assertIsNone(u.date_locked)
Exemple #21
0
    def test_no_updates_to_push(self, publish):
        """
        If there are no updates to push, no push message should get sent.
        """
        cli = CliRunner()
        python_nose = self.db.query(
            models.Update).filter_by(title=u'python-nose-1.3.7-11.fc17').one()
        python_paste_deploy = self.db.query(models.Update).filter_by(
            title=u'python-paste-deploy-1.5.2-8.fc17').one()
        python_nose.builds[0].signed = False
        python_paste_deploy.builds[0].signed = False
        self.db.commit()

        with mock.patch('bodhi.server.push.transactional_session_maker',
                        return_value=base.TransactionalSessionMaker(
                            self.Session)):
            result = cli.invoke(push.push, ['--username', 'bowlofeggs'],
                                input='y')

        self.assertEqual(result.exit_code, 0)
        self.assertEqual(result.output,
                         TEST_NO_UPDATES_TO_PUSH_EXPECTED_OUTPUT)
        self.assertEqual(publish.call_count, 0)

        # The updates should not be locked
        python_nose = self.db.query(
            models.Update).filter_by(title=u'python-nose-1.3.7-11.fc17').one()
        python_paste_deploy = self.db.query(models.Update).filter_by(
            title=u'python-paste-deploy-1.5.2-8.fc17').one()
        for u in [python_nose, python_paste_deploy]:
            self.assertFalse(u.locked)
            self.assertIsNone(u.date_locked)
Exemple #22
0
    def test_cert_prefix_flag(self, publish, init):
        """
        Test correct operation when the --cert-prefix flag is used.
        """
        cli = CliRunner()
        self.db.commit()

        with mock.patch('bodhi.server.push.transactional_session_maker',
                        return_value=base.TransactionalSessionMaker(
                            self.Session)):
            result = cli.invoke(
                push.push,
                ['--username', 'bowlofeggs', '--cert-prefix', 'some_prefix'],
                input='y')

        self.assertEqual(result.exit_code, 0)
        self.assertEqual(result.output, TEST_CERT_PREFIX_FLAG_EXPECTED_OUTPUT)
        init.assert_called_once_with(active=True, cert_prefix='some_prefix')
        publish.assert_called_once_with(
            topic='masher.start',
            msg={
                'updates': [
                    'python-nose-1.3.7-11.fc17',
                    u'python-paste-deploy-1.5.2-8.fc17'
                ],
                'resume':
                False,
                'agent':
                'bowlofeggs'
            },
            force=True)
Exemple #23
0
    def test_not_rawhide_update_signed_stays_pending(self, work_on_bugs,
                                                     fetch_test_cases, sleep):
        """
        Assert that a non rawhide pending update that was edited does not get moved to testing
        if all the builds in the update are signed.
        """
        update = models.Build.query.filter_by(
            nvr='bodhi-2.0-1.fc17').one().update
        update.status = models.UpdateStatus.pending
        update.release.composed_by_bodhi = True
        update.builds[0].signed = True

        h = updates.UpdatesHandler()
        h.db_factory = base.TransactionalSessionMaker(self.Session)
        h.run(api_version=1,
              data={
                  'action': 'edit',
                  'update': {
                      'alias': update.alias,
                      'builds': [{
                          'nvr': 'bodhi-2.0-1.fc17'
                      }],
                      'user': {
                          'name': 'bodhi'
                      },
                      'status': str(update.status),
                      'request': str(update.request)
                  },
                  'new_bugs': []
              })

        assert update.status == models.UpdateStatus.pending
Exemple #24
0
    def test_resume_human_says_no(self, publish):
        """
        Test correct operation when the --resume flag is given but the human says they don't want to
        resume one of the lockfiles.
        """
        cli = CliRunner()
        # Let's mark ejabberd as locked and already in a push. Since we are resuming and since we
        # will decline pushing the first time we are asked, it should be the only package that gets
        # included.
        ejabberd = self.create_update([u'ejabberd-16.09-4.fc17'])
        ejabberd.builds[0].signed = True
        ejabberd.locked = True
        compose = models.Compose(release=ejabberd.release,
                                 request=ejabberd.request)
        self.db.add(compose)
        python_nose = self.db.query(
            models.Update).filter_by(title=u'python-nose-1.3.7-11.fc17').one()
        python_nose.locked = True
        python_nose.request = models.UpdateRequest.stable
        compose = models.Compose(release=python_nose.release,
                                 request=python_nose.request)
        self.db.add(compose)
        self.db.commit()

        with mock.patch('bodhi.server.push.transactional_session_maker',
                        return_value=base.TransactionalSessionMaker(
                            self.Session)):
            result = cli.invoke(push.push,
                                ['--username', 'bowlofeggs', '--resume'],
                                input='y\nn\ny')

        self.assertEqual(result.exit_code, 0)
        self.assertEqual(result.output,
                         TEST_RESUME_HUMAN_SAYS_NO_EXPECTED_OUTPUT)
        ejabberd = self.db.query(
            models.Update).filter_by(title=u'ejabberd-16.09-4.fc17').one()
        python_nose = self.db.query(
            models.Update).filter_by(title=u'python-nose-1.3.7-11.fc17').one()
        python_paste_deploy = self.db.query(models.Update).filter_by(
            title=u'python-paste-deploy-1.5.2-8.fc17').one()
        publish.assert_called_once_with(
            topic='masher.start',
            msg={
                'composes': [ejabberd.compose.__json__(composer=True)],
                'resume': True,
                'agent': 'bowlofeggs',
                'api_version': 2
            },
            force=True)
        # These should still be locked.
        for u in [ejabberd, python_nose]:
            self.assertTrue(u.locked)
            self.assertTrue(u.date_locked <= datetime.utcnow())
            self.assertEqual(u.compose.release, u.release)
            self.assertEqual(u.compose.request, u.request)
        # paste_deploy should have been left alone
        self.assertFalse(python_paste_deploy.locked)
        self.assertIsNone(python_paste_deploy.date_locked)
        self.assertIsNone(python_paste_deploy.compose)
Exemple #25
0
    def test_gating_required_true(self, sleep):
        """Assert that test_gating_status is updated when test_gating is enabled."""
        update = models.Build.query.filter_by(
            nvr='bodhi-2.0-1.fc17').one().update
        update.test_gating_status = None

        h = updates.UpdatesHandler()
        h.db_factory = base.TransactionalSessionMaker(self.Session)
        with mock.patch('bodhi.server.models.util.greenwave_api_post'
                        ) as mock_greenwave:
            greenwave_response = {
                'policies_satisfied':
                False,
                'summary':
                'what have you done‽',
                'applicable_policies': ['taskotron_release_critical_tasks'],
                'unsatisfied_requirements': [{
                    'testcase': 'dist.rpmdeplint',
                    'item': {
                        'item': 'bodhi-2.0-1.fc17',
                        'type': 'koji_build'
                    },
                    'type': 'test-result-missing',
                    'scenario': None
                }, {
                    'testcase': 'dist.rpmdeplint',
                    'item': {
                        'item': update.alias,
                        'type': 'bodhi_update'
                    },
                    'type': 'test-result-missing',
                    'scenario': None
                }]
            }
            mock_greenwave.return_value = greenwave_response

            h.run(api_version=1,
                  data={
                      'action': 'testing',
                      'update': {
                          'alias': update.alias,
                          'builds': [{
                              'nvr': 'bodhi-2.0-1.fc17'
                          }],
                          'user': {
                              'name': 'brodhi'
                          },
                          'status': str(update.status),
                          'request': str(update.request)
                      },
                      'new_bugs': []
                  })

        update = models.Build.query.filter_by(
            nvr='bodhi-2.0-1.fc17').one().update
        self.assertEqual(update.test_gating_status,
                         models.TestGatingStatus.failed)
        sleep.assert_called_once_with(1)
Exemple #26
0
    def test_unknown_api_version(self, log_error, work_on_bugs,
                                 fetch_test_cases):
        """Test an unknown API version"""
        h = updates.UpdatesHandler()
        h.db_factory = base.TransactionalSessionMaker(self.Session)
        h.run(api_version="unknown", data={})

        work_on_bugs.assert_not_called()
        fetch_test_cases.assert_not_called()
        log_error.assert_called_with(
            "The Updates Handler doesn't know how to handle api_version unknown. "
            "Message was: {}")
Exemple #27
0
    def test_resume_flag(self, publish, mock_init):
        """
        Test correct operation when the --resume flag is given.
        """
        cli = CliRunner()
        # Let's mark ejabberd as locked and already in a push. Since we are resuming, it should be
        # the only package that gets included.
        ejabberd = self.create_update([u'ejabberd-16.09-4.fc17'])
        ejabberd.builds[0].signed = True
        ejabberd.locked = True
        compose = models.Compose(release=ejabberd.release,
                                 request=ejabberd.request)
        self.db.add(compose)
        self.db.commit()

        with mock.patch('bodhi.server.push.transactional_session_maker',
                        return_value=base.TransactionalSessionMaker(
                            self.Session)):
            result = cli.invoke(push.push,
                                ['--username', 'bowlofeggs', '--resume'],
                                input='y\ny')

        self.assertEqual(result.exit_code, 0)
        mock_init.assert_called_once_with(active=True, cert_prefix=u'shell')
        self.assertEqual(result.output, TEST_RESUME_FLAG_EXPECTED_OUTPUT)
        ejabberd = self.db.query(
            models.Update).filter_by(title=u'ejabberd-16.09-4.fc17').one()
        python_nose = self.db.query(
            models.Update).filter_by(title=u'python-nose-1.3.7-11.fc17').one()
        python_paste_deploy = self.db.query(models.Update).filter_by(
            title=u'python-paste-deploy-1.5.2-8.fc17').one()
        publish.assert_called_once_with(topic='masher.start',
                                        msg={
                                            'composes':
                                            [ejabberd.compose.__json__()],
                                            'resume':
                                            True,
                                            'agent':
                                            'bowlofeggs',
                                            'api_version':
                                            2
                                        },
                                        force=True)
        # ejabberd should be locked still
        self.assertTrue(ejabberd.locked)
        self.assertTrue(ejabberd.date_locked <= datetime.utcnow())
        self.assertEqual(ejabberd.compose.release, ejabberd.release)
        self.assertEqual(ejabberd.compose.request, ejabberd.request)
        # The other packages should have been left alone
        for u in [python_nose, python_paste_deploy]:
            self.assertFalse(u.locked)
            self.assertIsNone(u.date_locked)
            self.assertIsNone(u.compose)
Exemple #28
0
    def test_locked_updates(self, publish, mock_init):
        """
        Test correct operation when there are some locked updates.
        """
        cli = CliRunner()
        # Let's mark ejabberd as locked and already in a push. bodhi-push should prompt the user to
        # resume this compose rather than starting a new one.
        ejabberd = self.create_update([u'ejabberd-16.09-4.fc17'])
        ejabberd.builds[0].signed = True
        ejabberd.locked = True
        compose = models.Compose(release=ejabberd.release,
                                 request=ejabberd.request,
                                 state=models.ComposeState.failed,
                                 error_message=u'y r u so mean nfs')
        self.db.add(compose)
        self.db.commit()

        with mock.patch('bodhi.server.push.transactional_session_maker',
                        return_value=base.TransactionalSessionMaker(
                            self.Session)):
            result = cli.invoke(push.push, ['--username', 'bowlofeggs'],
                                input='y\ny')

        self.assertEqual(result.exit_code, 0)
        mock_init.assert_called_once_with(active=True, cert_prefix=u'shell')
        self.assertEqual(result.output, TEST_LOCKED_UPDATES_EXPECTED_OUTPUT)
        publish.assert_called_once_with(topic='masher.start',
                                        msg={
                                            'composes':
                                            [ejabberd.compose.__json__()],
                                            'resume':
                                            True,
                                            'agent':
                                            'bowlofeggs',
                                            'api_version':
                                            2
                                        },
                                        force=True)
        ejabberd = self.db.query(
            models.Update).filter_by(title=u'ejabberd-16.09-4.fc17').one()
        self.assertTrue(ejabberd.locked)
        self.assertTrue(ejabberd.date_locked <= datetime.utcnow())
        self.assertEqual(ejabberd.compose.release, ejabberd.release)
        self.assertEqual(ejabberd.compose.request, ejabberd.request)
        self.assertEqual(ejabberd.compose.state, models.ComposeState.requested)
        self.assertEqual(ejabberd.compose.error_message, '')
        python_nose = self.db.query(
            models.Update).filter_by(title=u'python-nose-1.3.7-11.fc17').one()
        python_paste_deploy = self.db.query(models.Update).filter_by(
            title=u'python-paste-deploy-1.5.2-8.fc17').one()
        for u in [python_nose, python_paste_deploy]:
            self.assertFalse(u.locked)
            self.assertIsNone(u.date_locked)
Exemple #29
0
    def test_edited_update_bug_not_in_update(self, work_on_bugs,
                                             fetch_test_cases, sleep):
        """
        Test an update edition when the list of bugs contains one that
        UpdatesHandler does not find in the update.
        """
        bug = models.Bug(bug_id=123456)
        self.db.add(bug)
        self.db.commit()

        h = updates.UpdatesHandler()
        h.db_factory = base.TransactionalSessionMaker(self.Session)
        update = models.Build.query.filter_by(
            nvr='bodhi-2.0-1.fc17').one().update

        h.run(api_version=1,
              data={
                  'action': 'edit',
                  'update': {
                      'alias': update.alias,
                      'builds': [{
                          'nvr': 'bodhi-2.0-1.fc17'
                      }],
                      'user': {
                          'name': 'brodhi'
                      },
                      'status': str(update.status),
                      'request': str(update.request)
                  },
                  'new_bugs': [12345, 123456]
              })

        self.assertEqual(work_on_bugs.call_count, 1)
        self.assertTrue(
            isinstance(work_on_bugs.mock_calls[0][1][0],
                       sqlalchemy.orm.session.Session))
        self.assertEqual(work_on_bugs.mock_calls[0][1][1].title,
                         'bodhi-2.0-1.fc17')
        self.assertEqual([b.bug_id for b in work_on_bugs.mock_calls[0][1][2]],
                         [12345, 123456])
        self.assertEqual(fetch_test_cases.call_count, 1)
        self.assertTrue(
            isinstance(fetch_test_cases.mock_calls[0][1][0],
                       sqlalchemy.orm.session.Session))
        sleep.assert_called_once_with(1)

        # Bug with id '123456' should be attached to update
        bug = models.Bug.query.filter_by(bug_id=123456).one()
        update = models.Build.query.filter_by(
            nvr='bodhi-2.0-1.fc17').one().update
        self.assertIn(bug, update.bugs)
Exemple #30
0
    def test_unsigned_updates_signed_updated(self, publish, mock_init):
        """
        Unsigned updates should get marked signed.
        """
        cli = CliRunner()
        # Let's mark nose unsigned so it gets marked signed.
        python_nose = self.db.query(
            models.Update).filter_by(title=u'python-nose-1.3.7-11.fc17').one()
        python_nose.builds[0].signed = False
        self.db.commit()

        with mock.patch('bodhi.server.push.transactional_session_maker',
                        return_value=base.TransactionalSessionMaker(
                            self.Session)):
            # Note: this is NOT the signing-pending tag
            with mock.patch('bodhi.server.buildsys.DevBuildsys.listTags',
                            return_value=[{
                                'name': 'f17-updates-testing'
                            }]):
                result = cli.invoke(push.push, ['--username', 'bowlofeggs'],
                                    input='y')

        self.assertEqual(result.exception, None)
        mock_init.assert_called_once_with(active=True, cert_prefix=u'shell')
        self.assertEqual(result.exit_code, 0)
        python_nose = self.db.query(
            models.Update).filter_by(title=u'python-nose-1.3.7-11.fc17').one()
        python_paste_deploy = self.db.query(models.Update).filter_by(
            title=u'python-paste-deploy-1.5.2-8.fc17').one()
        publish.assert_called_once_with(
            topic='masher.start',
            msg={
                'composes':
                [python_paste_deploy.compose.__json__(composer=True)],
                'resume': False,
                'agent': 'bowlofeggs',
                'api_version': 2
            },
            force=True)
        self.assertTrue(python_nose.locked)
        self.assertTrue(python_nose.date_locked <= datetime.utcnow())
        self.assertEqual(python_nose.compose.release,
                         python_paste_deploy.release)
        self.assertEqual(python_nose.compose.request,
                         python_paste_deploy.request)
        self.assertTrue(python_paste_deploy.locked)
        self.assertTrue(python_paste_deploy.date_locked <= datetime.utcnow())
        self.assertEqual(python_paste_deploy.compose.release,
                         python_paste_deploy.release)
        self.assertEqual(python_paste_deploy.compose.request,
                         python_paste_deploy.request)