Files
agentic-coding-workflow/internal/infra/git/runner_test.go
T

100 lines
2.7 KiB
Go

package git
import (
"context"
"errors"
"os/exec"
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestDefaultRunner_exec_BinaryNotFound(t *testing.T) {
t.Parallel()
r := NewDefaultRunner(Config{Binary: "this-is-not-a-real-binary-xyz"})
_, _, err := r.exec(context.Background(), "", nil, "--version")
require.Error(t, err)
var ge *GitError
require.True(t, errors.As(err, &ge))
}
func TestDefaultRunner_exec_NonZeroExit(t *testing.T) {
t.Parallel()
gitAvailable(t)
r := newTestRunner(t)
_, _, err := r.exec(context.Background(), t.TempDir(), nil, "rev-parse", "HEAD")
require.Error(t, err)
var ge *GitError
require.True(t, errors.As(err, &ge))
require.NotZero(t, ge.ExitCode)
}
func TestDefaultRunner_exec_Timeout(t *testing.T) {
t.Parallel()
gitAvailable(t)
r := newTestRunner(t)
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Nanosecond)
defer cancel()
// 任意命令都会因 ctx 已过期而立刻被 kill
_, _, err := r.exec(ctx, "", nil, "version")
require.Error(t, err)
}
func TestIsAuthError(t *testing.T) {
t.Parallel()
cases := []struct {
stderr string
want bool
}{
{"Authentication failed for https://...", true},
{"fatal: could not read Username for 'https://...'", true},
{"Permission denied (publickey).", true},
{"random other failure", false},
}
for _, c := range cases {
got := IsAuthError(&GitError{Stderr: c.stderr})
require.Equal(t, c.want, got, "stderr=%q", c.stderr)
}
}
func TestCredentialEnv_None(t *testing.T) {
t.Parallel()
env, cleanup, err := credentialEnv(t.TempDir(), nil)
require.NoError(t, err)
require.Nil(t, env)
cleanup() // 不应 panic
}
func TestCredentialEnv_PAT(t *testing.T) {
t.Parallel()
tmp := t.TempDir()
env, cleanup, err := credentialEnv(tmp, &Credential{Kind: CredentialPAT, Username: "alice", Secret: []byte("tok")})
require.NoError(t, err)
defer cleanup()
joined := strings.Join(env, "\n")
require.Contains(t, joined, "GIT_ASKPASS=")
require.Contains(t, joined, "GIT_PAT_USERNAME=alice")
require.Contains(t, joined, "GIT_PAT_TOKEN=tok")
require.Contains(t, joined, "GIT_TERMINAL_PROMPT=0")
}
func TestCredentialEnv_SSHKey(t *testing.T) {
t.Parallel()
if _, err := exec.LookPath("ssh"); err != nil {
t.Skip("ssh not available")
}
tmp := t.TempDir()
env, cleanup, err := credentialEnv(tmp, &Credential{
Kind: CredentialSSHKey,
Secret: []byte("-----BEGIN OPENSSH PRIVATE KEY-----\nstub\n-----END OPENSSH PRIVATE KEY-----\n"),
})
require.NoError(t, err)
defer cleanup()
require.Len(t, env, 1)
require.True(t, strings.HasPrefix(env[0], "GIT_SSH_COMMAND="))
require.Contains(t, env[0], "IdentitiesOnly=yes")
require.Contains(t, env[0], "StrictHostKeyChecking=accept-new")
}