A merge the gate handed is known by the bridge's word before the forge's, and finish wrote it already; an older forge-only merge heard in between overwrote it, since only the forge's word was dated and the write never compared with the head held. A merge is now dated by either word, and the write leaves a head that is a later merge, or one the gate cannot date while the merge is older than the records it keeps (a pruned newer merge).
135 lines
6.2 KiB
Go
135 lines
6.2 KiB
Go
package main
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
sdk "git.novox.be/novox/mesh-sdk/go/delivery"
|
|
)
|
|
|
|
// Issue 888: the checker judges on the trunk source.main names (mesh-delivery modules/mesh-delivery-checker main.go), and the
|
|
// gate moved it only for a merge it handed to the forge bridge (finish). A merge made at the forge directly moved every other
|
|
// delivery's trunk (trunkMoved) and left source.main, so the checker kept judging on the trunk before it.
|
|
|
|
const (
|
|
i888Other = "novox/other"
|
|
i888OtherH = "0000000000000000000000000000000000000001"
|
|
i888App = "novox/app"
|
|
i888Head1 = "1111111111111111111111111111111111111111"
|
|
i888Head2 = "2222222222222222222222222222222222222222"
|
|
i888Merge1 = "3333333333333333333333333333333333333333"
|
|
i888Merge2 = "4444444444444444444444444444444444444444"
|
|
)
|
|
|
|
func i888MergedAt(repo string, number int, head, merge string, at time.Time) PullEvent {
|
|
p := merged(repo, number, head, merge)
|
|
p.MergedAt = at.UTC().Format(time.RFC3339)
|
|
return p
|
|
}
|
|
|
|
// 888/AC1: a merge into main the gate did not hand is heard from the forge: source.main holds it, and keeps the others.
|
|
func TestAMergeHeardOnlyFromTheForgeMovesSourceMain(t *testing.T) {
|
|
w := newWorld(t)
|
|
w.source.main = &sdk.Source{V: sdk.Version, Group: "earlier", Heads: map[string]string{i888Other: i888OtherH}}
|
|
w.h.PullUpdated(pr(i888App, 3, i888Head1, "fix/x", "internal/a.go"))
|
|
w.settleAll()
|
|
w.h.PullMerged(i888MergedAt(i888App, 3, i888Head1, i888Merge1, w.now.Add(-time.Minute)))
|
|
w.settleAll()
|
|
if w.source.main == nil || w.source.main.Heads[i888App] != i888Merge1 || w.source.main.Heads[i888Other] != i888OtherH {
|
|
t.Fatalf("source.main is %+v; wanted %s at %s and %s kept", w.source.main, i888App, i888Merge1, i888Other)
|
|
}
|
|
n := len(w.source.moves)
|
|
w.settleAll()
|
|
w.h.PullMerged(i888MergedAt(i888App, 3, i888Head1, i888Merge1, w.now.Add(-time.Minute))) // heard again
|
|
w.settleAll()
|
|
if len(w.source.moves) != n || n != 1 {
|
|
t.Fatalf("source.main moved %d then %d times; wanted once", n, len(w.source.moves))
|
|
}
|
|
}
|
|
|
|
// 888/AC2: a group the gate merged through the bridge moves source.main once, in finish, though the forge's word of each
|
|
// member's merge is heard too.
|
|
func TestAGroupTheGateMergedMovesSourceMainOnceThoughTheForgeSaysItsMerges(t *testing.T) {
|
|
w := approvedGroup(t)
|
|
allGreen(w)
|
|
w.op.answer(w.op.open()[0], OptionApprove)
|
|
w.settleAll()
|
|
w.settleAll()
|
|
if len(w.forge.merges) != 2 || len(w.source.moves) != 1 {
|
|
t.Fatalf("merges %v, source.main moved %d times", w.forge.merges, len(w.source.moves))
|
|
}
|
|
commit := w.source.moves[0].Heads[gCat]
|
|
w.h.PullMerged(i888MergedAt(gCtl, 1, gHc, w.source.moves[0].Heads[gCtl], w.now))
|
|
w.h.PullMerged(i888MergedAt(gCat, 2, gHk, commit, w.now))
|
|
w.settleAll()
|
|
if len(w.source.moves) != 1 {
|
|
t.Fatalf("source.main moved %d times; wanted once, by the group: %+v", len(w.source.moves), w.source.moves)
|
|
}
|
|
}
|
|
|
|
// 888/AC3: an older merge heard after a newer one, or replayed as history, never moves source.main backwards.
|
|
func TestAnOlderMergeHeardLaterNeverMovesSourceMainBack(t *testing.T) {
|
|
w := newWorld(t)
|
|
w.h.PullMerged(i888MergedAt(i888App, 4, i888Head2, i888Merge2, w.now.Add(-time.Minute)))
|
|
w.settleAll()
|
|
w.h.PullMerged(i888MergedAt(i888App, 3, i888Head1, i888Merge1, w.now.Add(-2*time.Minute)))
|
|
w.settleAll()
|
|
if w.source.main == nil || w.source.main.Heads[i888App] != i888Merge2 || len(w.source.moves) != 1 {
|
|
t.Fatalf("source.main is %+v after %d moves; wanted the newer merge %s, moved once", w.source.main, len(w.source.moves), i888Merge2)
|
|
}
|
|
|
|
h := newWorld(t)
|
|
h.source.main = &sdk.Source{V: sdk.Version, Group: "now", Heads: map[string]string{i888App: i888Merge2}}
|
|
h.h.PullMerged(i888MergedAt(i888App, 3, i888Head1, i888Merge1, h.now.Add(-4*24*time.Hour)))
|
|
h.settleAll()
|
|
if h.source.main.Heads[i888App] != i888Merge2 || len(h.source.moves) != 0 {
|
|
t.Fatalf("a merge replayed as history moved source.main to %+v", h.source.main)
|
|
}
|
|
}
|
|
|
|
// 888/AC4: an approved group whose members were merged at the forge before the gate handed them moves source.main once.
|
|
func TestAnApprovedGroupMergedAtTheForgeMovesSourceMainOnce(t *testing.T) {
|
|
w := approvedGroup(t)
|
|
allGreen(w)
|
|
w.op.answer(w.op.open()[0], OptionApprove)
|
|
mc, mk := "5555555555555555555555555555555555555555", "6666666666666666666666666666666666666666"
|
|
w.h.PullMerged(i888MergedAt(gCtl, 1, gHc, mc, w.now))
|
|
w.h.PullMerged(i888MergedAt(gCat, 2, gHk, mk, w.now))
|
|
w.settleAll()
|
|
w.settleAll()
|
|
if len(w.source.moves) != 1 || w.source.main.Heads[gCtl] != mc || w.source.main.Heads[gCat] != mk {
|
|
t.Fatalf("source.main moved %d times to %+v; wanted once, both members at their merge commits", len(w.source.moves), w.source.main)
|
|
}
|
|
}
|
|
|
|
// 888/AC5 (review round 1): an older merge heard from the forge after the bridge merged a newer one, whose own pull.merged is
|
|
// not heard yet, never moves source.main back; nor does one older than the gate keeps records for, over a head it does not know.
|
|
func TestAnOlderForgeMergeNeverOverwritesANewerBridgeMergeOrAnUnknownHead(t *testing.T) {
|
|
w := approvedGroup(t)
|
|
allGreen(w)
|
|
w.op.answer(w.op.open()[0], OptionApprove)
|
|
w.settleAll()
|
|
w.settleAll()
|
|
if len(w.source.moves) != 1 {
|
|
t.Fatalf("the group did not move source.main once: %d", len(w.source.moves))
|
|
}
|
|
bridged := w.source.main.Heads[gCat]
|
|
w.h.PullUpdated(pr(gCat, 7, "7777777777777777777777777777777777777777", "fix/old", "modules/app/module.json"))
|
|
w.h.PullMerged(i888MergedAt(gCat, 7, "7777777777777777777777777777777777777777", "8888888888888888888888888888888888888888", w.now.Add(-10*time.Minute)))
|
|
w.settleAll()
|
|
if w.source.main.Heads[gCat] != bridged || len(w.source.moves) != 1 {
|
|
t.Fatalf("an older forge merge moved source.main from the bridge's %s to %s", bridged, w.source.main.Heads[gCat])
|
|
}
|
|
|
|
o := newWorld(t)
|
|
o.source.main = &sdk.Source{V: sdk.Version, Group: "pruned", Heads: map[string]string{i888App: i888Merge2}}
|
|
at := o.now
|
|
o.h.PullUpdated(pr(i888App, 3, i888Head1, "fix/x", "internal/a.go"))
|
|
o.later(keptFinal + 24*time.Hour)
|
|
o.h.PullMerged(i888MergedAt(i888App, 3, i888Head1, i888Merge1, at.Add(time.Minute)))
|
|
o.settleAll()
|
|
if o.source.main.Heads[i888App] != i888Merge2 || len(o.source.moves) != 0 {
|
|
t.Fatalf("a merge older than the records kept overwrote a head the gate does not know: %+v", o.source.main)
|
|
}
|
|
}
|