117 lines
2.7 KiB
Go
117 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func skipIfNoGit(t *testing.T) {
|
|
t.Helper()
|
|
if _, err := exec.LookPath("git"); err != nil {
|
|
t.Skip("git not installed")
|
|
}
|
|
}
|
|
|
|
func initRepo(t *testing.T, dir string) {
|
|
t.Helper()
|
|
mustRun := func(args ...string) {
|
|
c := exec.Command("git", args...)
|
|
c.Dir = dir
|
|
c.Env = append(os.Environ(),
|
|
"GIT_AUTHOR_NAME=test", "GIT_AUTHOR_EMAIL=test@x",
|
|
"GIT_COMMITTER_NAME=test", "GIT_COMMITTER_EMAIL=test@x")
|
|
out, err := c.CombinedOutput()
|
|
if err != nil {
|
|
t.Fatalf("git %v: %v\n%s", args, err, out)
|
|
}
|
|
}
|
|
mustRun("init", "-b", "master")
|
|
mustRun("config", "user.email", "test@x")
|
|
mustRun("config", "user.name", "test")
|
|
}
|
|
|
|
func TestGitCommit_OK(t *testing.T) {
|
|
skipIfNoGit(t)
|
|
tmp := t.TempDir()
|
|
repo := filepath.Join(tmp, "repo")
|
|
os.MkdirAll(repo, 0755)
|
|
initRepo(t, repo)
|
|
os.WriteFile(filepath.Join(repo, "f.txt"), []byte("hello"), 0644)
|
|
|
|
cap := tempCap(t, tmp+"/**")
|
|
res, _, err := runGitCommit(cap, map[string]any{
|
|
"repo": repo,
|
|
"message": "init",
|
|
"files": []any{"f.txt"},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("commit: %v", err)
|
|
}
|
|
m := res.(map[string]any)
|
|
if m["commit_sha"].(string) == "" {
|
|
t.Fatalf("empty sha")
|
|
}
|
|
}
|
|
|
|
func TestGitCommit_PathNotAllowed(t *testing.T) {
|
|
skipIfNoGit(t)
|
|
cap := tempCap(t, "/tmp/safe/**")
|
|
_, _, err := runGitCommit(cap, map[string]any{
|
|
"repo": "/etc",
|
|
"message": "evil",
|
|
})
|
|
if err == nil || !strings.Contains(err.Error(), "not allowed") {
|
|
t.Fatalf("expected reject, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestGitClone_Local(t *testing.T) {
|
|
skipIfNoGit(t)
|
|
tmp := t.TempDir()
|
|
src := filepath.Join(tmp, "src")
|
|
os.MkdirAll(src, 0755)
|
|
initRepo(t, src)
|
|
os.WriteFile(filepath.Join(src, "f.txt"), []byte("data"), 0644)
|
|
c := exec.Command("git", "add", ".")
|
|
c.Dir = src
|
|
c.Run()
|
|
c = exec.Command("git", "commit", "-m", "init")
|
|
c.Dir = src
|
|
c.Env = append(os.Environ(),
|
|
"GIT_AUTHOR_NAME=t", "GIT_AUTHOR_EMAIL=t@x",
|
|
"GIT_COMMITTER_NAME=t", "GIT_COMMITTER_EMAIL=t@x")
|
|
out, err := c.CombinedOutput()
|
|
if err != nil {
|
|
t.Fatalf("seed commit: %v %s", err, out)
|
|
}
|
|
|
|
dest := filepath.Join(tmp, "clone")
|
|
cap := tempCap(t, tmp+"/**")
|
|
res, code, err := runGitClone(cap, map[string]any{
|
|
"url": src,
|
|
"dest": dest,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("clone: %v code=%d", err, code)
|
|
}
|
|
m := res.(map[string]any)
|
|
if m["commit_sha"].(string) == "" {
|
|
t.Fatalf("empty sha")
|
|
}
|
|
if _, err := os.Stat(filepath.Join(dest, "f.txt")); err != nil {
|
|
t.Fatalf("file not present after clone")
|
|
}
|
|
}
|
|
|
|
func TestGitPush_PathNotAllowed(t *testing.T) {
|
|
skipIfNoGit(t)
|
|
cap := tempCap(t, "/tmp/safe/**")
|
|
_, _, err := runGitPush(cap, map[string]any{"repo": "/etc"})
|
|
if err == nil || !strings.Contains(err.Error(), "not allowed") {
|
|
t.Fatalf("expected reject, got %v", err)
|
|
}
|
|
}
|