mesh-self-check: the setting probes lists the probes that run, D13 and D-fill by default; one unlisted runs nothing and the verb says it is off by setting (the operator, 2026-10-30)
This commit is contained in:
@@ -40,6 +40,7 @@ func (runtimeStore) Keys(state string) ([]string, error) { return stdio.State(st
|
||||
// NewChecker is the self-check over the runtime.
|
||||
func NewChecker() *Checker {
|
||||
return &Checker{Store: runtimeStore{}, Registry: Registry(), Now: time.Now, Logf: logf, Host: os.Getenv("MESH_NODE"),
|
||||
Enabled: enabledProbes,
|
||||
Ask: func(key string, body any) (json.RawMessage, error) { return stdio.Ask(key, body) },
|
||||
Publish: stdio.SeatPublish}
|
||||
}
|
||||
@@ -55,3 +56,19 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// enabledProbes is the setting `probes`, read at each run so a change applies at the next; with it unreadable, the
|
||||
// default list.
|
||||
func enabledProbes() []string {
|
||||
raw, err := stdio.Config("probes")
|
||||
if err != nil {
|
||||
logf("the setting probes cannot be read (%v); the default list runs", err)
|
||||
return DefaultProbes
|
||||
}
|
||||
var list []string
|
||||
if json.Unmarshal(raw, &list) != nil {
|
||||
logf("the setting probes is not a list of probe ids (%s); the default list runs", raw)
|
||||
return DefaultProbes
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -63,6 +64,17 @@ type Store interface {
|
||||
Keys(state string) ([]string, error)
|
||||
}
|
||||
|
||||
// On says whether the setting lists the probe.
|
||||
func (c *Checker) On(id string) bool {
|
||||
if c.Enabled == nil {
|
||||
return true
|
||||
}
|
||||
return slices.Contains(c.Enabled(), id)
|
||||
}
|
||||
|
||||
// DefaultProbes are the probes that run unless the setting says otherwise.
|
||||
var DefaultProbes = []string{"D13", "D-fill"}
|
||||
|
||||
// Probe is one live invariant: its id, what it asserts, the kind it raises, and the run; or why it waits.
|
||||
type Probe struct {
|
||||
ID string
|
||||
@@ -87,7 +99,10 @@ type (
|
||||
// Checker is the self-check: the registry and what its probes reach.
|
||||
type Checker struct {
|
||||
Store Store
|
||||
Ask func(key string, body any) (json.RawMessage, error)
|
||||
// Enabled is the setting `probes`: the ids of the probes that run. Nil runs every probe in the registry; one not
|
||||
// listed runs nothing and raises nothing (the operator, 2026-10-30).
|
||||
Enabled func() []string
|
||||
Ask func(key string, body any) (json.RawMessage, error)
|
||||
// Publish says a seat event on its subject, de-duplicated by id (stdio.SeatPublish).
|
||||
Publish func(subject string, body any, id string) error
|
||||
Now func() time.Time
|
||||
@@ -137,7 +152,7 @@ func (c *Checker) RunOnce(ctx context.Context, why string) Run {
|
||||
results := make([]result, len(c.Registry))
|
||||
var wg sync.WaitGroup
|
||||
for i, p := range c.Registry {
|
||||
if p.Run == nil {
|
||||
if p.Run == nil || !c.On(p.ID) {
|
||||
continue
|
||||
}
|
||||
wg.Add(1)
|
||||
@@ -154,6 +169,12 @@ func (c *Checker) RunOnce(ctx context.Context, why string) Run {
|
||||
ran := map[string]bool{} // the sources whose findings this run judged whole
|
||||
var blind []Observation
|
||||
for i, p := range c.Registry {
|
||||
if !c.On(p.ID) {
|
||||
// Off by the setting: it ran nothing and sees nothing, so what it raised before is cleared, and it has no
|
||||
// verdict in the run.
|
||||
ran[p.ID] = true
|
||||
continue
|
||||
}
|
||||
v := ProbeVerdict{ID: p.ID}
|
||||
r := results[i]
|
||||
switch {
|
||||
|
||||
@@ -253,3 +253,43 @@ func TestTheVerbsAndReads(t *testing.T) {
|
||||
t.Errorf("probes answered %v", p)
|
||||
}
|
||||
}
|
||||
|
||||
// Only the probes the setting `probes` lists run: one not listed runs nothing, has no verdict, clears what it raised before,
|
||||
// and is reported by the verb as off by setting; the default list is D13 and D-fill (the operator, 2026-10-30).
|
||||
func TestOnlyTheProbesTheSettingListsRun(t *testing.T) {
|
||||
ran := map[string]int{}
|
||||
finds := Observation{Token: "stream-missing", Severity: Urgent, Subject: Subject{Scope: ScopeBus, ID: "EVENTS"}, Summary: "gone"}
|
||||
probe := func(id string) Probe {
|
||||
return Probe{ID: id, Kind: "stream-wrong", Run: func(context.Context, *Checker) ([]Observation, error) {
|
||||
ran[id]++
|
||||
return []Observation{finds}, nil
|
||||
}}
|
||||
}
|
||||
store := newStore()
|
||||
c, _ := checker(store, probe("D7"), probe("D13"))
|
||||
c.Enabled = func() []string { return []string{"D7", "D13"} }
|
||||
run := c.RunOnce(context.Background(), "test")
|
||||
if ran["D7"] != 1 || ran["D13"] != 1 || len(run.Probes) != 2 || len(store.findingKeys()) != 1 {
|
||||
t.Fatalf("both listed: ran %v, %d verdicts, findings %v", ran, len(run.Probes), store.findingKeys())
|
||||
}
|
||||
c.Enabled = func() []string { return []string{"D13"} }
|
||||
run = c.RunOnce(context.Background(), "test")
|
||||
if ran["D7"] != 1 || ran["D13"] != 2 || len(run.Probes) != 1 || run.Probes[0].ID != "D13" {
|
||||
t.Fatalf("D7 unlisted: ran %v, verdicts %+v", ran, run.Probes)
|
||||
}
|
||||
// What the unlisted probe raised stays only as long as another listed probe sees the same key (D13 raises the same
|
||||
// key here); an unlisted probe alone clears its findings.
|
||||
c.Enabled = func() []string { return nil }
|
||||
c.RunOnce(context.Background(), "test")
|
||||
if len(store.findingKeys()) != 0 {
|
||||
t.Fatalf("with nothing listed, findings are %v", store.findingKeys())
|
||||
}
|
||||
rows, _ := c.Probes()["probes"].([]map[string]any)
|
||||
if len(rows) != 2 || rows[0]["off"] != "off by setting" || rows[1]["off"] != "off by setting" {
|
||||
t.Fatalf("the verb says %v", rows)
|
||||
}
|
||||
c.Enabled = nil
|
||||
if !c.On("anything") || !slices.Equal(DefaultProbes, []string{"D13", "D-fill"}) {
|
||||
t.Fatal("no setting runs every probe, and the default list is D13 and D-fill")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +115,9 @@ func (c *Checker) Probes() map[string]any {
|
||||
if len(p.Raises) > 0 {
|
||||
row["raises"] = p.Raises
|
||||
}
|
||||
if p.Run == nil {
|
||||
if !c.On(p.ID) {
|
||||
row["off"] = "off by setting"
|
||||
} else if p.Run == nil {
|
||||
row["deferred"] = p.Deferred
|
||||
}
|
||||
out = append(out, row)
|
||||
|
||||
@@ -71,5 +71,16 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"config": {
|
||||
"probes": {
|
||||
"type": "list",
|
||||
"description": "The ids of the probes that run, each judging one thing of the mesh (mesh-self-check.probes lists them with what each asserts). A probe not listed runs nothing and raises nothing, and what it raised before is cleared. D8 and DA are in the code and off by default.",
|
||||
"trusted": true,
|
||||
"default": [
|
||||
"D13",
|
||||
"D-fill"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user