def test_copr_and_koji_build_for_one_trigger(clean_before_and_after): pr1 = PullRequestModel.get_or_create( pr_id=1, namespace="the-namespace", repo_name="the-repo-name", project_url="https://github.com/the-namespace/the-repo-name", ) # SRPMBuildModel is (sadly) not shared between Koji and Copr builds. srpm_build_for_copr, run_model_for_copr = SRPMBuildModel.create_with_new_run( trigger_model=pr1, commit_sha="687abc76d67d") srpm_build_for_copr.set_logs("asd\nqwe\n") srpm_build_for_copr.set_status("success") srpm_build_for_koji, run_model_for_koji = SRPMBuildModel.create_with_new_run( trigger_model=pr1, commit_sha="687abc76d67d") srpm_build_for_copr.set_logs("asd\nqwe\n") srpm_build_for_copr.set_status("success") copr_build = CoprBuildModel.create( build_id="123456", commit_sha="687abc76d67d", project_name="SomeUser-hello-world-9", owner="packit", web_url="https://copr.something.somewhere/123456", target=SampleValues.target, status="pending", run_model=run_model_for_copr, ) koji_build = KojiBuildModel.create( build_id="987654", commit_sha="687abc76d67d", web_url="https://copr.something.somewhere/123456", target=SampleValues.target, status="pending", run_model=run_model_for_koji, ) assert copr_build in pr1.get_copr_builds() assert koji_build in pr1.get_koji_builds() assert srpm_build_for_copr in pr1.get_srpm_builds() assert srpm_build_for_koji in pr1.get_srpm_builds() assert copr_build.get_job_trigger_model( ) == koji_build.get_job_trigger_model() assert srpm_build_for_copr.get_trigger_object() == pr1 assert srpm_build_for_koji.get_trigger_object() == pr1 assert copr_build.get_trigger_object() == pr1 assert koji_build.get_trigger_object() == pr1 assert len(koji_build.runs) == 1 assert koji_build.runs[0] == run_model_for_koji assert len(copr_build.runs) == 1 assert copr_build.runs[0] == run_model_for_copr
def test_get_srpm_logs(client): srpm_build = SRPMBuildModel() srpm_build.id = 2 srpm_build.logs = "asd\nqwe" flexmock(SRPMBuildModel).should_receive("get_by_id").and_return(srpm_build) url = "/srpm-build/2/logs" logs_url = get_srpm_log_url_from_flask(2) assert logs_url.endswith(url) resp = client.get(url).data.decode() assert srpm_build.logs in resp assert f"build {srpm_build.id}" in resp
def test_get_logs(client): chroot = "foo-1-x86_64" state = "pending" build_id = 2 project = GitProjectModel() project.namespace = "john-foo" project.repo_name = "bar" pr = PullRequestModel() pr.pr_id = 234 pr.project = project srpm_build = SRPMBuildModel() srpm_build.logs = "asd<br>qwe" c = CoprBuildModel() c.target = chroot c.build_id = str(build_id) c.srpm_build = srpm_build c.status = state c.web_url = ( "https://copr.fedorainfracloud.org/coprs/john-foo-bar/john-foo-bar/build/2/" ) c.build_logs_url = "https://localhost:5000/build/2/foo-1-x86_64/logs" flexmock(CoprBuildModel).should_receive("get_by_id").and_return(c) flexmock(CoprBuildModel).should_receive("get_project").and_return(project) flexmock(CoprBuildModel).should_receive("job_trigger").and_return( flexmock(get_trigger_object=lambda: pr)) url = f"/copr-build/1/logs" logs_url = get_copr_build_log_url_from_flask(1) assert logs_url.endswith(url) resp = client.get(url) expected = ( "<html><head>" f"<title>COPR build {project.namespace}/{project.repo_name}:" f" PR #{pr.pr_id}</title></head><body>" f"COPR build ID: {c.build_id}<br>" f"Submitted: {optional_time(c.build_submitted_time)}<br>" f"State: {c.status}<br><br>" f'Build web interface URL: <a href="{c.web_url}">{c.web_url}</a><br>' f'Build logs: <a href="{c.build_logs_url}">{c.build_logs_url}</a><br>' "SRPM creation logs:<br><br>" f"<pre>{c.srpm_build.logs}</pre>" "<br></body></html>") assert resp.data == expected.encode()
def test_get_logs(client): chroot = "foo-1-x86_64" state = "success" build_id = 2 project = GitProjectModel() project.namespace = "john-foo" project.repo_name = "bar" pr = PullRequestModel() pr.pr_id = 234 pr.project = project srpm = SRPMBuildModel() srpm.url = "https://some.random.copr.subdomain.org/my_srpm.srpm" c = CoprBuildModel() c.target = chroot c.build_id = str(build_id) c.srpm_build_id = 11 c.status = state c.srpm_build = srpm c.web_url = ( "https://copr.fedorainfracloud.org/coprs/john-foo-bar/john-foo-bar/build/2/" ) c.build_logs_url = "https://localhost:5000/build/2/foo-1-x86_64/logs" c.owner = "packit" c.project_name = "example_project" flexmock(CoprBuildModel).should_receive("get_by_id").and_return(c) flexmock(CoprBuildModel).should_receive("get_project").and_return(project) flexmock(CoprBuildModel).should_receive("job_trigger").and_return( flexmock(get_trigger_object=lambda: pr)) url = "/copr-build/1" logs_url = get_copr_build_info_url_from_flask(1) assert logs_url.endswith(url) resp = client.get(url).data.decode() assert f"srpm-build/{c.srpm_build_id}/logs" in resp assert c.web_url in resp assert c.build_logs_url in resp assert c.target in resp assert "Status: success" in resp assert "You can install" in resp assert "Download SRPM" in resp assert srpm.url in resp
def test_koji_build_target_not_supported(github_pr_event): flexmock(AddPullRequestDbTrigger).should_receive("db_trigger").and_return( flexmock(job_config_trigger_type=JobConfigTriggerType.release)) helper = build_helper( event=github_pr_event, metadata=JobMetadataConfig(targets=["nonexisting-target"]), ) flexmock(koji_build).should_receive("get_all_koji_targets").and_return( ["dark-past", "bright-future"]).once() flexmock(StatusReporter).should_receive("set_status").with_args( state=CommitStatus.pending, description="Building SRPM ...", check_name="packit-stg/production-build-nonexisting-target", url="", ).and_return() flexmock(StatusReporter).should_receive("set_status").with_args( state=CommitStatus.error, description="Target not supported: nonexisting-target", check_name="packit-stg/production-build-nonexisting-target", url=get_srpm_log_url_from_flask(1), ).and_return() flexmock(GitProject).should_receive( "set_commit_status").and_return().never() flexmock(SRPMBuildModel).should_receive("create").and_return( SRPMBuildModel(id=1, success=True)) flexmock(KojiBuildModel).should_receive("get_or_create").and_return( KojiBuildModel(id=1)) flexmock(PackitAPI).should_receive("create_srpm").and_return("my.srpm") response = helper.run_koji_build() assert not response["success"] assert ("Target not supported: nonexisting-target" == response["details"] ["errors"]["nonexisting-target"])
def test_copr_and_koji_build_for_one_trigger(clean_before_and_after): pr1 = PullRequestModel.get_or_create( pr_id=1, namespace="the-namespace", repo_name="the-repo-name" ) pr1_trigger = JobTriggerModel.get_or_create( type=JobTriggerModelType.pull_request, trigger_id=pr1.id ) srpm_build = SRPMBuildModel.create("asd\nqwe\n") copr_build = CoprBuildModel.get_or_create( build_id="123456", commit_sha="687abc76d67d", project_name="SomeUser-hello-world-9", owner="packit", web_url="https://copr.something.somewhere/123456", target=TARGET, status="pending", srpm_build=srpm_build, trigger_model=pr1, ) koji_build = KojiBuildModel.get_or_create( build_id="987654", commit_sha="687abc76d67d", web_url="https://copr.something.somewhere/123456", target=TARGET, status="pending", srpm_build=srpm_build, trigger_model=pr1, ) assert copr_build in pr1_trigger.copr_builds assert koji_build in pr1_trigger.koji_builds assert copr_build.job_trigger.get_trigger_object() == pr1 assert koji_build.job_trigger.get_trigger_object() == pr1
def get(self): """List all SRPM builds.""" result = [] first, last = indices() for build in SRPMBuildModel.get(first, last): build_dict = { "srpm_build_id": build.id, "success": build.success, "log_url": get_srpm_build_info_url(build.id), "build_submitted_time": optional_timestamp(build.build_submitted_time), } project = build.get_project() # Its possible that jobtrigger isnt stored in db if project: build_dict["repo_namespace"] = project.namespace build_dict["repo_name"] = project.repo_name build_dict["project_url"] = project.project_url build_dict["pr_id"] = build.get_pr_id() build_dict["branch_name"] = build.get_branch_name() result.append(build_dict) resp = response_maker( result, status=HTTPStatus.PARTIAL_CONTENT.value, ) resp.headers["Content-Range"] = f"srpm-builds {first + 1}-{last}/*" return resp
def test_copr_build_check_names(pull_request_event): flexmock(AddPullRequestDbTrigger).should_receive("db_trigger").and_return( flexmock(job_config_trigger_type=JobConfigTriggerType.release) ) helper = build_helper( event=pull_request_event, metadata=JobMetadataConfig(targets=["bright-future-x86_64"], owner="nobody"), ) flexmock(StatusReporter).should_receive("set_status").with_args( state=CommitStatus.pending, description="Building SRPM ...", check_name="packit-stg/rpm-build-bright-future-x86_64", url="", ).and_return() flexmock(StatusReporter).should_receive("set_status").with_args( state=CommitStatus.pending, description="Building RPM ...", check_name="packit-stg/rpm-build-bright-future-x86_64", url="https://localhost:5000/copr-build/1/logs", ).and_return() flexmock(GitProject).should_receive("set_commit_status").and_return().never() flexmock(SRPMBuildModel).should_receive("create").and_return(SRPMBuildModel()) flexmock(CoprBuildModel).should_receive("get_or_create").and_return( CoprBuildModel(id=1) ) flexmock(PullRequestEvent).should_receive("db_trigger").and_return(flexmock()) flexmock(PackitAPI).should_receive("run_copr_build").and_return(1, None) flexmock(Celery).should_receive("send_task").once() config = ServiceConfig.get_service_config() config.disable_sentry = True assert helper.run_copr_build()["success"]
def test_copr_build_for_release(release_event): # status is set for each build-target (4x): # - Building SRPM ... # - Building RPM ... branch_build_job = JobConfig( type=JobType.build, trigger=JobConfigTriggerType.release, metadata=JobMetadataConfig( targets=[ "fedora-29-x86_64", "fedora-30-x86_64", "fedora-31-x86_64", "fedora-rawhide-x86_64", ], owner="nobody", dist_git_branches=["build-branch"], ), ) flexmock(AddReleaseDbTrigger).should_receive("db_trigger").and_return( flexmock(job_config_trigger_type=JobConfigTriggerType.release) ) helper = build_helper(jobs=[branch_build_job], event=release_event) flexmock(ReleaseEvent).should_receive("get_project").and_return(helper.project) flexmock(GitProject).should_receive("set_commit_status").and_return().times(8) flexmock(GitProject).should_receive("get_sha_from_tag").and_return("123456").once() flexmock(SRPMBuildModel).should_receive("create").and_return(SRPMBuildModel()) flexmock(CoprBuildModel).should_receive("get_or_create").and_return( CoprBuildModel(id=1) ) flexmock(PackitAPI).should_receive("run_copr_build").and_return(1, None).once() flexmock(Celery).should_receive("send_task").once() assert helper.run_copr_build()["success"]
def test_copr_build_fails_in_packit(pull_request_event): # status is set for each build-target (4x): # - Building SRPM ... # - Build failed, check latest comment for details. helper = build_helper(event=pull_request_event) templ = "packit-stg/rpm-build-fedora-{ver}-x86_64" for v in ["29", "30", "31", "rawhide"]: flexmock(GitProject).should_receive("set_commit_status").with_args( "528b803be6f93e19ca4130bf4976f2800a3004c4", CommitStatus.pending, "", "Building SRPM ...", templ.format(ver=v), trim=True, ).and_return().once() for v in ["29", "30", "31", "rawhide"]: flexmock(GitProject).should_receive("set_commit_status").with_args( "528b803be6f93e19ca4130bf4976f2800a3004c4", CommitStatus.failure, "https://localhost:5000/srpm-build/2/logs", "SRPM build failed, check the logs for details.", templ.format(ver=v), trim=True, ).and_return().once() flexmock(SRPMBuildModel).should_receive("create").and_return(SRPMBuildModel(id=2)) flexmock(CoprBuildModel).should_receive("get_or_create").and_return( CoprBuildModel(id=1) ) flexmock(sentry_integration).should_receive("send_to_sentry").and_return().once() flexmock(PackitAPI).should_receive("run_copr_build").and_raise( FailedCreateSRPM, "some error" ) assert not helper.run_copr_build()["success"]
def get(self, id): """A specific SRPM build details.""" build = SRPMBuildModel.get_by_id(int(id)) if not build: return response_maker( {"error": "No info about build stored in DB"}, status=HTTPStatus.NOT_FOUND.value, ) build_dict = { "status": build.status, "build_submitted_time": optional_timestamp(build.build_submitted_time), "build_start_time": optional_timestamp(build.build_start_time), "build_finished_time": optional_timestamp(build.build_finished_time), "url": build.url, "logs": build.logs, "logs_url": build.logs_url, "copr_build_id": build.copr_build_id, "copr_web_url": build.copr_web_url, "run_ids": sorted(run.id for run in build.runs), } build_dict.update(get_project_info_from_build(build)) return response_maker(build_dict)
def multiple_koji_builds(pr_trigger_model, different_pr_trigger_model): srpm_build = SRPMBuildModel.create("asd\nqwe\n") yield [ KojiBuildModel.get_or_create( build_id="123456", commit_sha="687abc76d67d", web_url="https://copr.something.somewhere/123456", target="fedora-42-x86_64", status="pending", srpm_build=srpm_build, trigger_model=pr_trigger_model, ), # Same build_id but different chroot KojiBuildModel.get_or_create( build_id="123456", commit_sha="687abc76d67d", web_url="https://copr.something.somewhere/123456", target="fedora-43-x86_64", status="pending", srpm_build=srpm_build, trigger_model=pr_trigger_model, ), # Completely different build KojiBuildModel.get_or_create( build_id="987654", commit_sha="987def76d67e", web_url="https://copr.something.somewhere/987654", target="fedora-43-x86_64", status="pending", srpm_build=srpm_build, trigger_model=different_pr_trigger_model, ), ]
def test_koji_build_failed_srpm(github_pr_event): trigger = flexmock(job_config_trigger_type=JobConfigTriggerType.release, id=123) flexmock(AddPullRequestDbTrigger).should_receive("db_trigger").and_return(trigger) helper = build_helper( event=github_pr_event, metadata=JobMetadataConfig(targets=["bright-future"]), db_trigger=trigger, ) srpm_build_url = get_srpm_log_url_from_flask(2) flexmock(StatusReporter).should_receive("set_status").with_args( state=CommitStatus.pending, description="Building SRPM ...", check_name="packit-stg/production-build-bright-future", url="", ).and_return() flexmock(StatusReporter).should_receive("set_status").with_args( state=CommitStatus.failure, description="SRPM build failed, check the logs for details.", check_name="packit-stg/production-build-bright-future", url=srpm_build_url, ).and_return() flexmock(GitProject).should_receive("set_commit_status").and_return().never() flexmock(PackitAPI).should_receive("create_srpm").and_raise(Exception, "some error") flexmock(SRPMBuildModel).should_receive("create").and_return( SRPMBuildModel(id=2, success=False) ) flexmock(KojiBuildModel).should_receive("get_or_create").never() flexmock(sentry_integration).should_receive("send_to_sentry").and_return().once() result = helper.run_koji_build() assert not result["success"] assert "SRPM build failed" in result["details"]["msg"]
def from_build_id( cls, topic: str, build_id: int, chroot: str, status: int, owner: str, project_name: str, pkg: str, timestamp, ) -> Optional["AbstractCoprBuildEvent"]: """Return cls instance or None if build_id not in CoprBuildDB""" build: Optional[Union[SRPMBuildModel, CoprBuildModel]] if chroot == COPR_SRPM_CHROOT: build = SRPMBuildModel.get_by_copr_build_id(str(build_id)) else: build = CoprBuildModel.get_by_build_id(str(build_id), chroot) if not build: logger.warning( f"Build id {build_id} not in " f"{'SRPMBuildDB' if chroot == COPR_SRPM_CHROOT else 'CoprBuildDB'}." ) return None return cls(topic, build_id, build, chroot, status, owner, project_name, pkg, timestamp)
def test_copr_build_success(github_pr_event): # status is set for each build-target (4x): # - Building SRPM ... # - Starting RPM build... helper = build_helper(event=github_pr_event) flexmock(GitProject).should_receive("set_commit_status").and_return().times(8) flexmock(GitProject).should_receive("get_pr").and_return(flexmock()) flexmock(SRPMBuildModel).should_receive("create").and_return( SRPMBuildModel(success=True) ) flexmock(CoprBuildModel).should_receive("get_or_create").and_return( CoprBuildModel(id=1) ) flexmock(PullRequestGithubEvent).should_receive("db_trigger").and_return(flexmock()) flexmock(PackitAPI).should_receive("create_srpm").and_return("my.srpm") # copr build flexmock(CoprHelper).should_receive("create_copr_project_if_not_exists").and_return( None ) flexmock(CoprHelper).should_receive("get_copr_client").and_return( flexmock( config={"copr_url": "https://copr.fedorainfracloud.org/"}, build_proxy=flexmock() .should_receive("create_from_file") .and_return( flexmock(id=2, projectname="the-project-name", ownername="the-owner") ) .mock(), ) ) flexmock(Celery).should_receive("send_task").once() assert helper.run_copr_build()["success"]
def _create_srpm(self): # we want to get packit logs from the SRPM creation process # so we stuff them into a StringIO buffer stream = StringIO() handler = logging.StreamHandler(stream) packit_logger = logging.getLogger("packit") packit_logger.setLevel(logging.DEBUG) packit_logger.addHandler(handler) formatter = PackitFormatter(None, "%H:%M:%S") handler.setFormatter(formatter) srpm_success = True exception: Optional[Exception] = None extra_logs: str = "" try: self._srpm_path = Path( self.api.create_srpm(srpm_dir=self.api.up.local_project.working_dir) ) except SandcastleTimeoutReached as ex: exception = ex extra_logs = f"\nYou have reached 10-minute timeout while creating SRPM.\n" except ApiException as ex: exception = ex # this is an internal error: let's not expose anything to public extra_logs = ( "\nThere was a problem in the environment the packit-service is running in.\n" "Please hang tight, the help is coming." ) except Exception as ex: exception = ex # collect the logs now packit_logger.removeHandler(handler) stream.seek(0) srpm_logs = stream.read() if exception: logger.info(f"exception while running SRPM build: {exception}") logger.debug(f"{exception!r}") srpm_success = False # when do we NOT want to send stuff to sentry? sentry_integration.send_to_sentry(exception) # this needs to be done AFTER we gather logs # so that extra logs are after actual logs srpm_logs += extra_logs if hasattr(exception, "output"): output = getattr(exception, "output", "") # mypy srpm_logs += f"\nOutput of the command in the sandbox:\n{output}\n" srpm_logs += ( f"\nMessage: {exception}\nException: {exception!r}\n{self.msg_retrigger}" "\nPlease join the freenode IRC channel #packit for the latest info.\n" ) self._srpm_model = SRPMBuildModel.create(logs=srpm_logs, success=srpm_success)
def test_copr_build_check_names(github_pr_event): flexmock(AddPullRequestDbTrigger).should_receive("db_trigger").and_return( flexmock(job_config_trigger_type=JobConfigTriggerType.release)) helper = build_helper( event=github_pr_event, metadata=JobMetadataConfig(targets=["bright-future-x86_64"], owner="nobody"), ) flexmock(copr_build).should_receive( "get_copr_build_log_url_from_flask").and_return("https://test.url") flexmock(StatusReporter).should_receive("set_status").with_args( state=CommitStatus.pending, description="Building SRPM ...", check_name="packit-stg/rpm-build-bright-future-x86_64", url="", ).and_return() flexmock(StatusReporter).should_receive("set_status").with_args( state=CommitStatus.pending, description="Starting RPM build...", check_name="packit-stg/rpm-build-bright-future-x86_64", url="https://test.url", ).and_return() flexmock(GitProject).should_receive( "set_commit_status").and_return().never() flexmock(SRPMBuildModel).should_receive("create").and_return( SRPMBuildModel(success=True)) flexmock(CoprBuildModel).should_receive("get_or_create").and_return( CoprBuildModel(id=1)) flexmock(PullRequestGithubEvent).should_receive("db_trigger").and_return( flexmock()) flexmock(PackitAPI).should_receive("create_srpm").and_return("my.srpm") # copr build flexmock(CoprHelper).should_receive( "create_copr_project_if_not_exists").with_args( project="the-example-namespace-the-example-repo-342-stg", chroots=["bright-future-x86_64"], owner="nobody", description=None, instructions=None, ).and_return(None) flexmock(CoprHelper).should_receive("get_copr_client").and_return( flexmock( config={"copr_url": "https://copr.fedorainfracloud.org/"}, build_proxy=flexmock().should_receive( "create_from_file").and_return( flexmock(id=2, projectname="the-project-name", ownername="the-owner")).mock(), )) flexmock(Celery).should_receive("send_task").once() assert helper.run_copr_build()["success"]
def process_runs(runs): """ Process `RunModel`s and construct a JSON that is returned from the endpoints that return merged chroots. Args: runs: Iterator over merged `RunModel`s. Returns: List of JSON objects where each represents pipelines run on single SRPM. """ result = [] for pipeline in runs: response_dict = { "merged_run_id": pipeline.merged_id, "srpm": None, "copr": [], "koji": [], "test_run": [], } srpm_build = SRPMBuildModel.get_by_id(pipeline.srpm_build_id) if srpm_build: response_dict["srpm"] = { "packit_id": srpm_build.id, "status": srpm_build.status, } response_dict["time_submitted"] = optional_timestamp( srpm_build.build_submitted_time) response_dict["trigger"] = get_project_info_from_build(srpm_build) for model_type, Model, packit_ids in ( ("copr", CoprBuildModel, pipeline.copr_build_id), ("koji", KojiBuildModel, pipeline.koji_build_id), ("test_run", TFTTestRunModel, pipeline.test_run_id), ): for packit_id in set( filter(None, map(lambda ids: ids[0], packit_ids))): row = Model.get_by_id(packit_id) if row.status == "waiting_for_srpm": continue response_dict[model_type].append({ "packit_id": packit_id, "target": row.target, "status": row.status, }) if "trigger" not in response_dict: submitted_time = (row.submitted_time if isinstance( row, TFTTestRunModel) else row.build_submitted_time) response_dict["time_submitted"] = optional_timestamp( submitted_time) response_dict["trigger"] = get_project_info_from_build(row) result.append(response_dict) return result
def test_get_srpm_logs(client): srpm_build = SRPMBuildModel() srpm_build.id = 2 srpm_build.logs = "asd\nqwe" flexmock(SRPMBuildModel).should_receive("get_by_id").and_return(srpm_build) url = f"/srpm-build/2/logs" logs_url = get_srpm_log_url(2) assert logs_url.endswith(url) resp = client.get(url) expected = ("<html><head>" "<title>SRPM Build id=2</title></head><body>" "SRPM creation logs:<br><br>" "<pre>asd\nqwe</pre>" "<br></body></html>") assert resp.data == expected.encode()
def test_copr_build_for_release(release_event): # status is set for each build-target (4x): # - Building SRPM ... # - Starting RPM build... branch_build_job = JobConfig( type=JobType.build, trigger=JobConfigTriggerType.release, metadata=JobMetadataConfig( targets=[ "fedora-29-x86_64", "fedora-30-x86_64", "fedora-31-x86_64", "fedora-rawhide-x86_64", ], owner="nobody", dist_git_branches=["build-branch"], ), ) trigger = flexmock(job_config_trigger_type=JobConfigTriggerType.release, id=123) flexmock(AddReleaseDbTrigger).should_receive("db_trigger").and_return(trigger) flexmock(release_event.project).should_receive("get_sha_from_tag").and_return( "123456" ) helper = build_helper( jobs=[branch_build_job], event=release_event, db_trigger=trigger, ) flexmock(ReleaseEvent).should_receive("get_project").and_return(helper.project) flexmock(GitProject).should_receive("set_commit_status").and_return().times(8) flexmock(SRPMBuildModel).should_receive("create").and_return( SRPMBuildModel(success=True) ) flexmock(CoprBuildModel).should_receive("get_or_create").and_return( CoprBuildModel(id=1) ) flexmock(PackitAPI).should_receive("create_srpm").and_return("my.srpm") # copr build flexmock(CoprHelper).should_receive("create_copr_project_if_not_exists").and_return( None ) flexmock(CoprHelper).should_receive("get_copr_client").and_return( flexmock( config={"copr_url": "https://copr.fedorainfracloud.org/"}, build_proxy=flexmock() .should_receive("create_from_file") .and_return( flexmock(id=2, projectname="the-project-name", ownername="the-owner") ) .mock(), ) ) flexmock(Celery).should_receive("send_task").once() assert helper.run_copr_build()["success"]
def build(self): if not self._build: build_id = str(self.copr_event.build_id) if self.copr_event.chroot == COPR_SRPM_CHROOT: self._build = SRPMBuildModel.get_by_copr_build_id(build_id) else: self._build = CoprBuildModel.get_by_build_id( build_id, self.copr_event.chroot) return self._build
def get_srpm_build_logs_by_id(id_): log_service_versions() srpm_build = SRPMBuildModel.get_by_id(id_) if srpm_build: response = ("<html><head>" f"<title>SRPM Build id={id_}</title></head><body>" "SRPM creation logs:<br><br>" f"<pre>{srpm_build.logs}</pre>" "<br></body></html>") return response return f"We can't find any info about SRPM build {id_}.\n"
def a_koji_build(pr_model): srpm_build = SRPMBuildModel.create("asd\nqwe\n") yield KojiBuildModel.get_or_create( build_id="123456", commit_sha="687abc76d67d", web_url="https://copr.something.somewhere/123456", target=TARGET, status="pending", srpm_build=srpm_build, trigger_model=pr_model, )
def test_koji_build_check_names(github_pr_event): trigger = flexmock( job_config_trigger_type=JobConfigTriggerType.pull_request, id=123 ) flexmock(AddPullRequestDbTrigger).should_receive("db_trigger").and_return(trigger) helper = build_helper( event=github_pr_event, metadata=JobMetadataConfig(targets=["bright-future"], scratch=True), db_trigger=trigger, ) flexmock(koji_build).should_receive("get_all_koji_targets").and_return( ["dark-past", "bright-future"] ).once() koji_build_url = get_koji_build_info_url_from_flask(1) flexmock(StatusReporter).should_receive("set_status").with_args( state=CommitStatus.pending, description="Building SRPM ...", check_name="packit-stg/production-build-bright-future", url="", ).and_return() flexmock(StatusReporter).should_receive("set_status").with_args( state=CommitStatus.pending, description="Building RPM ...", check_name="packit-stg/production-build-bright-future", url=koji_build_url, ).and_return() flexmock(GitProject).should_receive("get_pr").and_return( flexmock(source_project=flexmock()) ) flexmock(GitProject).should_receive("set_commit_status").and_return().never() flexmock(SRPMBuildModel).should_receive("create").and_return( SRPMBuildModel(id=1, success=True) ) flexmock(KojiBuildModel).should_receive("get_or_create").and_return( KojiBuildModel(id=1) ) flexmock(PackitAPI).should_receive("create_srpm").and_return("my.srpm") # koji build flexmock(Upstream).should_receive("koji_build").and_return( "Uploading srpm: /python-ogr-0.11.1" ".dev21+gf2dec9b-1.20200407142424746041.21.gf2dec9b.fc31.src.rpm\n" "[====================================] 100% 00:00:11 1.67 MiB 148.10 KiB/sec\n" "Created task: 43429338\n" "Task info: https://koji.fedoraproject.org/koji/taskinfo?taskID=43429338\n" ) flexmock(PackitAPI).should_receive("init_kerberos_ticket").once() assert helper.run_koji_build()["success"]
def test_koji_build_failed_kerberos(github_pr_event): trigger = flexmock( job_config_trigger_type=JobConfigTriggerType.pull_request, id=123 ) flexmock(AddPullRequestDbTrigger).should_receive("db_trigger").and_return(trigger) helper = build_helper( event=github_pr_event, metadata=JobMetadataConfig(targets=["bright-future"], scratch=True), db_trigger=trigger, ) flexmock(koji_build).should_receive("get_all_koji_targets").and_return( ["dark-past", "bright-future"] ).never() flexmock(StatusReporter).should_receive("set_status").with_args( state=CommitStatus.pending, description="Building SRPM ...", check_name="packit-stg/production-build-bright-future", url="", ).and_return() flexmock(StatusReporter).should_receive("set_status").with_args( state=CommitStatus.error, description="Kerberos authentication error: the bad authentication error", check_name="packit-stg/production-build-bright-future", url=get_srpm_log_url_from_flask(1), ).and_return() flexmock(GitProject).should_receive("get_pr").and_return( flexmock(source_project=flexmock()) ) flexmock(GitProject).should_receive("set_commit_status").and_return().never() flexmock(SRPMBuildModel).should_receive("create").and_return( SRPMBuildModel(id=1, success=True) ) flexmock(KojiBuildModel).should_receive("get_or_create").and_return( KojiBuildModel(id=1) ) flexmock(PackitAPI).should_receive("create_srpm").and_return("my.srpm") flexmock(PackitAPI).should_receive("init_kerberos_ticket").and_raise( PackitCommandFailedError, "Command failed", stdout_output="", stderr_output="the bad authentication error", ) response = helper.run_koji_build() assert not response["success"] assert ( "Kerberos authentication error: the bad authentication error" == response["details"]["msg"] )
def test_copr_build_for_branch(branch_push_event): # status is set for each build-target (4x): # - Building SRPM ... # - Starting RPM build... branch_build_job = JobConfig( type=JobType.build, trigger=JobConfigTriggerType.commit, metadata=JobMetadataConfig( targets=DEFAULT_TARGETS, owner="nobody", dist_git_branches=["build-branch"], ), ) trigger = flexmock(job_config_trigger_type=JobConfigTriggerType.commit, id=123) flexmock(AddBranchPushDbTrigger).should_receive("db_trigger").and_return( trigger) helper = build_helper( jobs=[branch_build_job], event=branch_push_event, db_trigger=trigger, ) flexmock(GitProject).should_receive( "set_commit_status").and_return().times(8) flexmock(SRPMBuildModel).should_receive("create").and_return( SRPMBuildModel(success=True)) flexmock(CoprBuildModel).should_receive("get_or_create").and_return( CoprBuildModel(id=1)) flexmock(PushGitHubEvent).should_receive("db_trigger").and_return( flexmock()) flexmock(PackitAPI).should_receive("create_srpm").and_return("my.srpm") # copr build flexmock(CoprHelper).should_receive( "create_copr_project_if_not_exists").and_return(None) flexmock(CoprHelper).should_receive("get_copr_client").and_return( flexmock( config={"copr_url": "https://copr.fedorainfracloud.org/"}, build_proxy=flexmock().should_receive( "create_from_file").and_return( flexmock(id=2, projectname="the-project-name", ownername="the-owner")).mock(), mock_chroot_proxy=flexmock().should_receive("get_list").and_return( {target: "" for target in DEFAULT_TARGETS}).mock(), )) flexmock(Pushgateway).should_receive("push_copr_build_created") flexmock(Celery).should_receive("send_task").once() assert helper.run_copr_build()["success"]
def a_copr_build_for_release(release_model): srpm_build = SRPMBuildModel.create("asd\nqwe\n") yield CoprBuildModel.get_or_create( build_id="123456", commit_sha="687abc76d67d", project_name="SomeUser-hello-world-9", owner="packit", web_url="https://copr.something.somewhere/123456", target=TARGET, status="pending", srpm_build=srpm_build, trigger_model=release_model, )
def discard_old_srpm_build_logs(): """Called periodically (see celery_config.py) to discard logs of old SRPM builds.""" logger.info("About to discard old SRPM build logs & artifact urls.") outdated_after_days = getenv("SRPMBUILDS_OUTDATED_AFTER_DAYS", SRPMBUILDS_OUTDATED_AFTER_DAYS) ago = timedelta(days=int(outdated_after_days)) for build in SRPMBuildModel.get_older_than(ago): age = datetime.utcnow() - build.build_submitted_time logger.debug( f"SRPM build {build.id}, age '{age}' is older than '{ago}'. " "Discarding log and artifact url.") build.set_logs(None) build.set_url(None)
def test_copr_build_success_set_test_check(github_pr_event): # status is set for each test-target (2x): # - Building SRPM ... # - Starting RPM build... test_job = JobConfig( type=JobType.tests, trigger=JobConfigTriggerType.pull_request, metadata=JobMetadataConfig( owner="nobody", targets=["bright-future-x86_64", "brightest-future-x86_64"]), ) trigger = flexmock( job_config_trigger_type=JobConfigTriggerType.pull_request, id=123) flexmock(AddPullRequestDbTrigger).should_receive("db_trigger").and_return( trigger) helper = build_helper( jobs=[test_job], event=github_pr_event, db_trigger=trigger, ) flexmock(GitProject).should_receive( "set_commit_status").and_return().times(4) flexmock(GitProject).should_receive("get_pr").and_return(flexmock()) flexmock(SRPMBuildModel).should_receive("create").and_return( SRPMBuildModel(success=True)) flexmock(CoprBuildModel).should_receive("get_or_create").and_return( CoprBuildModel(id=1)) flexmock(PackitAPI).should_receive("create_srpm").and_return("my.srpm") # copr build flexmock(CoprHelper).should_receive( "create_copr_project_if_not_exists").and_return(None) flexmock(CoprHelper).should_receive("get_copr_client").and_return( flexmock( config={"copr_url": "https://copr.fedorainfracloud.org/"}, build_proxy=flexmock().should_receive( "create_from_file").and_return( flexmock(id=2, projectname="the-project-name", ownername="the-owner")).mock(), mock_chroot_proxy=flexmock().should_receive("get_list").and_return( { "bright-future-x86_64": "", "brightest-future-x86_64": "" }).mock(), )) flexmock(Pushgateway).should_receive("push_copr_build_created") flexmock(Celery).should_receive("send_task").once() assert helper.run_copr_build()["success"]
def run_copr_build(self) -> HandlerResults: if not (self.job_build or self.job_tests): msg = "No copr_build or tests job defined." # we can't report it to end-user at this stage return HandlerResults(success=False, details={"msg": msg}) self.report_status_to_all(description="Building SRPM ...", state=CommitStatus.pending) build_metadata = self._run_copr_build_and_save_output() srpm_build_model = SRPMBuildModel.create(build_metadata.srpm_logs) if build_metadata.srpm_failed: msg = "SRPM build failed, check the logs for details." self.report_status_to_all( state=CommitStatus.failure, description=msg, url=get_srpm_log_url(srpm_build_model.id), ) return HandlerResults(success=False, details={"msg": msg}) for chroot in self.build_chroots: copr_build = CoprBuildModel.get_or_create( build_id=str(build_metadata.copr_build_id), commit_sha=self.event.commit_sha, project_name=self.job_project, owner=self.job_owner, web_url=build_metadata.copr_web_url, target=chroot, status="pending", srpm_build=srpm_build_model, trigger_model=self.event.db_trigger, ) url = get_log_url(id_=copr_build.id) self.report_status_to_all_for_chroot( state=CommitStatus.pending, description="Building RPM ...", url=url, chroot=chroot, ) # release the hounds! celery_app.send_task( "task.babysit_copr_build", args=(build_metadata.copr_build_id, ), countdown=120, # do the first check in 120s ) return HandlerResults(success=True, details={})