69 lines
2.3 KiB
Go
69 lines
2.3 KiB
Go
//go:build integration
|
|
|
|
package main
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/novox/mesh-controller/internal/inventory"
|
|
)
|
|
|
|
func TestACarriedModuleTakesItsLeadsPassBeforeItsStepIsRead(t *testing.T) {
|
|
withTheGate(t) // the first-machine gate\'s own path (novox/hq ADR 0360 keeps it for earlier walks)
|
|
judgeLeavesAsTheCore(t)
|
|
tm := aTierMesh(t, "m01", "m02")
|
|
ctx := t.Context()
|
|
inv := tm.open.inventory
|
|
|
|
advancePlans(ctx, tm.open)
|
|
if !reflect.DeepEqual(tm.sent, [][]string{{"anchor"}}) {
|
|
t.Fatalf("sent %v: the first machine once, for the tier", tm.sent)
|
|
}
|
|
p := tm.plan(t)
|
|
lead, carried := p.Modules["m01"], p.Modules["m02"]
|
|
if lead.Gate == nil || carried.GatedBy != "m01" {
|
|
t.Fatalf("m02 is not carried by m01's send: lead %+v, carried %+v", lead.Gate, carried)
|
|
}
|
|
// The lead passed; the carried module's turn did not come. The first send is past the wait's bound.
|
|
sent := time.Now().UTC().Add(-planWaitBound - time.Minute)
|
|
judged := sent.Add(2 * time.Minute)
|
|
lead.FirstAt, carried.FirstAt, lead.Gate.Since = &sent, &sent, &sent
|
|
lead.Gate.Verdict, lead.Gate.Why, lead.Gate.JudgedAt, lead.Gate.Kept = inventory.GatePassed,
|
|
"healthy 3 times over 2m5s", &judged, true
|
|
carried.Gate = nil
|
|
if err := inv.SavePlan(ctx, &p); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Another walk's send reached anchor, which has not reported on it.
|
|
if err := inv.RecordSent(ctx, nodeID(t, tm.open, "anchor"), "d-anchor-elsewhere",
|
|
map[string]string{"m01": "c2", "m02": "c2"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
advancePlans(ctx, tm.open)
|
|
p = tm.plan(t)
|
|
if p.State == inventory.PlanFailed {
|
|
t.Fatalf("the plan failed after its gate passed: %s", p.Note)
|
|
}
|
|
if !reflect.DeepEqual(tm.sent, [][]string{{"anchor"}, {"laptop"}}) {
|
|
t.Fatalf("sent %v: the rest once, as the pass said", tm.sent)
|
|
}
|
|
current, err := inv.CurrentBuilds(ctx)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, m := range []string{"m01", "m02"} {
|
|
if current[m].Commit != "c2" {
|
|
t.Errorf("%s was put back to %s after its gate passed", m, current[m].Commit)
|
|
}
|
|
if failed, _ := inv.GateFailed(ctx, "build-"+m+"-2"); failed {
|
|
t.Errorf("%s's build was marked failed at its gate after the gate passed", m)
|
|
}
|
|
}
|
|
if g := p.Modules["m02"].Gate; g == nil || g.Verdict != inventory.GatePassed {
|
|
t.Errorf("m02 did not take over m01's pass: %+v", g)
|
|
}
|
|
}
|