From 09e8f40fcfc0a2f28a43ff7bcb7ad4280a25e3be Mon Sep 17 00:00:00 2001 From: Ralph Bean Date: Mar 01 2018 18:53:17 +0000 Subject: Factor in absence waivers. Previously, we did work to retrieve waivers from waiverdb that were stored in relation to the absence of a result. However, the `check` method of our rule short-circuited itself if a result was missing and it never even consulted the correctly retrieved waivers. This adjusts that logic to account for waivers-of-absences. It also adds a test, confirming that it works. --- diff --git a/greenwave/policies.py b/greenwave/policies.py index cfb7064..af8de2d 100644 --- a/greenwave/policies.py +++ b/greenwave/policies.py @@ -150,21 +150,31 @@ class PassingTestCaseRule(Rule): yaml_loader = yaml.SafeLoader def check(self, item, results, waivers): - matching_results = [r for r in results if r['testcase']['name'] == self.test_case_name] + matching_results = [ + r for r in results if r['testcase']['name'] == self.test_case_name] + matching_waivers = [ + w for w in waivers if (w['testcase'] == self.test_case_name and w['waived'] is True)] # Rules may optionally specify a scenario to limit applicability. if self._scenario: matching_results = [r for r in matching_results if self.scenario in r['data'].get('scenario', [])] + # Investigate the absence of results first. if not matching_results: - return TestResultMissing(item, self.test_case_name, self._scenario) + if not matching_waivers: + return TestResultMissing(item, self.test_case_name, self._scenario) + else: + # The result is absent, but the absence is waived. + return RuleSatisfied() + # If we find multiple matching results, we always use the first one which # will be the latest chronologically, because ResultsDB always returns # results ordered by `submit_time` descending. matching_result = matching_results[0] if matching_result['outcome'] in ['PASSED', 'INFO']: return RuleSatisfied() + # XXX limit who is allowed to waive if any(w['subject'] == dict([(key, value[0]) for key, value in matching_result['data'].items()]) and diff --git a/greenwave/tests/test_policies.py b/greenwave/tests/test_policies.py index c2fb390..cbe5493 100644 --- a/greenwave/tests/test_policies.py +++ b/greenwave/tests/test_policies.py @@ -6,7 +6,12 @@ import pytest from greenwave import __version__ from greenwave.app_factory import create_app -from greenwave.policies import summarize_answers, RuleSatisfied, TestResultMissing, TestResultFailed +from greenwave.policies import ( + summarize_answers, + RuleSatisfied, + TestResultMissing, + TestResultFailed, +) from greenwave.utils import load_policies @@ -24,6 +29,34 @@ def test_summarize_answers(): '1 of 2 required tests not found' +def test_waive_absence_of_result(tmpdir): + p = tmpdir.join('fedora.yaml') + p.write(""" +--- !Policy +id: "rawhide_compose_sync_to_mirrors" +product_versions: + - fedora-rawhide +decision_context: rawhide_compose_sync_to_mirrors +blacklist: [] +rules: + - !PassingTestCaseRule {test_case_name: sometest} + """) + policies = load_policies(tmpdir.strpath) + policy = policies[0] + + # Ensure that absence of a result is failure. + item, results, waivers = {}, [], [] + decision = policy.check(item, results, waivers) + assert len(decision) == 1 + assert isinstance(decision[0], TestResultMissing) + + # But also that waiving the absence works. + waivers = [{'testcase': 'sometest', 'waived': True}] + decision = policy.check(item, results, waivers) + assert len(decision) == 1 + assert isinstance(decision[0], RuleSatisfied) + + def test_load_policies(): app = create_app('greenwave.config.TestingConfig') assert len(app.config['policies']) > 0