Genesis's base step built only mesh-tools, the TypeScript toolchain. The store's and the bus's modules carry Go bundles, compiled in mesh-tools-go, so genesis stopped at the store step: "this mesh holds no copy of it. Build mesh-tools-go first". The base step now builds mesh-tools-go too, from --tools-go-source or the repository beside --tools-source, and a test holds every toolchain a genesis module's bundles compile in, read from the catalogue, to the ones the step builds.
90 lines
3.7 KiB
Go
90 lines
3.7 KiB
Go
package bootstrap
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// Defends novox/hq issue 616: genesis's base step builds the toolchain of every language a module
|
|
// genesis installs is compiled in. It built only mesh-tools, and the store's module, with Go code,
|
|
// stopped genesis at step 17: "this mesh holds no copy of it. Build mesh-tools-go first".
|
|
|
|
// genesisModules is every catalogue module genesis installs on its own, read from the steps that
|
|
// install them: the registry, the build agent, the store, the bus, the vault, the catalogue and the
|
|
// filter (extras are the operator's choice and come after the base too, but are not genesis's own).
|
|
var genesisModules = []string{RegistryModule, BuilderModule, "postgres", BusModule, "mesh-vault", "mesh-catalog", "nftables"}
|
|
|
|
// Every genesis module's bundles are compiled in a toolchain the base step builds, read from the real
|
|
// catalogue's manifests: a module that gains a language genesis does not build fails here, not at a
|
|
// genesis.
|
|
func TestTheBaseStepBuildsEveryToolchainAGenesisModuleIsCompiledIn(t *testing.T) {
|
|
built := map[string]bool{}
|
|
for _, tc := range genesisToolchains {
|
|
built[tc.Language] = true
|
|
}
|
|
for _, module := range genesisModules {
|
|
var m struct {
|
|
Build struct {
|
|
Artifacts []struct {
|
|
Name, Kind, Language string
|
|
} `json:"artifacts"`
|
|
} `json:"build"`
|
|
}
|
|
if err := json.Unmarshal(theCataloguesModule(t, module), &m); err != nil {
|
|
t.Fatalf("%s: %v", module, err)
|
|
}
|
|
for _, a := range m.Build.Artifacts {
|
|
if a.Kind != "bundle" {
|
|
continue // an image builds on the bases its Dockerfile names, pinned upstream
|
|
}
|
|
if !built[a.Language] {
|
|
t.Errorf("%s's %q is a %s bundle, and genesis's base step builds no %s toolchain",
|
|
module, a.Name, a.Language, a.Language)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// And the base step asks for each toolchain's build: the base, then the Go toolchain beside it.
|
|
func TestTheBaseStepBuildsTheGoToolchainBesideTheBase(t *testing.T) {
|
|
runtime := &asked{answer: aMeshThatAgrees(nil)}
|
|
control := controlPlane{container: "mesh-controller", run: runtime.run, timeout: time.Second}
|
|
o := Options{ToolsSource: Source{Repository: "git://192.0.2.30/mesh-tools.git"}}
|
|
if err := BuildBase(context.Background(), o, control, quietly); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var builds []string
|
|
for _, c := range runtime.commands {
|
|
if strings.Contains(c, "/mesh-controller build ") {
|
|
builds = append(builds, c[strings.Index(c, "build "):])
|
|
}
|
|
}
|
|
want := []string{
|
|
"build git://192.0.2.30/mesh-tools.git --ref main --wait 1200s",
|
|
"build git://192.0.2.30/mesh-tools-go.git --ref main --wait 1200s",
|
|
}
|
|
if strings.Join(builds, "\n") != strings.Join(want, "\n") {
|
|
t.Fatalf("the base step built\n%s\nand not\n%s", strings.Join(builds, "\n"), strings.Join(want, "\n"))
|
|
}
|
|
}
|
|
|
|
func TestTheGoToolchainIsAsGivenOrBesideTheBase(t *testing.T) {
|
|
for _, c := range []struct{ tools, given, want string }{
|
|
{"http://forge/novox/mesh-tools.git", "", "http://forge/novox/mesh-tools-go.git"},
|
|
{"http://forge/novox/mesh-tools", "", "http://forge/novox/mesh-tools-go"},
|
|
{"http://forge/other/base.git", "http://forge/other/go.git", "http://forge/other/go.git"},
|
|
} {
|
|
got, err := toolsGoSource(Options{ToolsSource: Source{Repository: c.tools}, ToolsGoSource: Source{Repository: c.given}})
|
|
if err != nil || got.Repository != c.want {
|
|
t.Errorf("tools %s, given %q: %q %v; want %s", c.tools, c.given, got.Repository, err, c.want)
|
|
}
|
|
}
|
|
if _, err := toolsGoSource(Options{ToolsSource: Source{Repository: "http://forge/other/base.git"}}); err == nil ||
|
|
!strings.Contains(err.Error(), "--tools-go-source") {
|
|
t.Errorf("a base not named mesh-tools, and no Go toolchain given, was not refused naming the flag: %v", err)
|
|
}
|
|
}
|