From 5f72bfe9adacee6ecc8e22976951f85f05a729f7 Mon Sep 17 00:00:00 2001 From: Matt Jia Date: Sep 22 2017 08:43:00 +0000 Subject: conditionally publish messages for new result/waiver events For new result/waiver events, we only publish a fedmsg message if the old decision is different from new decision. --- diff --git a/functional-tests/consumers/test_resultsdb.py b/functional-tests/consumers/test_resultsdb.py index 2352fc2..edc9aee 100644 --- a/functional-tests/consumers/test_resultsdb.py +++ b/functional-tests/consumers/test_resultsdb.py @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0+ import mock +import json from greenwave.consumers import resultsdb @@ -8,7 +9,7 @@ from greenwave.consumers import resultsdb @mock.patch('greenwave.consumers.resultsdb.fedmsg.config.load_config') @mock.patch('greenwave.consumers.resultsdb.fedmsg.publish') def test_consume_new_result( - mock_fedmsg, load_config, greenwave_server, testdatabuilder, monkeypatch): + mock_fedmsg, load_config, requests_session, greenwave_server, testdatabuilder, monkeypatch): monkeypatch.setenv('TEST', 'true') load_config.return_value = {'greenwave_api_url': greenwave_server.url + 'api/v1.0'} nvr = testdatabuilder.unique_nvr() @@ -34,6 +35,20 @@ def test_consume_new_result( handler = resultsdb.ResultsDBHandler(hub) assert handler.topic == ['topic_prefix.environment.taskotron.result.new'] handler.consume(message) + + # get old decision + data = { + 'decision_context': 'bodhi_update_push_stable', + 'product_version': 'fedora-26', + 'subject': [{'item': nvr, 'type': 'koji_build'}], + 'ignore_result': [result['id']] + } + r = requests_session.post(greenwave_server.url + 'api/v1.0/decision', + headers={'Content-Type': 'application/json'}, + data=json.dumps(data)) + assert r.status_code == 200 + old_decision = r.json() + msg = { 'policies_satisified': False, 'decision_context': 'bodhi_update_push_stable', @@ -63,7 +78,47 @@ def test_consume_new_result( 'type': 'koji_build' } ], - 'applicable_policies': ['taskotron_release_critical_tasks'] + 'applicable_policies': ['taskotron_release_critical_tasks'], + 'previous': old_decision, } mock_fedmsg.assert_called_once_with( topic='greenwave.decision.update', msg=msg) + + +@mock.patch('greenwave.consumers.resultsdb.fedmsg.config.load_config') +@mock.patch('greenwave.consumers.resultsdb.fedmsg.publish') +def test_no_message_for_unchanged_decision( + mock_fedmsg, load_config, requests_session, greenwave_server, testdatabuilder, monkeypatch): + monkeypatch.setenv('TEST', 'true') + load_config.return_value = {'greenwave_api_url': greenwave_server.url + 'api/v1.0'} + nvr = testdatabuilder.unique_nvr() + testdatabuilder.create_result(item=nvr, + testcase_name='dist.rpmdeplint', + outcome='PASSED') + # create another new result for dist.rpmdeplint which passed again. + new_result = testdatabuilder.create_result( + item=nvr, + testcase_name='dist.rpmdeplint', + outcome='PASSED') + message = { + 'topic': 'taskotron.result.new', + 'msg': { + 'result': { + 'id': new_result['id'], + 'outcome': 'PASSED' + }, + 'task': { + 'item': nvr, + 'type': 'koji_build', + 'name': 'dist.rpmdeplint' + } + } + } + hub = mock.MagicMock() + hub.config = {'environment': 'environment', 'topic_prefix': 'topic_prefix'} + handler = resultsdb.ResultsDBHandler(hub) + assert handler.topic == ['topic_prefix.environment.taskotron.result.new'] + handler.consume(message) + # No message should be published as the decision is unchanged since we + # are still missing the required tests. + mock_fedmsg.assert_not_called() diff --git a/functional-tests/consumers/test_waiverdb.py b/functional-tests/consumers/test_waiverdb.py index eff409b..f1cc935 100644 --- a/functional-tests/consumers/test_waiverdb.py +++ b/functional-tests/consumers/test_waiverdb.py @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0+ import mock +import json from greenwave.consumers import waiverdb @@ -14,8 +15,8 @@ TASKTRON_RELEASE_CRITICAL_TASKS = [ @mock.patch('greenwave.consumers.resultsdb.fedmsg.config.load_config') @mock.patch('greenwave.consumers.waiverdb.fedmsg.publish') -def test_consume_new_result( - mock_fedmsg, load_config, greenwave_server, testdatabuilder, monkeypatch): +def test_consume_new_waiver( + mock_fedmsg, load_config, requests_session, greenwave_server, testdatabuilder, monkeypatch): monkeypatch.setenv('TEST', 'true') load_config.return_value = {'greenwave_api_url': greenwave_server.url + 'api/v1.0'} nvr = testdatabuilder.unique_nvr() @@ -27,10 +28,11 @@ def test_consume_new_result( testdatabuilder.create_result(item=nvr, testcase_name=testcase_name, outcome='PASSED') - testdatabuilder.create_waiver(result_id=result['id'], product_version='fedora-26') + waiver = testdatabuilder.create_waiver(result_id=result['id'], product_version='fedora-26') message = { 'topic': 'waiver.new', "msg": { + "id": waiver['id'], "comment": "Because I said so", "username": "foo", "waived": "true", @@ -44,6 +46,20 @@ def test_consume_new_result( handler = waiverdb.WaiverDBHandler(hub) assert handler.topic == ['topic_prefix.environment.waiver.new'] handler.consume(message) + + # get old decision + data = { + 'decision_context': 'bodhi_update_push_stable', + 'product_version': 'fedora-26', + 'subject': [{'item': [nvr], 'type': ['koji_build']}], + 'ignore_waiver': [waiver['id']] + } + r = requests_session.post(greenwave_server.url + 'api/v1.0/decision', + headers={'Content-Type': 'application/json'}, + data=json.dumps(data)) + assert r.status_code == 200 + old_decision = r.json() + msg = { 'policies_satisified': True, 'decision_context': 'bodhi_update_push_stable', @@ -56,7 +72,8 @@ def test_consume_new_result( 'type': ['koji_build'] } ], - 'applicable_policies': ['taskotron_release_critical_tasks'] + 'applicable_policies': ['taskotron_release_critical_tasks'], + 'previous': old_decision, } mock_fedmsg.assert_called_once_with( topic='greenwave.decision.update', msg=msg) diff --git a/greenwave/api_v1.py b/greenwave/api_v1.py index ded3d47..7f1f0fd 100644 --- a/greenwave/api_v1.py +++ b/greenwave/api_v1.py @@ -197,6 +197,7 @@ def make_decision(): answers = [] for item in subjects: results = retrieve_results(item) + results = [r for r in results if r['id'] not in ignore_results] if results: waivers = retrieve_waivers(product_version, results) else: diff --git a/greenwave/consumers/resultsdb.py b/greenwave/consumers/resultsdb.py index 43d8265..680ec6b 100644 --- a/greenwave/consumers/resultsdb.py +++ b/greenwave/consumers/resultsdb.py @@ -81,12 +81,25 @@ class ResultsDBHandler(fedmsg.consumers.FedmsgConsumer): headers={'Content-Type': 'application/json'}, data=json.dumps(data)) response.raise_for_status() - msg = response.json() - msg.update({ - 'subject': [task], - 'decision_context': policy.decision_context, - 'product_version': product_version, + decision = response.json() + # get old decision + data.update({ + 'ignore_result': [msg['result']['id']], }) - log.debug('Emitted a fedmsg, %r, on the "%s" topic', msg, - 'greenwave.decision.update') - fedmsg.publish(topic='greenwave.decision.update', msg=msg) + response = requests_session.post( + self.fedmsg_config['greenwave_api_url'] + '/decision', + headers={'Content-Type': 'application/json'}, + data=json.dumps(data)) + response.raise_for_status() + old_decision = response.json() + if decision != old_decision: + msg = decision + decision.update({ + 'subject': [task], + 'decision_context': policy.decision_context, + 'product_version': product_version, + 'previous': old_decision, + }) + log.debug('Emitted a fedmsg, %r, on the "%s" topic', msg, + 'greenwave.decision.update') + fedmsg.publish(topic='greenwave.decision.update', msg=msg) diff --git a/greenwave/consumers/waiverdb.py b/greenwave/consumers/waiverdb.py index 3803284..b9a2378 100644 --- a/greenwave/consumers/waiverdb.py +++ b/greenwave/consumers/waiverdb.py @@ -65,6 +65,7 @@ class WaiverDBHandler(fedmsg.consumers.FedmsgConsumer): product_version = msg['product_version'] config = load_config() timeout = config['REQUESTS_TIMEOUT'] + # Get the waived result to figure out the item response = requests_session.get( config['RESULTSDB_API_URL'] + '/results/%d' % result_id, timeout=timeout) @@ -83,12 +84,27 @@ class WaiverDBHandler(fedmsg.consumers.FedmsgConsumer): self.fedmsg_config['greenwave_api_url'] + '/decision', headers={'Content-Type': 'application/json'}, data=json.dumps(data)) - msg = response.json() - msg.update({ - 'subject': [item], - 'decision_context': policy.decision_context, - 'product_version': product_version, + decision = response.json() + + # get old decision + data.update({ + 'ignore_waiver': [msg['id']], }) - log.debug('Emitted a fedmsg, %r, on the "%s" topic', msg, - 'greenwave.decision.update') - fedmsg.publish(topic='greenwave.decision.update', msg=msg) + response = requests_session.post( + self.fedmsg_config['greenwave_api_url'] + '/decision', + headers={'Content-Type': 'application/json'}, + data=json.dumps(data)) + response.raise_for_status() + old_decision = response.json() + + if decision != old_decision: + msg = decision + decision.update({ + 'subject': [item], + 'decision_context': policy.decision_context, + 'product_version': product_version, + 'previous': old_decision, + }) + log.debug('Emitted a fedmsg, %r, on the "%s" topic', msg, + 'greenwave.decision.update') + fedmsg.publish(topic='greenwave.decision.update', msg=msg)