CAT-N5: orphans: an empty accepted manifest asks nothing, so what was made is orphaned and kept until a drop
An entry made for a module whose newest accepted manifest no longer asks for it is said orphaned and raised, never removed; asked again it is kept, its binding said again with created and the condition cleared. A module missing from a first view keeps its key (a set-aside manifest is not in it); an entry never made leaves nothing, so the empty verdict ends that module's key. Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
@@ -349,6 +349,8 @@ func (k *Keeper) makeEntry(held *Asked, e catalogue.BusStateEntry) {
|
||||
wasOrphan := m.Orphaned
|
||||
m.Plan, m.Orphaned = plan, false
|
||||
if wasOrphan {
|
||||
// Asked again: kept, and its binding said again with created (design 25 § 12.3).
|
||||
m.Created = false
|
||||
k.clear(conditionOrphaned, module, e.Name)
|
||||
}
|
||||
k.ensure(held, &m)
|
||||
|
||||
@@ -367,6 +367,40 @@ func TestTheKeeperMakesWhatAVerdictAsksForAndSaysIt(t *testing.T) {
|
||||
t.Errorf("created %v, said %v: its binding said, nothing made twice", bus.created, out.events)
|
||||
}
|
||||
}},
|
||||
// CAT-N5: orphans (design 25 § 12.2-12.3): an empty manifest-accepted asks nothing now, so what was made is an
|
||||
// orphan, said and raised, kept until a drop; asked again it is kept and its binding said again; a module missing
|
||||
// from the first view (set aside to wait) keeps its key; one never made leaves nothing behind.
|
||||
{"an empty verdict orphans what was made, and asking again keeps it", func(t *testing.T, k *Keeper, bus *fakeBus, out *said) {
|
||||
k.Heard(Accepted{Module: "m", Revision: 1, BusState: []catalogue.BusStateEntry{drafts}})
|
||||
out.reset()
|
||||
k.Heard(Accepted{Module: "m", Revision: 2})
|
||||
a, held := k.Held()["m"]
|
||||
if !held || !a.Made["drafts"].Orphaned || len(bus.deleted) != 0 || fmt.Sprint(out.events) != "[orphaned m drafts]" ||
|
||||
fmt.Sprint(out.conds) != "[raised nats.orphaned.m_drafts]" {
|
||||
t.Fatalf("held %v %+v, deleted %v, said %v %v: orphaned, kept, raised", held, a, bus.deleted, out.events, out.conds)
|
||||
}
|
||||
k.Heard(Accepted{Module: "m", Revision: 3})
|
||||
k.Heard(Accepted{Module: "m", Revision: 4, BusState: []catalogue.BusStateEntry{drafts}})
|
||||
if fmt.Sprint(out.events) != "[orphaned m drafts created m drafts]" || out.conds[len(out.conds)-1] != "cleared nats.orphaned.m_drafts" {
|
||||
t.Errorf("said %v %v: orphaned once, then created again and cleared", out.events, out.conds)
|
||||
}
|
||||
}},
|
||||
{"a module missing from the first view keeps its key; one never made leaves none", func(t *testing.T, k *Keeper, bus *fakeBus, out *said) {
|
||||
k.Heard(Accepted{Module: "m", Revision: 1, BusState: []catalogue.BusStateEntry{drafts}})
|
||||
k.View = func() (FirstView, error) { return FirstView{Revision: 5}, nil }
|
||||
if _, err := k.AskFirstView(0); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if a := k.Held()["m"]; len(a.Entries) != 1 || a.Made["drafts"].Orphaned {
|
||||
t.Errorf("held %+v: kept as asked, never orphaned by a first view", a)
|
||||
}
|
||||
bus.refuse["KV_n_x"] = errors.New("no")
|
||||
k.Heard(Accepted{Module: "n", Revision: 1, BusState: []catalogue.BusStateEntry{entry("x", catalogue.StorageKeyValue, catalogue.TemplateState, nil)}})
|
||||
k.Heard(Accepted{Module: "n", Revision: 2})
|
||||
if _, held := k.Held()["n"]; held {
|
||||
t.Errorf("n's key is still held: nothing of it was made, so its empty verdict ends it")
|
||||
}
|
||||
}},
|
||||
} {
|
||||
t.Run(row.name, func(t *testing.T) {
|
||||
k, bus, _, out := newKeeper(FirstView{Revision: 1})
|
||||
|
||||
Reference in New Issue
Block a user