Commit f07502fc authored by Kirill Smelkov's avatar Kirill Smelkov

X xbtreetest: Teach T & Commit to automatically provide At in symbolic form

parent 6e619d3d
...@@ -22,6 +22,8 @@ package xbtreetest ...@@ -22,6 +22,8 @@ package xbtreetest
import ( import (
"context" "context"
"fmt"
"sort"
"testing" "testing"
"lab.nexedi.com/kirr/go123/exc" "lab.nexedi.com/kirr/go123/exc"
...@@ -44,15 +46,17 @@ type T struct { ...@@ -44,15 +46,17 @@ type T struct {
zstor zodb.IStorage zstor zodb.IStorage
DB *zodb.DB DB *zodb.DB
// all committed trees commitv []*Commit // all committed trees
commitv []*Commit at0idx int // index of current "at₀" in commitv
} }
// Commit represent test commit changing a tree. // Commit represent test commit changing a tree.
type Commit struct { type Commit struct {
T *T // created via T.CommitTree
idx int // lives in .T.commitv[idx]
Tree string // the tree in topology-encoding Tree string // the tree in topology-encoding
Prev *Commit // previous commit Prev *Commit // previous commit
At zodb.Tid // commit revision At zodb.Tid // committed revision
ΔZ *zodb.EventCommit // raw ZODB changes; δZ.tid == at ΔZ *zodb.EventCommit // raw ZODB changes; δZ.tid == at
Xkv RBucketSet // full tree state as of @at Xkv RBucketSet // full tree state as of @at
Δxkv map[Key]Δstring // full tree-diff against parent Δxkv map[Key]Δstring // full tree-diff against parent
...@@ -70,7 +74,7 @@ func NewT(t *testing.T) *T { ...@@ -70,7 +74,7 @@ func NewT(t *testing.T) *T {
X := exc.Raiseif X := exc.Raiseif
t.Helper() t.Helper()
tt := &T{T: t} tt := &T{T: t, at0idx: 1 /* at₀ starts from first CommitTree */}
var err error var err error
work := t.TempDir() work := t.TempDir()
...@@ -98,6 +102,8 @@ func NewT(t *testing.T) *T { ...@@ -98,6 +102,8 @@ func NewT(t *testing.T) *T {
head := tt.treeSrv.head head := tt.treeSrv.head
t1 := &Commit{ t1 := &Commit{
T: tt,
idx: 0,
Tree: "T/B:", // treegen.py creates the tree as initially empty Tree: "T/B:", // treegen.py creates the tree as initially empty
Prev: nil, Prev: nil,
At: head, At: head,
...@@ -130,6 +136,45 @@ func (t *T) Head() *Commit { ...@@ -130,6 +136,45 @@ func (t *T) Head() *Commit {
return t.commitv[len(t.commitv)-1] return t.commitv[len(t.commitv)-1]
} }
// XGetCommit finds and returns Commit created with revision at.
func (t *T) XGetCommit(at zodb.Tid) *Commit {
l := len(t.commitv)
i := sort.Search(l, func(i int) bool {
return at <= t.commitv[i].At
})
var commit *Commit
if i < l {
commit = t.commitv[i]
if commit.At != at {
commit = nil
}
}
if commit == nil {
panicf("no commit corresponding to @%s", at)
}
if commit.idx != i {
panicf("BUG: commit.idx (%d) != i (%d)", commit.idx, i)
}
return commit
}
// AtSymb returns symbolic representation of at, for example "at3".
//
// at must correspond to a Commit.
func (t *T) AtSymb(at zodb.Tid) string {
return t.XGetCommit(at).AtSymb()
}
// AtSymb returns symbolic representation of c.At, for example "at3".
func (c *Commit) AtSymb() string {
return fmt.Sprintf("at%d", c.idx - c.T.at0idx)
}
// AtSymbReset shifts symbolic numbers and adjust AtSymb setup so that c.AtSymb() returns "at<i>".
func (t *T) AtSymbReset(c *Commit, i int) {
t.at0idx = c.idx - i
}
// CommitTree calls t.treeSrv.Commit and returns Commit corresponding to committed transaction. // CommitTree calls t.treeSrv.Commit and returns Commit corresponding to committed transaction.
// XXX naming -> Commit ? // XXX naming -> Commit ?
func (t *T) CommitTree(tree string) *Commit { func (t *T) CommitTree(tree string) *Commit {
...@@ -183,6 +228,7 @@ func (t *T) CommitTree(tree string) *Commit { ...@@ -183,6 +228,7 @@ func (t *T) CommitTree(tree string) *Commit {
} }
ttree := &Commit{ ttree := &Commit{
T: t,
Tree: tree, Tree: tree,
At: δZ.Tid, At: δZ.Tid,
ΔZ: δZ, ΔZ: δZ,
...@@ -194,6 +240,7 @@ func (t *T) CommitTree(tree string) *Commit { ...@@ -194,6 +240,7 @@ func (t *T) CommitTree(tree string) *Commit {
ttree.Prev = tprev ttree.Prev = tprev
ttree.Δxkv = KVDiff(tprev.Xkv.Flatten(), ttree.Xkv.Flatten()) ttree.Δxkv = KVDiff(tprev.Xkv.Flatten(), ttree.Xkv.Flatten())
ttree.idx = len(t.commitv)
t.commitv = append(t.commitv, ttree) t.commitv = append(t.commitv, ttree)
return ttree return ttree
...@@ -252,23 +299,23 @@ func xGetBlkTab(db *zodb.DB, at zodb.Tid) map[zodb.Oid]ZBlkInfo { ...@@ -252,23 +299,23 @@ func xGetBlkTab(db *zodb.DB, at zodb.Tid) map[zodb.Oid]ZBlkInfo {
return blkTab return blkTab
} }
// XGetBlkData loads blk data for ZBlk<oid> @t.at // XGetBlkData loads blk data for ZBlk<oid> @c.at
// //
// For speed the load is done via preloaded t.blkDataTab instead of access to the DB. // For speed the load is done via preloaded c.blkDataTab instead of access to the DB.
func (t *Commit) XGetBlkData(oid zodb.Oid) string { func (c *Commit) XGetBlkData(oid zodb.Oid) string {
if oid == VDEL { if oid == VDEL {
return DEL return DEL
} }
zblki, ok := t.ZBlkTab[oid] zblki, ok := c.ZBlkTab[oid]
if !ok { if !ok {
exc.Raisef("getBlkData ZBlk<%s> @%s: no such ZBlk", oid, t.At) exc.Raisef("getBlkData ZBlk<%s> @%s: no such ZBlk", oid, c.At)
} }
return zblki.Data return zblki.Data
} }
// XGetBlkByName returns ZBlk info associated with ZBlk<name> // XGetBlkByName returns ZBlk info associated with ZBlk<name>
func (t *Commit) XGetBlkByName(name string) (zodb.Oid, ZBlkInfo) { func (c *Commit) XGetBlkByName(name string) (zodb.Oid, ZBlkInfo) {
for oid, zblki := range t.ZBlkTab { for oid, zblki := range c.ZBlkTab {
if zblki.Name == name { if zblki.Name == name {
return oid, zblki return oid, zblki
} }
......
...@@ -560,6 +560,7 @@ func testΔBTail(t_ *testing.T, testq chan ΔBTestEntry) { ...@@ -560,6 +560,7 @@ func testΔBTail(t_ *testing.T, testq chan ΔBTestEntry) {
for test := range testq { for test := range testq {
t1 := t.Head() t1 := t.Head()
t2 := t.CommitTree(test.tree) t2 := t.CommitTree(test.tree)
t.AtSymbReset(t2, 2)
subj := fmt.Sprintf("%s -> %s", t1.Tree, t2.Tree) subj := fmt.Sprintf("%s -> %s", t1.Tree, t2.Tree)
//t.Logf("\n\n\n**** %s ****\n\n", subj) //t.Logf("\n\n\n**** %s ****\n\n", subj)
...@@ -817,16 +818,9 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1 ...@@ -817,16 +818,9 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
tAllKeys := allTestKeys(t0, t1, t2) tAllKeys := allTestKeys(t0, t1, t2)
tAllKeyv := tAllKeys.SortedElements() tAllKeyv := tAllKeys.SortedElements()
// tid -> "at_i" //fmt.Printf("@%s: %v\n", t0.AtSymb(), t0.Xkv.Flatten())
xat := map[zodb.Tid]string{ //fmt.Printf("@%s: %v\n", t1.AtSymb(), t1.Xkv.Flatten())
t0.At: "at0", //fmt.Printf("@%s: %v\n", t2.AtSymb(), t2.Xkv.Flatten())
t1.At: "at1",
t2.At: "at2",
}
//fmt.Printf("@%s: %v\n", xat[t0.At], t0.Xkv.Flatten())
//fmt.Printf("@%s: %v\n", xat[t1.At], t1.Xkv.Flatten())
//fmt.Printf("@%s: %v\n", xat[t2.At], t2.Xkv.Flatten())
kadj10 := KAdj(t1,t0, allTestKeys(t0,t1,t2)) kadj10 := KAdj(t1,t0, allTestKeys(t0,t1,t2))
kadj21 := KAdj(t2,t1, allTestKeys(t0,t1,t2)) kadj21 := KAdj(t2,t1, allTestKeys(t0,t1,t2))
...@@ -863,13 +857,13 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1 ...@@ -863,13 +857,13 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
// assert trackSet=ø, trackNew=ø, vδB=[] // assert trackSet=ø, trackNew=ø, vδB=[]
δbtail.assertTrack(t, "@at0", ø, ø) δbtail.assertTrack(t, "@at0", ø, ø)
assertΔTtail(t, "@at0", δbtail, t0, treeRoot, xat, assertΔTtail(t, "@at0", δbtail, t0, treeRoot,
/*vδT=ø*/) /*vδT=ø*/)
xverifyΔBTail_rebuild_U(t, δbtail, treeRoot, t0, t1, xat, xverifyΔBTail_rebuild_U(t, δbtail, treeRoot, t0, t1,
/*trackSet=*/ø, /*trackSet=*/ø,
/*vδT=ø*/) /*vδT=ø*/)
xverifyΔBTail_rebuild_TR(t, δbtail, t1, treeRoot, xat, xverifyΔBTail_rebuild_TR(t, δbtail, t1, treeRoot,
// after Track(keys1) // after Track(keys1)
keys1, keys1,
/*trackSet=*/ ø, /*trackSet=*/ ø,
...@@ -907,7 +901,7 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1 ...@@ -907,7 +901,7 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
Tkeys1R2 := trackSet(t2.Xkv, keys1R2) Tkeys1R2 := trackSet(t2.Xkv, keys1R2)
xverifyΔBTail_rebuild_U(t, δbtail, treeRoot, t1, t2, xat, xverifyΔBTail_rebuild_U(t, δbtail, treeRoot, t1, t2,
/*trackSet=*/ Tkeys1R2, /*trackSet=*/ Tkeys1R2,
/*vδT=*/ δkv1_k1R2, δkv2_k1R2) /*vδT=*/ δkv1_k1R2, δkv2_k1R2)
...@@ -976,7 +970,7 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1 ...@@ -976,7 +970,7 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
// t.Run is expensive at this level of nest // t.Run is expensive at this level of nest
//t.Run(" T"+keys2.String()+";R", func(t *testing.T) { //t.Run(" T"+keys2.String()+";R", func(t *testing.T) {
δbtail_ := δbtail.Clone() δbtail_ := δbtail.Clone()
xverifyΔBTail_rebuild_TR(t, δbtail_, t2, treeRoot, xat, xverifyΔBTail_rebuild_TR(t, δbtail_, t2, treeRoot,
// after Track(keys2) // after Track(keys2)
keys2, keys2,
/*trackSet*/ Tkeys1R2, /*trackSet*/ Tkeys1R2,
...@@ -997,17 +991,17 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1 ...@@ -997,17 +991,17 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
} }
// xverifyΔBTail_rebuild_U verifies ΔBtail state after Update(ti->tj). // xverifyΔBTail_rebuild_U verifies ΔBtail state after Update(ti->tj).
func xverifyΔBTail_rebuild_U(t *testing.T, δbtail *ΔBtail, treeRoot zodb.Oid, ti, tj *xbtreetest.Commit, xat map[zodb.Tid]string, trackSet blib.PPTreeSubSet, vδTok ...map[Key]Δstring) { func xverifyΔBTail_rebuild_U(t *testing.T, δbtail *ΔBtail, treeRoot zodb.Oid, ti, tj *xbtreetest.Commit, trackSet blib.PPTreeSubSet, vδTok ...map[Key]Δstring) {
t.Helper() t.Helper()
X := exc.Raiseif X := exc.Raiseif
ø := blib.PPTreeSubSet{} ø := blib.PPTreeSubSet{}
subj := fmt.Sprintf("after Update(@%s→@%s)", xat[ti.At], xat[tj.At]) subj := fmt.Sprintf("after Update(@%s→@%s)", ti.AtSymb(), tj.AtSymb())
// Update ati -> atj // Update ati -> atj
δB, err := δbtail.Update(tj.ΔZ); X(err) δB, err := δbtail.Update(tj.ΔZ); X(err)
δbtail.assertTrack(t, subj, trackSet, ø) δbtail.assertTrack(t, subj, trackSet, ø)
assertΔTtail(t, subj, δbtail, tj, treeRoot, xat, vδTok...) assertΔTtail(t, subj, δbtail, tj, treeRoot, vδTok...)
// assert δB = vδTok[-1] // assert δB = vδTok[-1]
var δT, δTok map[Key]Δstring var δT, δTok map[Key]Δstring
...@@ -1042,14 +1036,14 @@ func xverifyΔBTail_rebuild_U(t *testing.T, δbtail *ΔBtail, treeRoot zodb.Oid, ...@@ -1042,14 +1036,14 @@ func xverifyΔBTail_rebuild_U(t *testing.T, δbtail *ΔBtail, treeRoot zodb.Oid,
} }
// xverifyΔBTail_rebuild_TR verifies ΔBtail state after Track(keys) + rebuild. // xverifyΔBTail_rebuild_TR verifies ΔBtail state after Track(keys) + rebuild.
func xverifyΔBTail_rebuild_TR(t *testing.T, δbtail *ΔBtail, tj *xbtreetest.Commit, treeRoot zodb.Oid, xat map[zodb.Tid]string, keys setKey, trackSet blib.PPTreeSubSet, trackNew, trackSetAfterRebuild blib.PPTreeSubSet, vδTok ...map[Key]Δstring) { func xverifyΔBTail_rebuild_TR(t *testing.T, δbtail *ΔBtail, tj *xbtreetest.Commit, treeRoot zodb.Oid, keys setKey, trackSet blib.PPTreeSubSet, trackNew, trackSetAfterRebuild blib.PPTreeSubSet, vδTok ...map[Key]Δstring) {
t.Helper() t.Helper()
ø := blib.PPTreeSubSet{} ø := blib.PPTreeSubSet{}
// Track(keys) // Track(keys)
trackKeys(δbtail, tj, keys) trackKeys(δbtail, tj, keys)
subj := fmt.Sprintf("@%s: after Track%v", xat[tj.At], keys) subj := fmt.Sprintf("@%s: after Track%v", tj.AtSymb(), keys)
δbtail.assertTrack(t, subj, trackSet, trackNew) δbtail.assertTrack(t, subj, trackSet, trackNew)
δbtail.rebuildAll() δbtail.rebuildAll()
...@@ -1060,7 +1054,7 @@ func xverifyΔBTail_rebuild_TR(t *testing.T, δbtail *ΔBtail, tj *xbtreetest.Co ...@@ -1060,7 +1054,7 @@ func xverifyΔBTail_rebuild_TR(t *testing.T, δbtail *ΔBtail, tj *xbtreetest.Co
// XXX verify Get -> XXX assertΔTtail ? // XXX verify Get -> XXX assertΔTtail ?
// verify δbtail.vδTbyRoot[treeRoot] // verify δbtail.vδTbyRoot[treeRoot]
assertΔTtail(t, subj, δbtail, tj, treeRoot, xat, vδTok...) assertΔTtail(t, subj, δbtail, tj, treeRoot, vδTok...)
} }
// xverifyΔBTail_GetAt verifies δBtail.Get on series of vt ZODB changes. // xverifyΔBTail_GetAt verifies δBtail.Get on series of vt ZODB changes.
...@@ -1074,12 +1068,9 @@ func ___xverifyΔBTail_GetAt(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, vt .. ...@@ -1074,12 +1068,9 @@ func ___xverifyΔBTail_GetAt(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, vt ..
} }
t.Run(fmt.Sprintf("Get/%s", subj), func(t *testing.T) { t.Run(fmt.Sprintf("Get/%s", subj), func(t *testing.T) {
// tid -> "at_i" // XXX ResetAtSymb(~vt[0])
xat := map[zodb.Tid]string{}
for i := range vt { for i := range vt {
xat[vt[i].At] = fmt.Sprintf("at%d", i) fmt.Printf("@%s: %v\n", vt[i].AtSymb(), vt[i].Xkv.Flatten())
fmt.Printf("@%s: %v\n", xat[vt[i].At], vt[i].Xkv.Flatten())
} }
tkeys := allTestKeys(vt...) tkeys := allTestKeys(vt...)
...@@ -1094,13 +1085,13 @@ func ___xverifyΔBTail_GetAt(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, vt .. ...@@ -1094,13 +1085,13 @@ func ___xverifyΔBTail_GetAt(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, vt ..
} }
t.Run(fmt.Sprintf("track=%s", keys), func(t *testing.T) { t.Run(fmt.Sprintf("track=%s", keys), func(t *testing.T) {
xverifyΔBTail_GetAt1(t, db, treeRoot, vt, xat, keys) xverifyΔBTail_GetAt1(t, db, treeRoot, vt, keys)
}) })
} }
}) })
} }
func xverifyΔBTail_GetAt1(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, vt []*xbtreetest.Commit, xat map[zodb.Tid]string, keys setKey) { func xverifyΔBTail_GetAt1(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, vt []*xbtreetest.Commit, keys setKey) {
X := exc.Raiseif X := exc.Raiseif
// t1->t2-> ... -> tn // t1->t2-> ... -> tn
...@@ -1145,9 +1136,9 @@ func xverifyΔBTail_GetAt1(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, vt []*x ...@@ -1145,9 +1136,9 @@ func xverifyΔBTail_GetAt1(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, vt []*x
if !(v == v_ && ok == ok_ && rev == rev_ && revExact == revExact_) { if !(v == v_ && ok == ok_ && rev == rev_ && revExact == revExact_) {
t.Errorf("Get(%d, @%s) ->\nhave: %s, %v, @%s, %v\nwant: %s, %v, @%s, %v", t.Errorf("Get(%d, @%s) ->\nhave: %s, %v, @%s, %v\nwant: %s, %v, @%s, %v",
k, xat[at], k, T.AtSymb(at),
v, ok, xat[rev], revExact, v, ok, T.AtSymb(rev), revExact,
v_, ok_, xat[rev_], revExact_) v_, ok_, T.AtSymb(rev_), revExact_)
} }
} }
} }
...@@ -1177,19 +1168,13 @@ func TestΔBtailForget(t_ *testing.T) { ...@@ -1177,19 +1168,13 @@ func TestΔBtailForget(t_ *testing.T) {
_, err = δbtail.Update(t3.ΔZ); X(err) _, err = δbtail.Update(t3.ΔZ); X(err)
xat := map[zodb.Tid]string{ assertΔTtail(t.T, "init", δbtail, t3, t.Root(), t1.Δxkv, t2.Δxkv, t3.Δxkv)
t0.At: "at0",
t1.At: "at1",
t2.At: "at2",
t3.At: "at3",
}
assertΔTtail(t.T, "init", δbtail, t3, t.Root(), xat, t1.Δxkv, t2.Δxkv, t3.Δxkv)
δbtail.ForgetPast(t0.At) δbtail.ForgetPast(t0.At)
assertΔTtail(t.T, "forget ≤ at0", δbtail, t3, t.Root(), xat, t1.Δxkv, t2.Δxkv, t3.Δxkv) assertΔTtail(t.T, "forget ≤ at0", δbtail, t3, t.Root(), t1.Δxkv, t2.Δxkv, t3.Δxkv)
δbtail.ForgetPast(t1.At) δbtail.ForgetPast(t1.At)
assertΔTtail(t.T, "forget ≤ at1", δbtail, t3, t.Root(), xat, t2.Δxkv, t3.Δxkv) assertΔTtail(t.T, "forget ≤ at1", δbtail, t3, t.Root(), t2.Δxkv, t3.Δxkv)
δbtail.ForgetPast(t3.At) δbtail.ForgetPast(t3.At)
assertΔTtail(t.T, "forget ≤ at3", δbtail, t3, t.Root(), xat, ) assertΔTtail(t.T, "forget ≤ at3", δbtail, t3, t.Root(), )
// XXX verify no aliasing // XXX verify no aliasing
} }
...@@ -1216,17 +1201,6 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) { ...@@ -1216,17 +1201,6 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) {
const a, b, c = "a", "b", "c" const a, b, c = "a", "b", "c"
const f, g, h = "f", "g", "h" const f, g, h = "f", "g", "h"
xat := map[zodb.Tid]string{
t0.At: "at0",
t1.At: "at1",
t2.At: "at2",
}
at2t := map[zodb.Tid]*xbtreetest.Commit{ // XXX -> move to treeenv
t0.At: t0,
t1.At: t1,
t2.At: t2,
}
δbtail := NewΔBtail(t0.At, t.DB) δbtail := NewΔBtail(t0.At, t.DB)
_, err := δbtail.Update(t1.ΔZ); X(err) _, err := δbtail.Update(t1.ΔZ); X(err)
_, err = δbtail.Update(t2.ΔZ); X(err) _, err = δbtail.Update(t2.ΔZ); X(err)
...@@ -1244,7 +1218,7 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) { ...@@ -1244,7 +1218,7 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) {
// convert vδT from ΔTree to ΔT // convert vδT from ΔTree to ΔT
var vδT_ []ΔT var vδT_ []ΔT
for _, δT := range vδT { for _, δT := range vδT {
tj := at2t[δT.Rev] tj := t.XGetCommit(δT.Rev)
δt := ΔT{δT.Rev, xgetδKV(tj.Prev, tj, δT.ΔKV)} δt := ΔT{δT.Rev, xgetδKV(tj.Prev, tj, δT.ΔKV)}
vδT_ = append(vδT_, δt) vδT_ = append(vδT_, δt)
} }
...@@ -1254,11 +1228,11 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) { ...@@ -1254,11 +1228,11 @@ func TestΔBtailSliceByRootRev(t_ *testing.T) {
} }
have := []string{} have := []string{}
for _, δT := range vδT_ { for _, δT := range vδT_ {
have = append(have, fmt.Sprintf("@%s·%v", xat[δT.Rev], δT.ΔKV)) have = append(have, fmt.Sprintf("@%s·%v", t.AtSymb(δT.Rev), δT.ΔKV))
} }
want := []string{} want := []string{}
for _, δT := range vδTok { for _, δT := range vδTok {
want = append(want, fmt.Sprintf("@%s·%v", xat[δT.Rev], δT.ΔKV)) want = append(want, fmt.Sprintf("@%s·%v", t.AtSymb(δT.Rev), δT.ΔKV))
} }
t.Errorf("%s:\nhave: %s\nwant: %s", subj, have, want) t.Errorf("%s:\nhave: %s\nwant: %s", subj, have, want)
} }
...@@ -1368,24 +1342,18 @@ func TestΔBtailClone(t_ *testing.T) { ...@@ -1368,24 +1342,18 @@ func TestΔBtailClone(t_ *testing.T) {
trackKeys(δbtail, t1, _2) trackKeys(δbtail, t1, _2)
err = δbtail.rebuildAll(); X(err) err = δbtail.rebuildAll(); X(err)
xat := map[zodb.Tid]string{
t0.At: "at0",
t1.At: "at1",
}
δkv1_1 := map[Key]Δstring{2:{"b","d"}} δkv1_1 := map[Key]Δstring{2:{"b","d"}}
assertΔTtail(t.T, "orig @at1", δbtail, t1, t.Root(), xat, δkv1_1) assertΔTtail(t.T, "orig @at1", δbtail, t1, t.Root(), δkv1_1)
δbklon := δbtail.Clone() δbklon := δbtail.Clone()
assertΔTtail(t.T, "klon @at1", δbklon, t1, t.Root(), xat, δkv1_1) assertΔTtail(t.T, "klon @at1", δbklon, t1, t.Root(), δkv1_1)
t2 := t.CommitTree("T/B1:b,2:a") t2 := t.CommitTree("T/B1:b,2:a")
_, err = δbtail.Update(t2.ΔZ); X(err) _, err = δbtail.Update(t2.ΔZ); X(err)
xat[t2.At] = "at2"
δkv1_2 := map[Key]Δstring{1:{"a","c"}, 2:{"b","d"}} δkv1_2 := map[Key]Δstring{1:{"a","c"}, 2:{"b","d"}}
δkv2_2 := map[Key]Δstring{1:{"c","b"}, 2:{"d","a"}} δkv2_2 := map[Key]Δstring{1:{"c","b"}, 2:{"d","a"}}
assertΔTtail(t.T, "orig @at2", δbtail, t2, t.Root(), xat, δkv1_2, δkv2_2) assertΔTtail(t.T, "orig @at2", δbtail, t2, t.Root(), δkv1_2, δkv2_2)
assertΔTtail(t.T, "klon @at1 after orig @at->@at2", δbklon, t1, t.Root(), xat, δkv1_1) assertΔTtail(t.T, "klon @at1 after orig @at->@at2", δbklon, t1, t.Root(), δkv1_1)
} }
...@@ -1549,14 +1517,15 @@ func _KAdj(t1, t2 *xbtreetest.Commit, keysv ...setKey) (kadj KAdjMatrix) { ...@@ -1549,14 +1517,15 @@ func _KAdj(t1, t2 *xbtreetest.Commit, keysv ...setKey) (kadj KAdjMatrix) {
// assertΔTtail verifies state of ΔTtail that corresponds to treeRoot in δbtail. // assertΔTtail verifies state of ΔTtail that corresponds to treeRoot in δbtail.
// it also verifies that δbtail.vδBroots matches ΔTtail data. // it also verifies that δbtail.vδBroots matches ΔTtail data.
func assertΔTtail(t *testing.T, subj string, δbtail *ΔBtail, tj *xbtreetest.Commit, treeRoot zodb.Oid, xat map[zodb.Tid]string, vδTok ...map[Key]Δstring) { func assertΔTtail(t *testing.T, subj string, δbtail *ΔBtail, tj *xbtreetest.Commit, treeRoot zodb.Oid, vδTok ...map[Key]Δstring) {
t.Helper() t.Helper()
// XXX +lastRevOf // XXX +lastRevOf
T := tj.T // XXX better require t to be xbtreetest.T instead?
l := len(vδTok) l := len(vδTok)
var vatOK []zodb.Tid var vatOK []zodb.Tid
var vδTok_ []map[Key]Δstring var vδTok_ []map[Key]Δstring
at2t := map[zodb.Tid]*xbtreetest.Commit{tj.At: tj} // XXX -> xbtreetest.T
t0 := tj t0 := tj
for i := 0; i<l; i++ { for i := 0; i<l; i++ {
// empty vδTok entries means they should be absent in vδT // empty vδTok entries means they should be absent in vδT
...@@ -1565,7 +1534,6 @@ func assertΔTtail(t *testing.T, subj string, δbtail *ΔBtail, tj *xbtreetest.C ...@@ -1565,7 +1534,6 @@ func assertΔTtail(t *testing.T, subj string, δbtail *ΔBtail, tj *xbtreetest.C
vδTok_ = append([]map[Key]Δstring{δTok}, vδTok_...) vδTok_ = append([]map[Key]Δstring{δTok}, vδTok_...)
} }
t0 = t0.Prev t0 = t0.Prev
at2t[t0.At] = t0
} }
vδTok = vδTok_ vδTok = vδTok_
δTtail, ok := δbtail.vδTbyRoot[treeRoot] δTtail, ok := δbtail.vδTbyRoot[treeRoot]
...@@ -1579,7 +1547,7 @@ func assertΔTtail(t *testing.T, subj string, δbtail *ΔBtail, tj *xbtreetest.C ...@@ -1579,7 +1547,7 @@ func assertΔTtail(t *testing.T, subj string, δbtail *ΔBtail, tj *xbtreetest.C
atPrev := t0.At atPrev := t0.At
for _, δToid := range vδToid { for _, δToid := range vδToid {
vat = append(vat, δToid.Rev) vat = append(vat, δToid.Rev)
δT := xgetδKV(at2t[atPrev], at2t[δToid.Rev], δToid.ΔKV) // {} k -> δ(ZBlk(oid).data) δT := xgetδKV(T.XGetCommit(atPrev), T.XGetCommit(δToid.Rev), δToid.ΔKV) // {} k -> δ(ZBlk(oid).data)
vδT = append(vδT, δT) vδT = append(vδT, δT)
atPrev = δToid.Rev atPrev = δToid.Rev
} }
...@@ -1597,14 +1565,14 @@ func assertΔTtail(t *testing.T, subj string, δbtail *ΔBtail, tj *xbtreetest.C ...@@ -1597,14 +1565,14 @@ func assertΔTtail(t *testing.T, subj string, δbtail *ΔBtail, tj *xbtreetest.C
emsg := fmt.Sprintf("%s: vδT:\n", subj) emsg := fmt.Sprintf("%s: vδT:\n", subj)
have := "" have := ""
for i := 0; i<len(vδT); i++ { for i := 0; i<len(vδT); i++ {
have += fmt.Sprintf("\n\t@%s: %v", xat[vat[i]], vδT[i]) have += fmt.Sprintf("\n\t@%s: %v", T.AtSymb(vat[i]), vδT[i])
} }
emsg += fmt.Sprintf("have: %s\n", have) emsg += fmt.Sprintf("have: %s\n", have)
if !tok { if !tok {
want := "" want := ""
for i := 0; i<len(vδTok); i++ { for i := 0; i<len(vδTok); i++ {
want += fmt.Sprintf("\n\t@%s: %v", xat[vatOK[i]], vδTok[i]) want += fmt.Sprintf("\n\t@%s: %v", T.AtSymb(vatOK[i]), vδTok[i])
} }
emsg += fmt.Sprintf("want: %s\n", want) emsg += fmt.Sprintf("want: %s\n", want)
} }
...@@ -1612,7 +1580,7 @@ func assertΔTtail(t *testing.T, subj string, δbtail *ΔBtail, tj *xbtreetest.C ...@@ -1612,7 +1580,7 @@ func assertΔTtail(t *testing.T, subj string, δbtail *ΔBtail, tj *xbtreetest.C
if !bok { if !bok {
vδb_root := "" vδb_root := ""
for i := 0; i<len(vatδB); i++ { for i := 0; i<len(vatδB); i++ {
vδb_root += fmt.Sprintf("\n\t@%s", xat[vatδB[i]]) vδb_root += fmt.Sprintf("\n\t@%s", T.AtSymb(vatδB[i]))
} }
emsg += fmt.Sprintf("vδb/root: %s\n", vδb_root) emsg += fmt.Sprintf("vδb/root: %s\n", vδb_root)
} }
......
...@@ -184,8 +184,6 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) { ...@@ -184,8 +184,6 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) {
t := xbtreetest.NewT(t_) t := xbtreetest.NewT(t_)
X := exc.Raiseif X := exc.Raiseif
xat := map[zodb.Tid]string{} // tid -> "at<i>"
// data built via applying changes from testq // data built via applying changes from testq
vδf := []*ΔFile{} // (rev↑, {}blk) vδf := []*ΔFile{} // (rev↑, {}blk)
vδE := []_ΔFileEpoch{} // (rev↑, EPOCH) vδE := []_ΔFileEpoch{} // (rev↑, EPOCH)
...@@ -203,7 +201,6 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) { ...@@ -203,7 +201,6 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) {
// start δFtail when zfile does not yet exists // start δFtail when zfile does not yet exists
// this way we'll verify how ΔFtail rebuilds vδE for started-to-be-tracked file // this way we'll verify how ΔFtail rebuilds vδE for started-to-be-tracked file
t0 := t.CommitTree("øf") t0 := t.CommitTree("øf")
xat[t0.At] = "at0"
t.Logf("# @at0 (%s)", t0.At) t.Logf("# @at0 (%s)", t0.At)
epochv = append(epochv, t0.At) epochv = append(epochv, t0.At)
δFtail := NewΔFtail(t.Head().At, t.DB) δFtail := NewΔFtail(t.Head().At, t.DB)
...@@ -212,7 +209,6 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) { ...@@ -212,7 +209,6 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) {
// vδf + friends will be updated after "load zfile" // vδf + friends will be updated after "load zfile"
δt1 := map[int64]string{0:"a"} δt1 := map[int64]string{0:"a"}
t1 := t.CommitTree(fmt.Sprintf("t%s D%s", xbtreetest.KVTxt(δt1), dataTabTxt(dataTab))) t1 := t.CommitTree(fmt.Sprintf("t%s D%s", xbtreetest.KVTxt(δt1), dataTabTxt(dataTab)))
xat[t1.At] = "at1"
δblk1 := setI64{} δblk1 := setI64{}
for blk := range δt1 { for blk := range δt1 {
δblk1.Add(blk) δblk1.Add(blk)
...@@ -276,9 +272,9 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) { ...@@ -276,9 +272,9 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) {
retrack() retrack()
// δfstr/vδfstr converts δf/vδf to string taking xat into account // δfstr/vδfstr converts δf/vδf to string taking symbolic at into account
δfstr := func(δf *ΔFile) string { δfstr := func(δf *ΔFile) string {
s := fmt.Sprintf("@%s·%s", xat[δf.Rev], δf.Blocks) s := fmt.Sprintf("@%s·%s", t.AtSymb(δf.Rev), δf.Blocks)
if δf.Epoch { if δf.Epoch {
s += "E" s += "E"
} }
...@@ -379,12 +375,11 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) { ...@@ -379,12 +375,11 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) {
if newEpoch { if newEpoch {
epochv = append(epochv, commit.At) epochv = append(epochv, commit.At)
} }
xat[commit.At] = fmt.Sprintf("at%d", i)
flags := "" flags := ""
if newEpoch { if newEpoch {
flags += "\tEPOCH" flags += "\tEPOCH"
} }
t.Logf("# → @%s (%s) δT%s δD%s\t; %s\tδ%s%s", xat[commit.At], commit.At, xbtreetest.KVTxt(test.δblkTab), test.δdataTab, commit.Tree, δblk, flags) t.Logf("# → @%s (%s) δT%s δD%s\t; %s\tδ%s%s", commit.AtSymb(), commit.At, xbtreetest.KVTxt(test.δblkTab), test.δdataTab, commit.Tree, δblk, flags)
//t.Logf("# vδf: %s", vδfstr(vδf)) //t.Logf("# vδf: %s", vδfstr(vδf))
...@@ -406,7 +401,7 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) { ...@@ -406,7 +401,7 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) {
} }
blkRevAt[commit.At] = blkRev blkRevAt[commit.At] = blkRev
/* /*
fmt.Printf("blkRevAt[@%s]:\n", xat[commit.At]) fmt.Printf("blkRevAt[@%s]:\n", commit.AtSymb())
blkv := []int64{} blkv := []int64{}
for blk := range blkRev { for blk := range blkRev {
blkv = append(blkv, blk) blkv = append(blkv, blk)
...@@ -515,7 +510,7 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) { ...@@ -515,7 +510,7 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) {
const ncut = 5 const ncut = 5
if len(vδf) >= ncut { if len(vδf) >= ncut {
revcut := vδf[0].Rev revcut := vδf[0].Rev
t.Logf("# forget ≤ @%s", xat[revcut]) t.Logf("# forget ≤ @%s", t.AtSymb(revcut))
δFtail.ForgetPast(revcut) δFtail.ForgetPast(revcut)
vδf = vδf[1:] vδf = vδf[1:]
//t.Logf("# vδf: %s", vδfstr(vδf)) //t.Logf("# vδf: %s", vδfstr(vδf))
...@@ -559,7 +554,7 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) { ...@@ -559,7 +554,7 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) {
vδf_ok := vδf[j:k+1] // [j,k] vδf_ok := vδf[j:k+1] // [j,k]
vδf_ := δFtail.SliceByFileRev(zfile, lo, hi) vδf_ := δFtail.SliceByFileRev(zfile, lo, hi)
if !reflect.DeepEqual(vδf_, vδf_ok) { if !reflect.DeepEqual(vδf_, vδf_ok) {
t.Errorf("slice (@%s,@%s]:\nhave: %v\nwant: %v", xat[lo], xat[hi], vδfstr(vδf_), vδfstr(vδf_ok)) t.Errorf("slice (@%s,@%s]:\nhave: %v\nwant: %v", t.AtSymb(lo), t.AtSymb(hi), vδfstr(vδf_), vδfstr(vδf_ok))
} }
} }
} }
...@@ -597,7 +592,7 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) { ...@@ -597,7 +592,7 @@ func testΔFtail(t_ *testing.T, testq chan ΔFTestEntry) {
revOK, exactOK = δFtail.Tail(), false revOK, exactOK = δFtail.Tail(), false
} }
if !(rev == revOK && exact == exactOK) { if !(rev == revOK && exact == exactOK) {
t.Errorf("blkrev #%d @%s:\nhave: @%s, %v\nwant: @%s, %v", blk, xat[at], xat[rev], exact, xat[revOK], exactOK) t.Errorf("blkrev #%d @%s:\nhave: @%s, %v\nwant: @%s, %v", blk, t.AtSymb(at), t.AtSymb(rev), exact, t.AtSymb(revOK), exactOK)
} }
} }
...@@ -619,31 +614,25 @@ func TestΔFtailSliceUntrackedUniform(t_ *testing.T) { ...@@ -619,31 +614,25 @@ func TestΔFtailSliceUntrackedUniform(t_ *testing.T) {
t := xbtreetest.NewT(t_) t := xbtreetest.NewT(t_)
X := exc.Raiseif X := exc.Raiseif
xat := map[zodb.Tid]string{}
at0 := t.Head().At at0 := t.Head().At
xat[at0] = "at0"
δFtail := NewΔFtail(at0, t.DB) δFtail := NewΔFtail(at0, t.DB)
// commit t1. all 0, 1 and 2 are in the same bucket. // commit t1. all 0, 1 and 2 are in the same bucket.
t1 := t.CommitTree("T/B0:a,1:b,2:c") t1 := t.CommitTree("T/B0:a,1:b,2:c")
xat[t1.At] = "at1"
δF, err := δFtail.Update(t1.ΔZ); X(err) δF, err := δFtail.Update(t1.ΔZ); X(err)
// XXX assert δF == ø // XXX assert δF == ø
_ = δF _ = δF
t2 := t.CommitTree("t0:d,1:e,2:c Da:a,b:b,c:c2,d:d,e:e") // 0:-a+d 1:-b+e δc₂ t2 := t.CommitTree("t0:d,1:e,2:c Da:a,b:b,c:c2,d:d,e:e") // 0:-a+d 1:-b+e δc₂
xat[t2.At] = "at2"
δF, err = δFtail.Update(t2.ΔZ); X(err) δF, err = δFtail.Update(t2.ΔZ); X(err)
// XXX assert δF // XXX assert δF
t3 := t.CommitTree("t0:d,1:e,2:c Da:a,b:b,c:c3,d:d3,e:e3") // δc₃ δd₃ δe₃ t3 := t.CommitTree("t0:d,1:e,2:c Da:a,b:b,c:c3,d:d3,e:e3") // δc₃ δd₃ δe₃
xat[t3.At] = "at3"
δF, err = δFtail.Update(t3.ΔZ); X(err) δF, err = δFtail.Update(t3.ΔZ); X(err)
// XXX assert δF // XXX assert δF
t4 := t.CommitTree("t0:d,1:e,2:c Da:a,b:b,c:c4,d:d3,e:e4") // δc₄ δe₄ t4 := t.CommitTree("t0:d,1:e,2:c Da:a,b:b,c:c4,d:d3,e:e4") // δc₄ δe₄
xat[t4.At] = "at4"
δF, err = δFtail.Update(t4.ΔZ); X(err) δF, err = δFtail.Update(t4.ΔZ); X(err)
// XXX assert δF // XXX assert δF
...@@ -675,10 +664,10 @@ func TestΔFtailSliceUntrackedUniform(t_ *testing.T) { ...@@ -675,10 +664,10 @@ func TestΔFtailSliceUntrackedUniform(t_ *testing.T) {
δFtail.Track(zfile, blk, path, zblk) δFtail.Track(zfile, blk, path, zblk)
} }
// δfstr/vδfstr converts δf/vδf to string taking xat into account // δfstr/vδfstr converts δf/vδf to string taking symbolic at into account
// XXX dup // XXX dup
δfstr := func(δf *ΔFile) string { δfstr := func(δf *ΔFile) string {
s := fmt.Sprintf("@%s·%s", xat[δf.Rev], δf.Blocks) s := fmt.Sprintf("@%s·%s", t.AtSymb(δf.Rev), δf.Blocks)
if δf.Epoch { if δf.Epoch {
s += "E" s += "E"
} }
...@@ -710,7 +699,7 @@ func TestΔFtailSliceUntrackedUniform(t_ *testing.T) { ...@@ -710,7 +699,7 @@ func TestΔFtailSliceUntrackedUniform(t_ *testing.T) {
&ΔFile{Rev: t4.At, Blocks: b( 1), Size: false}, &ΔFile{Rev: t4.At, Blocks: b( 1), Size: false},
} }
if !reflect.DeepEqual(vδf, vδf_ok) { if !reflect.DeepEqual(vδf, vδf_ok) {
t.Errorf("slice (@%s,@%s]:\nhave: %v\nwant: %v", xat[lo], xat[hi], vδfstr(vδf), vδfstr(vδf_ok)) t.Errorf("slice (@%s,@%s]:\nhave: %v\nwant: %v", t.AtSymb(lo), t.AtSymb(hi), vδfstr(vδf), vδfstr(vδf_ok))
} }
...@@ -721,7 +710,7 @@ func TestΔFtailSliceUntrackedUniform(t_ *testing.T) { ...@@ -721,7 +710,7 @@ func TestΔFtailSliceUntrackedUniform(t_ *testing.T) {
&ΔFile{Rev: t3.At, Blocks: b(0), Size: false}, &ΔFile{Rev: t3.At, Blocks: b(0), Size: false},
} }
if !reflect.DeepEqual(vδf, vδf_ok) { if !reflect.DeepEqual(vδf, vδf_ok) {
t.Errorf("slice (@%s,@%s]:\nhave: %v\nwant: %v", xat[lo], xat[hi], vδfstr(vδf), vδfstr(vδf_ok)) t.Errorf("slice (@%s,@%s]:\nhave: %v\nwant: %v", t.AtSymb(lo), t.AtSymb(hi), vδfstr(vδf), vδfstr(vδf_ok))
} }
// (at3, at4] -> changes to only 0, ----/---- // (at3, at4] -> changes to only 0, ----/----
...@@ -729,7 +718,7 @@ func TestΔFtailSliceUntrackedUniform(t_ *testing.T) { ...@@ -729,7 +718,7 @@ func TestΔFtailSliceUntrackedUniform(t_ *testing.T) {
vδf = δFtail.SliceByFileRev(zfile, lo, hi) vδf = δFtail.SliceByFileRev(zfile, lo, hi)
vδf_ok = []*ΔFile(nil) vδf_ok = []*ΔFile(nil)
if !reflect.DeepEqual(vδf, vδf_ok) { if !reflect.DeepEqual(vδf, vδf_ok) {
t.Errorf("slice (@%s,@%s]:\nhave: %v\nwant: %v", xat[lo], xat[hi], vδfstr(vδf), vδfstr(vδf_ok)) t.Errorf("slice (@%s,@%s]:\nhave: %v\nwant: %v", t.AtSymb(lo), t.AtSymb(hi), vδfstr(vδf), vδfstr(vδf_ok))
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment