Close the builder test's nodes from the bed's start, so no pull in hand takes the first ask (issue 1928)

This commit is contained in:
2026-10-23 23:03:38 +02:00
parent a31bd7d4a5
commit b303e32a41
@@ -179,7 +179,11 @@ type bed struct {
// startBed starts the bus, the buckets the controller makes from the builder's and the build modules' manifests, the // startBed starts the bus, the buckets the controller makes from the builder's and the build modules' manifests, the
// build modules' streams and the builder's durable consumers on them, two nodes' toolchains, the indexer's manifests, and // build modules' streams and the builder's durable consumers on them, two nodes' toolchains, the indexer's manifests, and
// the fake build modules. It runs no builder. // the fake build modules. It runs no builder.
func startBed(t *testing.T) *bed { func startBed(t *testing.T) *bed { return startBedWith(t, false) }
// startBedWith is startBed with the nodes' capacity 0 from the start when closed: a puller that reads its capacity before a
// test could close the nodes may be in a pull already and takes the first ask put (issue 1928).
func startBedWith(t *testing.T, closed bool) *bed {
dir, err := os.MkdirTemp(os.Getenv("TMPDIR"), "b") dir, err := os.MkdirTemp(os.Getenv("TMPDIR"), "b")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@@ -243,6 +247,7 @@ func startBed(t *testing.T) *bed {
b.builds = mk(delivery.BuilderBuildsBucket, delivery.BuilderBuildsHistory) b.builds = mk(delivery.BuilderBuildsBucket, delivery.BuilderBuildsHistory)
b.instances = mk(instancesBucket, 1) b.instances = mk(instancesBucket, 1)
b.fake = &fakeBuildModules{js: js, ctx: ctx, calls: map[string]int{}} b.fake = &fakeBuildModules{js: js, ctx: ctx, calls: map[string]int{}}
b.fake.closed.Store(closed)
b.fake.serve(t, "mesh-build-go", "n1", "n2") b.fake.serve(t, "mesh-build-go", "n1", "n2")
b.fake.serve(t, "mesh-build-node", "n1", "n2") b.fake.serve(t, "mesh-build-node", "n1", "n2")
b.fake.serve(t, "mesh-build-image", "n1") // the image build module runs on n1 only b.fake.serve(t, "mesh-build-image", "n1") // the image build module runs on n1 only
@@ -781,8 +786,7 @@ func (b *bed) asksPut(t *testing.T, nc *nats.Conn) func() []delivery.StepAsk {
// 1887/AC3: a builder that started again while its asks waited in the streams (no node had a free slot) puts no second // 1887/AC3: a builder that started again while its asks waited in the streams (no node had a free slot) puts no second
// ask: it waits for the asks its building key names, and the key is done once a node took them. // ask: it waits for the asks its building key names, and the key is done once a node took them.
func TestARestartedBuilderPutsNoSecondAsk(t *testing.T) { func TestARestartedBuilderPutsNoSecondAsk(t *testing.T) {
b := startBed(t) b := startBedWith(t, true) // 1928/AC1: no node can take an ask from the start, so no pull in hand takes the first one
b.fake.closed.Store(true)
b.module(t, "netcheck", "catalogue-a67f0196-netcheck.module.json", "modules/netcheck") b.module(t, "netcheck", "catalogue-a67f0196-netcheck.module.json", "modules/netcheck")
sub, err := nats.Connect(b.srvURL, nats.UserInfo("ctl", "pw")) sub, err := nats.Connect(b.srvURL, nats.UserInfo("ctl", "pw"))
if err != nil { if err != nil {
@@ -792,11 +796,13 @@ func TestARestartedBuilderPutsNoSecondAsk(t *testing.T) {
asked := b.asksPut(t, sub) asked := b.asksPut(t, sub)
b.start(t, "n1", nil) b.start(t, "n1", nil)
v := b.await(t, "netcheck", func(v delivery.BuilderBuild) bool { return v.State == delivery.BuildBuilding && len(v.Asks) == 2 }) v := b.await(t, "netcheck", func(v delivery.BuilderBuild) bool { return v.State == delivery.BuildBuilding && len(v.Asks) == 2 })
for deadline := time.Now().Add(5 * time.Second); len(asked()) < 2 && time.Now().Before(deadline); time.Sleep(20 * time.Millisecond) { for deadline := time.Now().Add(20 * time.Second); len(asked()) < 2; time.Sleep(20 * time.Millisecond) {
if time.Now().After(deadline) {
t.Fatalf("asks put = %+v within 20 s, want the two the key names", asked())
}
} }
b.stop() b.stop()
b.start(t, "n1", nil) // the same builder, started again, while both asks wait b.start(t, "n1", nil) // the same builder, started again, while both asks wait
time.Sleep(500 * time.Millisecond)
b.fake.open() b.fake.open()
done := b.await(t, "netcheck", isState(delivery.BuildDone)) done := b.await(t, "netcheck", isState(delivery.BuildDone))
if got := asked(); len(got) != 2 { if got := asked(); len(got) != 2 {