def validate(self) -> str: """ Create output for PackageConfig validation.""" schema_errors: Union[List[Any], Dict[Any, Any]] = None try: PackageConfig.get_from_dict( self.content, config_file_path=str(self.config_file_path), spec_file_path=str( get_local_specfile_path(self.config_file_path.parent)), ) except ValidationError as e: schema_errors = e.messages except PackitConfigException as e: return str(e) if not schema_errors: return f"{self.config_file_path.name} is valid and ready to be used" output = f"{self.config_file_path.name} does not pass validation:\n" if isinstance(schema_errors, list): output += "\n".join(map(str, schema_errors)) return output for field_name, errors in schema_errors.items(): output += self.validate_get_field_output(errors, field_name) return output
def test_trigger_build(copr_build, run_new_build): valid_commit_sha = "1111111111111111111111111111111111111111" package_config = PackageConfig() package_config.jobs = [] package_config.spec_source_id = 1 job_config = flexmock() job_config.type = JobType.build job_config.spec_source_id = 1 job_config.metadata = JobMetadataConfig() event = { "event_type": "CoprBuileEndEvent", "commit_sha": valid_commit_sha, } flexmock(TFJobHelper).should_receive("get_latest_copr_build").and_return(copr_build) if run_new_build: flexmock(TFJobHelper, job_owner="owner", job_project="project") flexmock(Signature).should_receive("apply_async").once() else: flexmock(TFJobHelper).should_receive("run_testing_farm").and_return( TaskResults(success=True, details={}) ) flexmock(cb).should_receive("get_valid_build_targets").and_return( {"target", "another-target"} ) tf_handler = TestingFarmHandler(package_config, job_config, event, "target") tf_handler.run()
def test_dist_git_package_url(): di = { "dist_git_base_url": "https://packit.dev/", "downstream_package_name": "packit", "dist_git_namespace": "awesome", "synced_files": ["fedora/foobar.spec"], "specfile_path": "fedora/package.spec", "create_pr": False, } new_pc = PackageConfig.get_from_dict(di) pc = PackageConfig( dist_git_base_url="https://packit.dev/", downstream_package_name="packit", dist_git_namespace="awesome", synced_files=SyncFilesConfig(files_to_sync=[ SyncFilesItem(src="fedora/foobar.spec", dest="fedora/foobar.spec") ]), specfile_path="fedora/package.spec", create_pr=False, jobs=get_default_job_config(), ) assert new_pc.specfile_path.endswith("fedora/package.spec") assert pc.specfile_path.endswith("fedora/package.spec") assert pc == new_pc assert pc.dist_git_package_url == "https://packit.dev/awesome/packit.git" assert new_pc.dist_git_package_url == "https://packit.dev/awesome/packit.git" assert not pc.create_pr
def test_get_specfile_sync_files_nodownstreamname_item(): pc = PackageConfig(specfile_path="fedora/python-ogr.spec") upstream_specfile_path = "fedora/python-ogr.spec" downstream_specfile_path = "python-ogr.spec" assert pc.get_specfile_sync_files_item() == SyncFilesItem( src=[upstream_specfile_path], dest=downstream_specfile_path) assert pc.get_specfile_sync_files_item( from_downstream=True) == SyncFilesItem(src=[downstream_specfile_path], dest=upstream_specfile_path)
def test_package_config_equal(job_config_simple): assert PackageConfig( specfile_path="fedora/package.spec", synced_files=[SyncFilesItem(src=["packit.yaml"], dest="packit.yaml")], jobs=[job_config_simple], downstream_package_name="package", create_pr=True, ) == PackageConfig( specfile_path="fedora/package.spec", synced_files=[SyncFilesItem(src=["packit.yaml"], dest="packit.yaml")], jobs=[job_config_simple], downstream_package_name="package", create_pr=True, )
def get_request_details(cls, request_id: str) -> Dict[str, Any]: """Testing Farm sends only request/pipeline id in a notification. We need to get more details ourselves.""" self = cls( service_config=ServiceConfig.get_service_config(), package_config=PackageConfig(), project=None, metadata=None, db_trigger=None, job_config=JobConfig( # dummy values to be able to construct the object type=JobType.tests, trigger=JobConfigTriggerType.pull_request, ), ) response = self.send_testing_farm_request( endpoint=f"requests/{request_id}", method="GET" ) if not response or response.status_code != 200: msg = f"Failed to get request/pipeline {request_id} details from TF. {response.reason}" logger.error(msg) return {} details = response.json() # logger.debug(f"Request/pipeline {request_id} details: {details}") return details
def pc_koji_build_pr(): return PackageConfig(jobs=[ JobConfig( type=JobType.production_build, trigger=JobConfigTriggerType.pull_request, metadata=JobMetadataConfig(_targets=["fedora-all"]), ) ])
def pc_build_push(): return PackageConfig(jobs=[ JobConfig( type=JobType.copr_build, trigger=JobConfigTriggerType.commit, metadata=JobMetadataConfig(_targets=["fedora-all"]), ) ])
def pc_tests(): return PackageConfig(jobs=[ JobConfig( type=JobType.tests, trigger=JobConfigTriggerType.pull_request, metadata={"targets": ["fedora-all"]}, ) ])
def pc_build_release(): return PackageConfig(jobs=[ JobConfig( type=JobType.copr_build, trigger=JobConfigTriggerType.release, metadata={"targets": ["fedora-all"]}, ) ])
def test_package_config_parse(raw, expected): package_config = PackageConfig.get_from_dict(raw_dict=raw) assert package_config # tests for https://github.com/packit-service/packit-service/pull/342 if expected.jobs: for j in package_config.jobs: assert j.type assert package_config == expected
def pc_build(): return PackageConfig(jobs=[ JobConfig( job=JobType.copr_build, trigger=JobTriggerType.pull_request, metadata={"targets": ["fedora-all"]}, ) ])
def pc_build_pr(): pc = PackageConfig(jobs=[ JobConfig( type=JobType.copr_build, trigger=JobConfigTriggerType.pull_request, metadata=JobMetadataConfig(targets=["fedora-all"]), ) ]) return pc
def validate(self) -> str: """Create output for PackageConfig validation.""" schema_errors: Union[List[Any], Dict[Any, Any]] = None config = None try: config = PackageConfig.get_from_dict( self.content, config_file_path=str(self.config_file_path), spec_file_path=str( get_local_specfile_path(self.config_file_path.parent)), ) except ValidationError as e: schema_errors = e.messages except PackitConfigException as e: return str(e) specfile_path = self.content.get("specfile_path", None) if specfile_path and not Path(specfile_path).is_file(): logger.warning( f"The spec file you defined ({specfile_path}) is not " f"present in the repository. If it's being generated " f"dynamically, you can verify the functionality by " f"running `packit srpm` to create an SRPM " f"from the current checkout. If it's not being generated, " f"please make sure the path is correct and " f"the file is present.") synced_files_errors = [] if config: synced_files_errors = [ f for f in iter_srcs(config.files_to_sync) if not Path(f).exists() ] output = f"{self.config_file_path.name} does not pass validation:\n" if schema_errors: if isinstance(schema_errors, list): output += "\n".join(map(str, schema_errors)) else: for field_name, errors in schema_errors.items(): output += self.validate_get_field_output( errors, field_name) if synced_files_errors: output += "The following {} configured to be synced but {} not exist: {}\n".format( *(( "paths are", "do", ) if (len(synced_files_errors) > 1) else ("path is", "does")), ", ".join(synced_files_errors), ) if schema_errors or synced_files_errors: return output else: return f"{self.config_file_path.name} is valid and ready to be used"
def test_package_config_not_equal(not_equal_package_config): config = PackageConfig( specfile_path="fedora/package.spec", synced_files=SyncFilesConfig(files_to_sync=[ SyncFilesItem(src="c", dest="c"), SyncFilesItem(src="d", dest="d"), ]), jobs=[get_job_config_full()], create_pr=True, ) assert config != not_equal_package_config
def get_distgit_kls_from_repo( repo_path: Path, config: Config ) -> Tuple[DistGit, Optional[str], Optional[str]]: """ :return: DistGit instance, centos package name, fedora package name """ path = Path(repo_path) pc = PackageConfig(downstream_package_name=path.name) lp = LocalProject(working_dir=path) if "fedoraproject.org" in lp.git_url: return DistGit(config, pc, local_project=lp), None, path.name elif "centos.org" in lp.git_url: return CentOSDistGit(config, pc, local_project=lp), path.name, None raise PackitException( f"Dist-git URL {lp.git_url} not recognized, we expected centos.org or fedoraproject.org" )
def get_distgit_kls_from_repo( repo_path: Path, config: Config) -> Tuple[DistGit, Optional[str], Optional[str]]: """ :return: DistGit instance, centos package name, fedora package name """ path = Path(repo_path) pc = PackageConfig(downstream_package_name=path.name) lp = LocalProject(working_dir=path) if FEDORA_DOMAIN in lp.git_url: return DistGit(config, pc, local_project=lp), None, path.name elif CENTOS_DOMAIN in lp.git_url: return CentOS8DistGit(config, pc, local_project=lp), path.name, None elif CENTOS_STREAM_GITLAB in lp.git_url: return CentOS9DistGit(config, pc, local_project=lp), path.name, None raise PackitException( f"Dist-git URL {lp.git_url} not recognized, we expected one of: " f"{FEDORA_DOMAIN}, {CENTOS_DOMAIN} or {CENTOS_STREAM_GITLAB}")
def test_package_config_overrides_bad(raw, err_message): with pytest.raises(ValidationError) as ex: PackageConfig.get_from_dict(raw_dict=raw) assert err_message in str(ex)
def test_package_config_overrides(raw, expected): package_config = PackageConfig.get_from_dict(raw_dict=raw) assert package_config == expected
def test_package_config_parse_error(raw): with pytest.raises(Exception): PackageConfig.get_from_dict(raw_dict=raw)
def test_copr_build_end_testing_farm(copr_build_end, copr_build): steve = SteveJobs() flexmock(SteveJobs, _is_private=False) flexmock(CoprHelper).should_receive("get_copr_client").and_return( Client( config={ "copr_url": "https://copr.fedorainfracloud.org", "username": "******", })) flexmock(CoprBuildJobHelper).should_receive("job_owner").and_return( "some-owner") flexmock(CoprBuildJobHelper).should_receive("copr_build_model").and_return( flexmock()) config = PackageConfig(jobs=[ JobConfig( type=JobType.copr_build, trigger=JobConfigTriggerType.pull_request, metadata={"targets": ["fedora-rawhide"]}, ), JobConfig( type=JobType.tests, trigger=JobConfigTriggerType.pull_request, metadata={"targets": ["fedora-rawhide"]}, ), ]) flexmock(CoprBuildEvent).should_receive("get_package_config").and_return( config) flexmock(GithubTestingFarmHandler).should_receive( "get_package_config_from_repo").and_return(config) flexmock(CoprBuildEndHandler).should_receive( "was_last_build_successful").and_return(False) flexmock(GithubProject).should_receive("pr_comment") flexmock(LocalProject).should_receive("refresh_the_arguments").and_return( None) flexmock(CoprBuild).should_receive("get_by_build_id").and_return( copr_build) flexmock(CoprBuild).should_receive("set_status").with_args("success") flexmock(CoprBuildDB).should_receive("get_build").and_return({ "commit_sha": "XXXXX", "pr_id": 24, "repo_name": "hello-world", "repo_namespace": "packit-service", "ref": "XXXX", "https_url": "https://github.com/packit-service/hello-world", }) url = "https://localhost:5000/copr-build/1/logs" flexmock(requests).should_receive("get").and_return(requests.Response()) flexmock( requests.Response).should_receive("raise_for_status").and_return(None) # check if packit-service set correct PR status flexmock(StatusReporter).should_receive("report").with_args( state=CommitStatus.success, description="RPMs were built successfully.", url=url, check_names=EXPECTED_BUILD_CHECK_NAME, ).once() flexmock(StatusReporter).should_receive("report").with_args( state=CommitStatus.pending, description="RPMs were built successfully.", url=url, check_names=EXPECTED_TESTING_FARM_CHECK_NAME, ).once() flexmock(uuid).should_receive("uuid4").and_return( uuid.UUID("5e8079d8-f181-41cf-af96-28e99774eb68")) payload: dict = { "pipeline": { "id": "5e8079d8-f181-41cf-af96-28e99774eb68" }, "api": { "token": "" }, "response-url": "https://stg.packit.dev/api/testing-farm/results", "artifact": { "repo-name": "bar", "repo-namespace": "foo", "copr-repo-name": "some-owner/foo-bar-123-stg", "copr-chroot": "fedora-rawhide-x86_64", "commit-sha": "0011223344", "git-url": "https://github.com/foo/bar.git", "git-ref": "0011223344", }, } flexmock(TestingFarmJobHelper).should_receive( "send_testing_farm_request").with_args( TESTING_FARM_TRIGGER_URL, "POST", {}, json.dumps(payload)).and_return( RequestResponse( status_code=200, ok=True, content='{"url": "some-url"}'.encode(), json={"url": "some-url"}, )) flexmock(StatusReporter).should_receive("report").with_args( state=CommitStatus.pending, description="Build succeeded. Submitting the tests ...", check_names=EXPECTED_TESTING_FARM_CHECK_NAME, url="", ).once() flexmock(StatusReporter).should_receive("report").with_args( state=CommitStatus.pending, description="Tests are running ...", url="some-url", check_names=EXPECTED_TESTING_FARM_CHECK_NAME, ).once() steve.process_message(copr_build_end)
def test_package_config_specfile_not_present_raise(raw): with pytest.raises(PackitConfigException): PackageConfig.get_from_dict(raw_dict=raw)
gp = flexmock(GitProject) gp.should_receive("full_repo_name").and_return("a/b") gp.should_receive("get_files").and_return(files) git_project = GitProject(repo="", service=GitService(), namespace="") assert get_specfile_path_from_repo(project=git_project) == expected @pytest.mark.parametrize( "package_config, project", [ ( PackageConfig( specfile_path="xxx", jobs=[ JobConfig( type=JobType.copr_build, trigger=JobConfigTriggerType.pull_request, ) ], ), None, ), ( PackageConfig( specfile_path="xxx", jobs=[ JobConfig( type=JobType.copr_build, trigger=JobConfigTriggerType.pull_request, metadata=JobMetadataConfig(project="example"), )
def test_package_config_upstream_and_downstream_package_names(raw, expected): package_config = PackageConfig.get_from_dict(raw_dict=raw, repo_name="package") assert package_config assert package_config == expected
def test_notifications_section(): pc = PackageConfig.get_from_dict({"specfile_path": "package.spec"}) assert pc.notifications.pull_request.successful_build
def test_copr_build_end_failed_testing_farm_no_json(copr_build_end, copr_build): steve = SteveJobs() flexmock(SteveJobs, _is_private=False) flexmock(CoprHelper).should_receive("get_copr_client").and_return( Client( config={ "copr_url": "https://copr.fedorainfracloud.org", "username": "******", })) flexmock(CoprBuildJobHelper).should_receive("job_owner").and_return( "some-owner") flexmock(CoprBuildJobHelper).should_receive("copr_build_model").and_return( flexmock()) config = PackageConfig(jobs=[ JobConfig( type=JobType.copr_build, trigger=JobConfigTriggerType.pull_request, metadata={"targets": ["fedora-rawhide"]}, ), JobConfig( type=JobType.tests, trigger=JobConfigTriggerType.pull_request, metadata={"targets": ["fedora-rawhide"]}, ), ]) flexmock(CoprBuildEvent).should_receive("get_package_config").and_return( config) flexmock(GithubTestingFarmHandler).should_receive( "get_package_config_from_repo").and_return(config) flexmock(CoprBuildEndHandler).should_receive( "was_last_build_successful").and_return(False) flexmock(GithubProject).should_receive("pr_comment") flexmock(LocalProject).should_receive("refresh_the_arguments").and_return( None) flexmock(CoprBuild).should_receive("get_by_build_id").and_return( copr_build) flexmock(CoprBuild).should_receive("set_status").with_args("success") flexmock(CoprBuildDB).should_receive("get_build").and_return({ "commit_sha": "XXXXX", "pr_id": 24, "repo_name": "hello-world", "repo_namespace": "packit-service", "ref": "XXXX", "https_url": "https://github.com/packit-service/hello-world", }) url = get_log_url(1) flexmock(requests).should_receive("get").and_return(requests.Response()) flexmock( requests.Response).should_receive("raise_for_status").and_return(None) # check if packit-service set correct PR status flexmock(StatusReporter).should_receive("report").with_args( state=CommitStatus.success, description="RPMs were built successfully.", url=url, check_names=EXPECTED_BUILD_CHECK_NAME, ).once() flexmock(StatusReporter).should_receive("report").with_args( state=CommitStatus.pending, description="RPMs were built successfully.", url=url, check_names=EXPECTED_TESTING_FARM_CHECK_NAME, ).once() flexmock(TestingFarmJobHelper).should_receive( "send_testing_farm_request").and_return( RequestResponse( status_code=400, ok=False, content="some text error".encode(), reason="some text error", json=None, )) flexmock(CoprBuild).should_receive("set_status").with_args("failure") flexmock(StatusReporter).should_receive("report").with_args( state=CommitStatus.pending, description="Build succeeded. Submitting the tests ...", check_names=EXPECTED_TESTING_FARM_CHECK_NAME, url="", ).once() flexmock(StatusReporter).should_receive("report").with_args( state=CommitStatus.failure, description="Failed to submit tests: some text error", check_names=EXPECTED_TESTING_FARM_CHECK_NAME, url="", ).once() steve.process_message(copr_build_end)
def test_package_config_validate_unknown_key(raw, is_valid): if not is_valid: with pytest.raises((ValidationError, ValueError)): PackageConfig.get_from_dict(raw) else: PackageConfig.get_from_dict(raw)
def test_package_config_specilfe_not_present_not_raise(raw): assert PackageConfig.get_from_dict(raw_dict=raw)
def test_copr_build_end_failed_testing_farm_no_json(copr_build_end, copr_build_pr): flexmock(GithubProject).should_receive("is_private").and_return(False) flexmock(GithubProject).should_receive("get_pr").and_return( flexmock( source_project=flexmock(get_web_url=lambda: "abc"), target_branch_head_commit="deadbeef", ).should_receive("comment").mock()) config = PackageConfig(jobs=[ JobConfig( type=JobType.copr_build, trigger=JobConfigTriggerType.pull_request, metadata=JobMetadataConfig( _targets=["fedora-rawhide"], owner="some-owner", project="some-project", ), ), JobConfig( type=JobType.tests, trigger=JobConfigTriggerType.pull_request, metadata=JobMetadataConfig(_targets=["fedora-rawhide"]), ), ]) flexmock(AbstractCoprBuildEvent).should_receive( "get_package_config").and_return(config) flexmock(PackageConfigGetter).should_receive( "get_package_config_from_repo").and_return(config) flexmock(CoprBuildEndHandler).should_receive( "was_last_packit_comment_with_congratulation").and_return(False) flexmock(LocalProject).should_receive("refresh_the_arguments").and_return( None) flexmock(CoprBuildModel).should_receive("get_by_build_id").and_return( copr_build_pr) flexmock(CoprBuildModel).should_receive("get_by_id").and_return( copr_build_pr) copr_build_pr.should_call("set_status").with_args("success").once() copr_build_pr.should_receive("set_end_time").once() url = get_copr_build_info_url(1) flexmock(requests).should_receive("get").and_return(requests.Response()) flexmock( requests.Response).should_receive("raise_for_status").and_return(None) # check if packit-service set correct PR status flexmock(StatusReporter).should_receive("report").with_args( state=BaseCommitStatus.success, description="RPMs were built successfully.", url=url, check_names=EXPECTED_BUILD_CHECK_NAME, markdown_content=None, ).once() flexmock(StatusReporter).should_receive("report").with_args( state=BaseCommitStatus.pending, description="RPMs were built successfully.", url=url, check_names=EXPECTED_TESTING_FARM_CHECK_NAME, markdown_content=None, ).once() flexmock(TestingFarmJobHelper).should_receive( "is_fmf_configured").and_return(True) flexmock(TestingFarmJobHelper).should_receive( "send_testing_farm_request").and_return( RequestResponse( status_code=400, ok=False, content=b"some text error", reason="some text error", json=None, )) flexmock(CoprBuildModel).should_receive("set_status").with_args("failure") flexmock(StatusReporter).should_receive("report").with_args( state=BaseCommitStatus.running, description="Build succeeded. Submitting the tests ...", check_names=EXPECTED_TESTING_FARM_CHECK_NAME, url="", markdown_content=None, ).once() flexmock(StatusReporter).should_receive("report").with_args( state=BaseCommitStatus.failure, description="Failed to submit tests: some text error", check_names=EXPECTED_TESTING_FARM_CHECK_NAME, url="", markdown_content=None, ).once() flexmock(Signature).should_receive("apply_async").twice() flexmock(Pushgateway).should_receive("push").twice().and_return() # skip SRPM url since it touches multiple classes flexmock(CoprBuildEndHandler).should_receive("set_srpm_url").and_return( None) processing_results = SteveJobs().process_message(copr_build_end) event_dict, job, job_config, package_config = get_parameters_from_results( processing_results) assert json.dumps(event_dict) flexmock(CoprBuildJobHelper).should_receive( "get_built_packages").and_return([]) run_copr_build_end_handler( package_config=package_config, event=event_dict, job_config=job_config, ) flexmock(TestingFarmHandler).should_receive("db_trigger").and_return( copr_build_pr.get_trigger_object()) run_testing_farm_handler( package_config=package_config, event=event_dict, job_config=job_config, chroot="fedora-rawhide-x86_64", build_id=flexmock(), )