The watchman raises what a node keeps of a module as it runs, for a manifest that does not yet say it, from the module's have, and clears it once the have says none (ADR 0601 §4; review round 1, finding 3)
This commit is contained in:
@@ -72,6 +72,29 @@ func TestTheWatchmansFindings(t *testing.T) {
|
||||
}
|
||||
w.ModuleVerdict("nats", value(""), Put)
|
||||
}, 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 {
|
||||
b, err := delivery.EncodeHave(delivery.Have{FP: "src2:" + strings.Repeat("a", 64), Phase: delivery.PhaseRunning, Health: delivery.HealthOK, Kept: kept})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
k := FindingKey(ScopeModule, "runner-x.ace", "kept")
|
||||
w.Have("ace.runner-x", have("runner-x runs the tool runner's process here"), Put)
|
||||
f := o.findings[k]
|
||||
if f.Kind != KindKeptAsRuns || f.Severity != Warning || !strings.Contains(f.Summary, "the tool runner's process") {
|
||||
t.Fatalf("findings = %v", o.findings)
|
||||
}
|
||||
c.t = c.t.Add(time.Minute)
|
||||
w.Have("ace.runner-x", have("runner-x runs the tool runner's process here"), Put)
|
||||
if !o.findings[k].Since.Equal(f.Since) {
|
||||
t.Errorf("a have written again moved the finding's since: %v, was %v", o.findings[k].Since, f.Since)
|
||||
}
|
||||
w.Have("ace.prov-y", have("prov-y carries its own secrets sealed"), Put)
|
||||
w.Have("ace.runner-x", have(), Put) // its manifest says tool-runner now
|
||||
w.Have("ace.prov-y", nil, Delete)
|
||||
}, map[string]string{}},
|
||||
{"WM4: a stuck key not moved is its finding, and its move deletes it", func(t *testing.T, w *Watchman, o *fakeOut, c *clock) {
|
||||
w.Step("go", "n1.ask1", runningStep("ask1", t0), Put)
|
||||
expire(w, c, pulseKeyOf(t, checksKey, "ask1"), 120*time.Second)
|
||||
|
||||
@@ -199,6 +199,7 @@ const (
|
||||
KindUnhealthy = "module-unhealthy"
|
||||
KindNeedsOperator = "needs-operator"
|
||||
KindDeadLetters = "max-deliveries"
|
||||
KindKeptAsRuns = "kept-as-it-runs"
|
||||
)
|
||||
|
||||
func stamp(t time.Time) string { return t.UTC().Format("2006-01-02 15:04 MST") }
|
||||
@@ -476,11 +477,13 @@ func (w *Watchman) haveFindings(key string, node, module string, h *delivery.Hav
|
||||
w.unsignal("unhealthy-confirm", module+"."+node)
|
||||
w.unsignal("unhealthy", module+"."+node)
|
||||
w.unfind(unhealthyKey)
|
||||
w.keptFinding(key, node, module, nil)
|
||||
w.applyCheck(node)
|
||||
return
|
||||
}
|
||||
w.haveState[key] = *h
|
||||
now := w.now()
|
||||
w.keptFinding(key, node, module, h.Kept)
|
||||
|
||||
// S21: a have refused or applied in part says phase failed, with the node's words in its detail.
|
||||
if h.Phase == delivery.PhaseFailed {
|
||||
@@ -531,6 +534,33 @@ func (w *Watchman) haveFindings(key string, node, module string, h *delivery.Hav
|
||||
}
|
||||
}
|
||||
|
||||
// keptFinding raises, as a warning, what a node keeps of a module as it runs because its manifest does not yet say what shared
|
||||
// code no longer infers (its have's Kept, novox/hq ADR 0601 §4: the tool runner, the core's credentials), naming each; and
|
||||
// clears it once the have says none, or is gone. Its since is the first have that said it, so a have written again moves
|
||||
// nothing.
|
||||
func (w *Watchman) keptFinding(key, node, module string, kept []string) {
|
||||
id := module + "." + node
|
||||
fkey := FindingKey(ScopeModule, id, "kept")
|
||||
if len(kept) == 0 {
|
||||
delete(w.keptSince, key)
|
||||
w.unfind(fkey)
|
||||
return
|
||||
}
|
||||
if w.keptSince == nil {
|
||||
w.keptSince = map[string]time.Time{}
|
||||
}
|
||||
since, ok := w.keptSince[key]
|
||||
if !ok {
|
||||
since = w.now()
|
||||
w.keptSince[key] = since
|
||||
}
|
||||
words := strings.Join(kept, "; ")
|
||||
w.find(Finding{Scope: ScopeModule, ID: id, Token: "kept", Kind: KindKeptAsRuns, Machine: node, Severity: Warning,
|
||||
Source: "node-engine", Since: since, Summary: fmt.Sprintf("%s on %s is kept as it runs: %s", module, node, words),
|
||||
Said: firstLine(words), Headline: fmt.Sprintf("%s kept as it runs on %s", module, node),
|
||||
Needs: "a build of " + module + " whose manifest says it (tool-runner, core-credentials)"})
|
||||
}
|
||||
|
||||
// ControlNodeModule is the module whose have names a control node: the bus module, so the control node is the bus node,
|
||||
// the one stably reachable node every part depends on (novox/hq ADR 0590, issue 1126: the controller that named it ended).
|
||||
// The same name the bus module's events are heard under (SlowConsumerSubject).
|
||||
|
||||
@@ -60,9 +60,11 @@ type Watchman struct {
|
||||
presence map[string]presence
|
||||
pulses map[string]*pulse // live pulses, by pulse key
|
||||
stuck map[string]delivery.Stuck
|
||||
wants map[string]string // the fingerprint of each want that stands, by want key
|
||||
haves map[string]string // the fingerprint each node runs of a module, by have key
|
||||
bound time.Duration
|
||||
// keptSince is, by have key, when its have first said what the node keeps of the module as it runs (keptFinding).
|
||||
keptSince map[string]time.Time
|
||||
wants map[string]string // the fingerprint of each want that stands, by want key
|
||||
haves map[string]string // the fingerprint each node runs of a module, by have key
|
||||
bound time.Duration
|
||||
// findings is every finding written, by key, as written; seededFindings those read at the start and not yet observed
|
||||
// again.
|
||||
findings map[string][]byte
|
||||
|
||||
Reference in New Issue
Block a user