def setUp(self): self.sample_message = Message( topic='', body={ 'build_id': 442562, 'name': 'colord', 'tag_id': 214, 'instance': 's390', 'tag': 'f26-updates-testing-pending', 'user': '******', 'version': '1.3.4', 'owner': 'sharkcz', 'release': '1.fc26' }, ) self.sample_side_tag_message = Message( topic='', body={ 'build_id': 442562, 'name': 'colord', 'tag_id': 214, 'instance': 's390', 'tag': 'f30-side-tag-testing', 'user': '******', 'version': '1.3.4', 'owner': 'sharkcz', 'release': '1.fc26' }, ) self.handler = signed.SignedHandler()
def test_year_prefix(self): """Assert the year prefix on fedmsg is removed.""" year = datetime.datetime.utcnow().year msg = Message(topic="dummy.topic", body={"body": "dummy-body"}) msg.id = "{}-dummy-msgid".format(year) self.consumer.on_message(msg) self.assertEqual(len(self.store), 1) self.assertIn("dummy-msgid", self.store) self.assertEqual(self.store["dummy-msgid"][1]["msg_id"], msg.id)
def test_without_message_id(self): """Assert it handles messages without a message_id.""" msg = Message(topic="dummy.topic", body={"body": "dummy-body"}) msg.id = None try: self.consumer.on_message(msg) except (TypeError, AttributeError) as e: self.fail(e) self.assertEqual(len(self.store), 0)
def test_without_year_prefix(self): """Assert it handles messages without the year prefix.""" msg = Message(topic="dummy.topic", body={"body": "dummy-body"}) msg.id = "dummy-msgid" self.consumer.on_message(msg) self.assertEqual(len(self.store), 1) self.assertIn("dummy-msgid", self.store) self.assertEqual(self.store["dummy-msgid"][1]["msg_id"], msg.id) self.assertEqual(self.store["dummy-msgid"][1]["topic"], "dummy.topic")
def test_messaging_callback_greenwave(self, Handler): msg = Message(topic="org.fedoraproject.prod.greenwave.decision.update", body={}) handler = mock.Mock() Handler.side_effect = lambda: handler Consumer()(msg) handler.assert_called_once_with(msg)
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)
def test_greenwave_bad_message(self, mock_log): """ Assert that the consumer ignores messages badly formed """ bad_message = Message(topic="", body={}) self.handler(bad_message) self.assertEqual(mock_log.debug.call_count, 1) mock_log.debug.assert_called_with("Ignoring message without body.")
def setUp(self): super().setUp() self.sample_message = Message( topic="org.fedoraproject.prod.greenwave.decision.update", body={"subject_identifier": "bodhi-2.0-1.fc17", "subject_type": "koji_build"}, ) self.handler = greenwave.GreenwaveHandler()
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)
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)
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)
def test_consume_no_nvr_in_kojiinfo(self, mock_getBuild, caplog): """ Assert that we handle message correctly if build is found in koji, but doesn't contain nvr field. """ caplog.set_level(logging.DEBUG) body = { 'contact': '*****@*****.**', 'run': { 'url': 'https://example.url', }, 'artifact': {}, 'pipeline': { 'id': 442562, }, 'test': 'test', 'generated_at': 'somedate', 'version': '1.3.4', } sample_message = Message(topic='', body=body) self.handler(sample_message) # assert that comment is not created assert len(self.update.comments) == 0 mock_getBuild.assert_called_with(442562) assert "Koji build info with id '442562' doesn't contain 'nvr'." in caplog.text
def v2_playbook_on_play_start(self, play): # This gets called once for each play.. but we just issue a message once # for the first one. One per "playbook" if self.playbook: # figure out where the playbook FILE is path = os.path.abspath(self.playbook._file_name) # Bail out early without publishing if we're in --check mode if self.play_context.check_mode: return if not self.playbook_path: try: msg = Message( topic="ansible.playbook.start", body={ 'playbook': path, 'userid': getlogin(), 'extra_vars': play._variable_manager.extra_vars, 'inventory': play._variable_manager._inventory._sources, 'playbook_checksum': secure_hash(path), 'check': self.play_context.check_mode }) publish(msg) except PublishReturned as e: LOGGER.warning( "Fedora Messaging broker rejected message %s: %s", msg.id, e) except ConnectionException as e: LOGGER.warning("Error sending message %s: %s", msg.id, e) self.playbook_path = path
def test_consume_run_url_field_is_missing(self, caplog): """ Assert that comment is created when run.url field is missing. """ caplog.set_level(logging.DEBUG) body = { 'contact': '*****@*****.**', 'run': {}, 'artifact': { 'nvr': 'colord-1.3.4-1.fc26' }, 'pipeline': { 'id': 442562, }, 'test': 'test', 'generated_at': 'somedate', 'version': '1.3.4', } sample_message = Message(topic='', body=body) self.handler(sample_message) comment = self.update.comments[-1] # Check if comment was created assert comment.text == "CI testing started." assert comment.user.name == "bodhi" assert "Committing changes to the database." in caplog.text
def test_consume_nvr_and_id_missing(self, caplog): """ Assert that we handle message correctly if both build id and nvr is missing. """ caplog.set_level(logging.DEBUG) body = { 'contact': '*****@*****.**', 'run': { 'url': 'https://example.url', }, 'artifact': {}, 'pipeline': {}, 'test': 'test', 'generated_at': 'somedate', 'version': '1.3.4', } sample_message = Message(topic='', body=body) self.handler(sample_message) # assert that comment is not created assert len(self.update.comments) == 0 assert "Received incomplete CI message. Missing: 'artifact.nvr', 'pipeline.id'." \ in caplog.text
def test_consume_nvr_field_missing(self, mock_getBuild, caplog): """ Assert that we use build_id if nvr field is missing in message. """ caplog.set_level(logging.DEBUG) body = { 'contact': '*****@*****.**', 'run': { 'url': 'https://example.url', }, 'artifact': {}, 'pipeline': { 'id': 442562, }, 'test': 'test', 'generated_at': 'somedate', 'version': '1.3.4', } sample_message = Message(topic='', body=body) self.handler(sample_message) comment = self.update.comments[-1] # Check if comment was created assert comment.text == "CI testing started: 'https://example.url'." assert comment.user.name == "bodhi" mock_getBuild.assert_called_with(442562) assert "Committing changes to the database." in caplog.text
def test_consume_build_not_exist(self, caplog): """ Assert that missing build is handled correctly. """ caplog.set_level(logging.DEBUG) body = { 'contact': '*****@*****.**', 'run': { 'url': 'https://example.url', }, 'artifact': { 'nvr': 'colord-1.3.4-2.fc26' }, 'pipeline': { 'id': 442562, }, 'test': 'test', 'generated_at': 'somedate', 'version': '1.3.4', } sample_message = Message(topic='', body=body) self.handler(sample_message) # assert that comment is not created assert len(self.update.comments) == 0 assert "Can't get build for 'colord-1.3.4-2.fc26'." in caplog.text
def test_messaging_callback_updates_edit(self, Handler): msg = Message(topic="org.fedoraproject.prod.bodhi.update.edit", body={}) handler = mock.Mock() Handler.side_effect = lambda: handler messaging_callback(msg) handler.assert_called_once_with(msg)
def test_messaging_callback_resultsdb(self, Handler): msg = Message(topic="org.fedoraproject.prod.resultsdb.result.new", body={}) handler = mock.Mock() Handler.side_effect = lambda: handler Consumer()(msg) handler.assert_called_once_with(msg)
def test_messaging_callback_exception(self, error): """Test catching an exception when processing messages.""" msg = Message( topic="org.fedoraproject.prod.buildsys.tag", body={} ) consumer = Consumer() with mock.patch.object( consumer, 'handler_infos', [HandlerInfo('.buildsys.tag', 'Automatic Update', mock.Mock())], ) as handler_infos: with pytest.raises(Nack) as exc: handler_infos[0].handler.side_effect = Exception("Something bad happened") consumer(msg) logmsg = (f"Something bad happened: Unable to handle message in " f"{consumer.handler_infos[-1].name} handler: {msg}") error.assert_called_with(logmsg) excmsg = ("Unable to (fully) handle message.\nAffected handlers:\n" + "".join(f"\t{hi.name}: Something bad happened\n" for hi in consumer.handler_infos) + "Message:\n{msg}") assert str(exc.value) == excmsg
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)
def fedora_messaging_change(change_id): change = Change.objects.get(pk=change_id) publish( Message( topic=get_change_topic(change), headers=get_change_headers(change), body=get_change_body(change), ))
def test_messaging_callback_signed(self, Handler): msg = Message(topic="org.fedoraproject.prod.buildsys.tag", body={}) handler = mock.Mock() Handler.side_effect = lambda: handler Consumer()(msg) handler.assert_called_once_with(msg)
def test_waiverdb_message_irrelevant_result_type(self, mock_log): """ Assert that the consumer logs and returns if the result type is not a relevant one. """ bad_message = Message(topic="", body={"subject": {"type": "foo"}}) self.handler(bad_message) assert mock_log.debug.call_count == 1 mock_log.debug.assert_called_with("Irrelevant item type foo")
def test_greenwave_message_missing_info(self, mock_log): """ Assert that the consumer raise an exception if we could not find the subject_identifier in the message """ bad_message = Message(topic="", body={"msg": {}}) self.handler(bad_message) self.assertEqual(mock_log.debug.call_count, 1) mock_log.debug.assert_called_with("Couldn't find subject_identifier in Greenwave message")
def test_waiverdb_message_missing_subject_type(self, mock_log): """ Assert that the consumer logs and returns if we could not find the subject type in the message. """ bad_message = Message(topic="", body={"subject": {"foo": "bar"}}) self.handler(bad_message) assert mock_log.error.call_count == 1 mock_log.error.assert_called_with( f"Couldn't find item type in message {bad_message.id}")
def test_resultsdb_message_missing_data(self, mock_log): """ Assert that the consumer logs and returns if we could not find the data dict in the message. """ bad_message = Message(topic="", body={"foo": "bar"}) self.handler(bad_message) assert mock_log.error.call_count == 1 mock_log.error.assert_called_with( f"Couldn't find data dict in ResultsDB message {bad_message.id}")
def test_messaging_callback_composer_installed(self, Handler): """Test receiving a composer.start message when the composer is installed.""" msg = Message(topic="org.fedoraproject.prod.bodhi.composer.start", body={}) handler = mock.Mock() Handler.side_effect = lambda: handler Consumer()(msg) handler.assert_called_once_with(msg)
def test_messaging_callback_updates_testing(self, Handler): msg = Message( topic="org.fedoraproject.prod.bodhi.update.request.testing", body={}) handler = mock.Mock() Handler.side_effect = lambda: handler Consumer()(msg) handler.assert_called_once_with(msg)
def test_greenwave_message_missing_policies_satisfied(self, mock_log): """ Assert that the consumer raise an exception if we could not find the policies_satisfied in the message """ bad_message = Message(topic="", body={"subject_identifier": "foobar"}) self.handler(bad_message) self.assertEqual(mock_log.debug.call_count, 1) mock_log.debug.assert_called_with( "Couldn't find policies_satisfied in Greenwave message")