mesh/merge-gate pass: builds mesh-delivery → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery delivered
keep wrote the whole delivery on every call, and Reconcile passes every walk the controller keeps through settleAndKeep every 30 seconds, so the deliveries bucket was rewritten about once per walk per pass with nothing changed: a key's revision no longer meant the delivery moved, and a watcher of the bucket would receive a stream of non-changes. keep now remembers each delivery as it last wrote it, encoded, and skips the write when the delivery encodes exactly the same and is not waiting to be written again. Anything a delivery holds that changes - its state, steps, walk record, owed effects and their tries - changes its encoding, so every change is still written; a failed write stays dirty and Flush writes it again. Events, notes, views and forge statuses are owed and done as before. A retry of an owed effect still writes its new try count: it is a change. The test fails before (five passes over unmoved walks wrote five times) and passes after; a walk that moves is still written and said.
90 lines
2.6 KiB
Go
90 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// novox/hq issue 326: a delivery whose state did not change is not written again — a reconcile pass over
|
|
// walks that did not move writes nothing — and one that changed is written, and said.
|
|
func TestADeliveryIsWrittenOnlyWhenItChanged(t *testing.T) {
|
|
w := newWorld(t)
|
|
id := IDOf("novox/app", head)
|
|
w.h.PullUpdated(pr("novox/app", 7, head, "feat/x", "src/a.go"))
|
|
w.h.Checked(verdict("novox/app", 7, head, "pass"))
|
|
w.ctl.put(aWalk("plan-1", "novox/app", merge, true))
|
|
w.h.PullMerged(merged("novox/app", 7, head, merge))
|
|
w.settleAll()
|
|
if err := w.h.Reconcile(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
w.settleAll()
|
|
// The word given moves the walk's record once more: read back, it is a change, and written.
|
|
if err := w.h.Reconcile(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
w.settleAll()
|
|
if w.state(id) != Delivering {
|
|
t.Fatalf("let go, it is %s", w.state(id))
|
|
}
|
|
|
|
// Passes over the same walks, as main.go's tickers run them: nothing changed, nothing written.
|
|
before, said := w.store.puts, len(w.said)
|
|
for range 5 {
|
|
w.later(30 * time.Second)
|
|
if err := w.h.Reconcile(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
w.settleAll()
|
|
}
|
|
if w.store.puts != before {
|
|
t.Fatalf("five passes over walks that did not move wrote %d delivery(ies)", w.store.puts-before)
|
|
}
|
|
if len(w.said) != said {
|
|
t.Fatalf("five passes over walks that did not move said %d event(s)", len(w.said)-said)
|
|
}
|
|
|
|
// The walk moves: the delivery changes, is written, and is said.
|
|
walk := w.ctl.walk("plan-1")
|
|
walk.State = walkDone
|
|
w.ctl.put(walk)
|
|
if err := w.h.Reconcile(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
w.settleAll()
|
|
if w.state(id) != Delivered {
|
|
t.Fatalf("a walk done left it %s", w.state(id))
|
|
}
|
|
if w.store.puts == before {
|
|
t.Fatal("a delivery that changed was not written")
|
|
}
|
|
back, err := w.store.Deliveries()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, d := range back {
|
|
if d.ID == id && d.State != Delivered {
|
|
t.Fatalf("the store holds it %s, the holder %s", d.State, Delivered)
|
|
}
|
|
}
|
|
if len(w.said) == said {
|
|
t.Fatal("a delivery that changed was not said")
|
|
}
|
|
}
|
|
|
|
// A delivery that could not be written is written again, even though it did not change since.
|
|
func TestADeliveryNotWrittenIsWrittenAgainUnchanged(t *testing.T) {
|
|
w := newWorld(t)
|
|
id := IDOf("novox/app", head)
|
|
w.store.failing = true
|
|
w.h.PullUpdated(pr("novox/app", 7, head, "feat/x", "src/a.go"))
|
|
if _, there := w.store.deliveries[id]; there {
|
|
t.Fatal("a failing store kept it")
|
|
}
|
|
w.store.failing = false
|
|
w.h.Flush()
|
|
if _, there := w.store.deliveries[id]; !there {
|
|
t.Fatal("a delivery that could not be written was not written again")
|
|
}
|
|
}
|