From 272576b9c09407e379798a06f1c6d2439052269b Mon Sep 17 00:00:00 2001 From: Chenxiong Qi Date: Nov 30 2017 12:51:03 +0000 Subject: Build images according to configurable Errata state * Use whitelist to allow to rebuild by advisory state. For development, either running freshmaker in development mode or running tests, states REL_PREP, PUSH_READY, IN_PUSH, SHIPPED_LIVE are set. * ErrataAdvisoryRPMsSignedHandler.handle is changed. If the advisory being handled currently is in SHIPPED_LIVE, do not request comopse from ODCS for it and start to rebuild the first batch images immediately. * Add new property errata_state to event class ErrataAdvisoryRPMsSignedEvent. It is used in ErrataAdvisoryRPMsSignedHandler.handle. And all code that initiate ErrataAdvisoryRPMsSignedEvent event object are updated by passing advisory.state accordingly. * Calling allow_build in BrewSignRPMHandler.handle and ErrataAdvisoryStateChangedHandler.handle by passing advisory state to determine whether the state is allowed by whitelist. * Add tests. Signed-off-by: Chenxiong Qi --- diff --git a/conf/config.py b/conf/config.py index 2e48831..0218b92 100644 --- a/conf/config.py +++ b/conf/config.py @@ -265,6 +265,23 @@ class TestConfiguration(BaseConfiguration): AUTH_LDAP_SERVER = 'ldap://ldap.example.com' AUTH_LDAP_GROUP_BASE = 'ou=groups,dc=example,dc=com' + HANDLER_BUILD_WHITELIST = { + 'BrewSignRPMHandler': { + 'image': [ + { + 'advisory_state': 'REL_PREP|PUSH_READY|IN_PUSH|SHIPPED_LIVE', + }, + ], + }, + 'ErrataAdvisoryStateChangedHandler': { + 'image': [ + { + 'advisory_state': 'REL_PREP|PUSH_READY|IN_PUSH|SHIPPED_LIVE', + }, + ], + }, + } + class ProdConfiguration(BaseConfiguration): pass diff --git a/conf/configrh.py b/conf/configrh.py index 015a35d..9e6d2f8 100644 --- a/conf/configrh.py +++ b/conf/configrh.py @@ -61,6 +61,23 @@ class BaseConfiguration(config.BaseConfiguration): AUTH_LDAP_SERVER = '' AUTH_LDAP_GROUP_BASE = 'ou=groups,dc=redhat,dc=com' + HANDLER_BUILD_WHITELIST = { + 'BrewSignRPMHandler': { + 'image': [ + { + 'advisory_state': 'SHIPPED_LIVE', + }, + ], + }, + 'ErrataAdvisoryStateChangedHandler': { + 'image': [ + { + 'advisory_state': 'SHIPPED_LIVE', + }, + ], + }, + } + class DevConfiguration(BaseConfiguration): DEBUG = True @@ -75,6 +92,23 @@ class DevConfiguration(BaseConfiguration): LIGHTBLUE_VERIFY_SSL = False + HANDLER_BUILD_WHITELIST = { + 'BrewSignRPMHandler': { + 'image': [ + { + 'advisory_state': 'REL_PREP|PUSH_READY|IN_PUSH|SHIPPED_LIVE', + }, + ], + }, + 'ErrataAdvisoryStateChangedHandler': { + 'image': [ + { + 'advisory_state': 'REL_PREP|PUSH_READY|IN_PUSH|SHIPPED_LIVE', + }, + ], + }, + } + class TestConfiguration(BaseConfiguration): LOG_BACKEND = 'console' diff --git a/freshmaker/events.py b/freshmaker/events.py index ddbc0aa..64d6d2e 100644 --- a/freshmaker/events.py +++ b/freshmaker/events.py @@ -267,11 +267,12 @@ class ErrataAdvisoryRPMsSignedEvent(BaseEvent): """ Event when all RPMs in Errata advisory are signed. """ - def __init__(self, msg_id, errata_name, errata_id, security_impact): + def __init__(self, msg_id, errata_name, errata_id, security_impact, state): super(ErrataAdvisoryRPMsSignedEvent, self).__init__(msg_id) self.errata_name = errata_name self.errata_id = errata_id self.security_impact = security_impact + self.errata_state = state @property def search_key(self): diff --git a/freshmaker/handlers/brew/sign_rpm.py b/freshmaker/handlers/brew/sign_rpm.py index 9fc7f7a..1ce1493 100644 --- a/freshmaker/handlers/brew/sign_rpm.py +++ b/freshmaker/handlers/brew/sign_rpm.py @@ -21,8 +21,7 @@ # # Written by Chenxiong Qi -from freshmaker import log -from freshmaker import db +from freshmaker import db, log from freshmaker.events import BrewSignRPMEvent, ErrataAdvisoryRPMsSignedEvent from freshmaker.handlers import BaseHandler from freshmaker.errata import Errata @@ -73,8 +72,10 @@ class BrewSignRPMHandler(BaseHandler): # Filter out advisories which are not allowed by configuration. advisories = [advisory for advisory in advisories if self.allow_build( - ArtifactType.IMAGE, advisory_name=advisory.name, - advisory_security_impact=advisory.security_impact)] + ArtifactType.IMAGE, + advisory_name=advisory.name, + advisory_security_impact=advisory.security_impact, + advisory_state=advisory.state)] # Filter out advisories which are already in Freshmaker DB. advisories = self._filter_out_existing_advisories(advisories) @@ -97,7 +98,8 @@ class BrewSignRPMHandler(BaseHandler): for advisory in advisories: new_event = ErrataAdvisoryRPMsSignedEvent( event.msg_id + "." + str(advisory.name), advisory.name, - advisory.errata_id, advisory.security_impact) + advisory.errata_id, advisory.security_impact, + advisory.state) db_event = Event.create( db.session, new_event.msg_id, new_event.search_key, new_event.__class__, released=False) diff --git a/freshmaker/handlers/errata/errata_advisory_rpms_signed.py b/freshmaker/handlers/errata/errata_advisory_rpms_signed.py index 5ebce94..ea4639d 100644 --- a/freshmaker/handlers/errata/errata_advisory_rpms_signed.py +++ b/freshmaker/handlers/errata/errata_advisory_rpms_signed.py @@ -28,7 +28,7 @@ import koji from freshmaker import conf, db, log from freshmaker.events import ErrataAdvisoryRPMsSignedEvent from freshmaker.events import ODCSComposeStateChangeEvent -from freshmaker.handlers import BaseHandler, fail_event_on_handler_exception +from freshmaker.handlers import ContainerBuildHandler, fail_event_on_handler_exception from freshmaker.kojiservice import koji_service from freshmaker.lightblue import LightBlue from freshmaker.pulp import Pulp @@ -43,7 +43,7 @@ from odcs.client.odcs import AuthMech from odcs.common.types import COMPOSE_STATES -class ErrataAdvisoryRPMsSignedHandler(BaseHandler): +class ErrataAdvisoryRPMsSignedHandler(ContainerBuildHandler): """ Rebuilds all Docker images which contain packages from the Errata advisory. @@ -77,7 +77,8 @@ class ErrataAdvisoryRPMsSignedHandler(BaseHandler): # Check if we are allowed to build this advisory. if not event.manual and not self.allow_build( - ArtifactType.IMAGE, advisory_name=event.errata_name, + ArtifactType.IMAGE, + advisory_name=event.errata_name, advisory_security_impact=event.security_impact): msg = ("Errata advisory {0} is not allowed by internal policy " "to trigger rebuilds.".format(event.errata_id)) @@ -99,47 +100,27 @@ class ErrataAdvisoryRPMsSignedHandler(BaseHandler): db.session.commit() return [] - # Generate the ODCS compose with RPMs from the current advisory. - repo_urls = [] - repo_urls.append(self._prepare_yum_repo(db_event)) # noqa - - # Find out extra events we want to include. These are advisories - # which are not released yet and touches some Docker images which - # are shared with the initial list of docker images we are going to - # rebuild. - # If we For example have NSS Errata advisory and httpd advisory, we - # need to rebuild some Docker images with both NSS and httpd - # advisories. - # We also want to search for extra events recursively, because there - # might for example be zlib advisory, and we want to include this zlib - # advisory when rebuilding NSS when rebuilding httpd... :) - prev_builds_count = 0 - seen_extra_events = [] - - # We stop when we did not find more docker images to rebuild and - # therefore cannot find more extra events. - while prev_builds_count != len(builds): - prev_builds_count = len(builds) - extra_events = self._find_events_to_include(db_event, builds) - log.info("Extra events: %r", extra_events) - for ev in extra_events: - if ev in seen_extra_events: - continue - seen_extra_events.append(ev) - db_event.add_event_dependency(db.session, ev) - for batches in self._find_images_to_rebuild(ev.search_key): - builds = self._record_batches(batches, event, builds) - repo_urls.append(self._prepare_yum_repo(ev)) - - db.session.commit() - # Remove duplicates from repo_urls. - repo_urls = list(set(repo_urls)) + if event.errata_state != 'SHIPPED_LIVE': + # If freshmaker is configured to rebuild images only when advisory + # moves to SHIPPED_LIVE state, there is no need to generate new + # composes for rebuild as all signed RPMs should already be + # available from official YUM repositories. + # + # Generate the ODCS compose with RPMs from the current advisory. + repo_urls = self._prepare_yum_repos_for_rebuilds( + db_event, event, builds) + log.info("Following repositories will be used for the rebuild:") + for url in repo_urls: + log.info(" - %s", url) # Log what we are going to rebuild self._check_images_to_rebuild(db_event, builds) - log.info("Following repositories will be used for the rebuild:") - for url in repo_urls: - log.info(" - %s", url) + + if event.errata_state == 'SHIPPED_LIVE': + # As mentioned above, no need to wait for the event of new compose + # is generated in ODCS, so we can start to rebuild the first batch + # from here immediately. + self._build_first_batch(db_event) db_event.transition(EventState.COMPLETE, "All docker images have been rebuilt.") @@ -174,6 +155,42 @@ class ErrataAdvisoryRPMsSignedHandler(BaseHandler): return new_compose + def _prepare_yum_repos_for_rebuilds(self, db_event, event, builds): + repo_urls = [] + repo_urls.append(self._prepare_yum_repo(db_event)) # noqa + + # Find out extra events we want to include. These are advisories + # which are not released yet and touches some Docker images which + # are shared with the initial list of docker images we are going to + # rebuild. + # If we For example have NSS Errata advisory and httpd advisory, we + # need to rebuild some Docker images with both NSS and httpd + # advisories. + # We also want to search for extra events recursively, because there + # might for example be zlib advisory, and we want to include this zlib + # advisory when rebuilding NSS when rebuilding httpd... :) + prev_builds_count = 0 + seen_extra_events = [] + + # We stop when we did not find more docker images to rebuild and + # therefore cannot find more extra events. + while prev_builds_count != len(builds): + prev_builds_count = len(builds) + extra_events = self._find_events_to_include(db_event, builds) + log.info("Extra events: %r", extra_events) + for ev in extra_events: + if ev in seen_extra_events: + continue + seen_extra_events.append(ev) + db_event.add_event_dependency(db.session, ev) + for batches in self._find_images_to_rebuild(ev.search_key): + builds = self._record_batches(batches, event, builds) + repo_urls.append(self._prepare_yum_repo(ev)) + + db.session.commit() + # Remove duplicates from repo_urls. + return list(set(repo_urls)) + def _prepare_yum_repo(self, db_event): """ Prepare a yum repo for rebuild diff --git a/freshmaker/handlers/errata/errata_advisory_state_changed.py b/freshmaker/handlers/errata/errata_advisory_state_changed.py index 0794b98..754ea36 100644 --- a/freshmaker/handlers/errata/errata_advisory_state_changed.py +++ b/freshmaker/handlers/errata/errata_advisory_state_changed.py @@ -25,7 +25,7 @@ from freshmaker.events import ( from freshmaker.models import Event, EVENT_TYPES from freshmaker.handlers import BaseHandler, fail_event_on_handler_exception from freshmaker.errata import Errata -from freshmaker.types import EventState +from freshmaker.types import EventState, ArtifactType class ErrataAdvisoryStateChangedHandler(BaseHandler): @@ -95,7 +95,7 @@ class ErrataAdvisoryStateChangedHandler(BaseHandler): advisory = advisories[0] db_event = ErrataAdvisoryRPMsSignedEvent( event.msg_id + "." + str(advisory.name), advisory.name, - advisory.errata_id, advisory.security_impact) + advisory.errata_id, advisory.security_impact, advisory.state) return [db_event] def handle(self, event): @@ -104,7 +104,7 @@ class ErrataAdvisoryStateChangedHandler(BaseHandler): extra_events = [] - if state in ["REL_PREP", "PUSH_READY", "IN_PUSH", "SHIPPED_LIVE"]: + if self.allow_build(ArtifactType.IMAGE, advisory_state=event.state): extra_events += self.rebuild_if_not_exists(event, errata_id) if state == "SHIPPED_LIVE": diff --git a/freshmaker/handlers/internal/manual_rebuild.py b/freshmaker/handlers/internal/manual_rebuild.py index baa49d0..b74c36b 100644 --- a/freshmaker/handlers/internal/manual_rebuild.py +++ b/freshmaker/handlers/internal/manual_rebuild.py @@ -74,7 +74,7 @@ class FreshmakerManualRebuildHandler(ContainerBuildHandler): advisory = advisories[0] new_event = ErrataAdvisoryRPMsSignedEvent( event.msg_id + "." + str(advisory.name), advisory.name, - advisory.errata_id, advisory.security_impact) + advisory.errata_id, advisory.security_impact, advisory.state) new_event.manual = True msg = ("Generated ErrataAdvisoryRPMsSignedEvent (%s) for errata: %s" % (event.msg_id, errata_id)) diff --git a/freshmaker/lightblue.py b/freshmaker/lightblue.py index 4c071ed..01c2543 100644 --- a/freshmaker/lightblue.py +++ b/freshmaker/lightblue.py @@ -228,9 +228,9 @@ class ContainerImage(dict): continue log.info("Container image %s does not have 'repositories' set " - "in Ligblue. Using child image %s content_sets: %r", - self["brew"]["build"], child["brew"]["build"], - child["content_sets"]) + "in Ligblue. Using child image %s content_sets: %r", + self["brew"]["build"], child["brew"]["build"], + child["content_sets"]) self.update({"content_sets": child["content_sets"]}) return diff --git a/tests/test_errata_advisory_rpms_signed_handler.py b/tests/test_errata_advisory_rpms_signed_handler.py index 449c031..426298f 100644 --- a/tests/test_errata_advisory_rpms_signed_handler.py +++ b/tests/test_errata_advisory_rpms_signed_handler.py @@ -39,18 +39,168 @@ class TestErrataAdvisoryRPMsSignedHandler(unittest.TestCase): db.create_all() db.session.commit() + # We do not want to send messages to message bus while running tests + self.messaging_publish_patcher = patch('freshmaker.messaging.publish') + self.mock_messaging_publish = self.messaging_publish_patcher.start() + + # Each time when recording a build into database, freshmaker has to + # request a pulp repo from ODCS. This is not necessary for running + # tests. + # There are 6 images used to run tests which will be created below, so + # there should be 6 composes created as Pulp repos. + self.prepare_pulp_repo_patcher = patch( + 'freshmaker.handlers.errata.ErrataAdvisoryRPMsSignedHandler.' + '_prepare_pulp_repo', + side_effect=[{'id': compose_id} for compose_id in range(1, 7)]) + self.mock_prepare_pulp_repo = self.prepare_pulp_repo_patcher.start() + + self.find_images_patcher = patch( + 'freshmaker.handlers.errata.ErrataAdvisoryRPMsSignedHandler.' + '_find_images_to_rebuild') + self.mock_find_images_to_rebuild = self.find_images_patcher.start() + + # Fake images found to rebuild has these relationships + # + # Batch 1 | Batch 2 | Batch 3 + # image_a | image_c (child of image_a) | image_f (child of image_e) + # image_b | image_d (child of image_a) | + # | image_e (child of image_b) | + # + self.image_a = { + 'repository': 'repo_1', + 'commit': '1234567', + 'target': 'docker-container-candidate', + 'git_branch': 'rhel-7.4', + 'content_sets': ['image_a_content_set_1', 'image_a_content_set_2'], + 'brew': { + 'build': 'image-a-1.0-2', + }, + 'parent': None, + } + self.image_b = { + 'repository': 'repo_2', + 'commit': '23e9f22', + 'target': 'docker-container-candidate', + 'git_branch': 'rhel-7.4', + 'content_sets': ['image_b_content_set_1', 'image_b_content_set_2'], + 'brew': { + 'build': 'image-b-1.0-1' + }, + 'parent': None, + } + self.image_c = { + 'repository': 'repo_2', + 'commit': '2345678', + 'target': 'docker-container-candidate', + 'git_branch': 'rhel-7.4', + 'content_sets': ['image_c_content_set_1', 'image_d_content_set_2'], + 'brew': { + 'build': 'image-c-0.2-9', + }, + 'parent': self.image_a, + } + self.image_d = { + 'repository': 'repo_2', + 'commit': '5678901', + 'target': 'docker-container-candidate', + 'git_branch': 'rhel-7.4', + 'content_sets': ['image_d_content_set_1', 'image_d_content_set_2'], + 'brew': { + 'build': 'image-d-2.14-1', + }, + 'parent': self.image_a, + } + self.image_e = { + 'repository': 'repo_2', + 'commit': '7890123', + 'target': 'docker-container-candidate', + 'git_branch': 'rhel-7.4', + 'content_sets': ['image_e_content_set_1', 'image_e_content_set_2'], + 'brew': { + 'build': 'image-e-1.0-1', + }, + 'parent': self.image_b, + } + self.image_f = { + 'repository': 'repo_2', + 'commit': '3829384', + 'target': 'docker-container-candidate', + 'git_branch': 'rhel-7.4', + 'content_sets': ['image_f_content_set_1', 'image_f_content_set_2'], + 'brew': { + 'build': 'image-f-0.2-1', + }, + 'parent': self.image_b, + } + # For simplicify, mocking _find_images_to_rebuild to just return one + # batch, which contains images found for rebuild from parent to + # childrens. + self.mock_find_images_to_rebuild.return_value = iter([ + [ + [self.image_a, self.image_b], + [self.image_c, self.image_d, self.image_e], + [self.image_f] + ] + ]) + def tearDown(self): + self.find_images_patcher.stop() + self.prepare_pulp_repo_patcher.stop() + self.messaging_publish_patcher.stop() + db.session.remove() db.drop_all() db.session.commit() - @patch("freshmaker.handlers.errata.ErrataAdvisoryRPMsSignedHandler._find_images_to_rebuild") - def test_event_state_updated_when_no_images_to_rebuild(self, mock_find_images): - mock_find_images.return_value = [] - event = ErrataAdvisoryRPMsSignedEvent("123", "RHBA-2017", 123, "") + def test_event_state_updated_when_no_images_to_rebuild(self): + self.mock_find_images_to_rebuild.return_value = iter([[[]]]) + event = ErrataAdvisoryRPMsSignedEvent( + "123", "RHBA-2017", 123, "", "REL_PREP") handler = ErrataAdvisoryRPMsSignedHandler() handler.handle(event) db_event = Event.get(db.session, message_id='123') self.assertEqual(db_event.state, EventState.SKIPPED.value) - self.assertEqual(db_event.state_reason, "No container images to rebuild for advisory 'RHBA-2017'") + self.assertEqual( + db_event.state_reason, + "No container images to rebuild for advisory 'RHBA-2017'") + + @patch('freshmaker.handlers.errata.ErrataAdvisoryRPMsSignedHandler.' + 'allow_build', return_value=True) + @patch('freshmaker.handlers.errata.ErrataAdvisoryRPMsSignedHandler.' + '_prepare_yum_repos_for_rebuilds') + @patch('freshmaker.handlers.errata.ErrataAdvisoryRPMsSignedHandler.' + '_build_first_batch') + def test_rebuild_if_errata_state_is_prior_to_SHIPPED_LIVE( + self, build_first_batch, prepare_yum_repos_for_rebuilds, + allow_build): + event = ErrataAdvisoryRPMsSignedEvent( + 'msg-id-123', 'RHSA-2017', 123, '', 'REL_PREP') + handler = ErrataAdvisoryRPMsSignedHandler() + handler.handle(event) + + prepare_yum_repos_for_rebuilds.assert_called_once() + build_first_batch.assert_not_called() + + db_event = Event.get(db.session, event.msg_id) + self.assertEqual(EventState.COMPLETE.value, db_event.state) + + @patch('freshmaker.handlers.errata.ErrataAdvisoryRPMsSignedHandler.' + 'allow_build', return_value=True) + @patch('freshmaker.handlers.errata.ErrataAdvisoryRPMsSignedHandler.' + '_prepare_yum_repos_for_rebuilds') + @patch('freshmaker.handlers.errata.ErrataAdvisoryRPMsSignedHandler.' + '_build_first_batch') + def test_rebuild_if_errata_state_is_SHIPPED_LIVE( + self, build_first_batch, prepare_yum_repos_for_rebuilds, + allow_build): + event = ErrataAdvisoryRPMsSignedEvent( + 'msg-id-123', 'RHSA-2017', 123, '', 'SHIPPED_LIVE') + handler = ErrataAdvisoryRPMsSignedHandler() + handler.handle(event) + + prepare_yum_repos_for_rebuilds.assert_not_called() + build_first_batch.assert_called_once() + + db_event = Event.get(db.session, event.msg_id) + self.assertEqual(EventState.COMPLETE.value, db_event.state) diff --git a/tests/test_errata_advisory_state_changed.py b/tests/test_errata_advisory_state_changed.py index 890b921..24290f1 100644 --- a/tests/test_errata_advisory_state_changed.py +++ b/tests/test_errata_advisory_state_changed.py @@ -32,7 +32,7 @@ from freshmaker.events import ErrataAdvisoryRPMsSignedEvent from freshmaker.events import ErrataAdvisoryStateChangedEvent from freshmaker.errata import ErrataAdvisory -from freshmaker import db, events +from freshmaker import conf, db, events from freshmaker.models import Event, ArtifactBuild from freshmaker.types import ArtifactBuildState, ArtifactType, EventState @@ -109,7 +109,7 @@ class TestAllowBuild(unittest.TestCase): """ Tests that allow_build filters out advisories based on advisory_name. """ - event = ErrataAdvisoryRPMsSignedEvent("123", "RHBA-2017", 123, "") + event = ErrataAdvisoryRPMsSignedEvent("123", "RHBA-2017", 123, "", "REL_PREP") handler = ErrataAdvisoryRPMsSignedHandler() handler.handle(event) @@ -125,7 +125,8 @@ class TestAllowBuild(unittest.TestCase): Tests that allow_build does not filter out advisories based on advisory_name. """ - event = ErrataAdvisoryRPMsSignedEvent("123", "RHSA-2017", 123, "") + event = ErrataAdvisoryRPMsSignedEvent( + "123", "RHSA-2017", 123, "", "REL_PREP") handler = ErrataAdvisoryRPMsSignedHandler() handler.handle(event) @@ -153,8 +154,8 @@ class TestAllowBuild(unittest.TestCase): Tests that allow_build does not filter out advisories based on advisory_security_impact. """ - event = ErrataAdvisoryRPMsSignedEvent("123", "RHSA-2017", 123, - "Important") + event = ErrataAdvisoryRPMsSignedEvent( + "123", "RHSA-2017", 123, "Important", "REL_PREP") handler = ErrataAdvisoryRPMsSignedHandler() handler.handle(event) @@ -180,7 +181,8 @@ class TestAllowBuild(unittest.TestCase): Tests that allow_build dost filter out advisories based on advisory_security_impact. """ - event = ErrataAdvisoryRPMsSignedEvent("123", "RHSA-2017", 123, "None") + event = ErrataAdvisoryRPMsSignedEvent( + "123", "RHSA-2017", 123, "None", "REL_PREP") handler = ErrataAdvisoryRPMsSignedHandler() handler.handle(event) @@ -204,7 +206,7 @@ class TestAllowBuild(unittest.TestCase): handler = ErrataAdvisoryRPMsSignedHandler() handler.event = ErrataAdvisoryRPMsSignedEvent( - "123", "RHSA-2017", 123, "None") + "123", "RHSA-2017", 123, "None", "REL_PREP") image = {"brew": {"build": "foo-1-2.3"}} ret = handler._filter_out_not_allowed_builds(image) @@ -241,7 +243,7 @@ class TestAllowBuild(unittest.TestCase): handler = ErrataAdvisoryRPMsSignedHandler() handler.event = ErrataAdvisoryRPMsSignedEvent( - "123", "RHSA-2017", 123, "None") + "123", "RHSA-2017", 123, "None", "REL_PREP") image = {"brew": {"build": "foo-1-2.3"}} ret = handler._filter_out_not_allowed_builds(image) @@ -799,6 +801,15 @@ class TestErrataAdvisoryStateChangedHandler(unittest.TestCase): self.assertEqual(ret[0].errata_name, "RHSA-2017") @patch('freshmaker.errata.Errata.advisories_from_event') + @patch.object(conf, 'handler_build_whitelist', new={ + 'ErrataAdvisoryStateChangedHandler': { + 'image': [ + { + 'advisory_state': r'REL_PREP|SHIPPED_LIVE', + } + ] + } + }) def test_rebuild_if_not_exists_unknown_states( self, advisories_from_event): handler = ErrataAdvisoryStateChangedHandler() @@ -884,6 +895,32 @@ class TestErrataAdvisoryStateChangedHandler(unittest.TestCase): handler = ErrataAdvisoryStateChangedHandler() handler.handle(ev) + @patch('freshmaker.handlers.errata.ErrataAdvisoryStateChangedHandler' + '.rebuild_if_not_exists') + @patch.object(conf, 'handler_build_whitelist', new={ + 'ErrataAdvisoryStateChangedHandler': { + 'image': [ + { + 'advisory_state': r'REL_PREP', + } + ] + } + }) + def test_not_rebuild_if_errata_state_is_not_allowed( + self, rebuild_if_not_exists): + rebuild_if_not_exists.return_value = [Mock(), Mock()] + + Event.create(db.session, "msg-id-123", "123456", + ErrataAdvisoryRPMsSignedEvent, False) + db.session.commit() + + event = ErrataAdvisoryStateChangedEvent( + 'msg-id-123', '123456', 'SHIPPED_LIVE') + handler = ErrataAdvisoryStateChangedHandler() + msgs = handler.handle(event) + + self.assertEqual([], msgs) + class TestRecordBatchesImages(unittest.TestCase): """Test ErrataAdvisoryRPMsSignedHandler._record_batches"""