messenger: send an ask's message alone even when only one answer can be given there
mesh/merge-gate fail: builds messenger, sudo → ace, g14, novox, shanks; no bus step; a manifest the change touches fails the module check: modules/messenge…
mesh/repo-check fail: its merge-check.sh failed: files asking for a setting without saying whether it is trusted: 20
mesh/delivery-group group feat/asks-answered-on-any-channel rejected: a member's own check failed
mesh/delivery superseded: a newer head of the same pull request
mesh/merge-gate fail: builds messenger, sudo → ace, g14, novox, shanks; no bus step; a manifest the change touches fails the module check: modules/messenge…
mesh/repo-check fail: its merge-check.sh failed: files asking for a setting without saying whether it is trusted: 20
mesh/delivery-group group feat/asks-answered-on-any-channel rejected: a member's own check failed
mesh/delivery superseded: a newer head of the same pull request
The lab's proof showed an ask whose approval was held back (an agent could become root where the channel runs) folded into a burst's digest with a condition, and its one remaining answer, Decline, lost with it. A message carrying an ask's answer now always goes alone.
This commit is contained in:
@@ -839,3 +839,38 @@ func codeOf(t *testing.T, m Message) string {
|
||||
t.Fatalf("no code in %q", m.Body)
|
||||
return ""
|
||||
}
|
||||
|
||||
// An ask's message goes alone even when only one of its answers can be given on a channel: folded into a burst's
|
||||
// digest, its one button was lost (found by the lab's proof, mesh-lab asks/, with approval held by an open
|
||||
// agent-root condition and that condition's message in the same burst).
|
||||
func TestAnAsksMessageWithOneAnswerIsNotFoldedIntoADigest(t *testing.T) {
|
||||
h, tg, _, c, store, _ := newRouter(t)
|
||||
link(h, store, c, "42", c.now().Add(-2*time.Hour))
|
||||
settle(h, c)
|
||||
// Something was just said on the channel, so what follows waits for the burst.
|
||||
submit(t, h, "mesh-delivery", heldAsk(c, "d-0"))
|
||||
settle(h, c)
|
||||
h.mu.Lock()
|
||||
h.open["machine.anchor.agent-root"] = &Record{Key: "machine.anchor.agent-root", Kind: KindAgentRoot, Severity: Urgent,
|
||||
Origin: "condition", Raised: c.now()}
|
||||
h.mu.Unlock()
|
||||
k := cond("machine.anchor.disk", Urgent, "the disk on anchor is full")
|
||||
k.Raised = c.now()
|
||||
h.Condition(EventRaised, k)
|
||||
before := len(tg.sends)
|
||||
submit(t, h, "mesh-delivery", heldAsk(c, "d-1"))
|
||||
settle(h, c)
|
||||
var asked *Message
|
||||
for i := range tg.sends[before:] {
|
||||
m := tg.sends[before+i]
|
||||
if ticketFor(m, "Silence for a week") != "" {
|
||||
asked = &m
|
||||
}
|
||||
}
|
||||
if asked == nil {
|
||||
t.Fatalf("the ask's one answer was not offered on Telegram: %+v", tg.sends[before:])
|
||||
}
|
||||
if ticketFor(*asked, "Release") != "" {
|
||||
t.Errorf("an approval was offered while an agent can become root there: %q", labelsOf(*asked))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,10 +287,12 @@ func (h *Holder) flushChannel(ch Channel, now time.Time, force bool) {
|
||||
return
|
||||
}
|
||||
if len(entries) > 1 {
|
||||
// A message that asks the operator something goes alone, so its answers come with it.
|
||||
// A message that asks the operator something goes alone, so its answers come with it: one with several
|
||||
// answers, and one carrying an ask's answer even when only one can be given here (the lab's proof found
|
||||
// an ask whose approval was not offered folded into a digest, and its one answer lost with it).
|
||||
var alone, rest []entry
|
||||
for _, e := range entries {
|
||||
if len(e.msg.Actions) > 1 {
|
||||
if len(e.msg.Actions) > 1 || (len(e.msg.Actions) > 0 && e.r != nil && e.r.Ask != "") {
|
||||
alone = append(alone, e)
|
||||
} else {
|
||||
rest = append(rest, e)
|
||||
|
||||
Reference in New Issue
Block a user