package bootstrap import ( "context" "fmt" "net/http" "os" "path/filepath" "strings" "testing" "time" ) // Step 7 installs the one module whose image can never come from the mesh's own registry, because // it IS the mesh's own registry (novox/hq 04-ISSUES/029). These tests defend that, and defend the // distinction the whole verify layer of this program is built on: a container that is up is not a // service that answers. // catalogueWith writes a fake catalogue checkout holding one module's manifest. // // A fixture here rather than the real catalogue, unlike the substrate example the rewrite tests // use: the catalogue is a different repository on a different branch, and a test that read it // would pass or fail according to what somebody else had checked out. func catalogueWith(t *testing.T, module, manifest string) string { t.Helper() root := t.TempDir() dir := filepath.Join(root, catalogueDir, module) if err := os.MkdirAll(dir, 0o755); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(dir, "module.json"), []byte(manifest), 0o644); err != nil { t.Fatal(err) } return root } const upstreamRegistryManifest = `{ "module": "registry", "version": "1", "provides": [{"name": "artifact-store", "scope": "mesh"}], "capabilities": ["container-runtime"], "resources": [ {"id": "state", "type": "directory", "path": "/var/lib/mesh/registry", "mode": "0700"}, {"id": "store", "type": "container", "name": "mesh-registry", "image": "registry@sha256:a3d8aaa63ed8681a604f1dea0aa03f100d5895b6a58ace528858a7b332415373", "ports": ["5000:5000"]} ] }` // aMeshThatAgrees answers every command the installer issues at steps 7 and 9 the way a working // mesh would, except for whatever a test overrides. func aMeshThatAgrees(answers map[string]string) func(string, []string) (string, error) { return func(name string, args []string) (string, error) { joined := strings.Join(args, " ") for fragment, said := range answers { if strings.Contains(joined, fragment) { return said, nil } } switch { case name != "docker": return "", fmt.Errorf("unexpected program %q", name) case args[0] == "cp": return "", nil case args[0] == "inspect": return "true running\n", nil case args[0] == "exec": return "", nil } return "", fmt.Errorf("unexpected: %v", args) } } func installing(t *testing.T, catalogue string) Options { t.Helper() return Options{ Node: "anchor", Catalogue: catalogue, Registry: "127.0.0.1:5000", Timeout: time.Second, Wait: 0, } } // A container that is up is not a registry that serves. `/v2/` is the registry API's own "yes, I // am one and I am ready", and the step after this pushes to it — so it is refused here rather than // discovered inside a `docker push`. func TestARegistryContainerThatIsUpIsNotARegistryThatServes(t *testing.T) { previous := answerEvery answerEvery = time.Millisecond defer func() { answerEvery = previous }() runtime := &asked{answer: aMeshThatAgrees(nil)} deps := Deps{ Run: runtime.run, Fetch: func(context.Context, string) (int, string, error) { return http.StatusInternalServerError, "", nil }, } _, err := InstallRegistry(context.Background(), installing(t, catalogueWith(t, RegistryModule, upstreamRegistryManifest)), deps, controlPlane{container: "temp-mesh-control", run: runtime.run, timeout: time.Second}, func(string) {}) if err == nil { t.Fatal("a registry whose container is up and which answers 500 was accepted") } for _, wanted := range []string{"/v2/", "Running is not serving"} { if !strings.Contains(err.Error(), wanted) { t.Errorf("the refusal does not mention %q:\n%v", wanted, err) } } } // The whole of step 7, against a mesh that agrees: registered, assigned, pushed, up, and answering. func TestARegistryThatAnswersIsAccepted(t *testing.T) { runtime := &asked{answer: aMeshThatAgrees(nil)} deps := Deps{ Run: runtime.run, Fetch: func(context.Context, string) (int, string, error) { return http.StatusOK, "{}", nil }, } out, err := InstallRegistry(context.Background(), installing(t, catalogueWith(t, RegistryModule, upstreamRegistryManifest)), deps, controlPlane{container: "temp-mesh-control", run: runtime.run, timeout: time.Second}, func(string) {}) if err != nil { t.Fatal(err) } if out.Container != "mesh-registry" { t.Errorf("the registry's container is %q", out.Container) } if out.Answered != http.StatusOK { t.Errorf("the registry answered %d", out.Answered) } // Registered, assigned and pushed, through the same three commands a person types. for _, wanted := range []string{ "module add /registry-module.json", "assign anchor registry", "push anchor", } { if !runtime.ran(wanted) { t.Errorf("the installer never ran %q: %v", wanted, runtime.commands) } } } // **The registry's image is upstream and it is never built.** A manifest carrying the catalogue's // placeholder digest would mean somebody had made this module buildable — which is the cycle // novox/hq 04-ISSUES/029 settled: a module that provides the artifact store cannot be delivered // through the artifact store. func TestARegistryManifestThatWantsBuildingIsRefused(t *testing.T) { wants := strings.Replace(upstreamRegistryManifest, "registry@sha256:a3d8aaa63ed8681a604f1dea0aa03f100d5895b6a58ace528858a7b332415373", "mesh-runtime-registry@"+placeholderDigest, 1) runtime := &asked{answer: aMeshThatAgrees(nil)} _, err := InstallRegistry(context.Background(), installing(t, catalogueWith(t, RegistryModule, wants)), Deps{Run: runtime.run}, controlPlane{container: "temp-mesh-control", run: runtime.run}, func(string) {}) if err == nil { t.Fatal("a registry manifest naming an image the mesh would have to build was accepted") } if !strings.Contains(err.Error(), "04-ISSUES/029") { t.Errorf("the refusal does not name the decision it rests on: %v", err) } if runtime.ran("module add") { t.Error("it was registered anyway") } } // A catalogue that is not there is said plainly, with what --catalog is. This is the most likely // mistake anybody makes at this step and the least interesting to debug. func TestACatalogueThatIsNotThereIsSaidPlainly(t *testing.T) { runtime := &asked{answer: aMeshThatAgrees(nil)} _, err := InstallRegistry(context.Background(), installing(t, filepath.Join(t.TempDir(), "nowhere")), Deps{Run: runtime.run}, controlPlane{container: "temp-mesh-control", run: runtime.run}, func(string) {}) if err == nil { t.Fatal("a catalogue that does not exist was accepted") } if !strings.Contains(err.Error(), "--catalog") { t.Errorf("the refusal does not say what to fix: %v", err) } } // A refusal from the control plane is repeated verbatim. mesh-control refuses in paragraphs — // "nothing provides route, wanted by registry" — and an installer that reported "exit status 1" // would throw away the only thing a person can act on. func TestWhatTheMeshRefusedIsRepeated(t *testing.T) { refusal := "nothing provides \"route\", wanted by registry" runtime := &asked{answer: func(name string, args []string) (string, error) { if strings.Contains(strings.Join(args, " "), "push") { return refusal, fmt.Errorf("exit status 1") } return aMeshThatAgrees(nil)(name, args) }} _, err := InstallRegistry(context.Background(), installing(t, catalogueWith(t, RegistryModule, upstreamRegistryManifest)), Deps{Run: runtime.run}, controlPlane{container: "temp-mesh-control", run: runtime.run, timeout: time.Second}, func(string) {}) if err == nil { t.Fatal("a push the mesh refused was reported as successful") } if !strings.Contains(err.Error(), refusal) { t.Errorf("what the mesh said is not in the failure:\n%v", err) } if !strings.Contains(err.Error(), "run this installer again") { t.Errorf("the failure does not say a re-run continues from here:\n%v", err) } }