Every look rewrote the condition's value in the conditions bucket, because the value carried the count of looks, the last look and the newest evidence: 131 647 writes in four days for twelve open conditions, against ADR 0289's rule that a bucket is written only when what it describes changed. The looks now live in the controller's store (migration 0095, condition_looks), the bucket holds what a condition says and is written only when that changes, and the conditions verb and the condition events put the looks back.
54 lines
2.0 KiB
Go
54 lines
2.0 KiB
Go
package inventory
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// **A condition's looks are kept in the store, replaced on every look and forgotten when it clears**
|
|
// (novox/hq issue 420): written under the lease, read back whole.
|
|
func TestAConditionsLooksAreKeptBesideTheBucket(t *testing.T) {
|
|
inv := ForTest(t)
|
|
ctx := t.Context()
|
|
inv.ActsUnder(func(context.Context) (uint64, error) { return 0, errors.New("the lease is not held") })
|
|
if err := inv.KeepConditionLooks(ctx, ConditionLooks{Key: "machine.ace.silent", Observations: 1,
|
|
LastObserved: time.Now()}); err == nil {
|
|
t.Fatal("looks were kept by a process that may not act")
|
|
}
|
|
inv.ActsUnder(func(context.Context) (uint64, error) { return 57, nil })
|
|
at := time.Now().UTC().Truncate(time.Microsecond)
|
|
for n := 1; n <= 3; n++ {
|
|
evidence, _ := json.Marshal([]map[string]any{{"at": at, "said": "ace has not been heard from"}})
|
|
if err := inv.KeepConditionLooks(ctx, ConditionLooks{Key: "machine.ace.silent", Observations: n,
|
|
LastObserved: at, Evidence: evidence}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
if err := inv.KeepConditionLooks(ctx, ConditionLooks{Key: "machine.ace.late", Observations: 2,
|
|
LastObserved: at}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got, kept, err := inv.ConditionLooksOf(ctx, "machine.ace.silent")
|
|
if err != nil || !kept || got.Observations != 3 || !got.LastObserved.Equal(at) {
|
|
t.Fatalf("read %+v kept %v: %v", got, kept, err)
|
|
}
|
|
var evidence []map[string]any
|
|
if err := json.Unmarshal(got.Evidence, &evidence); err != nil || len(evidence) != 1 {
|
|
t.Fatalf("evidence %s: %v", got.Evidence, err)
|
|
}
|
|
all, err := inv.AllConditionLooks(ctx)
|
|
if err != nil || len(all) != 2 || all["machine.ace.late"].Observations != 2 ||
|
|
string(all["machine.ace.late"].Evidence) != "[]" {
|
|
t.Fatalf("all %+v: %v", all, err)
|
|
}
|
|
if err := inv.ForgetConditionLooks(ctx, "machine.ace.silent"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, kept, err := inv.ConditionLooksOf(ctx, "machine.ace.silent"); kept || err != nil {
|
|
t.Fatalf("a cleared condition's looks kept %v: %v", kept, err)
|
|
}
|
|
}
|