package main import ( "os" "os/exec" "path/filepath" "strings" "testing" ) // offline is a Go that fetches nothing: what the build seat is once the forge credential is gone, for a pin // its module cache does not hold (novox/hq issue 385). func offline(t *testing.T) { t.Helper() t.Setenv("GOPROXY", "off") t.Setenv("GOFLAGS", "") t.Setenv("GOWORK", "off") // Not GOPRIVATE: a private module is fetched directly by git, around GOPROXY, with whatever credential // the machine running the test holds. t.Setenv("GOPRIVATE", "") t.Setenv("GONOPROXY", "") t.Setenv("GOSUMDB", "off") t.Setenv("GOMODCACHE", t.TempDir()) } func git(t *testing.T, dir string, args ...string) string { t.Helper() cmd := exec.Command("git", args...) cmd.Dir = dir cmd.Env = append(os.Environ(), "GIT_AUTHOR_NAME=t", "GIT_AUTHOR_EMAIL=t@t", "GIT_COMMITTER_NAME=t", "GIT_COMMITTER_EMAIL=t@t", "GIT_AUTHOR_DATE=2026-10-12T08:21:13Z", "GIT_COMMITTER_DATE=2026-10-12T08:21:13Z") out, err := cmd.CombinedOutput() if err != nil { t.Fatalf("git %s: %v\n%s", strings.Join(args, " "), err, out) } return strings.TrimSpace(string(out)) } func write(t *testing.T, path, content string) { t.Helper() if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil { t.Fatal(err) } if err := os.WriteFile(path, []byte(content), 0o644); err != nil { t.Fatal(err) } } // sdkBeside is the SDK's repository cloned beside a check, its Go module under go/, one commit tagged // go/v0.1.7. It answers the beside root and the commit. func sdkBeside(t *testing.T) (string, string) { t.Helper() beside := t.TempDir() repo := filepath.Join(beside, "mesh-sdk") write(t, filepath.Join(repo, "go", "go.mod"), "module git.novox.be/novox/mesh-sdk/go\n\ngo 1.22\n") write(t, filepath.Join(repo, "go", "sdk", "sdk.go"), "package sdk\n\nfunc Hello() string { return \"hello\" }\n") write(t, filepath.Join(repo, "README.md"), "the SDK\n") git(t, repo, "init", "--quiet") git(t, repo, "add", ".") git(t, repo, "commit", "--quiet", "-m", "sdk") git(t, repo, "tag", "go/v0.1.7") return beside, git(t, repo, "rev-parse", "HEAD") } // moduleRequiring is a catalogue module whose code and test use the SDK at the version given. func moduleRequiring(t *testing.T, version string) string { t.Helper() dir := filepath.Join(t.TempDir(), "messenger") write(t, filepath.Join(dir, "go.mod"), "module git.novox.be/novox/mesh-catalog/modules/messenger\n\ngo 1.22\n\n"+ "require git.novox.be/novox/mesh-sdk/go "+version+"\n") write(t, filepath.Join(dir, "main.go"), "package main\n\nimport \"git.novox.be/novox/mesh-sdk/go/sdk\"\n\n"+ "func main() { println(sdk.Hello()) }\n") return dir } func builds(t *testing.T, dir, modfile string) { t.Helper() args := []string{"vet"} if modfile != "" { args = append(args, "-modfile="+modfile) } cmd := exec.Command("go", append(args, "./...")...) cmd.Dir = dir if out, err := cmd.CombinedOutput(); err != nil { t.Fatalf("the module does not build with %q: %v\n%s", modfile, err, out) } } // A module that needs nothing it cannot fetch is left as it is: no other go.mod. func TestAModuleThatFetchesItsDependenciesNeedsNothingBeside(t *testing.T) { offline(t) dir := filepath.Join(t.TempDir(), "plain") write(t, filepath.Join(dir, "go.mod"), "module example.com/plain\n\ngo 1.22\n") write(t, filepath.Join(dir, "main.go"), "package main\n\nfunc main() {}\n") modfile, err := resolve(dir, "", t.TempDir()) if err != nil || modfile != "" { t.Fatalf("resolve = %q, %v; want nothing", modfile, err) } } // The case of issue 385: the module pins an SDK commit the build seat cannot fetch. It is taken from the // SDK's clone beside the check, and the module builds against it. func TestAPinnedSDKCommitIsTakenFromTheCloneBeside(t *testing.T) { offline(t) beside, commit := sdkBeside(t) dir := moduleRequiring(t, "v0.1.14-0.20261012082113-"+commit[:12]) modfile, err := resolve(dir, beside, t.TempDir()) if err != nil { t.Fatalf("resolve: %v", err) } if modfile == "" { t.Fatal("resolve said the module fetches its dependencies, with nothing to fetch them from") } builds(t, dir, modfile) if raw, _ := os.ReadFile(filepath.Join(dir, "go.mod")); strings.Contains(string(raw), "replace") { t.Fatalf("the module's own go.mod was changed:\n%s", raw) } } // A released SDK is found by the tag it is released under: go/. func TestATaggedSDKIsTakenFromTheCloneBeside(t *testing.T) { offline(t) beside, _ := sdkBeside(t) dir := moduleRequiring(t, "v0.1.7") modfile, err := resolve(dir, beside, t.TempDir()) if err != nil { t.Fatalf("resolve: %v", err) } builds(t, dir, modfile) } // A commit the clone beside does not hold (a branch never pushed) cannot be tested, and says which. func TestACommitTheCloneBesideDoesNotHoldIsSaid(t *testing.T) { offline(t) beside, _ := sdkBeside(t) dir := moduleRequiring(t, "v0.1.14-0.20261010132341-4f3efc98e0c0") _, err := resolve(dir, beside, t.TempDir()) if err == nil { t.Fatal("resolve found a commit nothing holds") } for _, want := range []string{"git.novox.be/novox/mesh-sdk/go@v0.1.14-0.20261010132341-4f3efc98e0c0", "4f3efc98e0c0"} { if !strings.Contains(err.Error(), want) { t.Errorf("the reason %q does not name %s", err, want) } } } // With nothing cloned beside (a check by hand without the forge), the reason says that. func TestNoCloneBesideIsSaid(t *testing.T) { offline(t) _, commit := sdkBeside(t) dir := moduleRequiring(t, "v0.1.14-0.20261012082113-"+commit[:12]) for _, beside := range []string{"", t.TempDir()} { _, err := resolve(dir, beside, t.TempDir()) if err == nil { t.Fatalf("resolve with %q beside found what is not there", beside) } if !strings.Contains(err.Error(), "mesh-sdk") { t.Errorf("the reason %q does not name the repository it needed", err) } } } func TestTheRefOfAVersion(t *testing.T) { cases := []struct{ sub, version, want string }{ {"go", "v0.1.14-0.20261012082113-9747f3e1b1ac", "9747f3e1b1ac"}, {"go", "v0.0.0-20261012082113-9747f3e1b1ac", "9747f3e1b1ac"}, {"go", "v0.1.7", "go/v0.1.7"}, {"", "v1.2.0", "v1.2.0"}, {"", "v2.0.0+incompatible", "v2.0.0"}, } for _, c := range cases { if got := refOf(c.sub, c.version); got != c.want { t.Errorf("refOf(%q, %q) = %q, want %q", c.sub, c.version, got, c.want) } } }