diff --git a/modules/mesh-issues/README.md b/modules/mesh-issues/README.md index 7a33bad7..15cfb68d 100644 --- a/modules/mesh-issues/README.md +++ b/modules/mesh-issues/README.md @@ -207,9 +207,8 @@ sessions writing a record at once never take one number. accepted, proposed, reserved or withdrawn; hq issue 488), the setting `decision-floor` or `research-floor`, and the reservations kept. The first number handed out is one above. hq's folders are not read: the records live in the knowledge base, and those folders empty when they leave hq (hq issue 426). When the knowledge base - does not answer (or holds none of the kind), the counter starts from the floor alone and the answer's - `warning` says it was not checked; with no floor either, the first reserve of a kind is refused and nothing - is spent. + does not answer (or holds none of the kind), the first reserve of a kind is refused and nothing is spent, + whatever the floor says: a floor raises the start, and never stands in for the knowledge base's answer. - **Never at or below a number held**: each reserve asks the knowledge base again, and a counter that stands below the highest number there is raised to it first, written only at the revision read. When the knowledge base does not answer once the counter has started, the counter is used as it stands, and the answer's @@ -284,8 +283,8 @@ the counter written without its revision check, it fails. what the knowledge base holds — is `TestFortyReservationsAtOnceFromTwoInstancesGetFortyDistinctConsecutiveNumbers` on the same bus, with the knowledge base played by the test, and the tests in `reserve_test.go`: the start above the knowledge base, the floor and the reservations kept, a counter behind the knowledge base raised, a refused -reserve spending nothing, the first reserve refused while neither the knowledge base nor a floor answers, the -floor alone starting it with a warning, a kind held none of being no answer, hq's folders never read, and a +reserve spending nothing, the first reserve refused while the knowledge base does not answer, even with a floor +set, a kind held none of being no answer, hq's folders never read, and a reservation that cannot be kept leaving its number spent. The import is tested over `testdata/hq`, copies of seven real reports of hq chosen for their shapes (a diff --git a/modules/mesh-issues/cmd/mesh-issues/reserve.go b/modules/mesh-issues/cmd/mesh-issues/reserve.go index a3eac621..f078698f 100644 --- a/modules/mesh-issues/cmd/mesh-issues/reserve.go +++ b/modules/mesh-issues/cmd/mesh-issues/reserve.go @@ -180,8 +180,8 @@ func busHighest() (map[string]uint64, error) { } // nextOf takes a sequence's next number. A counter not yet started is started once, above the highest the -// knowledge base holds, the operator's floor and every reservation kept. With the knowledge base silent it starts -// from the floor alone, saying so, and with neither it is not started and nothing is spent. A started counter +// knowledge base holds, the operator's floor and every reservation kept; with the knowledge base silent it is not +// started, floor or no floor, and nothing is spent. A started counter // behind the knowledge base (a number taken by hand, or imported) is raised to it first; a knowledge base that // does not answer then leaves the counter as it is, and the warning answered says so. func (t *Tracker) nextOf(seq sequence, highest uint64, heldErr error) (uint64, string, error) { @@ -192,15 +192,9 @@ func (t *Tracker) nextOf(seq sequence, highest uint64, heldErr error) (uint64, s } if e == nil { if heldErr != nil { - s, serr := t.Settings() - if serr != nil || seq.floor(s) == 0 { - return 0, "", fmt.Errorf("the %s counter has not started, and neither the knowledge base answers the highest %s "+ - "number it holds (%v) nor the operator set a %s floor: it starts above them, so no number was taken. Ask "+ - "again when the knowledge base answers", seq.kind, seq.kind, heldErr, seq.kind) - } - warning = fmt.Sprintf("the knowledge base did not answer the highest %s number it holds (%v): the %s counter "+ - "started above the operator's floor %d alone, unchecked against the records held. Check that the knowledge "+ - "base holds no %s at or above it", seq.kind, heldErr, seq.kind, seq.floor(s), seq.kind) + return 0, "", fmt.Errorf("the %s counter has not started, and the knowledge base does not answer the highest %s "+ + "number it holds (%v): the counter starts above it, and a floor alone cannot say a number is free, so no "+ + "number was taken. Ask again when the knowledge base answers", seq.kind, seq.kind, heldErr) } if err := t.startSequence(seq, highest); err != nil { return 0, "", err diff --git a/modules/mesh-issues/cmd/mesh-issues/reserve_test.go b/modules/mesh-issues/cmd/mesh-issues/reserve_test.go index 31b8103d..5a32e48a 100644 --- a/modules/mesh-issues/cmd/mesh-issues/reserve_test.go +++ b/modules/mesh-issues/cmd/mesh-issues/reserve_test.go @@ -232,9 +232,8 @@ func TestARefusedReservationSpendsNothing(t *testing.T) { func TestAKnowledgeBaseThatDoesNotAnswerRefusesTheFirstNumberAndNotTheNext(t *testing.T) { h, k := reserveHarness(t) k.err = errors.New("nothing answers mesh-knowledge.knowledge_highest") - if _, err := h.Reserve(ReserveAsk{Kind: KindDecision}); err == nil || !strings.Contains(err.Error(), "knowledge_highest") || - !strings.Contains(err.Error(), "floor") { - t.Fatalf("a first reservation with the knowledge base silent and no floor: %v", err) + if _, err := h.Reserve(ReserveAsk{Kind: KindDecision}); err == nil || !strings.Contains(err.Error(), "knowledge_highest") { + t.Fatalf("a first reservation with the knowledge base silent: %v", err) } if h.mem.counterOf(t, KindDecision) != 0 || len(h.said()) != 0 { t.Fatal("a refused first reservation started the counter or said something") @@ -259,18 +258,21 @@ func TestAKnowledgeBaseThatDoesNotAnswerRefusesTheFirstNumberAndNotTheNext(t *te } } -// With the knowledge base silent, the operator's floor alone starts a counter, above it and every reservation -// kept, and the answer says it was not checked against what is held. -func TestTheFloorAloneStartsACounterWhenTheKnowledgeBaseDoesNotAnswer(t *testing.T) { +// A counter not started never starts without the knowledge base's answer, floor or no floor: a floor alone +// cannot say a number above it is free. Nothing is spent. With the answer, the floor still raises the start. +func TestAFloorDoesNotStartACounterTheKnowledgeBaseDoesNotAnswerFor(t *testing.T) { h, k := reserveHarness(t) k.err = errors.New("the knowledge base holds no record yet") h.settings.ResearchFloor = 47 - out, err := h.Reserve(ReserveAsk{Kind: KindResearch}) - if err != nil || out.Number != 48 || !strings.Contains(out.Warning, "floor") || !strings.Contains(out.Warning, "unchecked") { - t.Fatalf("%+v %v", out, err) + if out, err := h.Reserve(ReserveAsk{Kind: KindResearch}); err == nil || !strings.Contains(err.Error(), "the knowledge base holds no record yet") { + t.Fatalf("a research number from the floor alone: %+v %v", out, err) } - if _, err := h.Reserve(ReserveAsk{Kind: KindDecision}); err == nil { - t.Fatal("a decision number with no floor and no answer was handed out") + if keys, _ := h.mem.Keys(ReservationsState); len(keys) != 0 || h.mem.counterOf(t, KindResearch) != 0 { + t.Fatal("a refused first reservation spent a number or started the counter") + } + k.err = nil + if got := h.reserve(t, KindResearch); got != 48 { + t.Fatalf("got %d, want 48: one above the floor 47, above the 045 held", got) } }