issue 974: a rollout's wait for a machine is a key on the bus that its report deletes and its expiry names silent
This commit is contained in:
@@ -322,6 +322,73 @@ func TestTheMergeWindowsKeysExpireAndAWatcherHearsIt(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// **A rollout's wait for a machine is a bucket whose keys expire** (novox/hq ADR 0406 §5, issue 974): a key made with a
|
||||
// time to live goes when it is up, and a watcher hears it go as a purge; a key a report deleted is a delete. The
|
||||
// controller may write it, and it is no undeclared state.
|
||||
func TestTheRolloutsSilentKeysExpireAsAPurgeAndAReportsDeleteIsNot(t *testing.T) {
|
||||
controller, err := PermissionsFor(Principal{Kind: KindController, PasswordHash: "x"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !slices.Contains(controller.Publish, "$KV."+RolloutSilentBucket+".>") {
|
||||
t.Error("the controller may not write the rollout's silent keys' bucket")
|
||||
}
|
||||
if !IsControllerBucket(RolloutSilentBucket) || !slices.Contains(ControllerBuckets(), RolloutSilentBucket) {
|
||||
t.Error("the rollout's silent keys' bucket is not asserted as the controller's own")
|
||||
}
|
||||
js, err := Dial(testbus.URL(t))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer js.Close()
|
||||
if err := js.EnsureControllerBuckets(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||
defer cancel()
|
||||
api, err := jetstream.New(js.Conn())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
kv, err := api.KeyValue(ctx, RolloutSilentBucket)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
w, err := kv.WatchAll(ctx, jetstream.UpdatesOnly())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer w.Stop()
|
||||
if _, err := kv.Create(ctx, "plan-1.0.ace", []byte("x"), jetstream.KeyTTL(time.Hour)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := kv.Delete(ctx, "plan-1.0.ace"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if _, err := kv.Create(ctx, "plan-1.0.g14", []byte("x"), jetstream.KeyTTL(time.Second)); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for {
|
||||
select {
|
||||
case e := <-w.Updates():
|
||||
if e == nil || e.Operation() == jetstream.KeyValuePut {
|
||||
continue
|
||||
}
|
||||
if e.Key() == "plan-1.0.ace" && e.Operation() != jetstream.KeyValueDelete {
|
||||
t.Fatalf("a report's delete was heard as %v", e.Operation())
|
||||
}
|
||||
if e.Key() == "plan-1.0.g14" {
|
||||
if e.Operation() != jetstream.KeyValuePurge {
|
||||
t.Fatalf("an expiry was heard as %v, not a purge", e.Operation())
|
||||
}
|
||||
return
|
||||
}
|
||||
case <-ctx.Done():
|
||||
t.Fatal("no watcher heard the key expire")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// **The merges have a consumer of their own, which a reset of the events consumer leaves alone** (issue 973, novox/hq
|
||||
// ADR 0407 decision 3): healer H4 re-makes the events consumer from now, dropping what it holds pending; a merge
|
||||
// waiting in the merges consumer is not that consumer's, and nothing would catch it up.
|
||||
|
||||
Reference in New Issue
Block a user