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={ "branch": "build-branch", "owner": "nobody", "targets": [ "fedora-29-x86_64", "fedora-30-x86_64", "fedora-31-x86_64", "fedora-rawhide-x86_64", ], }, ) helper = build_helper(jobs=[branch_build_job], event=release_event) flexmock(GitProject).should_receive("set_commit_status").and_return().times(8) flexmock(RedisCoprBuild).should_receive("create").and_return(FakeCoprBuildModel()) flexmock(SRPMBuild).should_receive("create").and_return(SRPMBuild()) flexmock(CoprBuild).should_receive("get_or_create").and_return(CoprBuild(id=1)) flexmock(PackitAPI).should_receive("run_copr_build").and_return(1, None).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(RedisCoprBuild).should_receive("create").and_return(FakeCoprBuildModel()) flexmock(SRPMBuild).should_receive("create").and_return(SRPMBuild(id=2)) flexmock(CoprBuild).should_receive("get_or_create").and_return(CoprBuild(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 test_copr_build_check_names(): metadata = {"owner": "nobody", "targets": ["bright-future-x86_64"]} handler = build_handler(metadata) flexmock(BuildStatusReporter).should_receive("set_status").with_args( state="pending", description="Building SRPM ...", check_name="packit-stg/rpm-build-bright-future-x86_64", url="", ).and_return() flexmock(BuildStatusReporter).should_receive("set_status").with_args( state="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(RedisCoprBuild).should_receive("create").and_return( FakeCoprBuildModel()) flexmock(SRPMBuild).should_receive("create").and_return(SRPMBuild()) flexmock(CoprBuild).should_receive("get_or_create").and_return( CoprBuild(id=1)) flexmock(PackitAPI).should_receive("run_copr_build").and_return(1, None) assert handler.run_copr_build()["success"]
def test_get_logs(client): chroot = "foo-1-x86_64" state = "pending" build_id = 2 project = GitProject() project.namespace = "john-foo" project.repo_name = "bar" pr = PullRequest() pr.pr_id = 234 pr.project = project srpm_build = SRPMBuild() srpm_build.logs = "asd<br>qwe" c = CoprBuild() 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" c.pr = pr flexmock(CoprBuild).should_receive("get_by_id").and_return(c) url = f"/copr-build/1/logs" logs_url = get_log_url(1) assert logs_url.endswith(url) resp = client.get(url) expected = ( "<html><head>" f"<title>Build {c.pr.project.namespace}/{c.pr.project.repo_name}" f" #{c.pr.pr_id}</title></head><body>" f"COPR Build ID: {c.build_id}<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 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 = SRPMBuild.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 = CoprBuild.get_or_create( pr_id=self.pr_id, build_id=str(build_metadata.copr_build_id), commit_sha=self.event.commit_sha, repo_name=self.project.repo, namespace=self.project.namespace, 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, ) 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, ) self.copr_build_model.build_id = build_metadata.copr_build_id self.copr_build_model.save() # 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={})
def get_srpm_build_logs_by_id(id_): srpm_build = SRPMBuild.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 test_get_srpm_logs(client): srpm_build = SRPMBuild() srpm_build.id = 2 srpm_build.logs = "asd\nqwe" flexmock(SRPMBuild).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_no_targets(pull_request_event): # status is set for each build-target (fedora-stable => 2x): # - Building SRPM ... # - Building RPM ... helper = build_helper(event=pull_request_event, metadata={"owner": "nobody"}) flexmock(GitProject).should_receive("set_commit_status").and_return().times(4) flexmock(RedisCoprBuild).should_receive("create").and_return(FakeCoprBuildModel()) flexmock(SRPMBuild).should_receive("create").and_return(SRPMBuild()) flexmock(CoprBuild).should_receive("get_or_create").and_return(CoprBuild(id=1)) flexmock(PackitAPI).should_receive("run_copr_build").and_return(1, None).once() assert helper.run_copr_build()["success"]
def multiple_copr_builds(): with get_sa_session() as session: session.query(CoprBuild).delete() srpm_build = SRPMBuild.create("asd\nqwe\n") yield [ CoprBuild.get_or_create( pr_id=1, build_id="123456", commit_sha="687abc76d67d", repo_name="lithium", namespace="nirvana", project_name="SomeUser-hello-world-9", owner="packit", web_url="https://copr.something.somewhere/123456", target="fedora-42-x86_64", status="pending", srpm_build=srpm_build, ), # Same build_id but different chroot CoprBuild.get_or_create( pr_id=1, build_id="123456", commit_sha="687abc76d67d", repo_name="lithium", namespace="nirvana", project_name="SomeUser-hello-world-9", owner="packit", web_url="https://copr.something.somewhere/123456", target="fedora-43-x86_64", status="pending", srpm_build=srpm_build, ), # Completely different build CoprBuild.get_or_create( pr_id=4, build_id="987654", commit_sha="987def76d67e", repo_name="cockpit-project", namespace="cockpit", project_name="SomeUser-random-text-7", owner="cockpit-project", web_url="https://copr.something.somewhere/987654", target="fedora-43-x86_64", status="pending", srpm_build=srpm_build, ), ] clean_db()
def test_copr_build_success(): # status is set for each build-target (4x): # - Building SRPM ... # - Building RPM ... handler = build_handler() flexmock(GitProject).should_receive( "set_commit_status").and_return().times(8) flexmock(RedisCoprBuild).should_receive("create").and_return( FakeCoprBuildModel()) flexmock(SRPMBuild).should_receive("create").and_return(SRPMBuild()) flexmock(CoprBuild).should_receive("get_or_create").and_return( CoprBuild(id=1)) flexmock(PackitAPI).should_receive("run_copr_build").and_return( 1, None).once() assert handler.run_copr_build()["success"]
def a_copr_build(): with get_sa_session() as session: session.query(CoprBuild).delete() srpm_build = SRPMBuild.create("asd\nqwe\n") yield CoprBuild.get_or_create( pr_id=1, build_id="123456", commit_sha="687abc76d67d", repo_name="lithium", namespace="nirvana", web_url="https://copr.something.somewhere/123456", target=TARGET, status="pending", srpm_build=srpm_build, ) clean_db()
def test_copr_build_success_set_test_check(pull_request_event): # status is set for each build-target (4x): # - Building SRPM ... # - Building RPM ... # status is set for each test-target (4x): # - Building SRPM ... # - Building RPM ... test_job = JobConfig( type=JobType.tests, trigger=JobConfigTriggerType.pull_request, metadata={} ) helper = build_helper(jobs=[test_job], event=pull_request_event) flexmock(GitProject).should_receive("set_commit_status").and_return().times(16) flexmock(RedisCoprBuild).should_receive("create").and_return(FakeCoprBuildModel()) flexmock(SRPMBuild).should_receive("create").and_return(SRPMBuild()) flexmock(CoprBuild).should_receive("get_or_create").and_return(CoprBuild(id=1)) flexmock(PackitAPI).should_receive("run_copr_build").and_return(1, None).once() assert helper.run_copr_build()["success"]
def packit_build_752(): with get_sa_session() as session: session.query(CoprBuild).delete() srpm_build = SRPMBuild.create("asd\nqwe\n") yield CoprBuild.get_or_create( pr_id=752, build_id=str(BUILD_ID), commit_sha="687abc76d67d", repo_name="packit", namespace="packit-service", project_name="packit-service-packit-752", owner="packit", web_url=("https://download.copr.fedorainfracloud.org/" "results/packit/packit-service-packit-752"), target="fedora-rawhide-x86_64", status="pending", srpm_build=srpm_build, ) clean_db()
def test_copr_build_fails_in_packit(): # status is set for each build-target (4x): # - Building SRPM ... # - Build failed, check latest comment for details. handler = build_handler() flexmock(GitProject, pr_comment=lambda *args, **kw: None) flexmock(GitProject).should_receive( "set_commit_status").and_return().times(8) flexmock(GitProject).should_receive("pr_comment").and_return().once() flexmock(RedisCoprBuild).should_receive("create").and_return( FakeCoprBuildModel()) flexmock(SRPMBuild).should_receive("create").and_return(SRPMBuild()) flexmock(CoprBuild).should_receive("get_or_create").and_return( CoprBuild(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 handler.run_copr_build()["success"]
def run_copr_build(self) -> HandlerResults: if not (self.job_copr_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}) try: self.report_status_to_all(description="Building SRPM ...", state="pending") # 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) build_id, _ = self.api.run_copr_build( project=self.job_project, chroots=self.build_chroots, owner=self.job_owner, ) packit_logger.removeHandler(handler) stream.seek(0) logs = stream.read() web_url = get_copr_build_url_for_values(self.job_owner, self.job_project, build_id) srpm_build = SRPMBuild.create(logs) status = "pending" description = "Building RPM ..." for chroot in self.build_chroots: copr_build = CoprBuild.get_or_create( pr_id=self.event.pr_id, build_id=str(build_id), commit_sha=self.event.commit_sha, repo_name=self.event.base_repo_name, namespace=self.event.base_repo_namespace, web_url=web_url, target=chroot, status=status, srpm_build=srpm_build, ) url = get_log_url(id_=copr_build.id) self.status_reporter.report( state=status, description=description, url=url, check_names=PRCheckName.get_build_check(chroot), ) if chroot in self.tests_chroots: self.status_reporter.report( state=status, description=description, url=url, check_names=PRCheckName.get_testing_farm_check(chroot), ) except SandcastleTimeoutReached: return self._process_timeout() except SandcastleCommandFailed as ex: return self._process_failed_command(ex) except ApiException as ex: return self._process_openshift_error(ex) except PackitSRPMException as ex: return self._process_failed_srpm_build(ex) except PackitCoprProjectException as ex: return self._process_copr_submit_exception(ex) except PackitCoprException as ex: return self._process_general_exception(ex) except Exception as ex: return self._process_general_exception(ex) self.copr_build_model.build_id = build_id self.copr_build_model.save() return HandlerResults(success=True, details={})
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}) try: self.report_status_to_all(description="Building SRPM ...", state="pending") build_id, logs = self._run_copr_build_and_save_output() web_url = get_copr_build_url_for_values( self.job_owner, self.job_project, build_id ) srpm_build_model = SRPMBuild.create(logs) for chroot in self.build_chroots: copr_build = CoprBuild.get_or_create( pr_id=self.event.pr_id, build_id=str(build_id), commit_sha=self.event.commit_sha, repo_name=self.event.base_repo_name, namespace=self.event.base_repo_namespace, web_url=web_url, target=chroot, status="pending", srpm_build=srpm_build_model, ) url = get_log_url(id_=copr_build.id) self.report_status_to_all_for_chroot( state="pending", description="Building RPM ...", url=url, chroot=chroot, ) except SandcastleTimeoutReached: return self._process_timeout() except SandcastleCommandFailed as ex: return self._process_failed_command(ex) except ApiException as ex: return self._process_openshift_error(ex) except PackitSRPMException as ex: return self._process_failed_srpm_build(ex) except PackitCoprProjectException as ex: return self._process_copr_submit_exception(ex) except PackitCoprException as ex: return self._process_general_exception(ex) except Exception as ex: return self._process_general_exception(ex) self.copr_build_model.build_id = build_id self.copr_build_model.save() return HandlerResults(success=True, details={})