Files
device_agent/capability_git_test.go
2026-05-30 17:28:38 +02:00

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)
}
}