Serve a ledger owner its repairs rebuild, reindex, snapshot and lag as tools, its own ledgers only, marked acts or reads (issue 1966 T4)

This commit is contained in:
2026-11-03 13:46:54 +01:00
parent 63c1e3faa2
commit 8fe7ef3b82
6 changed files with 656 additions and 3 deletions
+55 -2
View File
@@ -8,8 +8,8 @@ import (
"git.novox.be/novox/mesh-sdk/go/buscalls"
)
// 1966/AC15 and the other reads of a ledger: get, query (ADR 0597 §10; design 25 § 12.5).
func TestReadsOfALedger(t *testing.T) {
// 1966/AC15, the other reads of a ledger (get, query) and its repairs (ADR 0597 §8, §10; design 25 § 12.5).
func TestReadsAndRepairsOfALedger(t *testing.T) {
cases := []struct {
name string
run func(t *testing.T, l *Ledger, f fakes)
@@ -57,6 +57,59 @@ func TestReadsOfALedger(t *testing.T) {
t.Fatalf("an undeclared index: %v", err)
}
}},
{"a lost state rebuilds from the history, an expired one from its snapshot, and lag says what is behind", func(t *testing.T, l *Ledger, f fakes) {
applied(t, l, "decision/1", "title", `{"title":"One"}`, owner)
applied(t, l, "decision/1", "note", `{"says":"kept"}`, owner)
want, _, _ := f.state.Get("decision.1")
f.state.kv = nil
lag, _ := l.Lag(buscalls.LedgerRequest{})
if len(lag.Instances) != 1 || lag.Instances[0].History != 2 || lag.Instances[0].State != 0 || lag.Instances[0].Snapshot != 2 {
t.Fatalf("lag says %+v", lag)
}
if got, err := l.Rebuild(buscalls.RebuildRequest{}); err != nil || got.Written != 1 {
t.Fatalf("rebuilt %+v, %v", got, err)
}
if got, _, _ := f.state.Get("decision.1"); string(record(t, got).State) != string(record(t, want).State) {
t.Fatalf("rebuilt from the history %s, want %s", got, want)
}
f.state.kv = nil
f.history.Expire()
if got, err := l.Rebuild(buscalls.RebuildRequest{Instance: "decision/1", From: buscalls.RebuildFromSnapshot}); err != nil || got.Written != 1 {
t.Fatalf("rebuilt %+v, %v", got, err)
}
if got, _, _ := f.state.Get("decision.1"); string(got) != string(want) {
t.Fatalf("rebuilt from the snapshot %s, want %s", got, want)
}
}},
{"reindex builds a declared index from the states, and lag says an index behind until it does", func(t *testing.T, l *Ledger, f fakes) {
applied(t, l, "decision/1", "title", `{"title":"One ledger"}`, owner)
applied(t, l, "decision/2", "note", `{"says":"untitled"}`, owner)
_ = f.index.Put("stale.decision.9", []byte(`{}`))
if lag, _ := l.Lag(buscalls.LedgerRequest{}); len(lag.Indexes) != 1 || lag.Indexes[0].Behind != 1 {
t.Fatalf("lag says %+v", lag)
}
if got, err := l.Reindex(buscalls.ReindexRequest{Index: "by-title"}); err != nil || got.Written != 1 {
t.Fatalf("reindexed %+v, %v", got, err)
}
entries, _ := f.index.Entries("", 0)
if len(entries) != 1 || entries[0].Key != "One_ledger.decision.1" || string(entries[0].Value) != `{"instance":"decision/1","sequence":1}` {
t.Fatalf("the index holds %+v", entries)
}
if lag, _ := l.Lag(buscalls.LedgerRequest{}); len(lag.Indexes) != 0 || len(lag.Instances) != 0 {
t.Fatalf("lag after reindex says %+v", lag)
}
}},
{"snapshot rewrites a snapshot behind its state", func(t *testing.T, l *Ledger, f fakes) {
applied(t, l, "decision/1", "title", `{"title":"One"}`, owner)
f.snapshots.kv = nil
if got, err := l.Snapshot(buscalls.InstanceRequest{}); err != nil || got.Written != 1 {
t.Fatalf("snapshot %+v, %v", got, err)
}
state, _, _ := f.state.Get("decision.1")
if snap, _, _ := f.snapshots.Get("decision.1"); string(snap) != string(state) {
t.Fatalf("the snapshot %s, the state %s", snap, state)
}
}},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {