From 1ec1ceca68a71251a68f5eea273e2458b8cafb4c Mon Sep 17 00:00:00 2001 From: Lukas Holecek Date: Aug 29 2018 14:24:42 +0000 Subject: Fetch all results when verbose=true Fixes #287 --- diff --git a/conf/policies/fedora.yaml b/conf/policies/fedora.yaml index 698723b..433f0d3 100644 --- a/conf/policies/fedora.yaml +++ b/conf/policies/fedora.yaml @@ -72,6 +72,14 @@ blacklist: [] rules: - !PassingTestCaseRule {test_case_name: a_package_test} +--- !Policy +id: "taskotron_release_critical_tasks_for_stable" +product_versions: + - fedora-28 +decision_context: bodhi_update_push_stable_with_no_rules +subject_type: koji_build +rules: [] + # No Fedora product has *actually* used an empty policy like this, # but we cover it in our tests for completeness. --- !Policy diff --git a/functional-tests/consumers/test_resultsdb.py b/functional-tests/consumers/test_resultsdb.py index a1b8f98..f85881a 100644 --- a/functional-tests/consumers/test_resultsdb.py +++ b/functional-tests/consumers/test_resultsdb.py @@ -320,8 +320,13 @@ def test_invalidate_new_result_with_mocked_cache( #'topic_prefix.environment.waiver.new', ] handler.consume(message) - cache_key = 'greenwave.resources:CachedResults|koji_build {} dist.rpmdeplint'.format(nvr) - handler.cache.delete.assert_called_once_with(cache_key) + cache_key1 = 'greenwave.resources:CachedResults|koji_build {} dist.rpmdeplint'.format(nvr) + cache_key2 = 'greenwave.resources:CachedResults|koji_build {} None'.format(nvr) + handler.cache.delete.assert_has_calls([ + mock.call(cache_key1), + mock.call(cache_key2) + ]) + assert handler.cache.delete.call_count == 2 @mock.patch('greenwave.consumers.resultsdb.fedmsg.config.load_config') @@ -442,8 +447,13 @@ def test_invalidate_new_result_with_no_preexisting_cache( #'topic_prefix.environment.waiver.new', ] handler.consume(message) - cache_key = 'greenwave.resources:CachedResults|koji_build {} dist.rpmdeplint'.format(nvr) - handler.cache.delete.assert_called_once_with(cache_key) + cache_key1 = 'greenwave.resources:CachedResults|koji_build {} dist.rpmdeplint'.format(nvr) + cache_key2 = 'greenwave.resources:CachedResults|koji_build {} None'.format(nvr) + handler.cache.delete.assert_has_calls([ + mock.call(cache_key1), + mock.call(cache_key2) + ]) + assert handler.cache.delete.call_count == 2 @mock.patch('greenwave.consumers.resultsdb.fedmsg.config.load_config') diff --git a/functional-tests/test_api_v1.py b/functional-tests/test_api_v1.py index ea04fde..392b3e3 100644 --- a/functional-tests/test_api_v1.py +++ b/functional-tests/test_api_v1.py @@ -36,7 +36,7 @@ def test_inspect_policies(requests_session, greenwave_server): assert r.status_code == 200 body = r.json() policies = body['policies'] - assert len(policies) == 9 + assert len(policies) == 10 assert any(p['id'] == 'taskotron_release_critical_tasks' for p in policies) assert any(p['decision_context'] == 'bodhi_update_push_stable' for p in policies) assert any(p['product_versions'] == ['fedora-26'] for p in policies) @@ -953,3 +953,38 @@ def test_make_a_decision_about_compose_new_variants_architectures( assert r.status_code == 200 res_data = r.json() assert res_data['policies_satisfied'] + + +def test_make_a_decision_for_bodhi_with_verbose_flag( + requests_session, greenwave_server, testdatabuilder): + """ + Bodhi uses verbose flag to get all results. + """ + nvrs = [ + testdatabuilder.unique_nvr(), + testdatabuilder.unique_nvr(), + ] + + results = [] + for nvr in reversed(nvrs): + for testcase_name in TASKTRON_RELEASE_CRITICAL_TASKS: + results.append(testdatabuilder.create_result( + item=nvr, testcase_name=testcase_name, outcome='PASSED')) + + update = testdatabuilder.create_bodhi_update(build_nvrs=nvrs) + data = { + 'decision_context': 'bodhi_update_push_stable_with_no_rules', + 'product_version': 'fedora-28', + 'subject_type': 'bodhi_update', + 'subject_identifier': update['updateid'], + 'verbose': True, + } + + r = requests_session.post(greenwave_server + 'api/v1.0/decision', json=data) + assert r.status_code == 200 + res_data = r.json() + + assert len(res_data['results']) == len(TASKTRON_RELEASE_CRITICAL_TASKS) * len(nvrs) + assert res_data['results'] == list(reversed(results)) + assert res_data['waivers'] == [] + assert res_data['satisfied_requirements'] == [] diff --git a/greenwave/api_v1.py b/greenwave/api_v1.py index e5fafde..95c95e6 100644 --- a/greenwave/api_v1.py +++ b/greenwave/api_v1.py @@ -354,6 +354,8 @@ def make_decision(): for policy in build_policies: answers.extend(policy.check(nvr, results_retriever, nvr_waivers)) + else: + build_nvrs = [] res = { 'policies_satisfied': all(answer.is_satisfied for answer in answers), @@ -363,8 +365,13 @@ def make_decision(): if not answer.is_satisfied], } if verbose: + # Retrieve test results for all items when verbose output is requested. + results = list(results_retriever.retrieve(subject_type, subject_identifier)) + for nvr in build_nvrs: + results += results_retriever.retrieve('koji_build', nvr) + res.update({ - 'results': results_retriever.all_retrieved_results(), + 'results': results, 'waivers': waivers, 'satisfied_requirements': [answer.to_json() for answer in answers if answer.is_satisfied], diff --git a/greenwave/consumers/resultsdb.py b/greenwave/consumers/resultsdb.py index fbc2d10..9e0cbc9 100644 --- a/greenwave/consumers/resultsdb.py +++ b/greenwave/consumers/resultsdb.py @@ -39,6 +39,11 @@ def _invalidate_results_cache( except KeyError: log.debug("No cache value found for %r", key) + # Also invalidate query results without test case name. + if testcase: + _invalidate_results_cache( + cache, subject_type, subject_identifier, testcase=None) + class ResultsDBHandler(fedmsg.consumers.FedmsgConsumer): """ diff --git a/greenwave/resources.py b/greenwave/resources.py index ee1534d..9285ab9 100644 --- a/greenwave/resources.py +++ b/greenwave/resources.py @@ -52,22 +52,13 @@ class ResultsRetriever(object): self.timeout = timeout self.verify = verify self.url = url - self.all_results = [] - def all_retrieved_results(self): - """ - Returns all results retrieved from cache or ResultsDB by this instance. - """ - return sorted(self.all_results, key=lambda x: x['id'], reverse=True) - - def retrieve(self, subject_type, subject_identifier, testcase): + def retrieve(self, subject_type, subject_identifier, testcase=None): """ Return generator over results. """ for result in self._retrieve_helper(subject_type, subject_identifier, testcase): if result['id'] not in self.ignore_results: - if result not in self.all_results: - self.all_results.append(result) yield result def _retrieve_helper(self, subject_type, subject_identifier, testcase): @@ -100,11 +91,13 @@ class ResultsRetriever(object): def _retrieve_page(self, page, subject_type, subject_identifier, testcase): params = { - 'testcases': testcase, 'limit': 1, 'page': page, } + if testcase: + params['testcases'] = testcase + results = [] if subject_type == 'bodhi_update': params['type'] = subject_type