Delete the declarations' stream once every node runs the new node-engine, and assert it no more (issue 1945, B13)
A node away during the switch finds its last declaration on the stream; once every node's have names the node-engine registered, no node reads one, so the stream and the nodes' consumers on it go, said once, and a raise leaves them out (ADR 0539 clause 11).
This commit is contained in:
@@ -154,7 +154,9 @@ type trunkKeys struct {
|
||||
trunk sdkdelivery.Module
|
||||
}
|
||||
|
||||
func (k trunkKeys) ModuleAt(context.Context, string, string) (sdkdelivery.Module, error) { return k.trunk, nil }
|
||||
func (k trunkKeys) ModuleAt(context.Context, string, string) (sdkdelivery.Module, error) {
|
||||
return k.trunk, nil
|
||||
}
|
||||
|
||||
// 1945/AC3 (and AC1, AC2's half for a new fingerprint): a done key of a new fingerprint of an assigned module is taken
|
||||
// in, its composition is written on the node it is assigned to, signed by the controller's key, with its digest beside
|
||||
@@ -315,3 +317,59 @@ func TestAFreshStartComposesEveryNodeAndDeletesThePlansBucketsOnce(t *testing.T)
|
||||
}
|
||||
m.noDeclarationSent(t)
|
||||
}
|
||||
|
||||
// 1945/AC14: the declarations' stream stays while one node's have names another node-engine than the one registered,
|
||||
// and goes, said once, when every node's names it (ADR 0539 clause 11).
|
||||
func TestTheDeclarationsStreamGoesOnceEveryNodeRunsTheNewEngine(t *testing.T) {
|
||||
m := aComposingMesh(t)
|
||||
ctx := t.Context()
|
||||
legacy, err := m.conn.JetStream()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := legacy.AddStream(&nats.StreamConfig{Name: broker.DeclarationsStream, Subjects: []string{"mesh.node.*.declare"},
|
||||
MaxMsgsPerSubject: 1}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// The new node-engine registered at its fingerprint, from its done key.
|
||||
n6 := fpOf('6')
|
||||
keys, trunk := aKeyFor("mesh-host", "6", n6, "novox/mesh-host", "", "f00d0123456789ab")
|
||||
if _, err := liveDoneKeySteps(m.open, trunkKeys{keyBuckets: keys, trunk: trunk}).take(ctx, "mesh-host"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := m.js.CreateOrUpdateKeyValue(ctx, jetstream.KeyValueConfig{Bucket: sdkdelivery.HaveBucket, History: sdkdelivery.HaveHistory}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
haves, err := m.js.KeyValue(ctx, sdkdelivery.HaveBucket)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
have := func(node, fp string) {
|
||||
key, _ := sdkdelivery.HaveKey(node, "mesh-host")
|
||||
raw, _ := sdkdelivery.EncodeHave(sdkdelivery.Have{FP: fp, Phase: sdkdelivery.PhaseRunning, Health: sdkdelivery.HealthOK})
|
||||
if _, err := haves.Put(ctx, key, raw); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
have("anchor", n6)
|
||||
have("laptop", fpOf('5'))
|
||||
if done, err := retireDeclarations(ctx, m.open); err != nil || done {
|
||||
t.Fatalf("with laptop on the old node-engine: done %v (%v)", done, err)
|
||||
}
|
||||
if _, err := m.js.Stream(ctx, broker.DeclarationsStream); err != nil {
|
||||
t.Fatalf("the stream went while laptop runs the old node-engine: %v", err)
|
||||
}
|
||||
have("laptop", n6)
|
||||
if done, err := retireDeclarations(ctx, m.open); err != nil || !done {
|
||||
t.Fatalf("with every node on the new node-engine: done %v (%v)", done, err)
|
||||
}
|
||||
if _, err := m.js.Stream(ctx, broker.DeclarationsStream); !errors.Is(err, jetstream.ErrStreamNotFound) {
|
||||
t.Errorf("the stream is still there: %v", err)
|
||||
}
|
||||
if done, err := retireDeclarations(ctx, m.open); err != nil || !done {
|
||||
t.Errorf("a second look: done %v (%v)", done, err)
|
||||
}
|
||||
if !declarationsRetiredNow(ctx, m.open.inventory) {
|
||||
t.Errorf("a raise after the retirement would assert the stream again")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user