107 lines
3.5 KiB
Go
107 lines
3.5 KiB
Go
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)
|
|
}
|
|
}
|