def test_parse_git_repo_from_git_url(): flexmock(local_project).should_receive("get_repo").with_args( "http://some.example/url/reponame").and_return(flexmock()) project = LocalProject(git_url="http://some.example/url/reponame", refresh=False) changed = project._parse_git_repo_from_git_url() assert changed assert project.git_url assert project.git_repo assert project.working_dir_temporary project.working_dir_temporary = False
def test_parse_git_url_from_git_repo(): project = LocalProject( git_repo=flexmock().should_receive("remote") # must be a generator .replace_with(lambda: flexmock(urls=( x for x in ["[email protected]:org/name"]))).once().mock(), refresh=False, ) changed = project._parse_git_url_from_git_repo() assert changed assert project.git_repo assert project.git_url == "[email protected]:org/name"
def test_parse_git_repo_from_working_dir(): flexmock(local_project).should_receive("is_git_repo").with_args( "some/example/path" ).and_return(True) flexmock( git, Repo=flexmock(active_branch="branch", head=flexmock(is_detached=False)) ) project = LocalProject(working_dir="some/example/path", refresh=False) changed = project._parse_git_repo_from_working_dir() assert changed assert project.git_repo assert project.git_repo.active_branch == "branch" assert not project.working_dir_temporary
def test_parse_git_url_from_git_project(): project = LocalProject( git_project=flexmock().should_receive("get_git_urls").and_return({ "git": "http://some.example/namespace/reponame" }).once().mock(), refresh=False, ) changed = project._parse_git_url_from_git_project() assert changed assert project.git_project assert project.git_url == "http://some.example/namespace/reponame"
def test_parse_git_project_from_repo_namespace_and_git_project(): service_mock = (flexmock().should_receive("get_project").with_args( repo="repo", namespace="namespace").replace_with( lambda repo, namespace: flexmock()).mock()) project = LocalProject(git_service=service_mock, repo_name="repo", namespace="namespace", refresh=False) changed = project._parse_git_project_from_repo_namespace_and_git_project() assert changed assert project.git_service assert project.git_project
def convert(self, value, param, ctx): try: if os.path.isdir(value): return LocalProject(working_dir=value) try: res = requests.get(value) if res.ok: return LocalProject(git_url=value) self.fail("Cannot connect to specified url.", param, ctx) except requests.exceptions.BaseHTTPError as ex: self.fail("Cannot connect to specified url.", param, ctx) except ValueError as ex: self.fail(ex, param, ctx)
def test_from_git_url_path_or_url_repo_name_git_service(): flexmock(path).should_receive("isdir").with_args( "./local/directory/to/git" ).and_return(True).once() flexmock(local_project).should_receive("is_git_repo").with_args( "./local/directory/to/git" ).and_return(True) flexmock(git).should_receive("Repo").with_args( path="./local/directory/to/git" ).and_return(flexmock(active_branch="branch", head=flexmock(is_detached=False))) project = LocalProject( git_url="https://server.git/my_namespace/package_name", namespace="my_namespace", repo_name="package_name", path_or_url="./local/directory/to/git", git_service=flexmock() .should_receive("get_project") .and_return(flexmock()) .mock(), ) assert project assert project.git_url == "https://server.git/my_namespace/package_name" assert project.namespace == "my_namespace" assert project.repo_name == "package_name" assert project.working_dir == "./local/directory/to/git" assert project.git_service assert project.git_project assert project.git_repo assert project.ref == "branch"
def test_clone_project_checkout_new_branch(): """Checkout newly created branch""" branches = {} project = LocalProject( git_repo=flexmock( active_branch="branch", working_dir="something", branches=branches, head=flexmock(is_detached=False), ) .should_receive("create_head") .with_args("other") .replace_with( lambda x: branches.setdefault( x, flexmock().should_receive("checkout").once().mock() ) ) .once() .mock(), ref="other", git_url="[email protected]:org/name", ) assert project.git_repo assert project.working_dir == "something" assert project._ref == "other"
def test_working_dir(): work_dir = Path("./local/directory/to/git") flexmock(local_project).should_receive("is_git_repo").with_args( work_dir ).and_return(True) flexmock(git).should_receive("Repo").with_args(path=work_dir).and_return( flexmock( active_branch=flexmock(name="branch"), head=flexmock(is_detached=False), remotes=[ flexmock( name="origin", url="https://server.git/my_namespace/package_name" ) ], ) ) project = LocalProject(working_dir=work_dir) assert project assert project.git_url == "https://server.git/my_namespace/package_name" assert project.namespace == "my_namespace" assert project.working_dir == work_dir assert project.git_repo assert project.ref == "branch"
def run(self) -> HandlerResults: self.local_project = LocalProject( git_project=self.project, working_dir=self.config.command_handler_work_dir) logger.info("Running testing farm") return self.testing_farm_helper.run_testing_farm(chroot=self.chroot)
def local_project(self) -> LocalProject: if self._local_project is None: self._local_project = LocalProject( git_project=self.project, working_dir=self.config.command_handler_work_dir, ) return self._local_project
def test_basic_local_update_direct_push(upstream_distgit_remote, mock_remote_functionality_upstream): """ basic propose-update test: mock remote API, use local upstream and dist-git """ upstream, distgit, remote_dir = upstream_distgit_remote with cwd(upstream): c = get_test_config() pc = get_local_package_config(str(upstream)) pc.upstream_project_url = str(upstream) pc.dist_git_clone_path = str(distgit) up_lp = LocalProject(working_dir=str(upstream)) api = PackitAPI(c, pc, up_lp) api.sync_release("master", "0.1.0", create_pr=False) remote_dir_clone = Path(f"{remote_dir}-clone") subprocess.check_call( ["git", "clone", remote_dir, str(remote_dir_clone)], cwd=str(remote_dir_clone.parent), ) spec = get_specfile(str(remote_dir_clone / "beer.spec")) assert spec.get_version() == "0.1.0" assert (remote_dir_clone / "README.packit").is_file()
def test_set_spec_ver_empty_changelog(tmpdir): t = Path(str(tmpdir)) u_remote_path = t / "upstream_remote" u_remote_path.mkdir(parents=True, exist_ok=True) subprocess.check_call(["git", "init", "--bare", "."], cwd=u_remote_path) u = t / "upstream_git" shutil.copytree(EMPTY_CHANGELOG, u) initiate_git_repo(u, tag="0.1.0") with cwd(tmpdir): c = get_test_config() pc = get_local_package_config(str(u)) pc.upstream_project_url = str(u) lp = LocalProject(working_dir=str(u)) ups = Upstream(c, pc, lp) new_ver = "1.2.3" ups.specfile.set_spec_version(version=new_ver, changelog_entry="- asdqwe") assert ups.get_specfile_version() == new_ver assert "%changelog" not in u.joinpath("beer.spec").read_text()
def run(self): # rev is a commit # we use branch on purpose so we get the latest thing # TODO: check if rev is HEAD on {branch}, warn then? branch = nested_get(self.event, "msg", "commit", "branch") # self.project is dist-git, we need to get upstream dg = DistGit(self.config, self.package_config) self.package_config.upstream_project_url = ( dg.get_project_url_from_distgit_spec()) if not self.package_config.upstream_project_url: raise PackitException( "URL in specfile is not set. We don't know where the upstream project lives." ) n, r = get_namespace_and_repo_name( self.package_config.upstream_project_url) up = self.upstream_service.get_project(repo=r, namespace=n) lp = LocalProject(git_project=up) api = PackitAPI(self.config, self.package_config, lp) api.sync_from_downstream( dist_git_branch=branch, upstream_branch="master", # TODO: this should be configurable )
def api_instance(upstream_and_remote, distgit_and_remote): u, _ = upstream_and_remote d, _ = distgit_and_remote c = get_test_config() api = get_packit_api(config=c, local_project=LocalProject(working_dir=Path.cwd())) return u, d, api
def mock_remote_functionality(distgit: Path, upstream: Path): def mocked_create_pr(*args, **kwargs): return PullRequestReadOnly( title="", id=42, status=PRStatus.open, url="", description="", author="", source_branch="", target_branch="", created=datetime.datetime(1969, 11, 11, 11, 11, 11, 11), ) flexmock(GithubService) github_service = GithubService() flexmock( GithubService, get_project=lambda repo, namespace: GithubProject( "also-not", github_service, "set", github_repo=flexmock() ), ) flexmock( PagureProject, get_git_urls=lambda: {"git": DOWNSTREAM_PROJECT_URL}, fork_create=lambda: None, get_fork=lambda: PagureProject("", "", PagureService()), create_pr=mocked_create_pr, ) flexmock( GithubProject, get_git_urls=lambda: {"git": UPSTREAM_PROJECT_URL}, fork_create=lambda: None, ) flexmock(PagureUser, get_username=lambda: "packito") dglp = LocalProject( working_dir=distgit, git_url="https://packit.dev/rpms/beer", git_service=PagureService(), ) flexmock( DistGit, push_to_fork=lambda *args, **kwargs: None, # let's not hammer the production lookaside cache webserver is_archive_in_lookaside_cache=lambda archive_path: False, local_project=dglp, ) flexmock(DistGit).should_receive("existing_pr").and_return(None) def mocked_new_sources(sources=None): if not Path(sources).is_file(): raise RuntimeError("archive does not exist") flexmock(PkgTool, new_sources=mocked_new_sources) flexmock(PackitAPI, init_kerberos_ticket=lambda: None) pc = get_local_package_config(str(upstream)) pc.dist_git_clone_path = str(distgit) pc.upstream_project_url = str(upstream) return upstream, distgit
def test_update_on_cockpit_ostree(cockpit_ostree): def mocked_new_sources(sources=None): if not Path(sources).is_file(): raise RuntimeError("archive does not exist") flexmock(FedPKG, init_ticket=lambda x=None: None, new_sources=mocked_new_sources) flexmock( DistGit, push_to_fork=lambda *args, **kwargs: None, is_archive_in_lookaside_cache=lambda archive_path: False, ) flexmock( PackitAPI, push_and_create_pr=lambda pr_title, pr_description, dist_git_branch: None, ) pc = get_local_package_config(str(cockpit_ostree)) up_lp = LocalProject(working_dir=str(cockpit_ostree)) c = get_test_config() api = PackitAPI(c, pc, up_lp) with cwd(cockpit_ostree): api.sync_release( "master", use_local_content=False, version="179", force_new_sources=False, create_pr=True, ) assert api.dg.download_upstream_archive().is_file()
def test_centos_conf(cronie, tmp_path: Path): """ make sure the centos-specific configuration is correct """ source_git_path = tmp_path.joinpath("cronie-sg") # create src-git source_git_path.mkdir() create_new_repo(source_git_path, []) sgg = SourceGitGenerator( LocalProject(working_dir=source_git_path), Config(), dist_git_path=cronie, upstream_ref="cronie-1.5.2", centos_package="cronie", ) dg = sgg.dist_git assert isinstance(dg, CentOS8DistGit) flexmock( DistGit, download_upstream_archive=lambda: cronie / "SOURCES" / "cronie-1.5.2.tar.gz", ) assert sgg.primary_archive == cronie / "SOURCES" / "cronie-1.5.2.tar.gz" assert dg.absolute_source_dir == cronie / "SOURCES" assert dg.absolute_specfile_dir == cronie / "SPECS" assert dg.absolute_specfile_path == cronie / "SPECS" / "cronie.spec"
def test_from_path_or_url_ref_path(): flexmock(path).should_receive("isdir").with_args( "./local/directory/to/git" ).and_return(True).once() flexmock(local_project).should_receive("is_git_repo").with_args( "./local/directory/to/git" ).and_return(True) flexmock(git).should_receive("Repo").with_args( path="./local/directory/to/git" ).and_return( flexmock(active_branch="branch", head=flexmock(is_detached=False)) .should_receive("remote") .replace_with( lambda: flexmock(urls=["https://server.git/my_namespace/package_name"]) ) .once() .mock() ) project = LocalProject(path_or_url="./local/directory/to/git") assert project assert project.git_url == "https://server.git/my_namespace/package_name" assert project.namespace == "my_namespace" assert project.working_dir == "./local/directory/to/git" assert project.git_repo assert project.ref == "branch"
def run(self) -> HandlerResults: # self.project is dist-git, we need to get upstream dg = DistGit(self.config, self.package_config) self.package_config.upstream_project_url = ( dg.get_project_url_from_distgit_spec() ) if not self.package_config.upstream_project_url: return HandlerResults( success=False, details={ "msg": "URL in specfile is not set. " "We don't know where the upstream project lives." }, ) n, r = get_namespace_and_repo_name(self.package_config.upstream_project_url) up = self.project.service.get_project(repo=r, namespace=n) self.local_project = LocalProject( git_project=up, working_dir=self.config.command_handler_work_dir ) self.api = PackitAPI(self.config, self.package_config, self.local_project) self.api.sync_from_downstream( # rev is a commit # we use branch on purpose so we get the latest thing # TODO: check if rev is HEAD on {branch}, warn then? dist_git_branch=self.distgit_event.branch, upstream_branch="master", # TODO: this should be configurable ) return HandlerResults(success=True, details={})
def sync_upstream_release_with_fedmsg(self, fedmsg: Dict): """ Sync the upstream release to the distgit pull-request. :param fedmsg: fedmsg dict """ repo_name = fedmsg["msg"]["repository"]["name"] namespace = fedmsg["msg"]["repository"]["owner"]["login"] version = fedmsg["msg"]["release"]["tag_name"] https_url = fedmsg["msg"]["repository"]["html_url"] github_repo = self._github_service.get_project( # type: ignore repo=repo_name, namespace=namespace) local_project = LocalProject(git_project=github_repo) package_config = get_packit_config_from_repo( sourcegit_project=github_repo, ref=version) if not package_config: logger.info( f"No packit config: skipping release {version} for {namespace}/{repo_name}." ) return if not package_config.upstream_project_url: package_config.upstream_project_url = https_url # TODO: https://github.com/packit-service/packit/issues/103 self.sync_upstream_release( package_config=package_config, version=version, dist_git_branch="master", upstream_local_project=local_project, )
def test_pr_id_and_ref(tmp_path: Path): """ p-s passes both ref and pr_id, we want to check out PR """ remote = tmp_path / "remote" remote.mkdir() subprocess.check_call(["git", "init", "--bare", "."], cwd=remote) upstream_git = tmp_path / "upstream_git" upstream_git.mkdir() initiate_git_repo(upstream_git, push=True, upstream_remote=str(remote)) # mimic github PR pr_id = "123" ref = (subprocess.check_output(["git", "rev-parse", "HEAD^"], cwd=upstream_git).strip().decode()) local_tmp_branch = "asdqwe" subprocess.check_call(["git", "branch", local_tmp_branch, ref], cwd=upstream_git) subprocess.check_call( [ "git", "push", "origin", f"{local_tmp_branch}:refs/pull/{pr_id}/head" ], cwd=upstream_git, ) subprocess.check_call(["git", "branch", "-D", local_tmp_branch], cwd=upstream_git) LocalProject(working_dir=str(upstream_git), offline=True, pr_id=pr_id, ref=ref) assert (subprocess.check_output( ["git", "rev-parse", "--abbrev-ref", "HEAD"], cwd=upstream_git).strip().decode() == f"pr/{pr_id}")
def test_set_spec_macro_source(tmp_path): u_remote_path = tmp_path / "upstream_remote" u_remote_path.mkdir(parents=True, exist_ok=True) create_new_repo(u_remote_path, ["--bare"]) u = tmp_path / "upstream_git" shutil.copytree(UPSTREAM_MACRO_IN_SOURCE, u) initiate_git_repo(u, tag="0.1.0") with cwd(tmp_path): c = get_test_config() pc = get_local_package_config(str(u)) pc.upstream_project_url = str(u) lp = LocalProject(working_dir=u) ups = Upstream(c, pc, lp) expected_sources = ups.specfile.sources new_ver = "1.2.3" ups.specfile.set_spec_version(version=new_ver, changelog_entry="- asdqwe") assert ups.get_specfile_version() == new_ver assert ups.specfile.sources == expected_sources expected_sources = ups.specfile.sources new_rel = "121" ups.specfile.set_spec_version(release=new_rel) assert ups.specfile.get_release() == new_rel assert ups.specfile.sources == expected_sources
def test_working_dir_namespace_repo_name(): url = "https://server.git/my_namespace/package_name" flexmock(local_project).should_receive("is_git_repo").with_args( "./local/directory/to/git").and_return(True) flexmock(git).should_receive("Repo").with_args( path="./local/directory/to/git").and_return( flexmock(active_branch=flexmock(name="branch"), head=flexmock(is_detached=False))) project = LocalProject( working_dir="./local/directory/to/git", namespace="my_namespace", repo_name="package_name", git_service=flexmock().should_receive("get_project").and_return( flexmock(get_git_urls=lambda: {"git": url})).mock(), ) assert project assert project.git_url == url assert project.namespace == "my_namespace" assert project.repo_name == "package_name" assert project.git_service assert project.git_project assert project.git_repo assert project.ref == "branch"
def sync_upstream_pull_request_with_fedmsg(self, fedmsg: Dict): repo_name = fedmsg["msg"]["pull_request"]["head"]["repo"]["name"] namespace = fedmsg["msg"]["pull_request"]["head"]["repo"]["owner"][ "login"] ref = fedmsg["msg"]["pull_request"]["head"]["ref"] pr_id = fedmsg["msg"]["pull_request"]["number"] github_repo = self._github_service.get_project( # type: ignore repo=repo_name, namespace=namespace) local_project = LocalProject(git_project=github_repo) package_config = get_packit_config_from_repo( sourcegit_project=github_repo, ref=ref) if not package_config: logger.debug( f"No packit config: skipping pull-request {pr_id} for {namespace}/{repo_name}." ) return self.sync_upstream_pull_request( package_config=package_config, pr_id=pr_id, dist_git_branch="master", upstream_local_project=local_project, )
def test_dg_downstream_package_name_is_set( api_mock, path, downstream_package_name, expectation ): api_mock._dg = None api_mock.package_config.downstream_package_name = downstream_package_name api_mock.downstream_local_project = LocalProject(working_dir=path) assert api_mock.dg.package_config.downstream_package_name == expectation
def test_centos_cronie(dist_git_branch, upstream_ref, api_instance_source_git, tmp_path: Path): source_git_path = tmp_path.joinpath("cronie-sg") # create src-git source_git_path.mkdir() create_new_repo(source_git_path, []) sgg = SourceGitGenerator( LocalProject(working_dir=source_git_path), api_instance_source_git.config, "https://github.com/cronie-crond/cronie", upstream_ref=upstream_ref, centos_package="cronie", dist_git_branch=dist_git_branch, ) sgg.create_from_upstream() if dist_git_branch == "c8s": assert CENTOS_DOMAIN in sgg.dist_git.local_project.git_url else: assert CENTOS_STREAM_GITLAB in sgg.dist_git.local_project.git_url # verify it subprocess.check_call(["packit", "srpm"], cwd=source_git_path) srpm_path = list(source_git_path.glob("cronie-*.src.rpm"))[0] assert srpm_path.is_file()
def run(self) -> HandlerResults: """ Sync the upstream release to dist-git as a pull request. """ self.local_project = LocalProject( git_project=self.project, working_dir=self.config.command_handler_work_dir) self.api = PackitAPI(self.config, self.package_config, self.local_project) errors = [] for branch in get_branches( self.job.metadata.get("dist-git-branch", "master")): try: self.api.sync_release(dist_git_branch=branch, version=self.event.tag_name) except Exception as ex: sentry_integration.send_to_sentry(ex) errors.append( f"Propose update for branch {branch} failed: {ex}") if errors: return HandlerResults( success=False, details={ "msg": "Propose update failed.", "errors": errors }, ) return HandlerResults(success=True, details={})
def test_from_path_repo_name_git_service(): flexmock(git.Repo).should_receive("clone_from").and_return( flexmock( active_branch=flexmock(name="branch"), working_dir="some/temp/dir", head=flexmock(is_detached=False), )) flexmock(tempfile).should_receive("mkdtemp").and_return("some/temp/dir") project = LocalProject( git_url="https://server.git/my_namespace/package_name", repo_name="package_name", git_service=flexmock().should_receive("get_project").and_return( flexmock()).mock(), ) assert project assert project.working_dir == "some/temp/dir" assert project.git_url == "https://server.git/my_namespace/package_name" assert project.namespace == "my_namespace" assert project.repo_name == "package_name" assert project.git_service assert project.git_project assert project.git_repo assert project.ref == "branch"
def test_set_spec_ver_empty_changelog(tmp_path): u_remote_path = tmp_path / "upstream_remote" u_remote_path.mkdir(parents=True, exist_ok=True) create_new_repo(u_remote_path, ["--bare"]) u = tmp_path / "upstream_git" shutil.copytree(EMPTY_CHANGELOG, u) initiate_git_repo(u, tag="0.1.0") with cwd(tmp_path): c = get_test_config() pc = get_local_package_config(str(u)) pc.upstream_project_url = str(u) lp = LocalProject(working_dir=u) ups = Upstream(c, pc, lp) new_ver = "1.2.3" ups.specfile.version = new_ver ups.specfile.add_changelog_entry("- asdqwe") assert ups.get_specfile_version() == new_ver assert "%changelog" not in u.joinpath("beer.spec").read_text()