Files
unkin-agent 8093933500
ci/woodpecker/pr/build Pipeline was successful
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
add the catalog-impact binary
Work out which hosts a puppet-prod change can affect, so a catalog test can
fan out over exactly those hosts instead of the whole estate.

- add cmd/catalog-impact and internal/impact
- map hieradata paths onto fact selectors from the hiera hierarchy
- trace manifest classes back to role classes through include, contain,
  class {} and hiera_include, to a fixed point
- fetch the estate fact table from pdbmux in one query via FactsByName
- widen to all hosts, loudly, for any path that matches no rule
- ship the binary and its completions in the RPM
2026-09-12 16:15:00 +10:00

90 lines
2.3 KiB
Go

package impact
import (
"os"
"os/exec"
"path/filepath"
"reflect"
"testing"
)
func gitRepo(t *testing.T) string {
t.Helper()
if _, err := exec.LookPath("git"); err != nil {
t.Skip("git not available")
}
dir := t.TempDir()
run := func(args ...string) {
t.Helper()
cmd := exec.Command("git", append([]string{"-C", dir}, args...)...)
cmd.Env = append(os.Environ(), "GIT_CONFIG_GLOBAL=/dev/null", "GIT_CONFIG_SYSTEM=/dev/null")
if out, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("git %v: %v: %s", args, err, out)
}
}
write := func(name, body string) {
t.Helper()
p := filepath.Join(dir, name)
if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(p, []byte(body), 0o600); err != nil {
t.Fatal(err)
}
}
run("init", "--initial-branch=develop")
run("config", "user.email", "test@example.net")
run("config", "user.name", "test")
write("keep.pp", "keep\n")
write("gone.pp", "gone\n")
write("old/name.pp", "some reasonably long body so rename detection fires\n")
run("add", ".")
run("commit", "-m", "base")
run("checkout", "-b", "feature")
write("added.pp", "added\n")
write("keep.pp", "changed\n")
if err := os.Remove(filepath.Join(dir, "gone.pp")); err != nil {
t.Fatal(err)
}
if err := os.MkdirAll(filepath.Join(dir, "new"), 0o755); err != nil {
t.Fatal(err)
}
run("mv", "old/name.pp", "new/name.pp")
run("add", "-A")
run("commit", "-m", "feature")
run("checkout", "develop")
return dir
}
func TestChangedFilesCoversAddDeleteAndRename(t *testing.T) {
dir := gitRepo(t)
got, err := ChangedFiles(dir, "develop", "feature")
if err != nil {
t.Fatalf("ChangedFiles: %v", err)
}
want := []string{"added.pp", "gone.pp", "keep.pp", "new/name.pp", "old/name.pp"}
if !reflect.DeepEqual(got, want) {
t.Errorf("ChangedFiles = %v, want %v", got, want)
}
}
func TestCurrentBranch(t *testing.T) {
dir := gitRepo(t)
got, err := CurrentBranch(dir)
if err != nil {
t.Fatalf("CurrentBranch: %v", err)
}
if got != "develop" {
t.Errorf("CurrentBranch = %q, want develop", got)
}
}
func TestChangedFilesReportsGitErrors(t *testing.T) {
dir := gitRepo(t)
if _, err := ChangedFiles(dir, "develop", "no-such-branch"); err == nil {
t.Fatal("expected an error for a missing ref")
}
}