From 90836e10f845edfe34bb3335e3901f947859594d Mon Sep 17 00:00:00 2001 From: Lukas Holecek Date: Sep 12 2018 08:24:51 +0000 Subject: Try to get product version for decision change Omits publishing incorrect policies in decision change messages when it's possible to get the product version from the new test result subject. Fixes #198 --- diff --git a/functional-tests/conftest.py b/functional-tests/conftest.py index e1b9ae9..0135ab7 100644 --- a/functional-tests/conftest.py +++ b/functional-tests/conftest.py @@ -249,11 +249,11 @@ class TestDataBuilder(object): self.distgit_url = distgit_url self._counter = itertools.count(1) - def unique_nvr(self, name='glibc'): - return '{}-1.0-{}.el7'.format(name, next(self._counter)) + def unique_nvr(self, name='glibc', product_version='el7'): + return '{}-1.0-{}.{}'.format(name, next(self._counter), product_version) def unique_compose_id(self): - return 'Fedora-9000-19700101.n.{}'.format(next(self._counter)) + return 'Fedora-Rawhide-19700101.n.{}'.format(next(self._counter)) def _create_result(self, data): response = self.requests_session.post( diff --git a/functional-tests/consumers/test_resultsdb.py b/functional-tests/consumers/test_resultsdb.py index f32d672..1010a03 100644 --- a/functional-tests/consumers/test_resultsdb.py +++ b/functional-tests/consumers/test_resultsdb.py @@ -13,7 +13,7 @@ def test_consume_new_result( mock_fedmsg, load_config, requests_session, greenwave_server, testdatabuilder): load_config.return_value = {'greenwave_api_url': greenwave_server + 'api/v1.0'} - nvr = testdatabuilder.unique_nvr() + nvr = testdatabuilder.unique_nvr(product_version='fc26') update = testdatabuilder.create_bodhi_update(build_nvrs=[nvr]) updateid = update['updateid'] result = testdatabuilder.create_result(item=nvr, @@ -122,7 +122,7 @@ def test_consume_new_result( assert actual_msgs_sent[1] == { 'policies_satisfied': True, 'decision_context': 'bodhi_update_push_testing', - 'product_version': 'fedora-*', + 'product_version': 'fedora-26', 'satisfied_requirements': [ { 'result_id': result['id'], @@ -531,7 +531,7 @@ def test_consume_legacy_result( """ load_config.return_value = {'greenwave_api_url': greenwave_server + 'api/v1.0'} - nvr = testdatabuilder.unique_nvr() + nvr = testdatabuilder.unique_nvr(product_version='fc26') result = testdatabuilder.create_result(item=nvr, testcase_name='dist.rpmdeplint', outcome='PASSED') @@ -636,7 +636,7 @@ def test_consume_legacy_result( second_msg = { 'policies_satisfied': True, 'decision_context': 'bodhi_update_push_testing', - 'product_version': 'fedora-*', + 'product_version': 'fedora-26', 'satisfied_requirements': [{ 'result_id': result['id'], 'testcase': 'dist.rpmdeplint', diff --git a/greenwave/consumers/resultsdb.py b/greenwave/consumers/resultsdb.py index 717a1ae..05c87ad 100644 --- a/greenwave/consumers/resultsdb.py +++ b/greenwave/consumers/resultsdb.py @@ -11,6 +11,7 @@ to the message bus about the newly satisfied/unsatisfied policy. import collections import logging +import re from flask import current_app import fedmsg.consumers @@ -20,10 +21,65 @@ import greenwave.app_factory import greenwave.resources from greenwave.api_v1 import subject_type_identifier_to_list +import xmlrpc.client + log = logging.getLogger(__name__) +def _guess_product_version(toparse, koji_build=False): + if toparse == 'rawhide' or toparse.startswith('Fedora-Rawhide'): + return 'fedora-rawhide' + + product_version = None + if toparse.startswith('f') and koji_build: + product_version = 'fedora-' + elif toparse.startswith('epel'): + product_version = 'epel-' + elif toparse.startswith('el'): + product_version = 'rhel-' + elif toparse.startswith('fc') or toparse.startswith('Fedora'): + product_version = 'fedora-' + + if product_version: + # seperate the prefix from the number + result = list(filter(None, '-'.join(re.split(r'(\d+)', toparse)).split('-'))) + if len(result) >= 2: + try: + int(result[1]) + product_version += result[1] + return product_version + except ValueError: + pass + + return None + + +def _subject_product_version(subject_identifier, subject_type): + if subject_type == 'koji_build': + try: + short_prod_version = subject_identifier.split('.')[-1] + return _guess_product_version(short_prod_version, koji_build=True) + except KeyError: + pass + + if subject_type == "compose": + return _guess_product_version(subject_identifier) + + koji_base_url = current_app.config['KOJI_BASE_URL'] + if koji_base_url: + proxy = xmlrpc.client.ServerProxy(koji_base_url) + try: + build = proxy.getBuild(subject_identifier) + if build: + target = proxy.getTaskRequest(build['task_id'])[1] + return _guess_product_version(target, koji_build=True) + except KeyError: + pass + except xmlrpc.client.Fault: + pass + + def _invalidate_results_cache( cache, subject_type, subject_identifier, testcase): """ @@ -180,9 +236,14 @@ class ResultsDBHandler(fedmsg.consumers.FedmsgConsumer): # Given all of our applicable policies, build a map of all decision # context we know about, and which product versions they relate to. decision_contexts = collections.defaultdict(set) + product_version = _subject_product_version(subject_identifier, subject_type) for policy in applicable_policies: - versions = set(policy.product_versions) - decision_contexts[policy.decision_context].update(versions) + if not product_version or policy.applies_to_product_version(product_version): + if product_version: + versions = set([product_version]) + else: + versions = set(policy.product_versions) + decision_contexts[policy.decision_context].update(versions) log.debug("messaging: found %i decision contexts", len(decision_contexts)) # For every context X version combination, ask greenwave if this new @@ -226,5 +287,4 @@ class ResultsDBHandler(fedmsg.consumers.FedmsgConsumer): }) log.debug('Emitted a fedmsg, %r, on the "%s" topic', decision, 'greenwave.decision.update') - print('--------------------', decision['satisfied_requirements']) fedmsg.publish(topic='decision.update', msg=decision) diff --git a/greenwave/policies.py b/greenwave/policies.py index 3f02e34..486f9d4 100644 --- a/greenwave/policies.py +++ b/greenwave/policies.py @@ -493,7 +493,7 @@ class Policy(SafeYAMLObject): def applies_to(self, decision_context, product_version, subject_type): return (decision_context == self.decision_context and - self._applies_to_product_version(product_version) and + self.applies_to_product_version(product_version) and subject_type == self.subject_type) def check(self, subject_identifier, results_retriever, waivers): @@ -511,7 +511,7 @@ class Policy(SafeYAMLObject): answers.append(response) return answers - def _applies_to_product_version(self, product_version): + def applies_to_product_version(self, product_version): return any(fnmatch(product_version, version) for version in self.product_versions) @property