From 121c6d9c48207c27f5cdb3ba8e7c88f23ad6909a Mon Sep 17 00:00:00 2001 From: jochen Date: Wed, 4 Nov 2026 18:10:16 +0100 Subject: [PATCH] G-delivery 2: sdk/heard's cases are rows of the watchman's findings table mesh-delivery is over its unit budget, so the new function goes; its three cases run as rows of an existing table of a user of the package. Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig --- .../internal/watch/findings_test.go | 40 ++++++++++++++ sdk/heard/heard_test.go | 54 ------------------- 2 files changed, 40 insertions(+), 54 deletions(-) delete mode 100644 sdk/heard/heard_test.go diff --git a/modules/mesh-delivery-watchman/internal/watch/findings_test.go b/modules/mesh-delivery-watchman/internal/watch/findings_test.go index a3d1c906..6875c4d6 100644 --- a/modules/mesh-delivery-watchman/internal/watch/findings_test.go +++ b/modules/mesh-delivery-watchman/internal/watch/findings_test.go @@ -9,6 +9,7 @@ import ( "git.novox.be/novox/mesh-sdk/go/catalogue" "git.novox.be/novox/mesh-sdk/go/delivery" + "git.novox.be/novox/mesh-sdk/go/health" "git.novox.be/novox/mesh-delivery/sdk/heard" "git.novox.be/novox/mesh-sdk/go/provisions" @@ -152,6 +153,45 @@ func TestTheWatchmansFindings(t *testing.T) { w.NotHeard("membership", "a consumer not there yet is not opened", errors.New("no bucket")) w.Heard("EVENTS") w.Heard("membership") + // sdk/heard's Writer, as the indexer, the assigner and the builder use it: Bind writes the finding with why + // when the consumer does not bind and answers the error, deletes it when it binds, and with no findings + // state says it in the log alone. + at := time.Date(2026, 11, 4, 17, 0, 0, 0, time.UTC) + for _, row := range []struct { + name string + bindErr error + noState bool + want string + }{ + {name: "not there yet", bindErr: errors.New("consumer not found"), + want: "mesh-delivery-indexer does not hear assigner-views: the placement is the first view's alone (consumer not found)"}, + {name: "bound"}, + {name: "no findings state", bindErr: errors.New("consumer not found"), noState: true}, + } { + key := heard.Key("mesh-delivery-indexer", "assigner-views") + kept := map[string][]byte{key: []byte("{}")} + var logs []string + hw := heard.Writer{Observer: "mesh-delivery-indexer", Now: func() time.Time { return at }, Logf: func(f string, a ...any) { logs = append(logs, f) }} + if !row.noState { + hw.Put = func(k string, v []byte) error { kept[k] = v; return nil } + hw.Delete = func(k string) error { delete(kept, k); return nil } + } + if err := hw.Bind("assigner-views", "the placement is the first view's alone", func() error { return row.bindErr }); !errors.Is(err, row.bindErr) { + t.Errorf("%s: Bind answered %v, want %v", row.name, err, row.bindErr) + } + raw, stands := kept[key] + switch { + case row.noState && len(logs) == 0: + t.Errorf("%s: nothing said", row.name) + case !row.noState && row.want == "" && stands: + t.Errorf("%s: the finding stands once bound", row.name) + case row.want != "": + f, err := health.DecodeFinding(raw) + if err != nil || f.Kind != heard.Kind || f.Summary != row.want || f.Observer != "mesh-delivery-indexer" { + t.Errorf("%s: the finding %+v (%v), want summary %q", row.name, f, err, row.want) + } + } + } }, map[string]string{}}, {"ADR 0601 §4: what a node keeps of a module as it runs, for a manifest that does not say it yet, is a warning until the have says none", func(t *testing.T, w *Watchman, o *fakeOut, c *clock) { have := func(kept ...string) []byte { diff --git a/sdk/heard/heard_test.go b/sdk/heard/heard_test.go deleted file mode 100644 index 0c5ed6d9..00000000 --- a/sdk/heard/heard_test.go +++ /dev/null @@ -1,54 +0,0 @@ -package heard - -import ( - "errors" - "strings" - "testing" - "time" - - "git.novox.be/novox/mesh-sdk/go/health" -) - -// Review round 1 of the registry milestone (ADR 0615 §5): a consumer that does not bind is a finding naming the observer -// and the family, with why; binding deletes it; no findings state still says it in the log. -func TestAConsumerNotHeardIsAFindingUntilItBinds(t *testing.T) { - at := time.Date(2026, 11, 4, 17, 0, 0, 0, time.UTC) - for _, row := range []struct { - name string - bindErr error - noState bool - want string // the finding's summary, or "" when none stands - }{ - {name: "not there yet", bindErr: errors.New("consumer not found"), - want: "mesh-delivery-indexer does not hear assigner-views: the placement is the first view's alone (consumer not found)"}, - {name: "bound"}, - {name: "no findings state", bindErr: errors.New("consumer not found"), noState: true}, - } { - kept := map[string][]byte{Key("mesh-delivery-indexer", "assigner-views"): []byte("{}")} - var logs []string - w := Writer{Observer: "mesh-delivery-indexer", Now: func() time.Time { return at }, - Logf: func(f string, a ...any) { logs = append(logs, f) }} - if !row.noState { - w.Put = func(k string, v []byte) error { kept[k] = v; return nil } - w.Delete = func(k string) error { delete(kept, k); return nil } - } - err := w.Bind("assigner-views", "the placement is the first view's alone", func() error { return row.bindErr }) - if !errors.Is(err, row.bindErr) { - t.Errorf("%s: Bind answered %v, want %v", row.name, err, row.bindErr) - } - raw, stands := kept[Key("mesh-delivery-indexer", "assigner-views")] - switch { - case row.noState: - if len(logs) == 0 { - t.Errorf("%s: nothing said", row.name) - } - case row.want == "" && stands: - t.Errorf("%s: the finding stands once bound", row.name) - case row.want != "": - f, err := health.DecodeFinding(raw) - if err != nil || f.Kind != Kind || f.Summary != row.want || f.Observer != "mesh-delivery-indexer" || !strings.Contains(f.Subject.ID, "assigner-views") { - t.Errorf("%s: the finding %+v (%v), want summary %q", row.name, f, err, row.want) - } - } - } -}