Swaps three import paths for mesh-sdk's go/catalogue, go/overlay and go/validate (the same packages, copied from this repository at 6c2a8d62) and lets gofmt order the groups. The six swap commits compile together once the pin commit (go.mod, modules.txt) is on the branch; each alone does not, because a file on the SDK's types cannot call one still on the old package.
103 lines
4.2 KiB
Go
103 lines
4.2 KiB
Go
//go:build integration
|
|
|
|
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
"github.com/novox/mesh-controller/internal/inventory"
|
|
"github.com/novox/mesh-controller/internal/link"
|
|
)
|
|
|
|
func TestOnlyAWalksAskTakesAChecksBuildAndADryRunNever(t *testing.T) {
|
|
p := &inventory.Plan{Delivery: &inventory.PlanDelivery{Merges: []inventory.PlanMerge{
|
|
{Repository: "novox/shop", Number: 7}, {Repository: "http://forge.invalid/novox/web.git", Number: 3},
|
|
{Repository: "novox/shop", Number: 7}, {Repository: "novox/shop"}}}}
|
|
asked := reuseAskOf(p)
|
|
if want := []link.PullRef{{Owner: "novox", Repo: "shop", Number: 7}, {Owner: "novox", Repo: "web", Number: 3}}; !reflect.DeepEqual(asked.Pulls, want) {
|
|
t.Fatalf("the walk names %+v", asked.Pulls)
|
|
}
|
|
walk := withReuse(t.Context(), asked)
|
|
if reuseAsked(walk, false) != asked {
|
|
t.Fatal("a walk's ask does not carry its leave")
|
|
}
|
|
if reuseAsked(walk, true) != nil {
|
|
t.Fatal("a dry run carries a leave to take a check's build")
|
|
}
|
|
if reuseAsked(t.Context(), false) != nil {
|
|
t.Fatal("an ask that is not a walk's carries a leave")
|
|
}
|
|
}
|
|
|
|
func TestAReusedCheckBuildIsRegisteredByItsDigestAndGatedAsABuiltOne(t *testing.T) {
|
|
withTheGate(t) // the first-machine gate's own path (novox/hq ADR 0360 keeps it for earlier walks)
|
|
g := aGateMesh(t)
|
|
ctx := t.Context()
|
|
inv := g.open.inventory
|
|
gateEvery = 0
|
|
|
|
digest := "sha256:" + strings.Repeat("c", 64)
|
|
reused := func(id, reference string) link.BuildResult {
|
|
manifest := mustJSON(t, catalogue.Manifest{Module: "app", Version: "c3", Resources: []map[string]any{
|
|
{"id": "svc", "type": "container", "name": "app", "image": reference}}})
|
|
return link.BuildResult{ID: id, Repository: "novox/mesh-catalog", Path: "modules/app", Ref: "main", On: "anchor",
|
|
Commit: "c3", Manifest: manifest, Trunk: "main", OnTrunk: true, Branches: []string{"main"},
|
|
Made: []link.MadeArtifact{{Name: "server", Kind: "image", Reference: reference}},
|
|
Source: &link.SourceOnSeat{Seat: "git", Repository: "novox/mesh-catalog"},
|
|
Reused: "reused from the check of novox/mesh-catalog#9 at head abcdefabcdef (merged into trunk 123456123456): server " + digest,
|
|
ReusedFrom: &link.ReusedFrom{Pull: link.PullRef{Owner: "novox", Repo: "mesh-catalog", Number: 9},
|
|
Head: "abcdefabcdef", Trunk: "123456123456", Key: "r1:" + strings.Repeat("1", 64)}}
|
|
}
|
|
if _, _, err := takeIn(ctx, inv, reused(link.NewBuildID(time.Now()), "store.internal:5000/scratch/app/server@"+digest)); err == nil ||
|
|
!strings.Contains(err.Error(), "scratch") {
|
|
t.Fatalf("a build in the scratch namespace was registered: %v", err)
|
|
}
|
|
id := link.NewBuildID(time.Now().Add(time.Second))
|
|
result := reused(id, "store.internal:5000/app/server@"+digest)
|
|
if _, _, err := takeIn(ctx, inv, result); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
current, err := inv.CurrentBuilds(ctx)
|
|
if err != nil || current["app"].Commit != "c3" {
|
|
t.Fatalf("the reused build is not what app is registered at: %+v %v", current["app"], err)
|
|
}
|
|
shelf, err := inv.Catalogue(ctx)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
raw, _ := json.Marshal(shelf["app"].Resources)
|
|
if !strings.Contains(string(raw), "app/server@"+digest) {
|
|
t.Fatalf("app is registered as %s, not by the check's digest in its own namespace", raw)
|
|
}
|
|
|
|
// The walk asked it: the walk keeps what its build did, and its gate judges the registered build.
|
|
asked := time.Now().UTC()
|
|
p := g.plan(t)
|
|
p.Commit = "c3"
|
|
p.Modules["app"] = &inventory.PlanModule{State: "asked", AskedAt: &asked, Build: id}
|
|
if err := inv.SavePlan(ctx, &p); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
planBuiltSaying(ctx, g.open, "app", "c3", "", asked, id, result.MadeWords())
|
|
p = g.plan(t)
|
|
if m := p.Modules["app"]; m.State != "built" || !strings.HasPrefix(m.Made, "reused from the check of novox/mesh-catalog#9") {
|
|
t.Fatalf("the walk keeps %+v", m)
|
|
}
|
|
for i := 0; i < 6; i++ {
|
|
advancePlans(ctx, g.open)
|
|
}
|
|
p = g.plan(t)
|
|
gate := p.Modules["app"].Gate
|
|
if gate == nil || gate.To != "c3" || gate.Verdict != inventory.GatePassed {
|
|
t.Fatalf("the gate judged %+v, not the reused build", gate)
|
|
}
|
|
if sent, _, _ := inv.SentBuilds(ctx, "anchor"); sent["app"] != "c3" {
|
|
t.Fatalf("the first machine was sent %v, not the reused build", sent)
|
|
}
|
|
}
|