package builder import ( "strings" "testing" "github.com/novox/mesh-controller/internal/catalogue" ) // A module naming a base the mesh has not built is refused, and the refusal names what is missing. // // **This is the whole point of naming a base rather than pinning one** (novox/hq issue 044). A // recipe with a fingerprint typed into it fails inside a container runtime, on its first line, with // a message about an image nobody can look up. This fails before anything is built, saying which // module has to exist first. func TestABaseTheMeshHasNotBuiltIsRefused(t *testing.T) { manifest := catalogue.Manifest{ Module: "postgres", Build: &catalogue.Build{ On: []catalogue.BuildsOn{{Arg: "RUNTIME_BASE", Module: "mesh-tools", Artifact: "runtime"}}, }, } _, err := standingOn(manifest, map[string]string{}) if err == nil { t.Fatal("a base nothing has built was accepted; the build would have failed on its first line") } for _, want := range []string{"mesh-tools", "postgres"} { if !strings.Contains(err.Error(), want) { t.Errorf("the refusal does not name %s: %v", want, err) } } } // And one the mesh holds becomes the argument the recipe reads it from. func TestABaseTheMeshHoldsBecomesABuildArgument(t *testing.T) { manifest := catalogue.Manifest{ Module: "postgres", Build: &catalogue.Build{ On: []catalogue.BuildsOn{{Arg: "RUNTIME_BASE", Module: "mesh-tools", Artifact: "runtime"}}, }, } held := map[string]string{"mesh-tools/runtime": "127.0.0.1:5000/mesh-tools/runtime@sha256:" + strings.Repeat("a", 64)} args, err := standingOn(manifest, held) if err != nil { t.Fatalf("a base this mesh holds was refused: %v", err) } want := []string{"--build-arg", "RUNTIME_BASE=" + held["mesh-tools/runtime"]} if len(args) != len(want) || args[0] != want[0] || args[1] != want[1] { t.Fatalf("the build was invoked with %v, not %v", args, want) } } // A module naming no base asks for nothing, which is most modules. func TestAModuleNamingNoBaseAddsNoArguments(t *testing.T) { args, err := standingOn(catalogue.Manifest{Module: "hello-web", Build: &catalogue.Build{}}, nil) if err != nil || args != nil { t.Fatalf("a module naming no base produced %v, %v", args, err) } } // Half a base is refused rather than half-applied. func TestAnIncompleteBaseIsRefused(t *testing.T) { manifest := catalogue.Manifest{ Module: "postgres", Build: &catalogue.Build{On: []catalogue.BuildsOn{{Module: "mesh-tools", Artifact: "runtime"}}}, } if _, err := standingOn(manifest, map[string]string{"mesh-tools/runtime": "x"}); err == nil { t.Fatal("a base with no build argument was accepted; nothing would have read it") } }