package bootstrap import ( "errors" "os" "path/filepath" "strings" "testing" "github.com/Pingu-Studio/MaidnCLI/internal/config" ) func TestEnsureTemplateRevisionsLocksFirstCheckout(t *testing.T) { workspace, cfg, git := templateRevisionTestConfig(t) original := runGit runGit = git.run t.Cleanup(func() { runGit = original }) if err := ensureTemplateRevisions(workspace, cfg); err != nil { t.Fatal(err) } lock, err := readTemplateRevisionLock(filepath.Join(workspace, "maidn-template-revisions.yaml")) if err != nil { t.Fatal(err) } if lock.CICD.Commit != git.commits["cicd"] || lock.Manifests.Commit != git.commits["manifests"] || lock.Talos.Commit != git.commits["talos"] { t.Fatalf("lock did not record checked-out commits: %#v", lock) } data, err := os.ReadFile(filepath.Join(workspace, "maidn-template-revisions.yaml")) if err != nil { t.Fatal(err) } if strings.Contains(string(data), "template-password") || strings.Contains(git.commands(), "template-password") { t.Fatal("template credentials reached the lock or Git command arguments") } } func TestEnsureTemplateRevisionsReusesLockedCommitAfterBranchDrift(t *testing.T) { workspace, cfg, git := templateRevisionTestConfig(t) original := runGit runGit = git.run t.Cleanup(func() { runGit = original }) if err := ensureTemplateRevisions(workspace, cfg); err != nil { t.Fatal(err) } locked := git.commits["cicd"] git.commits["cicd"] = strings.Repeat("d", 40) git.resetCalls() if err := ensureTemplateRevisions(workspace, cfg); err != nil { t.Fatal(err) } if git.fetched["cicd"] != locked || git.checkedOut["cicd"] != locked { t.Fatalf("branch drift changed locked CICD revision: fetched %q, checked out %q", git.fetched["cicd"], git.checkedOut["cicd"]) } if strings.Contains(git.commands(), "fetch origin main") { t.Fatal("later run fetched a mutable branch instead of the lock commit") } } func TestEnsureTemplateRevisionsRejectsChangedRefWithoutGit(t *testing.T) { workspace, cfg, git := templateRevisionTestConfig(t) original := runGit runGit = git.run t.Cleanup(func() { runGit = original }) if err := ensureTemplateRevisions(workspace, cfg); err != nil { t.Fatal(err) } git.resetCalls() cfg.Templates.CICDRepoRef = "release" err := ensureTemplateRevisions(workspace, cfg) if err == nil || !strings.Contains(err.Error(), "workspace revision lock") || !strings.Contains(err.Error(), "new empty workspaceDir") { t.Fatalf("changed ref error was not safe and actionable: %v", err) } if git.commands() != "" { t.Fatal("changed ref touched Git before rejecting the lock mismatch") } } func TestEnsureTemplateRevisionsHidesSourceWhenLockedCommitIsUnavailable(t *testing.T) { workspace, cfg, git := templateRevisionTestConfig(t) original := runGit runGit = git.run t.Cleanup(func() { runGit = original }) if err := ensureTemplateRevisions(workspace, cfg); err != nil { t.Fatal(err) } git.failFetch = true err := ensureTemplateRevisions(workspace, cfg) if err == nil || !strings.Contains(err.Error(), "locked template revision cannot be resolved") || !strings.Contains(err.Error(), "new empty workspaceDir") || strings.Contains(err.Error(), "template-password") { t.Fatalf("locked revision failure exposed source details or lacked recovery guidance: %v", err) } } func templateRevisionTestConfig(t *testing.T) (string, config.Config, *fakeTemplateGit) { t.Helper() workspace := t.TempDir() cloneParent := filepath.Join(workspace, "checkouts") if err := os.MkdirAll(cloneParent, 0755); err != nil { t.Fatal(err) } git := &fakeTemplateGit{ commits: map[string]string{ "cicd": strings.Repeat("a", 40), "manifests": strings.Repeat("b", 40), "talos": strings.Repeat("c", 40), }, origins: map[string]string{}, fetched: map[string]string{}, checkedOut: map[string]string{}, } return workspace, config.Config{ WorkspaceDir: workspace, Git: config.GitConfig{CloneParent: cloneParent}, Talos: config.TalosConfig{RepoDirName: "talos"}, Templates: config.TemplateConfig{ CICDRepoURL: "https://reader:template-password@git.example.test/templates/cicd.git", CICDRepoRef: "main", ManifestsRepoURL: "https://git.example.test/templates/manifests.git", ManifestsRepoRef: "main", TalosRepoURL: "https://git.example.test/templates/talos.git", TalosRepoRef: "main", }, }, git } type fakeTemplateGit struct { commits map[string]string origins map[string]string fetched map[string]string checkedOut map[string]string calls []string failFetch bool } func (git *fakeTemplateGit) run(dir string, args ...string) ([]byte, error) { git.calls = append(git.calls, strings.Join(args, " ")) if len(args) == 0 { return nil, errors.New("missing Git command") } switch args[0] { case "clone": dir = args[len(args)-1] if err := os.MkdirAll(dir, 0755); err != nil { return nil, err } git.origins[dir] = args[len(args)-2] return nil, nil case "remote": return []byte(git.origins[dir] + "\n"), nil case "status": return nil, nil case "fetch": if git.failFetch { return nil, errors.New("not found") } target := args[len(args)-1] name := git.templateName(dir) if len(target) == 40 { git.fetched[name] = target } else { git.fetched[name] = git.commits[name] } return nil, nil case "checkout": git.checkedOut[git.templateName(dir)] = args[len(args)-1] return nil, nil case "rev-parse": if len(args) == 2 && args[1] == "--is-inside-work-tree" { return []byte("true\n"), nil } target := args[len(args)-1] if target == "FETCH_HEAD^{commit}" { return []byte(git.fetched[git.templateName(dir)] + "\n"), nil } if target == "HEAD^{commit}" { return []byte(git.checkedOut[git.templateName(dir)] + "\n"), nil } } return nil, errors.New("unexpected Git command") } func (git *fakeTemplateGit) templateName(dir string) string { switch filepath.Base(dir) { case "maidn-cicd-cluster-template": return "cicd" case "cicd-deployment-manifests-template": return "manifests" default: return "talos" } } func (git *fakeTemplateGit) resetCalls() { git.calls = nil } func (git *fakeTemplateGit) commands() string { return strings.Join(git.calls, "\n") }