Join 11: the toolchain-change test leaves no old toolchain report for the builder to agree on first

Cause: the bed reports go1.27.1 for both nodes at its start, and the test then reports go1.27.2. The builder's new
durable on EVENTS hears the old reports first, so for a moment it agrees on go1.27.1 (said as toolchain-agreed
go1.27.1 by n1, seen in a run's EVENTS); a netcheck entry heard in that moment is built at its old fingerprint
("the old fingerprint, naming go1.27.1, was built with go1.27.2", integration_test.go:767, twice on 2026-11-12).
The builder acts as ADR 0465 says on what it heard; the bed told it a story the test does not mean. The test now
purges the bed's go reports before its own, and asserts that no toolchain-agreed of go1.27.1 is ever said.

Builds: design 47 G §492, §604, A-282

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-12 13:26:58 +01:00
parent 347db8d4fd
commit 299f0b56e0
@@ -755,6 +755,16 @@ func TestAFailedKeyIsBuiltAgainAsANewRevisionFromANewModulesValueWithTheSameFing
// module value naming go1.27.2 (the new fingerprint, computed by the indexer) is built.
func TestAToolchainChangeDoesNotBuildTheOldFingerprint(t *testing.T) { // 1615/AC4
b := startBed(t)
// The nodes' word is go1.27.2 when the module comes: the bed's go1.27.1 reports are not left before them on EVENTS, where the
// builder's new durable would hear them first and agree on go1.27.1 for a moment, building the old fingerprint if its entry
// is heard then (the cause of this test's failures, twice on 2026-11-12).
st, err := b.js.Stream(b.ctx, eventsStream)
if err != nil {
t.Fatal(err)
}
if err := st.Purge(b.ctx, jetstream.WithPurgeSubject("mesh.seat.node-build-go.event.toolchain-reported.>")); err != nil {
t.Fatal(err)
}
b.report(t, "mesh-build-go", "n1", "go", "go1.27.2", "1")
b.report(t, "mesh-build-go", "n2", "go", "go1.27.2", "1")
b.module(t, "netcheck", "catalogue-a67f0196-netcheck.module.json", "modules/netcheck") // names go1.27.1
@@ -763,6 +773,23 @@ func TestAToolchainChangeDoesNotBuildTheOldFingerprint(t *testing.T) { // 1615/A
b.moduleCommit(t, "netcheck2", "catalogue-a67f0196-netcheck.module.json", "modules/netcheck",
map[string]builds.ToolchainUsed{"go": {Version: "go1.27.2", Recipe: "1"}, "typescript": {Version: "tsc5", Recipe: "1"}}, commit)
b.await(t, "netcheck2", isState(builds.BuildDone))
// The builder never agreed on go1.27.1, not for a moment: that is what would build the old fingerprint.
info, err := st.Info(b.ctx)
if err != nil {
t.Fatal(err)
}
for seq := info.State.FirstSeq; seq <= info.State.LastSeq; seq++ {
m, err := st.GetMsg(b.ctx, seq)
if errors.Is(err, jetstream.ErrMsgNotFound) {
continue
}
if err != nil {
t.Fatal(err)
}
if strings.HasSuffix(m.Subject, ".toolchain-agreed") && strings.Contains(string(m.Data), `"version":"go1.27.1"`) {
t.Errorf("the builder said the nodes agree on go1.27.1: %s", m.Data)
}
}
if _, err := b.builds.Get(b.ctx, mustKey(t, "netcheck")); err == nil {
t.Error("the old fingerprint, naming go1.27.1, was built with go1.27.2; the log: " + b.out.String())
}