package buildstep import ( "context" "os" "path/filepath" "strings" "testing" "git.novox.be/novox/mesh-sdk/go/forgekey" ) // Issue 890 C1 (ADR 0536 ยง2): a fetch through a bare mirror names the mirror in .git/objects/info/alternates, a // plain file, and never links it. func TestFetchCommitWithMirrorWritesAlternates(t *testing.T) { mirror := t.TempDir() ws := t.TempDir() f := &fakeGit{} // the fake's init does not create .git; make the objects directory as git init would. if err := os.MkdirAll(filepath.Join(ws, ".git", "objects", "info"), 0o755); err != nil { t.Fatal(err) } err := FetchCommit(context.Background(), f.run, ws, "ssh://mesh-forge/novox/mesh-sdk.git", sha, "", WithMirror(mirror)) if err != nil { t.Fatal(err) } p := filepath.Join(ws, ".git", "objects", "info", "alternates") b, err := os.ReadFile(p) if err != nil { t.Fatal(err) } if got, want := strings.TrimSpace(string(b)), filepath.Join(mirror, "objects"); got != want { t.Errorf("alternates %q, want %q", got, want) } if fi, err := os.Lstat(p); err != nil || !fi.Mode().IsRegular() { t.Errorf("alternates is not a plain file: %v %v", fi, err) } // the alternates exist before the fetch runs if len(f.calls) < 3 || !strings.Contains(f.calls[2], "fetch") { t.Errorf("calls %v", f.calls) } } func TestWithMirrorRefusesARelativeOrMissingMirror(t *testing.T) { for _, m := range []string{"rel/mirror", filepath.Join(t.TempDir(), "absent")} { f := &fakeGit{} err := FetchCommit(context.Background(), f.run, t.TempDir(), "ssh://mesh-forge/novox/x.git", sha, "", WithMirror(m)) if err == nil || len(f.calls) != 0 { t.Errorf("mirror %q: err %v, calls %v", m, err, f.calls) } } } func TestUpdateMirrorInitsBareThenFetches(t *testing.T) { mirror := filepath.Join(t.TempDir(), "mirror.git") f := &fakeGit{} if err := UpdateMirror(context.Background(), f.run, mirror, "ssh://mesh-forge/novox/x.git", sha, ""); err != nil { t.Fatal(err) } pm := "git -c credential.helper= -C " + mirror + " " want := []string{ "git -c credential.helper= init -q --bare " + mirror, pm + "remote add origin ssh://mesh-forge/novox/x.git", pm + "fetch --no-tags origin " + sha, pm + "cat-file -e " + sha + "^{commit}", } if strings.Join(f.calls, "\n") != strings.Join(want, "\n") { t.Errorf("commands:\n%s\nwant:\n%s", strings.Join(f.calls, "\n"), strings.Join(want, "\n")) } } func TestUpdateMirrorKeepsAnExistingMirrorAndFallsBackToTheRef(t *testing.T) { mirror := t.TempDir() // exists: no init if err := os.WriteFile(filepath.Join(mirror, "HEAD"), []byte("ref: refs/heads/main\n"), 0o644); err != nil { t.Fatal(err) } f := &fakeGit{} f.rule = func(args string) (r forgekey.Ran) { if strings.HasSuffix(args, "origin "+sha) { r.Status = 1 r.Stderr = "not our ref" } return } if err := UpdateMirror(context.Background(), f.run, mirror, "ssh://mesh-forge/novox/x.git", sha, "refs/pull/3/head"); err != nil { t.Fatal(err) } all := strings.Join(f.calls, "\n") if strings.Contains(all, "init") || strings.Contains(all, "remote add") || !strings.Contains(all, "fetch --no-tags origin refs/pull/3/head") { t.Errorf("commands:\n%s", all) } } func TestUpdateMirrorRefusesBeforeRunning(t *testing.T) { f := &fakeGit{} for _, c := range []struct{ remote, commit string }{ {"https://x/y.git", sha}, {"ssh://u@h/o/r.git", sha}, {"ssh://h/o/r.git", "abc"}, } { if err := UpdateMirror(context.Background(), f.run, t.TempDir(), c.remote, c.commit, ""); err == nil { t.Errorf("%v accepted", c) } } if len(f.calls) != 0 { t.Errorf("ran %v", f.calls) } }