From fdaedaf69f1797ae0cf7d453017b66c826c9eb5a Mon Sep 17 00:00:00 2001 From: Giulia Naponiello Date: Feb 05 2019 14:58:40 +0000 Subject: Retrieve only latest results with verbose=True When asking for a decision to the GW APIs with flag verbose=True, Greenwave retrieves all matching results from ResulsDB. When those results are *a lot*, the request hits timeout causing the all decision call to fail. It would be just better to ask the lastest results for that filtering, since we don't really care about the old ones. --- diff --git a/functional-tests/test_api_v1.py b/functional-tests/test_api_v1.py index 06cc3f2..91f05a6 100644 --- a/functional-tests/test_api_v1.py +++ b/functional-tests/test_api_v1.py @@ -1114,3 +1114,31 @@ def test_decision_on_redhat_module(requests_session, greenwave_server, testdatab expected_summary = 'All required tests passed' assert res_data['summary'] == expected_summary res_data['results'][0]['data']['type'][0] == 'redhat-module' + + +def test_verbose_retrieve_latest_results(requests_session, greenwave_server, testdatabuilder): + nvr = testdatabuilder.unique_nvr() + for outcome in ['FAILED', 'PASSED']: + for testcase_name in TASKTRON_RELEASE_CRITICAL_TASKS: + testdatabuilder.create_result(item=nvr, + testcase_name=testcase_name, + outcome=outcome) + data = { + 'decision_context': 'bodhi_update_push_stable', + 'product_version': 'fedora-26', + 'subject_type': 'koji_build', + 'subject_identifier': nvr, + 'verbose': True + } + + r = requests_session.post(greenwave_server + 'api/v1.0/decision', + headers={'Content-Type': 'application/json'}, + data=json.dumps(data)) + assert r.status_code == 200 + res_data = r.json() + assert res_data['policies_satisfied'] is True + expected_summary = 'All required tests passed' + assert res_data['summary'] == expected_summary + assert len(res_data['results']) == 3 + for result in res_data['results']: + assert result['outcome'] == 'PASSED' diff --git a/greenwave/api_v1.py b/greenwave/api_v1.py index fe11adf..3c4d55d 100644 --- a/greenwave/api_v1.py +++ b/greenwave/api_v1.py @@ -360,7 +360,8 @@ def make_decision(): if verbose: # Retrieve test results for all items when verbose output is requested. - verbose_results.extend(results_retriever.retrieve(subject_type, subject_identifier)) + verbose_results.extend( + results_retriever.retrieve_latest(subject_type, subject_identifier)) verbose_waivers.extend(waivers) response = { diff --git a/greenwave/resources.py b/greenwave/resources.py index 48cebf5..d200618 100644 --- a/greenwave/resources.py +++ b/greenwave/resources.py @@ -54,15 +54,22 @@ class ResultsRetriever(object): self.verify = verify self.url = url + def retrieve_latest(self, subject_type, subject_identifier): + """ + Return generator over latest results. + """ + params = {} + return self._retrieve_helper(params, subject_type, subject_identifier, latest=True) + def retrieve(self, subject_type, subject_identifier, testcase=None): """ Return generator over results. """ - for result in self._retrieve_helper(subject_type, subject_identifier, testcase): + for result in self._retrieve_all(subject_type, subject_identifier, testcase): if result['id'] not in self.ignore_results: yield result - def _retrieve_helper(self, subject_type, subject_identifier, testcase): + def _retrieve_all(self, subject_type, subject_identifier, testcase): cache_key = results_cache_key( subject_type, subject_identifier, testcase) @@ -75,50 +82,50 @@ class ResultsRetriever(object): while cached_results.can_fetch_more: cached_results.last_page += 1 - results = self._retrieve_page( - cached_results.last_page, subject_type, subject_identifier, - testcase) + params = { + 'limit': 1, + 'page': cached_results.last_page, + } + + if testcase: + params['testcases'] = testcase + results = self._retrieve_helper(params, subject_type, subject_identifier) cached_results.results.extend(results) cached_results.can_fetch_more = bool(results) self.cache.set(cache_key, cached_results) for result in results: yield result - def _make_request(self, params): + def _make_request(self, params, latest=False): + request_url = self.url + '/results' + if latest: + request_url += '/latest' response = requests_session.get( - self.url + '/results', params=params, verify=self.verify, timeout=self.timeout) + request_url, params=params, verify=self.verify, timeout=self.timeout) response.raise_for_status() return response.json()['data'] - def _retrieve_page(self, page, subject_type, subject_identifier, testcase): - params = { - 'limit': 1, - 'page': page, - } - - if testcase: - params['testcases'] = testcase - + def _retrieve_helper(self, params, subject_type, subject_identifier, latest=False): results = [] if subject_type == 'koji_build': params['type'] = subject_type params['item'] = subject_identifier - results = self._make_request(params=params) + results = self._make_request(params=params, latest=latest) params['type'] = 'brew-build' - results.extend(self._make_request(params=params)) + results.extend(self._make_request(params=params, latest=latest)) del params['type'] del params['item'] params['original_spec_nvr'] = subject_identifier - results.extend(self._make_request(params=params)) + results.extend(self._make_request(params=params, latest=latest)) elif subject_type == 'compose': params['productmd.compose.id'] = subject_identifier - results = self._make_request(params=params) + results = self._make_request(params=params, latest=latest) else: params['type'] = subject_type params['item'] = subject_identifier - results = self._make_request(params=params) + results = self._make_request(params=params, latest=latest) return results diff --git a/greenwave/tests/test_policies.py b/greenwave/tests/test_policies.py index a008149..3c2a015 100644 --- a/greenwave/tests/test_policies.py +++ b/greenwave/tests/test_policies.py @@ -37,7 +37,7 @@ class DummyResultsRetriever(ResultsRetriever): self.testcase = testcase self.outcome = outcome - def _make_request(self, params): + def _make_request(self, params, latest=False): if (params.get('item') == self.subject_identifier and params.get('type') == self.subject_type and params.get('testcases') == self.testcase):