def test_creating_event_and_builds(self): event = Event.create(db.session, "test_msg_id", "RHSA-2017-284", events.TestingEvent) build = ArtifactBuild.create(db.session, event, "ed", "module", 1234, rebuild_reason=RebuildReason.DIRECTLY_AFFECTED.value) ArtifactBuild.create(db.session, event, "mksh", "module", 1235, build, rebuild_reason=RebuildReason.DEPENDENCY.value) db.session.commit() db.session.expire_all() e = db.session.query(Event).filter(event.id == 1).one() self.assertEqual(e.message_id, "test_msg_id") self.assertEqual(e.search_key, "RHSA-2017-284") self.assertEqual(e.event_type, events.TestingEvent) self.assertEqual(len(e.builds.all()), 2) self.assertEqual(e.builds[0].name, "ed") self.assertEqual(e.builds[0].type, 2) self.assertEqual(e.builds[0].state, 0) self.assertEqual(e.builds[0].build_id, 1234) self.assertEqual(e.builds[0].dep_on, None) self.assertEqual(e.builds[0].rebuild_reason, RebuildReason.DIRECTLY_AFFECTED.value) self.assertEqual(e.builds[1].name, "mksh") self.assertEqual(e.builds[1].type, 2) self.assertEqual(e.builds[1].state, 0) self.assertEqual(e.builds[1].build_id, 1235) self.assertEqual(e.builds[1].dep_on.name, "ed") self.assertEqual(e.builds[1].rebuild_reason, RebuildReason.DEPENDENCY.value)
def test_event_json_min(self): with patch('freshmaker.models.datetime') as datetime_patch: datetime_patch.utcnow.return_value = datetime.datetime(2017, 8, 21, 13, 42, 20) event = Event.create(db.session, "test_msg_id5", "RHSA-2017-289", events.TestingEvent) build = ArtifactBuild.create(db.session, event, "ed", "module", 1234) build.state = ArtifactBuildState.FAILED ArtifactBuild.create(db.session, event, "mksh", "module", 1235, build) db.session.commit() self.assertEqual(event.json_min(), { 'builds_summary': {'BUILD': 1, 'FAILED': 1, 'total': 2}, 'dry_run': False, 'event_type_id': 3, 'id': 1, 'message_id': 'test_msg_id5', 'requester': None, 'search_key': 'RHSA-2017-289', 'state': 0, 'state_name': 'INITIALIZED', 'state_reason': None, 'time_created': '2017-08-21T13:42:20Z', 'time_done': None, 'url': 'http://localhost:5001/api/1/events/1', 'requested_rebuilds': [], 'requester_metadata': {}, 'depending_events': [], 'depends_on_events': [], })
def test_handle(self, allow_build, handle_auto_rebuild, prepare_builds, start_to_build_images): event = BotasErrataShippedEvent("test_msg_id", self.botas_advisory) db_event = Event.get_or_create_from_event(db.session, event) allow_build.return_value = True handle_auto_rebuild.return_value = [{"bundle": 1}, {"bundle": 2}] prepare_builds.return_value = [ ArtifactBuild.create(db.session, db_event, "ed0", "image", 1234, original_nvr="some_name-2-12345", rebuilt_nvr="some_name-2-12346"), ArtifactBuild.create(db.session, db_event, "ed0", "image", 12345, original_nvr="some_name_2-2-2", rebuilt_nvr="some_name_2-2-210") ] self.handler.handle(event) self.handler._prepare_builds.assert_called_once() self.assertEqual(self.handler._prepare_builds.call_args[0][0], db_event) self.assertEqual(self.handler._prepare_builds.call_args[0][1], [{ "bundle": 1 }, { "bundle": 2 }])
def test_depending_artifact_builds(self): event = Event.create(db.session, "test_msg_id", "test", events.TestingEvent) parent = ArtifactBuild.create(db.session, event, "parent", "module", 1234) build2 = ArtifactBuild.create(db.session, event, "mksh", "module", 1235, parent) build3 = ArtifactBuild.create(db.session, event, "runtime", "module", 1236, parent) ArtifactBuild.create(db.session, event, "perl-runtime", "module", 1237) db.session.commit() deps = set(parent.depending_artifact_builds()) self.assertEqual(deps, set([build2, build3]))
def setUp(self): super(TestPrepareYumRepo, self).setUp() self.ev = Event.create(db.session, 'msg-id', '123', 100) ArtifactBuild.create(db.session, self.ev, "parent", "image", state=ArtifactBuildState.PLANNED) db.session.commit()
def test_get_root_dep_on(self): event = Event.create(db.session, "test_msg_id", "test", events.TestingEvent) build1 = ArtifactBuild.create(db.session, event, "ed", "module", 1234) build2 = ArtifactBuild.create(db.session, event, "mksh", "module", 1235, build1) build3 = ArtifactBuild.create(db.session, event, "runtime", "module", 1236, build2) build4 = ArtifactBuild.create(db.session, event, "perl-runtime", "module", 1237, build3) db.session.commit() db.session.expire_all() self.assertEqual(build1.get_root_dep_on(), None) self.assertEqual(build2.get_root_dep_on(), build1) self.assertEqual(build3.get_root_dep_on(), build1) self.assertEqual(build4.get_root_dep_on(), build1)
def test_get_published_original_nvr_single_event(self): event1 = Event.create(db.session, "id1", "RHSA-1", TestingEvent) ArtifactBuild.create(db.session, event1, "ed0", "image", 1234, original_nvr="nvr1-0-1", rebuilt_nvr="nvr1-0-2") db.session.commit() self.pyxis()._pagination.return_value = [ {"repositories": [{"published": True}]} ] ret_nvr = self.handler.get_published_original_nvr("nvr1-0-2") self.assertEqual(ret_nvr, "nvr1-0-1")
def test_build_transition_recursion_not_done_for_ok_states(self): for i, state in enumerate([ArtifactBuildState.DONE.value, ArtifactBuildState.PLANNED.value]): event = Event.create(db.session, "test_msg_id_{}".format(i), "test", events.TestingEvent) build1 = ArtifactBuild.create(db.session, event, "ed", "module", 1234) build2 = ArtifactBuild.create(db.session, event, "mksh", "module", 1235, build1) build3 = ArtifactBuild.create(db.session, event, "runtime", "module", 1236, build2) build4 = ArtifactBuild.create(db.session, event, "perl-runtime", "module", 1237) db.session.commit() build1.transition(state, "reason") self.assertEqual(build1.state, state) self.assertEqual(build1.state_reason, "reason") for build in [build2, build3, build4]: self.assertEqual(build4.state, ArtifactBuildState.BUILD.value) self.assertEqual(build4.state_reason, None)
def test_get_repo_urls_extra_image_repo(self): build_3 = ArtifactBuild.create( db.session, self.event, 'build-3', ArtifactType.IMAGE, state=ArtifactBuildState.PLANNED, original_nvr="build-3-1") handler = MyHandler() repos = handler.get_repo_urls(build_3) self.assertEqual(repos, ["http://localhost/test.repo"])
def test_start_to_build_images(self, build_artifact): build_artifact.side_effect = [HTTPError('500 Server Error'), 1] db_event = Event.get_or_create(db.session, 'msg1', 'current_event', ErrataAdvisoryRPMsSignedEvent) build = ArtifactBuild.create(db.session, db_event, 'parent1-1-4', 'image') build2 = ArtifactBuild.create(db.session, db_event, 'parent1-1-5', 'image') db.session.commit() handler = MyHandler() with self.assertLogs('freshmaker', 'ERROR'): handler.start_to_build_images([build, build2]) self.assertEqual(build.state, ArtifactBuildState.FAILED.value) self.assertEqual(build2.state, ArtifactBuildState.BUILD.value) self.assertEqual(len(db.session.query(ArtifactBuild).all()), 2)
def setUp(self): super(TestArtifactBuildComposesRel, self). setUp() self.compose_1 = Compose(odcs_compose_id=-1) self.compose_2 = Compose(odcs_compose_id=2) self.compose_3 = Compose(odcs_compose_id=3) self.compose_4 = Compose(odcs_compose_id=4) db.session.add(self.compose_1) db.session.add(self.compose_2) db.session.add(self.compose_3) db.session.add(self.compose_4) self.event = Event.create( db.session, 'msg-1', 'search-key-1', EVENT_TYPES[ErrataAdvisoryRPMsSignedEvent], state=EventState.INITIALIZED, released=False) self.build_1 = ArtifactBuild.create( db.session, self.event, 'build-1', ArtifactType.IMAGE) self.build_1.build_id = 3 self.build_2 = ArtifactBuild.create( db.session, self.event, 'build-2', ArtifactType.IMAGE) self.build_2.build_id = -2 self.build_3 = ArtifactBuild.create( db.session, self.event, 'build-3', ArtifactType.IMAGE) self.build_3.build_id = None db.session.commit() rels = ( (self.build_1.id, self.compose_1.id), (self.build_1.id, self.compose_2.id), (self.build_1.id, self.compose_3.id), (self.build_2.id, self.compose_2.id), (self.build_2.id, self.compose_4.id), ) for build_id, compose_id in rels: db.session.add( ArtifactBuildCompose( build_id=build_id, compose_id=compose_id)) db.session.commit()
def test_context_artifact_build(self): db_event = Event.get_or_create(db.session, "msg1", "current_event", ErrataAdvisoryRPMsSignedEvent) build = ArtifactBuild.create(db.session, db_event, "parent1-1-4", "image") db.session.commit() handler = MyHandler() handler.set_context(build) self.assertEqual(handler.current_db_event_id, db_event.id) self.assertEqual(handler.current_db_artifact_build_id, build.id)
def setUp(self): super(TestPrepareYumReposForRebuilds, self).setUp() self.patcher = helpers.Patcher() self.mock_prepare_yum_repo = self.patcher.patch( 'freshmaker.odcsclient.FreshmakerODCSClient.prepare_yum_repo', side_effect=[ { 'id': 1, 'result_repofile': 'http://localhost/repo/1' }, { 'id': 2, 'result_repofile': 'http://localhost/repo/2' }, { 'id': 3, 'result_repofile': 'http://localhost/repo/3' }, { 'id': 4, 'result_repofile': 'http://localhost/repo/4' }, ]) self.mock_find_dependent_event = self.patcher.patch( 'freshmaker.models.Event.find_dependent_events') self.db_event = Event.create(db.session, 'msg-1', 'search-key-1', 1, state=EventState.INITIALIZED, released=False) self.build_1 = ArtifactBuild.create(db.session, self.db_event, 'build-1', ArtifactType.IMAGE) self.build_2 = ArtifactBuild.create(db.session, self.db_event, 'build-2', ArtifactType.IMAGE) db.session.commit()
def __init__(self, profile=None, dry_run=False): self._config = koji.read_config(profile or 'koji') self.dry_run = dry_run # In case we run in DRY_RUN mode, we need to initialize # _FAKE_TASK_ID to the id of last ODCS builds to have the IDs # increasing and unique even between Freshmaker restarts. if self.dry_run: KojiService._FAKE_TASK_ID = \ ArtifactBuild.get_lowest_build_id(db.session) - 1 if KojiService._FAKE_TASK_ID >= 0: KojiService._FAKE_TASK_ID = -1
def test_build_transition_recursion(self): for i, state in enumerate([ArtifactBuildState.FAILED.value, ArtifactBuildState.CANCELED.value]): event = Event.create(db.session, "test_msg_id_{}".format(i), "test", events.TestingEvent) build1 = ArtifactBuild.create(db.session, event, "ed", "module", 1234) build2 = ArtifactBuild.create(db.session, event, "mksh", "module", 1235, build1) build3 = ArtifactBuild.create(db.session, event, "runtime", "module", 1236, build2) build4 = ArtifactBuild.create(db.session, event, "perl-runtime", "module", 1237) db.session.commit() build1.transition(state, "reason") self.assertEqual(build1.state, state) self.assertEqual(build1.state_reason, "reason") for build in [build2, build3]: self.assertEqual(build.state, state) self.assertEqual( build.state_reason, "Cannot build artifact, because its " "dependency cannot be built.") self.assertEqual(build4.state, ArtifactBuildState.BUILD.value) self.assertEqual(build4.state_reason, None)
def setUp(self): super(TestCheckUnfinishedKojiTasks, self).setUp() self.koji_read_config_patcher = patch( 'koji.read_config', return_value={'server': 'http://localhost/'}) self.koji_read_config_patcher.start() db_event = Event.get_or_create( db.session, "msg1", "current_event", ErrataAdvisoryRPMsSignedEvent) db_event.state = EventState.BUILDING self.build = ArtifactBuild.create(db.session, db_event, "parent1-1-4", "image") self.build.state = ArtifactBuildState.BUILD self.build.build_id = 10 db.session.commit()
def _create_test_event(self, event_id, search_key, build_name, compose_id): db_event = Event.create(db.session, event_id, search_key, EVENT_TYPES[ErrataAdvisoryRPMsSignedEvent], state=EventState.INITIALIZED, released=False) build_1 = ArtifactBuild.create(db.session, db_event, build_name, ArtifactType.IMAGE, state=ArtifactBuildState.PLANNED) compose_1 = Compose(odcs_compose_id=compose_id) db.session.add(compose_1) db.session.commit() db.session.add( ArtifactBuildCompose(build_id=build_1.id, compose_id=compose_1.id)) db.session.commit() return db_event
def test_get_pullspecs_mapping(self): event = ManualBundleRebuild( "test_msg_id", container_images=[], bundle_images=["bundle_image_1", "bundle_image_2"]) event2 = BotasErrataShippedEvent("test_msg_id", self.botas_advisory) db_event = Event.get_or_create_from_event(db.session, event2) build = ArtifactBuild.create(db.session, db_event, "ed0", "image", 1234, rebuilt_nvr="bundle_image_1") build.bundle_pullspec_overrides = { "pullspec_replacements": [{ "new": "some_pullspec", "original": "original_pullspec", "pinned": True }, { "new": "new_pullspec", "original": "original_pullspec", "pinned": True, "_old": "old_pullspec" }] } self.handler.event = event db.session.commit() with self.assertLogs("freshmaker", "WARNING") as log: pullspec_map = self.handler._get_pullspecs_mapping() expected_map = {"old_pullspec": "new_pullspec"} self.assertTrue( "Can't find build for a bundle image \"bundle_image_2\"" in log.output[0]) self.assertEqual(pullspec_map, expected_map)
def test_get_published_original_nvr(self): event1 = Event.create(db.session, "id1", "RHSA-1", TestingEvent) ArtifactBuild.create(db.session, event1, "ed0", "image", 1234, original_nvr="nvr1", rebuilt_nvr="nvr1-001") event2 = Event.create(db.session, "id2", "RHSA-1", ManualRebuildWithAdvisoryEvent) ArtifactBuild.create(db.session, event2, "ed1", "image", 12345, original_nvr="nvr1-001", rebuilt_nvr="nvr1-002") event3 = Event.create(db.session, "id3", "RHSA-1", ManualRebuildWithAdvisoryEvent) ArtifactBuild.create(db.session, event3, "ed2", "image", 123456, original_nvr="nvr1-002", rebuilt_nvr="nvr1-003") db.session.commit() self.pyxis()._pagination.side_effect = [[{ "repositories": [{ "published": False }] }], [{ "repositories": [{ "published": True }] }]] ret_nvr = self.handler.get_published_original_nvr("nvr1-003") self.assertEqual(ret_nvr, "nvr1-001")
def mocked_handle(cls, msg): event = Event.get_or_create(db.session, "msg_id", "msg_id", 0) ArtifactBuild.create(db.session, event, "foo", 0) db.session.commit() cls.set_context(event) raise ValueError("Expected exception")
def setUp(self): super(TestRebuildImagesOnODCSComposeDone, self).setUp() # Test data # (Inner build depends on outer build) # Event (ErrataAdvisoryRPMsSignedEvent): # build 1: [compose 1, pulp compose 1] # build 2: [compose 1, pulp compose 2] # build 3: [compose 1, pulp compose 3] # build 4: [compose 1, pulp compose 4] # build 5: [compose 1, pulp compose 5] # build 6 (not planned): [compose 1, pulp compose 6] self.db_event = Event.create( db.session, 'msg-1', 'search-key-1', EVENT_TYPES[ErrataAdvisoryRPMsSignedEvent], state=EventState.INITIALIZED, released=False) self.build_1 = ArtifactBuild.create(db.session, self.db_event, 'build-1', ArtifactType.IMAGE, state=ArtifactBuildState.PLANNED) self.build_2 = ArtifactBuild.create(db.session, self.db_event, 'build-2', ArtifactType.IMAGE, dep_on=self.build_1, state=ArtifactBuildState.PLANNED) self.build_3 = ArtifactBuild.create(db.session, self.db_event, 'build-3', ArtifactType.IMAGE, state=ArtifactBuildState.PLANNED) self.build_4 = ArtifactBuild.create(db.session, self.db_event, 'build-4', ArtifactType.IMAGE, dep_on=self.build_3, state=ArtifactBuildState.PLANNED) self.build_5 = ArtifactBuild.create(db.session, self.db_event, 'build-5', ArtifactType.IMAGE, dep_on=self.build_3, state=ArtifactBuildState.PLANNED) self.build_6 = ArtifactBuild.create(db.session, self.db_event, 'build-6', ArtifactType.IMAGE, state=ArtifactBuildState.BUILD) self.compose_1 = Compose(odcs_compose_id=1) db.session.add(self.compose_1) db.session.commit() builds = [ self.build_1, self.build_2, self.build_3, self.build_4, self.build_5, self.build_6 ] composes = [self.compose_1] * 6 for build, compose in zip(builds, composes): db.session.add( ArtifactBuildCompose(build_id=build.id, compose_id=compose.id)) db.session.commit() # Create another DB event, build and compose just to have more data # in database. another_db_event = Event.create( db.session, 'msg-2', 'search-key-2', EVENT_TYPES[ErrataAdvisoryRPMsSignedEvent], state=EventState.INITIALIZED, released=False) another_build_1 = ArtifactBuild.create( db.session, another_db_event, 'another-build-1', ArtifactType.IMAGE, state=ArtifactBuildState.PLANNED) another_compose_1 = Compose(odcs_compose_id=2) db.session.add(another_compose_1) db.session.commit() db.session.add( ArtifactBuildCompose(build_id=another_build_1.id, compose_id=another_compose_1.id)) db.session.commit()
def test_handle_manual_rebuild(self, get_pullspecs_mapping, get_build, get_csv_updates): get_pullspecs_mapping.return_value = { "old_pullspec": "new_pullspec", "old_pullspec_2": "new_pullspec_2" } build_by_nvr = { "container_image_2_nvr": { "extra": { "image": { "operator_manifests": { "related_images": { "pullspecs": [{ "new": "newer_pullspes", "original": "original_pullspec", "pinned": True, }, { "new": "old_pullspec_2", "original": "original_pullspec_2", "pinned": True, }] } } } } } } bundle_pullspec_overrides = { "pullspec_replacements": [{ "new": "old_pullspec", "original": "original_pullspec_3", "pinned": True }] } digest_by_nvr = { "container_image_1_nvr": "container_image_1_digest", "container_image_2_nvr": "container_image_2_digest", } bundle_by_digest = { "container_image_1_digest": [{ "bundle_path_digest": "bundle_1", "csv_name": "image.1.2.5", "version": "1.2.5", }], "container_image_2_digest": [{ "bundle_path_digest": "bundle_2", "csv_name": "image.1.2.5", "version": "1.2.5", }], } event = ManualBundleRebuild("test_msg_id", container_images=[ "container_image_1_nvr", "container_image_2_nvr" ], bundle_images=[]) db_event = Event.get_or_create_from_event(db.session, event) self.handler.event = event get_build.side_effect = lambda nvr: build_by_nvr[nvr] build = ArtifactBuild.create(db.session, db_event, "ed0", "image", 1234, rebuilt_nvr="container_image_1_nvr") build.bundle_pullspec_overrides = bundle_pullspec_overrides def gmldbn(nvr, must_be_published=True): return digest_by_nvr[nvr] self.pyxis().get_manifest_list_digest_by_nvr.side_effect = gmldbn self.pyxis().get_bundles_by_digest.side_effect = \ lambda digest: bundle_by_digest[digest] get_csv_updates.return_value = {"update": "csv_update_placeholder"} db.session.commit() bundles_to_rebuild = self.handler._handle_manual_rebuild(db_event) expected_bundles = [{ "nvr": "container_image_1_nvr", "update": "csv_update_placeholder", "pullspec_replacements": [{ "new": "new_pullspec", "original": "original_pullspec_3", "pinned": True }] }, { "nvr": "container_image_2_nvr", "update": "csv_update_placeholder", "pullspec_replacements": [{ "new": "newer_pullspes", "original": "original_pullspec", "pinned": True, }, { "new": "new_pullspec_2", "original": "original_pullspec_2", "pinned": True, }], }] self.assertCountEqual(bundles_to_rebuild, expected_bundles) self.pyxis().get_manifest_list_digest_by_nvr.assert_has_calls( [call("container_image_1_nvr"), call("container_image_2_nvr")], any_order=True) self.assertEqual(self.pyxis().get_bundles_by_digest.call_count, 2) self.pyxis().get_bundles_by_digest.assert_has_calls([ call("container_image_1_digest"), call("container_image_2_digest") ], any_order=True)
def setUp(self): super(TestFindDependentEvents, self). setUp() self.event_1 = Event.create( db.session, 'msg-1', 'search-key-1', EVENT_TYPES[ErrataAdvisoryRPMsSignedEvent], state=EventState.INITIALIZED, released=False) ArtifactBuild.create( db.session, self.event_1, 'build-1', ArtifactType.IMAGE) ArtifactBuild.create( db.session, self.event_1, 'build-2', ArtifactType.IMAGE) ArtifactBuild.create( db.session, self.event_1, 'build-3', ArtifactType.IMAGE) ArtifactBuild.create( db.session, self.event_1, 'build-4', ArtifactType.IMAGE) self.event_2 = Event.create( db.session, 'msg-2', 'search-key-2', EVENT_TYPES[ErrataAdvisoryRPMsSignedEvent], state=EventState.BUILDING, released=False) ArtifactBuild.create( db.session, self.event_2, 'build-2', ArtifactType.IMAGE) ArtifactBuild.create( db.session, self.event_2, 'build-5', ArtifactType.IMAGE) ArtifactBuild.create( db.session, self.event_2, 'build-6', ArtifactType.IMAGE) self.event_3 = Event.create( db.session, 'msg-3', 'search-key-3', EVENT_TYPES[ErrataAdvisoryRPMsSignedEvent], state=EventState.COMPLETE, released=False) ArtifactBuild.create( db.session, self.event_3, 'build-2', ArtifactType.IMAGE) ArtifactBuild.create( db.session, self.event_3, 'build-4', ArtifactType.IMAGE) ArtifactBuild.create( db.session, self.event_3, 'build-7', ArtifactType.IMAGE) ArtifactBuild.create( db.session, self.event_3, 'build-8', ArtifactType.IMAGE) # Some noises # Failed events should not be included self.event_4 = Event.create( db.session, 'msg-4', 'search-key-4', EVENT_TYPES[ErrataAdvisoryRPMsSignedEvent], state=EventState.FAILED, released=False) ArtifactBuild.create( db.session, self.event_4, 'build-3', ArtifactType.IMAGE) # Manual triggered rebuild should not be included as well self.event_5 = Event.create( db.session, 'msg-5', 'search-key-5', EVENT_TYPES[ErrataAdvisoryRPMsSignedEvent], state=EventState.BUILDING, released=False, manual=True) ArtifactBuild.create( db.session, self.event_5, 'build-4', ArtifactType.IMAGE) # Released event should not be included also self.event_6 = Event.create( db.session, 'msg-6', 'search-key-6', EVENT_TYPES[ErrataAdvisoryRPMsSignedEvent], state=EventState.COMPLETE, released=True) ArtifactBuild.create( db.session, self.event_5, 'build-4', ArtifactType.IMAGE) db.session.commit()
def test_get_lowest_build_id(self): build_id = ArtifactBuild.get_lowest_build_id(db.session) self.assertEqual(build_id, -2)
def setUp(self): super(TestGetRepoURLs, self).setUp() self.compose_1 = Compose(odcs_compose_id=5) self.compose_2 = Compose(odcs_compose_id=6) self.compose_3 = Compose(odcs_compose_id=7) self.compose_4 = Compose(odcs_compose_id=8) db.session.add(self.compose_1) db.session.add(self.compose_2) db.session.add(self.compose_3) db.session.add(self.compose_4) self.event = Event.create(db.session, 'msg-1', 'search-key-1', EVENT_TYPES[ErrataAdvisoryRPMsSignedEvent], state=EventState.BUILDING, released=False) build_args = {} build_args["repository"] = "repo" build_args["commit"] = "hash" build_args["original_parent"] = None build_args["target"] = "target" build_args["branch"] = "branch" build_args["arches"] = "x86_64" build_args["renewed_odcs_compose_ids"] = None self.build_1 = ArtifactBuild.create(db.session, self.event, 'build-1', ArtifactType.IMAGE, state=ArtifactBuildState.PLANNED, original_nvr="foo-1-2") self.build_1.build_args = json.dumps(build_args) self.build_2 = ArtifactBuild.create(db.session, self.event, 'build-2', ArtifactType.IMAGE, state=ArtifactBuildState.PLANNED, original_nvr="foo-2-2") self.build_2.build_args = json.dumps(build_args) db.session.commit() rels = ( (self.build_1.id, self.compose_1.id), (self.build_1.id, self.compose_2.id), (self.build_1.id, self.compose_3.id), (self.build_1.id, self.compose_4.id), ) for build_id, compose_id in rels: db.session.add( ArtifactBuildCompose(build_id=build_id, compose_id=compose_id)) db.session.commit() def mocked_odcs_get_compose(compose_id): return { "id": compose_id, "result_repofile": "http://localhost/%d.repo" % compose_id, "state": COMPOSE_STATES["done"], } self.patch_odcs_get_compose = patch( "freshmaker.handlers.ContainerBuildHandler.odcs_get_compose", side_effect=mocked_odcs_get_compose) self.odcs_get_compose = self.patch_odcs_get_compose.start()
def test_handle(self): event = BotasErrataShippedEvent("test_msg_id", self.botas_advisory) self.handler.allow_build = MagicMock(return_value=True) self.handler._create_original_to_rebuilt_nvrs_map = \ MagicMock(return_value={"original_1": "some_name-1-12345", "original_2": "some_name_2-2-2"}) nvr_to_digest = { "original_1": "original_1_digest", "some_name-1-12345": "some_name-1-12345_digest", "original_2": "original_2_digest", "some_name_2-2-2": "some_name_2-2-2_digest", } bundles = [{ "bundle_path_digest": "original_1_digest" }, { "bundle_path_digest": "some_name-1-12345_digest" }, { "bundle_path_digest": "original_2_digest" }, { "bundle_path_digest": "some_name_2-2-2_digest" }] bundles_with_related_images = { "original_1_digest": [ { "bundle_path_digest": "bundle_with_related_images_1_digest", "csv_name": "image.1.2.3", "version": "1.2.3", }, ], "original_2_digest": [ { "bundle_path_digest": "bundle_with_related_images_2_digest", "csv_name": "image.1.2.4", "version": "1.2.4", }, ] } image_by_digest = { "bundle_with_related_images_1_digest": { "brew": { "build": "bundle1_nvr-1-1" } }, "bundle_with_related_images_2_digest": { "brew": { "build": "bundle2_nvr-1-1" } }, } self.pyxis( ).get_manifest_list_digest_by_nvr.side_effect = lambda x: nvr_to_digest[ x] self.pyxis().get_operator_indices.return_value = [] self.pyxis().get_latest_bundles.return_value = bundles # return bundles for original images self.pyxis( ).get_bundles_by_related_image_digest.side_effect = lambda x, y: bundles_with_related_images[ x] self.pyxis( ).get_images_by_digest.side_effect = lambda x: [image_by_digest[x]] self.handler.image_has_auto_rebuild_tag = MagicMock(return_value=True) get_build = self.patcher.patch( "freshmaker.kojiservice.KojiService.get_build") builds = { "bundle1_nvr-1-1": { "task_id": 1, "extra": { "image": { "operator_manifests": { "related_images": { "created_by_osbs": True, "pullspecs": [{ "new": "registry/repo/operator1@original_1_digest", "original": "registry/repo/operator1:v2.2.0", "pinned": True, }] }, } } } }, "bundle2_nvr-1-1": { "task_id": 2, "extra": { "image": { "operator_manifests": { "related_images": { "created_by_osbs": True, "pullspecs": [{ "new": "registry/repo/operator2@original_2_digest", "original": "registry/repo/operator2:v2.2.0", "pinned": True, }] }, } } } } } get_build.side_effect = lambda x: builds[x] db_event = Event.get_or_create_from_event(db.session, event) self.handler._prepare_builds = MagicMock(return_value=[ ArtifactBuild.create(db.session, db_event, "ed0", "image", 1234, original_nvr="some_name-2-12345", rebuilt_nvr="some_name-2-12346"), ArtifactBuild.create(db.session, db_event, "ed0", "image", 12345, original_nvr="some_name_2-2-2", rebuilt_nvr="some_name_2-2-210") ]) self.handler.start_to_build_images = MagicMock() db.session.commit() now = datetime(year=2020, month=12, day=25, hour=0, minute=0, second=0) with freezegun.freeze_time(now): self.handler.handle(event) self.assertEqual(db_event.state, EventState.BUILDING.value) get_build.assert_has_calls( [call("bundle1_nvr-1-1"), call("bundle2_nvr-1-1")], any_order=True) bundles_by_digest = { "bundle_with_related_images_1_digest": { "append": { "spec": { "skips": ["1.2.3"] } }, "auto_rebuild": True, "images": [{ "brew": { "build": "bundle1_nvr-1-1" } }], "nvr": "bundle1_nvr-1-1", "osbs_pinning": True, "pullspecs": [{ "new": "registry/repo/operator1@some_name-1-12345_digest", "original": "registry/repo/operator1:v2.2.0", "pinned": True, }], "update": { "metadata": { "name": "image.1.2.3+0.1608854400.patched", "substitutes-for": "1.2.3", }, "spec": { "version": "1.2.3+0.1608854400.patched" }, }, }, "bundle_with_related_images_2_digest": { "append": { "spec": { "skips": ["1.2.4"] } }, "auto_rebuild": True, "images": [{ "brew": { "build": "bundle2_nvr-1-1" } }], "nvr": "bundle2_nvr-1-1", "osbs_pinning": True, "pullspecs": [{ "new": "registry/repo/operator2@some_name_2-2-2_digest", "original": "registry/repo/operator2:v2.2.0", "pinned": True, }], "update": { "metadata": { "name": "image.1.2.4+0.1608854400.patched", "substitutes-for": "1.2.4", }, "spec": { "version": "1.2.4+0.1608854400.patched" }, }, }, } self.handler._prepare_builds.assert_called_with( db_event, bundles_by_digest, { 'bundle_with_related_images_1_digest', 'bundle_with_related_images_2_digest' })