// Package beside is where a test finds another repository of the mesh it reads: the catalogue's manifests, // the node-engine's genesis template (novox/hq issue 432). // // A test used to read the checkout beside this one, `../../../mesh-catalog`, so its verdict depended on // whatever sat on the machine running it: a stale or dirty checkout failed it on a desktop, and where none // was beside it skipped and said nothing. Now there are two inputs, both named, and no third: // // - In a merge check, the build seat clones each core repository beside the one checked (the catalogue // at its main, the node-engine at the commit the mesh runs) and says where in MESH_CHECK_BESIDE. A // test judges against those clones, so agreement with the other repository is checked where // `mesh/repo-check` runs; a repository missing there fails the test, never skips it. Which clones a // check gets is chosen from the inventory: mesh-catalog by the source of the `nats` module, mesh-host // by the source of `mesh-host`. In a mesh where either module has no source repository nothing is // cloned, and these tests fail loudly with "not beside this check": a cause in the setup, not in the // change. And in a delivery group that holds a mesh-catalog pull request, these tests read the // catalogue's main, not the group's head. // - Anywhere else, the test judges against the copy captured in this repository's testdata/beside, at the // commit testdata/beside/CAPTURED names. Never against a developer's own checkout: to judge one, set // MESH_CHECK_BESIDE to the directory holding it, as the check does. // // The captured manifests are named module.json.captured, and put back as module.json in a directory of // the test's own: a module.json anywhere in this repository is a module of it to the forge's announcer and // the planner, and a merge would build and register a hundred copies of the catalogue's. package beside import ( "io/fs" "os" "path/filepath" "runtime" "strings" "testing" ) // Env is where a merge check says the repositories cloned beside the one checked are (internal/builder's // EnvBeside, repeated here so a test does not import the builder). const Env = "MESH_CHECK_BESIDE" // CapturedSuffix is what a captured file's name carries that the repository's own does not. const CapturedSuffix = ".captured" // Dir is the named repository a test reads — the clone beside a merge check, or the captured copy — and // says which in the test's log. func Dir(t testing.TB, repository string) string { t.Helper() if root := os.Getenv(Env); root != "" { dir := filepath.Join(root, repository) if _, err := os.Stat(dir); err != nil { t.Fatalf("%s is not beside this check in %s=%s, so its agreement with this repository cannot be "+ "judged here: %v", repository, Env, root, err) } t.Logf("judged against %s as cloned beside this check", dir) return dir } from := filepath.Join(Captured(), repository) if _, err := os.Stat(from); err != nil { t.Fatalf("no captured copy of %s at %s: %v", repository, from, err) } dir := filepath.Join(t.TempDir(), repository) err := filepath.WalkDir(from, func(path string, d fs.DirEntry, err error) error { if err != nil { return err } rel, _ := filepath.Rel(from, path) into := filepath.Join(dir, strings.TrimSuffix(rel, CapturedSuffix)) if d.IsDir() { return os.MkdirAll(into, 0o755) } raw, err := os.ReadFile(path) if err != nil { return err } return os.WriteFile(into, raw, 0o644) }) if err != nil { t.Fatalf("the captured copy of %s could not be laid out: %v", repository, err) } t.Logf("judged against the copy of %s captured in testdata/beside (see CAPTURED); a merge check "+ "judges it against the repository's own clone", repository) return dir } // Catalogue is the catalogue's modules directory, as Dir finds the catalogue. func Catalogue(t testing.TB) string { t.Helper() return filepath.Join(Dir(t, "mesh-catalog"), "modules") } // Captured is this repository's testdata/beside, found from this file rather than from the working // directory, so a test in any package reaches it. func Captured() string { _, file, _, _ := runtime.Caller(0) return filepath.Join(filepath.Dir(file), "..", "..", "testdata", "beside") }