async def test_pr_push_failure(tmp_path: Path, session: ClientSession) -> None: setup_repo(tmp_path) config = Configuration(github_user="******", github_token="some-token") update = HelmUpdate( path=tmp_path / "Chart.yaml", applied=False, name="gafaelfawr", current="1.0.0", latest="2.0.0", ) push_error = PushInfo(PushInfo.ERROR, None, "", None, summary="Some error") user = {"name": "Someone", "email": "*****@*****.**"} with aioresponses() as mock_responses: mock_responses.get("https://api.github.com/user", payload=user) mock_responses.get( "https://api.github.com/repos/foo/bar", payload={"default_branch": "master"}, ) pattern = re.compile( r"https://api.github.com/repos/foo/bar/pulls\?.*base=master.*") mock_responses.get(pattern, payload=[]) pr = PullRequester(tmp_path, config, session) with patch.object(Remote, "push") as mock: mock.return_value = [push_error] with pytest.raises(PushError) as excinfo: await pr.make_pull_request([update]) assert "Some error" in str(excinfo.value)
def mock_push() -> Iterator[Mock]: """Mock out `git.Remote.push`. The mock will always return success with a status indicating that a new remote head was created. """ with patch.object(Remote, "push") as mock: mock.return_value = [PushInfo(PushInfo.NEW_HEAD, None, "", None)] yield mock
def test_base_push_good(upstream_distgit_remote): _, distgit, _ = upstream_distgit_remote b = PackitRepositoryBase(config=Config(), package_config=PackageConfig()) b.local_project = LocalProject( working_dir=str(distgit), git_url="https://github.com/packit-service/lol") flexmock( LocalProject, push=lambda *args, **kwargs: [PushInfo(PushInfo.FAST_FORWARD, None, None, None, None)], ) b.push("master")
def test_base_push_bad(upstream_distgit_remote): _, distgit, _ = upstream_distgit_remote b = PackitRepositoryBase(config=Config(), package_config=PackageConfig()) b.local_project = LocalProject( working_dir=str(distgit), git_url="https://github.com/packit-service/lol") flexmock( LocalProject, push=lambda *args, **kwargs: [PushInfo(PushInfo.REMOTE_REJECTED, None, None, None, None)], ) with pytest.raises(PackitException) as e: b.push("master") assert "unable to push" in str(e.value)
def test_when_the_remote_repository_reject_the_push_is_returned_exception( self, repo_mock): repo_full_path = "/tmp/appteste-ndeploy" remote_name = "dokku-deploy" branch_local_name = "master" branch_remote_name = "master" mock_instance = repo_mock.return_value mock_remote = mock_instance.remote.return_value mock_remote.push = MagicMock(return_value=[ PushInfo(flags=GitExec.REMOTE_REJECTED, local_ref=branch_local_name, remote_ref_string=branch_remote_name, remote=remote_name) ]) with self.assertRaises(expected_exception=GitExecError): self.git_exec.git_push(repo_full_path, remote_name, branch_local_name, branch_remote_name)
def test_should_be_possible_to_run_git_push_for_repository( self, repo_mock): repo_full_path = "/tmp/appteste-ndeploy" remote_name = "dokku-deploy" branch_local_name = "master" branch_remote_name = "master" mock_instance = repo_mock.return_value mock_remote = mock_instance.remote.return_value mock_remote.push = MagicMock(return_value=[ PushInfo(flags=0, local_ref=branch_local_name, remote_ref_string=branch_remote_name, remote=remote_name) ]) self.git_exec.git_push(repo_full_path, remote_name, branch_local_name, branch_remote_name) mock_instance.remote.assert_called_with(remote_name) mock_remote.push.assert_called_with( "{branch_local}:{branch_remote}".format( branch_local=branch_local_name, branch_remote=branch_remote_name), progress=self.git_exec.progress)
async def test_processor(tmp_path: Path, session: ClientSession) -> None: tmp_repo = setup_python_repo(tmp_path / "tmp", require_venv=True) upstream_path = tmp_path / "upstream" create_upstream_git_repository(tmp_repo, upstream_path) config = Configuration( repositories=[GitHubRepository(owner="foo", repo="bar")], work_area=tmp_path / "work", ) user = {"name": "Someone", "email": "*****@*****.**"} push_result = [PushInfo(PushInfo.NEW_HEAD, None, "", None)] created_pr = False def check_pr_post(url: str, **kwargs: Any) -> CallbackResult: changes = [ "Update frozen Python dependencies", "Update ambv/black pre-commit hook from 19.10b0 to 20.0.0", ] body = "- " + "\n- ".join(changes) + "\n" assert json.loads(kwargs["data"]) == { "title": CommitMessage.title, "body": body, "head": "u/neophile", "base": "main", "maintainer_can_modify": True, "draft": False, } repo = Repo(str(tmp_path / "work" / "bar")) assert repo.head.ref.name == "u/neophile" yaml = YAML() data = yaml.load(tmp_path / "work" / "bar" / ".pre-commit-config.yaml") assert data["repos"][2]["rev"] == "20.0.0" commit = repo.head.commit assert commit.author.name == "Someone" assert commit.author.email == "*****@*****.**" assert commit.message == f"{CommitMessage.title}\n\n{body}" nonlocal created_pr created_pr = True return CallbackResult(status=201) with aioresponses() as mock: register_mock_github_tags(mock, "ambv", "black", ["20.0.0", "19.10b0"]) mock.get("https://api.github.com/user", payload=user) mock.get( "https://api.github.com/repos/foo/bar", payload={"default_branch": "main"}, ) pattern = re.compile(r"https://api.github.com/repos/foo/bar/pulls\?.*") mock.get(pattern, payload=[]) mock.post( "https://api.github.com/repos/foo/bar/pulls", callback=check_pr_post, ) # Unfortunately, the mock_push fixture can't be used here because we # want to use git.Remote.push in create_upstream_git_repository. factory = Factory(config, session) processor = factory.create_processor() with patch_clone_from("foo", "bar", upstream_path): with patch.object(Remote, "push") as mock_push: mock_push.return_value = push_result await processor.process() assert mock_push.call_args_list == [ call("u/neophile:u/neophile", force=True) ] assert created_pr repo = Repo(str(tmp_path / "work" / "bar")) assert not repo.is_dirty() assert repo.head.ref.name == "master" assert "u/neophile" not in [h.name for h in repo.heads] assert "tmp-neophile" not in [r.name for r in repo.remotes]
async def test_allow_expressions(tmp_path: Path, session: ClientSession) -> None: tmp_repo = setup_kubernetes_repo(tmp_path / "tmp") upstream_path = tmp_path / "upstream" create_upstream_git_repository(tmp_repo, upstream_path) config = Configuration( allow_expressions=True, cache_enabled=False, repositories=[GitHubRepository(owner="foo", repo="bar")], work_area=tmp_path / "work", ) user = {"name": "Someone", "email": "*****@*****.**"} push_result = [PushInfo(PushInfo.NEW_HEAD, None, "", None)] created_pr = False def check_pr_post(url: str, **kwargs: Any) -> CallbackResult: assert json.loads(kwargs["data"]) == { "title": CommitMessage.title, "body": "- Update gafaelfawr Helm chart from 1.3.1 to v1.4.0\n", "head": "u/neophile", "base": "main", "maintainer_can_modify": True, "draft": False, } nonlocal created_pr created_pr = True return CallbackResult(status=201) with aioresponses() as mock: register_mock_helm_repository( mock, "https://kubernetes-charts.storage.googleapis.com/index.yaml", { "elasticsearch": ["1.26.2"], "kibana": ["3.0.1"] }, ) register_mock_helm_repository( mock, "https://kiwigrid.github.io/index.yaml", {"fluentd-elasticsearch": ["3.0.0"]}, ) register_mock_helm_repository( mock, "https://lsst-sqre.github.io/charts/index.yaml", {"gafaelfawr": ["1.3.1", "v1.4.0"]}, ) mock.get("https://api.github.com/user", payload=user) mock.get( "https://api.github.com/repos/foo/bar", payload={"default_branch": "main"}, ) pattern = re.compile(r"https://api.github.com/repos/foo/bar/pulls\?.*") mock.get(pattern, payload=[]) mock.post( "https://api.github.com/repos/foo/bar/pulls", callback=check_pr_post, ) # Unfortunately, the mock_push fixture can't be used here because we # want to use git.Remote.push in create_upstream_git_repository. factory = Factory(config, session) processor = factory.create_processor() with patch_clone_from("foo", "bar", upstream_path): with patch.object(Remote, "push") as mock_push: mock_push.return_value = push_result await processor.process() assert created_pr