Keep a module's condition open when the controller's conditions are read (issue 1217, review round 1 finding 1)
This commit is contained in:
@@ -59,19 +59,22 @@ const (
|
||||
|
||||
// Condition is what this holder needs of one.
|
||||
type Condition struct {
|
||||
Key string
|
||||
Kind string
|
||||
Scope string
|
||||
ID string
|
||||
Machine string
|
||||
Severity string
|
||||
Summary string
|
||||
Headline string
|
||||
Explanation string
|
||||
Resolved string
|
||||
Needs string
|
||||
Actions []Action
|
||||
Source string
|
||||
Key string
|
||||
Kind string
|
||||
Scope string
|
||||
ID string
|
||||
Machine string
|
||||
Severity string
|
||||
Summary string
|
||||
Headline string
|
||||
Explanation string
|
||||
Resolved string
|
||||
Needs string
|
||||
Actions []Action
|
||||
Source string
|
||||
// Publisher is the module that said the condition on the operator channel's one subject; empty for the
|
||||
// controller's own, which a reading of the controller's conditions may end.
|
||||
Publisher string
|
||||
Resolver string
|
||||
Raised time.Time
|
||||
LastObserved time.Time
|
||||
@@ -360,7 +363,7 @@ func (h *Holder) takeCondition(publisher string, body []byte) {
|
||||
}
|
||||
c := Condition{Key: sc.Key, Scope: sc.Subject.Scope, ID: sc.Subject.ID, Machine: sc.Subject.Machine,
|
||||
Severity: sc.Severity, Summary: sc.Summary, Headline: sc.Headline, Explanation: sc.Explanation,
|
||||
Resolved: sc.Resolved, Needs: sc.Needs, Source: publisher}
|
||||
Resolved: sc.Resolved, Needs: sc.Needs, Source: publisher, Publisher: publisher}
|
||||
if i := strings.LastIndex(sc.Key, "."); i >= 0 {
|
||||
c.Kind = sc.Key[i+1:]
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/asks"
|
||||
)
|
||||
@@ -132,3 +133,24 @@ func TestABodyThatIsNotAConditionIsDroppedAndTheLogNamesThePublisher(t *testing.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAModulesConditionStaysOpenWhenTheControllersConditionsAreRead(t *testing.T) { // 1217/AC7
|
||||
h, tg, dt, c, _ := newHolder(t)
|
||||
body := conditionBody(t, sdkCondition("look at it."))
|
||||
if err := h.TakeAsk("condition", "mesh-delivery-teller", body); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
settle(h, c)
|
||||
c.pass(time.Second)
|
||||
res := h.Sync(nil, c.now()) // the controller lists nothing: the teller's condition is not its to end
|
||||
if len(res.Gone) != 0 || len(h.Open()) != 1 {
|
||||
t.Fatalf("the reading ended a module's condition: gone %v, open %+v", res.Gone, h.Open())
|
||||
}
|
||||
if err := h.TakeAsk("condition", "mesh-delivery-teller", body); err != nil { // raised again: the same message
|
||||
t.Fatal(err)
|
||||
}
|
||||
settle(h, c)
|
||||
if len(dt.sends)+len(tg.sends) != 1 {
|
||||
t.Fatalf("said %d times, want once", len(dt.sends)+len(tg.sends))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,8 +184,10 @@ type Record struct {
|
||||
Answered string `json:"answered,omitempty"`
|
||||
// Ask is the open ask about this record, `<asker>.<id>`: its options are this record's answers
|
||||
// (novox/hq ADR 0259).
|
||||
Ask string `json:"ask,omitempty"`
|
||||
Origin string `json:"origin"`
|
||||
Ask string `json:"ask,omitempty"`
|
||||
Origin string `json:"origin"`
|
||||
// Publisher is the module that said it on the operator channel's one subject; empty for the controller's.
|
||||
Publisher string `json:"publisher,omitempty"`
|
||||
More string `json:"more"`
|
||||
Raised time.Time `json:"raised"`
|
||||
SilencedTill time.Time `json:"silenced_till,omitempty"`
|
||||
@@ -228,8 +230,8 @@ func recordOf(c Condition) Record {
|
||||
return Record{Key: c.Key, Kind: c.Kind, Subject: c.SubjectWords(), Scope: c.Scope, SubjectID: c.ID, Machine: c.Machine,
|
||||
Severity: c.Severity, Summary: c.Summary,
|
||||
Headline: c.Headline, Explanation: c.Explanation, Resolved: c.Resolved, Needs: c.Needs, Actions: c.Actions,
|
||||
Origin: "condition",
|
||||
More: "conditions show " + c.Key, Raised: c.Raised, SilencedTill: c.SilencedTill, SilencedWhy: c.SilencedWhy}
|
||||
Origin: "condition", Publisher: c.Publisher,
|
||||
More: "conditions show " + c.Key, Raised: c.Raised, SilencedTill: c.SilencedTill, SilencedWhy: c.SilencedWhy}
|
||||
}
|
||||
|
||||
// takeWords keeps the plain words current, as the summary is: a condition's words follow what is seen.
|
||||
|
||||
@@ -33,13 +33,14 @@ func (h *Holder) Sync(open []Condition, asked time.Time) SyncResult {
|
||||
for _, c := range open {
|
||||
in[c.Key] = true
|
||||
}
|
||||
// A module's condition (Publisher set) is not the controller's to end: only what it said is ended here.
|
||||
// What is open here and no longer there ended while this holder was not told: forgotten without
|
||||
// a message — said only where an edit notifies nobody. What this holder heard of after the
|
||||
// reading was asked for is newer than it, and stands.
|
||||
h.mu.Lock()
|
||||
var gone []*Record
|
||||
for _, r := range h.open {
|
||||
if r.Origin == "condition" && r.Cleared.IsZero() && !in[r.Key] && !r.Seen.After(asked) {
|
||||
if r.Origin == "condition" && r.Publisher == "" && r.Cleared.IsZero() && !in[r.Key] && !r.Seen.After(asked) {
|
||||
gone = append(gone, r)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user