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) } }