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
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user