def test_fetch_all_with_errors(mock_repo): """ GIVEN GitRepo is initialized with a path and repo WHEN remote.fetch_all is called AND one remote fails THEN the other remotes still fetch AND an exception is raised """ mock_remoteA, mock_remoteB, mock_remoteC = Mock(), Mock(), Mock() mock_remoteA.fetch.side_effect = git.GitCommandError("fetch", "") mock_remotes = { "origin": mock_remoteA, "a_remote": mock_remoteB, "other": mock_remoteC } mock_repo.remote = lambda r: mock_remotes[r] repo = GitRepo(repo=mock_repo) repo.remote.names = Mock(return_value=["origin", "a_remote", "other"]) with pytest.raises(exceptions.RemoteException) as exc_info: repo.remote.fetch_all() assert 'origin' in str(exc_info.value) assert mock_remoteA.fetch.called is True assert mock_remoteB.fetch.called is True assert mock_remoteC.fetch.called is True
def create_commit(repo, tree, message, parents=None, commit_cls=sync_commit.Commit): """ :param tree: A dictionary of path: file data """ # TODO: use some lock around this since it writes to the index # First we create an empty index assert tree repo.git.read_tree(empty=True) for path, data in tree.iteritems(): proc = repo.git.hash_object(w=True, path=path, stdin=True, as_process=True, istream=subprocess.PIPE) stdout, stderr = proc.communicate(data) if proc.returncode is not 0: raise git.GitCommandError( ["git", "hash-object", "-w", "--path=%s" % path], proc.returncode, stderr, stdout) repo.git.update_index("100644", stdout, path, add=True, cacheinfo=True) tree_id = repo.git.write_tree() args = ["-m", message] if parents is not None: for item in parents: args.extend(["-p", item]) args.append(tree_id) sha1 = repo.git.commit_tree(*args) repo.git.read_tree(empty=True) return commit_cls(repo, sha1)
def test_gitrepo_commitsquashlocal(gitrepo, gitmock): """ Test commit and squash """ gitmock.return_value.remotes.__contains__.return_value = False gitmock.return_value.is_dirty.return_value = True gitmock.return_value.git.reset.side_effect = git.GitCommandError([''], '') gitrepo.commit('msg', squash=True) gitmock.return_value.git.update_ref.assert_called_once_with('-d', 'HEAD') gitmock.return_value.index.commit.assert_called_once_with('msg')
def test_clone_and_archive_clone_failed(mock_git_clone, mock_temp_dir, gitsubmodule): # Mock the tempfile.TemporaryDirectory context manager mock_temp_dir.return_value.__enter__.return_value = "/tmp/cachito-temp" # Mock the git clone call mock_git_clone.side_effect = git.GitCommandError("some error", 1) git_obj = scm.Git(url, ref) with pytest.raises(CachitoError, match="Cloning the Git repository failed"): git_obj.clone_and_archive(gitsubmodule)
def test_update_git_submodules_failed(mock_repo): repo = mock_repo.return_value # Set up the side effect for submodule_update call repo.submodule_update.side_effect = git.GitCommandError("some error", 1) expected = re.escape("Updating the Git submodule(s) failed") git_obj = scm.Git(url, ref) with pytest.raises(CachitoError, match=expected): git_obj.update_git_submodules(repo)
def test_clone_git_repo_raises_explicit_exception_on_clone_fail( self, mock_clone: mock.MagicMock): mock_clone.side_effect = git.GitCommandError( command="git clone foo.git", status=42, stderr="Error cloning repo!") with self.assertRaisesRegex(types.GitRemoteException, "stderr: 'Error cloning repo!'"): util.clone_git_repo("https://github.com/godaddy/tartufo.git")
def test_explicit_exception_is_raised_if_fetch_fails( self, mock_repo: mock.MagicMock): mock_repo.return_value.remotes.origin.fetch.side_effect = git.GitCommandError( command="git fetch -v origin", status=42, stderr="Fetch failed!") test_scanner = scanner.GitRepoScanner(self.global_options, self.git_options, ".") with self.assertRaisesRegex(types.GitRemoteException, "stderr: 'Fetch failed!'"): for _ in test_scanner.chunks: pass
def test_clone_failed(): """ GIVEN GitRepo without a path or repo WHEN clone is called with a valid clone_from URL and clone_to path AND Repo.clone_from fails with an exception THEN a RepoCreationException is raised """ with patch('git.repo.base.Repo.clone_from') as mock_clone: mock_clone.side_effect = git.GitCommandError('clone', '') with pytest.raises(exceptions.RepoCreationException): GitRepo.clone('./', './testclone')
def test_abort_patch_apply_error(mock_repo): """ GIVEN GitRepo initialized with a path and repo WHEN abort_patch_apply is called AND the abort_patch_apply fails with an exception THEN an Abort_Patch_ApplyException is raised """ mock_repo.git.am.side_effect = git.GitCommandError('abort_patch_apply', '') repo = GitRepo('./', mock_repo) with pytest.raises(exceptions.AbortException): repo.branch.abort_patch_apply()
def test_reverse_diff_error(mock_repo): """ GIVEN GitRepo initialized with a path and repo WHEN reverse_diff is called with a valid diff_path AND the reverse_diff fails with an exception THEN an RevertException is raised """ mock_repo.git.apply.side_effect = git.GitCommandError('apply', '') repo = GitRepo('./', mock_repo) with pytest.raises(exceptions.RevertException): repo.branch.reverse_diff('./requirements.txt')
def test_rebase_abort_error(mock_repo): """ GIVEN GitWrapperRebase initialized with a path and repo WHEN abort is called AND the abort fails with an exception THEN an AbortException is raised """ mock_repo.git.rebase.side_effect = git.GitCommandError('rebase', '') rebase = GitWrapperRebase('./', mock_repo) with pytest.raises(exceptions.AbortException): rebase.abort()
def test_push_tag_failed(mock_repo): """ GIVEN GitRepo is initialized with a path and repo WHEN tag.push is called with a valid tag name and remote AND git.push fails THEN a PushException is raised """ repo = GitRepo(repo=mock_repo) repo.git.push.side_effect = git.GitCommandError('push', '') with patch('git.repo.fun.name_to_object'): with pytest.raises(exceptions.PushException): repo.tag.push("my_tag", "origin")
def test_names_failed(mock_repo): """ GIVEN GitRepo is initialized with a path and repo WHEN GitTag.names() is called AND repo.tags fails THEN a TaggingException is raised """ type(mock_repo).tags = PropertyMock( side_effect=git.GitCommandError('tags', '')) repo = GitRepo(repo=mock_repo) with pytest.raises(exceptions.TaggingException): repo.tag.names()
def test_revert_error(mock_repo): """ GIVEN GitRepo initialized with a path and repo WHEN commit.revert is called AND the revert fails with an exception THEN a RevertException is raised """ mock_repo.git.revert.side_effect = git.GitCommandError('revert', '') repo = GitRepo('./', mock_repo) with patch('git.repo.fun.name_to_object'): with pytest.raises(exceptions.RevertException): repo.commit.revert('123456')
def test_abort_cherrypick_error(mock_repo): """ GIVEN GitRepo initialized with a path and repo WHEN commit.abort_cherrypick is called AND the abort fails with an exception THEN an AbortException is raised """ mock_repo.git.cherry_pick.side_effect = git.GitCommandError( 'cherrypick', '') repo = GitRepo('./', mock_repo) with pytest.raises(exceptions.AbortException): repo.commit.abort_cherrypick()
def test_delete_tag_failed(mock_repo): """ GIVEN GitRepo is initialized with a path and repo WHEN tag.delete is called with a valid tag name AND git.tag fails THEN a TaggingException is raised """ repo = GitRepo(repo=mock_repo) mock_repo.git.tag.side_effect = git.GitCommandError('delete_tag', '') with patch('git.repo.fun.name_to_object'): with pytest.raises(exceptions.TaggingException): repo.tag.delete("my_tag")
def _credentials(client, request, action="fill"): # Set up and execute 'git credential' process, passing stringized token to # the process's stdin p = client.credential(action, as_process=True, istream=subprocess.PIPE) out, err = p.communicate(input=str(request)) # Raise exception if process failed if p.returncode != 0: raise git.GitCommandError(["credential", action], p.returncode, err.rstrip()) # Return token parsed from the command's output return _CredentialToken(out)
def test_apply_patch_apply_error(mock_repo): """ GIVEN GitRepo initialized with a path and repo WHEN apply_patch is called with a valid branch name and a valid path AND git.am fails with an exception THEN a ChangeNotAppliedException is raised """ mock_repo.git.am.side_effect = git.GitCommandError('am', '') repo = GitRepo('./', mock_repo) with patch('git.repo.fun.name_to_object'): with pytest.raises(exceptions.ChangeNotAppliedException): repo.branch.apply_patch('test_branch', './requirements.txt')
def test_reset_reset_failure(mock_repo): """ GIVEN GitRepo is initialized with a path and repo WHEN reset is called AND git.reset fails THEN ResetException is raised """ repo = GitRepo(repo=mock_repo) with patch('git.repo.fun.name_to_object'): mock_repo.head.reset.side_effect = git.GitCommandError('reset', '') with pytest.raises(exceptions.ResetException): repo.branch.hard_reset(refresh=False)
def test_clone_repo_failed(app, pipeline): with mock.patch.object(pipeline, 'clone') as mock_clone, \ mock.patch.object(pipeline, '_report_git_error') as report_git_error, \ mock.patch.object(pipeline, 'parse_spec') as mock_spec, \ mock.patch.object(PullRequest, 'comment') as pr_comment, \ mock.patch.object(Changesets, 'comment') as cs_comment: mock_clone.side_effect = git.GitCommandError('git clone', 1) report_git_error.return_value = None pr_comment.return_value = None cs_comment.return_value = None pipeline.start() assert report_git_error.called mock_spec.assert_not_called()
def test_clone_repo_failed(app, push_runner): with mock.patch.object(push_runner, 'update_build_status') as status, \ mock.patch.object(push_runner, 'clone_repository') as clone_repo, \ mock.patch.object(push_runner, 'validate_settings') as validate_settings, \ mock.patch.object(PullRequest, 'comment') as pr_comment, \ mock.patch.object(Changesets, 'comment') as cs_comment: status.return_value = None clone_repo.side_effect = git.GitCommandError('git clone', 1) pr_comment.return_value = None cs_comment.return_value = None push_runner.run() validate_settings.assert_not_called()
def test_rebase_error_during_rebase(mock_repo): """ GIVEN GitWrapperRebase initialized with a path and repo WHEN to_hash is called with a valid branch name and a valid hash AND rebase fails with an exception THEN a RebaseException is raised """ mock_repo.is_dirty.return_value = False mock_repo.git.rebase.side_effect = git.GitCommandError('rebase', '') rebase = GitWrapperRebase('./', mock_repo) with patch('git.repo.fun.name_to_object'): with pytest.raises(exceptions.RebaseException): rebase.to_hash('branchA', '12345')
def test_clone_and_archive_checkout_failed(mock_git_clone, mock_temp_dir, gitsubmodule): # Mock the tempfile.TemporaryDirectory context manager mock_temp_dir.return_value.__enter__.return_value = "/tmp/cachito-temp" # Mock the git calls mock_git_clone.return_value.commit.side_effect = git.GitCommandError("commit is invalid", 1) git_obj = scm.Git(url, ref) expected = ( "Checking out the Git repository failed. Please verify the supplied reference of " f'"{ref}" is valid.' ) with mock.patch.object(git_obj.sources_dir, "archive_path", new=archive_path): with pytest.raises(CachitoError, match=expected): git_obj.clone_and_archive(gitsubmodule)
def test_rebase_error_during_checkout(mock_repo): """ GIVEN GitRepo initialized with a path and repo WHEN branch.rebase_to_hash is called with a valid branch name and a valid hash AND checkout fails with an exception THEN a CheckoutException is raised """ mock_repo.is_dirty.return_value = False mock_repo.git.checkout.side_effect = git.GitCommandError('checkout', '') repo = GitRepo('./', mock_repo) with patch('git.repo.fun.name_to_object'): with pytest.raises(exceptions.CheckoutException): repo.branch.rebase_to_hash('branchA', '12345')
def test_fetch_with_fetch_error(mock_repo): """ GIVEN GitRepo is initialized with a path and repo WHEN remote.fetch is called AND fetch raises an error THEN RemoteException is raised """ mock_remote = Mock() mock_remote.fetch.side_effect = git.GitCommandError('fetch', '') mock_repo.remote.return_value = mock_remote repo = GitRepo(repo=mock_repo) with pytest.raises(exceptions.RemoteException): repo.remote.fetch("origin")
def test_apply_diff_apply_fails(mock_repo): """ GIVEN GitRepo initialized with a path and repo WHEN apply_diff is called with a valid branch_name and valid diff_path and valid message AND git.apply fails with an exception THEN an ChangeNotAppliedException is raised """ mock_repo.is_dirty.return_value = False mock_repo.git.apply.side_effect = git.GitCommandError('apply', '') repo = GitRepo('./', mock_repo) with patch('git.repo.fun.name_to_object'): with pytest.raises(exceptions.ChangeNotAppliedException): repo.branch.apply_diff('test_branch', './requirements.txt', 'message') assert repo.git.commit.called is False
def test_cherrypick_error_during_cherrypick(mock_repo): """ GIVEN GitRepo initialized with a path and repo WHEN commit.cherrypick_to_hash is called with a valid branch name and a valid hash AND cherry_pick fails with an exception THEN a ChangeNotAppliedException is raised """ mock_repo.is_dirty.return_value = False mock_repo.git.cherry_pick.side_effect = git.GitCommandError( 'cherrypick', '') repo = GitRepo('./', mock_repo) with patch('git.repo.fun.name_to_object'): with pytest.raises(exceptions.ChangeNotAppliedException): repo.commit.cherrypick('12345', 'test')
def test_apply_patch_checkout_error(mock_repo): """ GIVEN GitRepo initialized with a path and repo WHEN apply_patch is called with a valid branch name and a valid path AND checkout fails with an exception THEN a CheckoutException is raised AND git.am not called """ mock_repo.git.checkout.side_effect = git.GitCommandError('checkout', '') repo = GitRepo('./', mock_repo) with patch('git.repo.fun.name_to_object'): with pytest.raises(exceptions.CheckoutException): repo.branch.apply_patch('test_branch', './requirements.txt') assert repo.git.am.called is False
def test_clone_and_archive_checkout_failed(mock_archive_path, mock_git_clone, mock_temp_dir): # Mock the tempfile.TemporaryDirectory context manager mock_temp_dir.return_value.__enter__.return_value = '/tmp/cachito-temp' # Mock the git calls mock_git_clone.return_value.commit.side_effect = git.GitCommandError( 'commit is invalid', 1) # Mock the Git.archives_dir property mock_archive_path.return_value = archive_path git_obj = scm.Git(url, ref) expected = ( 'Checking out the Git repository failed. Please verify the supplied reference of ' f'"{ref}" is valid.') with pytest.raises(CachitoError, match=expected): git_obj.clone_and_archive()
def test_apply_diff_checkout_error(mock_repo): """ GIVEN GitRepo initialized with a path and repo WHEN apply_diff is called with valid parameters AND checkout fails with an exception THEN a CheckoutException is raised AND index.commit not called """ mock_repo.is_dirty.return_value = False mock_repo.git.checkout.side_effect = git.GitCommandError('checkout', '') repo = GitRepo('./', mock_repo) with patch('git.repo.fun.name_to_object'): with pytest.raises(exceptions.CheckoutException): repo.branch.apply_diff('invalid_branch', './requirements.txt', 'my message') assert repo.git.commit.called is False