Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
W
wendelin.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
Kirill Smelkov
wendelin.core
Commits
ee9d003b
Commit
ee9d003b
authored
Jun 24, 2021
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
45ce369a
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
35 additions
and
50 deletions
+35
-50
wcfs/internal/xbtree/δbtail_test.go
wcfs/internal/xbtree/δbtail_test.go
+35
-50
No files found.
wcfs/internal/xbtree/δbtail_test.go
View file @
ee9d003b
...
@@ -269,6 +269,7 @@ func (tg *AllStructsSrv) AllStructs(kv1, kv2 map[Key]string, maxdepth, maxsplit,
...
@@ -269,6 +269,7 @@ func (tg *AllStructsSrv) AllStructs(kv1, kv2 map[Key]string, maxdepth, maxsplit,
// RTree represents Tree node covering [lo, hi_] key range in its parent tree.
// RTree represents Tree node covering [lo, hi_] key range in its parent tree.
// XXX actually no coverage here -> kill? -> change to just `path []zodb.Oid` in RBucket?
type
RTree
struct
{
type
RTree
struct
{
oid
zodb
.
Oid
oid
zodb
.
Oid
parent
*
RTree
parent
*
RTree
...
@@ -379,6 +380,7 @@ func (rbs RBucketSet) trackSetWithCov(tracked SetKey) (trackSet PPTreeSubSet, ke
...
@@ -379,6 +380,7 @@ func (rbs RBucketSet) trackSetWithCov(tracked SetKey) (trackSet PPTreeSubSet, ke
// XGetTree loads Tree from zurl@at->obj<root>.
// XGetTree loads Tree from zurl@at->obj<root>.
//
// Tree values must be ZBlk whose data is returned instead of references to ZBlk objects.
// Tree values must be ZBlk whose data is returned instead of references to ZBlk objects.
// The tree is returned structured by buckets as
// The tree is returned structured by buckets as
//
//
...
@@ -518,9 +520,9 @@ func XGetδKV(db *zodb.DB, at1, at2 zodb.Tid, δkvOid map[Key]ΔValue) map[Key]
...
@@ -518,9 +520,9 @@ func XGetδKV(db *zodb.DB, at1, at2 zodb.Tid, δkvOid map[Key]ΔValue) map[Key]
// i.e. = δ(Av, Bv) for k: k ∈ U kadj(A,B)[·]
// i.e. = δ(Av, Bv) for k: k ∈ U kadj(A,B)[·]
// ·∈T
// ·∈T
//
//
// XXX fix definition for "and changed"
// XXX fix definition for "and changed
, or coverage changed
"
//
//
//
XXX adjacency matrix is symmetric: XXX KAdj verifies this at runtime
//
Note: adjacency matrix is symmetric (KAdj verifies this at runtime):
//
//
// kadj(A,B) == kadj(B,A)
// kadj(A,B) == kadj(B,A)
type
KAdjMatrix
map
[
Key
]
SetKey
type
KAdjMatrix
map
[
Key
]
SetKey
...
@@ -686,11 +688,11 @@ func xverifyΔBTail_Update(t *testing.T, subj string, db *zodb.DB, treeRoot zodb
...
@@ -686,11 +688,11 @@ func xverifyΔBTail_Update(t *testing.T, subj string, db *zodb.DB, treeRoot zodb
keys
.
Add
(
allKeyv
[
idx
])
keys
.
Add
(
allKeyv
[
idx
])
}
}
// XXX
allocates and keeps too much memory in -verylong
// this t.Run
allocates and keeps too much memory in -verylong
// XXX also not so useful as above "Update/t1->t2" ?
// also it is not so useful as above "Update/t1->t2"
//
t.Run(fmt.Sprintf(" track=%s", keys), func(t *testing.T) {
//
t.Run(fmt.Sprintf(" track=%s", keys), func(t *testing.T) {
xverifyΔBTail_Update1
(
t
,
subj
,
db
,
treeRoot
,
t1
.
at
,
t2
.
at
,
t1
.
xkv
,
t2
.
xkv
,
t2
.
δZ
,
t2
.
δxkv
,
keys
,
kadj12
)
xverifyΔBTail_Update1
(
t
,
subj
,
db
,
treeRoot
,
t1
.
at
,
t2
.
at
,
t1
.
xkv
,
t2
.
xkv
,
t2
.
δZ
,
t2
.
δxkv
,
keys
,
kadj12
)
//
})
//
})
}
}
})
})
}
}
...
@@ -699,7 +701,7 @@ func xverifyΔBTail_Update(t *testing.T, subj string, db *zodb.DB, treeRoot zodb
...
@@ -699,7 +701,7 @@ func xverifyΔBTail_Update(t *testing.T, subj string, db *zodb.DB, treeRoot zodb
// tracked state defined by initialTrackedKeys.
// tracked state defined by initialTrackedKeys.
func
xverifyΔBTail_Update1
(
t
*
testing
.
T
,
subj
string
,
db
*
zodb
.
DB
,
treeRoot
zodb
.
Oid
,
at1
,
at2
zodb
.
Tid
,
xkv1
,
xkv2
RBucketSet
,
δZ
*
zodb
.
EventCommit
,
d12
map
[
Key
]
Δstring
,
initialTrackedKeys
SetKey
,
kadj
KAdjMatrix
)
{
func
xverifyΔBTail_Update1
(
t
*
testing
.
T
,
subj
string
,
db
*
zodb
.
DB
,
treeRoot
zodb
.
Oid
,
at1
,
at2
zodb
.
Tid
,
xkv1
,
xkv2
RBucketSet
,
δZ
*
zodb
.
EventCommit
,
d12
map
[
Key
]
Δstring
,
initialTrackedKeys
SetKey
,
kadj
KAdjMatrix
)
{
X
:=
exc
.
Raiseif
X
:=
exc
.
Raiseif
//
t.Logf("\n>>> Track=%s\n", initialTrackedKeys)
//
t.Logf("\n>>> Track=%s\n", initialTrackedKeys)
var
TrackedδZ
SetKey
=
nil
var
TrackedδZ
SetKey
=
nil
var
kadjTrackedδZ
SetKey
=
nil
var
kadjTrackedδZ
SetKey
=
nil
...
@@ -758,15 +760,8 @@ func xverifyΔBTail_Update1(t *testing.T, subj string, db *zodb.DB, treeRoot zod
...
@@ -758,15 +760,8 @@ func xverifyΔBTail_Update1(t *testing.T, subj string, db *zodb.DB, treeRoot zod
}
}
// XXX why "except ∞" ?
// assert TrackedδZ ∈ kadj[TrackedδZ]
// assert TrackedδZ ∈ kadj[TrackedδZ] except ∞ XXX -> initialTrackedKeys.Difference(kadjTrackedδZ)
trackNotInKadj
:=
TrackedδZ
.
Difference
(
kadjTrackedδZ
)
trackNotInKadj
:=
SetKey
{}
for
k
:=
range
TrackedδZ
{
if
!
kadjTrackedδZ
.
Has
(
k
)
{
trackNotInKadj
.
Add
(
k
)
}
}
trackNotInKadj
.
Del
(
KeyMax
)
if
len
(
trackNotInKadj
)
>
0
{
if
len
(
trackNotInKadj
)
>
0
{
badf
(
"BUG: Tracked^δZ ∉ kadj[Tracked^δZ] ; extra=%v"
,
trackNotInKadj
)
badf
(
"BUG: Tracked^δZ ∉ kadj[Tracked^δZ] ; extra=%v"
,
trackNotInKadj
)
return
return
...
@@ -808,9 +803,6 @@ func xverifyΔBTail_Update1(t *testing.T, subj string, db *zodb.DB, treeRoot zod
...
@@ -808,9 +803,6 @@ func xverifyΔBTail_Update1(t *testing.T, subj string, db *zodb.DB, treeRoot zod
// assert δtkeycov == δ(tkeyCov1, tkeyCov2)
// assert δtkeycov == δ(tkeyCov1, tkeyCov2)
δtkeycovOK
:=
tkeyCov2
.
Difference
(
tkeyCov1
)
δtkeycovOK
:=
tkeyCov2
.
Difference
(
tkeyCov1
)
//fmt.Printf("tkeyCov1: %s\n", tkeyCov1)
//fmt.Printf("tkeyCov2: %s\n", tkeyCov2)
//fmt.Printf("δtkeycov: %s\n", δtkeycovOK)
δtkeycov
:=
&
RangedKeySet
{}
δtkeycov
:=
&
RangedKeySet
{}
if
__
,
ok
:=
δB1
.
ByRoot
[
treeRoot
];
ok
{
if
__
,
ok
:=
δB1
.
ByRoot
[
treeRoot
];
ok
{
δtkeycov
=
__
.
δtkeycov1
δtkeycov
=
__
.
δtkeycov1
...
@@ -946,8 +938,6 @@ func (δBtail *ΔBtail) assertTrack(t *testing.T, subj string, trackSetOK PPTree
...
@@ -946,8 +938,6 @@ func (δBtail *ΔBtail) assertTrack(t *testing.T, subj string, trackSetOK PPTree
//
//
// It also exercises rebuild phase of ΔBtail.Update.
// It also exercises rebuild phase of ΔBtail.Update.
func
xverifyΔBTail_rebuild
(
t
*
testing
.
T
,
db
*
zodb
.
DB
,
treeRoot
zodb
.
Oid
,
t0
,
t1
,
t2
*
tTreeCommit
)
{
func
xverifyΔBTail_rebuild
(
t
*
testing
.
T
,
db
*
zodb
.
DB
,
treeRoot
zodb
.
Oid
,
t0
,
t1
,
t2
*
tTreeCommit
)
{
// t1 := t2.prev
// t0 := t1.prev
t
.
Run
(
fmt
.
Sprintf
(
"rebuild/%s→%s"
,
t0
.
tree
,
t1
.
tree
),
func
(
t
*
testing
.
T
)
{
t
.
Run
(
fmt
.
Sprintf
(
"rebuild/%s→%s"
,
t0
.
tree
,
t1
.
tree
),
func
(
t
*
testing
.
T
)
{
tAllKeys
:=
allTestKeys
(
t0
,
t1
,
t2
)
tAllKeys
:=
allTestKeys
(
t0
,
t1
,
t2
)
tAllKeyv
:=
tAllKeys
.
SortedElements
()
tAllKeyv
:=
tAllKeys
.
SortedElements
()
...
@@ -1089,7 +1079,7 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
...
@@ -1089,7 +1079,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
,
db
,
δbtail_
,
t2
,
treeRoot
,
xat
,
xverifyΔBTail_rebuild_TR
(
t
,
db
,
δbtail_
,
t2
,
treeRoot
,
xat
,
// after Track(keys2)
// after Track(keys2)
...
@@ -1108,7 +1098,7 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
...
@@ -1108,7 +1098,7 @@ func xverifyΔBTail_rebuild(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, t0, t1
// ΔBtail.Clone had bug that aliased klon data to orig
// ΔBtail.Clone had bug that aliased klon data to orig
assertΔTtail
(
t
,
"BUG: after clone check"
,
δbtail
,
db
,
t2
,
treeRoot
,
xat
,
assertΔTtail
(
t
,
"BUG: after clone check"
,
δbtail
,
db
,
t2
,
treeRoot
,
xat
,
/*vδT=*/
δkv1_k1R2
,
δkv2_k1R2
)
/*vδT=*/
δkv1_k1R2
,
δkv2_k1R2
)
//
})
//
})
}
}
})
})
})
})
...
@@ -1126,7 +1116,7 @@ func xverifyΔBTail_rebuild_U(t *testing.T, δbtail *ΔBtail, db *zodb.DB, treeR
...
@@ -1126,7 +1116,7 @@ func xverifyΔBTail_rebuild_U(t *testing.T, δbtail *ΔBtail, db *zodb.DB, treeR
// Update ati -> atj
// Update ati -> atj
δB
,
err
:=
δbtail
.
Update
(
tj
.
δZ
);
X
(
err
)
δB
,
err
:=
δbtail
.
Update
(
tj
.
δZ
);
X
(
err
)
// XXX assert δB.Rev = tj.at; δB = δ(ti,tj)/
initially tracked
// XXX assert δB.Rev = tj.at; δB = δ(ti,tj)/
tracked (= vδTok[-1])
δbtail
.
assertTrack
(
t
,
subj
,
trackSet
,
ø
)
δbtail
.
assertTrack
(
t
,
subj
,
trackSet
,
ø
)
_
=
δB
_
=
δB
assertΔTtail
(
t
,
subj
,
δbtail
,
db
,
tj
,
treeRoot
,
xat
,
vδTok
...
)
assertΔTtail
(
t
,
subj
,
δbtail
,
db
,
tj
,
treeRoot
,
xat
,
vδTok
...
)
...
@@ -1148,7 +1138,7 @@ func xverifyΔBTail_rebuild_TR(t *testing.T, db *zodb.DB, δbtail *ΔBtail, tj *
...
@@ -1148,7 +1138,7 @@ func xverifyΔBTail_rebuild_TR(t *testing.T, db *zodb.DB, δbtail *ΔBtail, tj *
subj
+=
" + rebuild"
subj
+=
" + rebuild"
δbtail
.
assertTrack
(
t
,
subj
,
trackSetAfterRebuild
,
ø
)
δbtail
.
assertTrack
(
t
,
subj
,
trackSetAfterRebuild
,
ø
)
// XXX assert vδB=[δ1/T(keys)]
// XXX assert vδB=[δ1/T(keys)]
(= vδTok[-1])
// XXX verify Get
// XXX verify Get
...
@@ -1331,6 +1321,8 @@ func xverifyΔBTail_GetAt1(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, vt []*t
...
@@ -1331,6 +1321,8 @@ func xverifyΔBTail_GetAt1(t *testing.T, db *zodb.DB, treeRoot zodb.Oid, vt []*t
*/
*/
// ----------------------------------------
// ΔBTestEntry represents one entry in ΔBTail tests.
// ΔBTestEntry represents one entry in ΔBTail tests.
type
ΔBTestEntry
struct
{
type
ΔBTestEntry
struct
{
tree
string
// next tree topology
tree
string
// next tree topology
...
@@ -1463,19 +1455,19 @@ func testΔBTail(t *testing.T, testq chan ΔBTestEntry) {
...
@@ -1463,19 +1455,19 @@ func testΔBTail(t *testing.T, testq chan ΔBTestEntry) {
var
t0
*
tTreeCommit
var
t0
*
tTreeCommit
t1
:=
&
tTreeCommit
{
t1
:=
&
tTreeCommit
{
tree
:
"T/B:"
,
// treegen.py creates the tree as initially empty
tree
:
"T/B:"
,
// treegen.py creates the tree as initially empty
prev
:
nil
,
// XXX ok?
prev
:
nil
,
at
:
tg
.
head
,
at
:
tg
.
head
,
xkv
:
XGetTree
(
db
,
tg
.
head
,
tg
.
treeRoot
),
xkv
:
XGetTree
(
db
,
tg
.
head
,
tg
.
treeRoot
),
δZ
:
nil
,
// XXX ok?
δZ
:
nil
,
δxkv
:
nil
,
// XXX ok?
δxkv
:
nil
,
}
}
for
test
:=
range
testq
{
for
test
:=
range
testq
{
t2
:=
XCommitTree
(
test
.
tree
)
t2
:=
XCommitTree
(
test
.
tree
)
t2
.
δxkv
=
kvdiff
(
t1
.
xkv
.
Flatten
(),
t2
.
xkv
.
Flatten
())
// XXX move to XCommitTree?
t2
.
δxkv
=
kvdiff
(
t1
.
xkv
.
Flatten
(),
t2
.
xkv
.
Flatten
())
t2
.
prev
=
t1
// XXX ----//----
t2
.
prev
=
t1
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)
// KAdj
// KAdj
if
kadjOK
:=
test
.
kadjOK
;
kadjOK
!=
nil
{
if
kadjOK
:=
test
.
kadjOK
;
kadjOK
!=
nil
{
...
@@ -1638,9 +1630,9 @@ func TestΔBTail(t *testing.T) {
...
@@ -1638,9 +1630,9 @@ func TestΔBTail(t *testing.T) {
oo
:
K
(
1
,
2
,
3
,
4
,
5
,
8
,
9
,
oo
)}),
oo
:
K
(
1
,
2
,
3
,
4
,
5
,
8
,
9
,
oo
)}),
// 2 reflow to right B neighbour; 8 split into new B; δ=ø
// 2 reflow to right B neighbour; 8 split
s
into new B; δ=ø
"T3/B1:a,2:b-B4:d,8:h"
,
"T3/B1:a,2:b-B4:d,8:h"
,
"T2,5/B1:a-B2:b,4:d-B8:h"
,
// XXX add A
"T2,5/B1:a-B2:b,4:d-B8:h"
,
// case where kadj does not grow too much as leafs coverage remains stable
// case where kadj does not grow too much as leafs coverage remains stable
"T4,8/B1:a,2:b-B5:d,6:e-B10:g,11:h"
,
"T4,8/B1:a,2:b-B5:d,6:e-B10:g,11:h"
,
...
@@ -1664,22 +1656,25 @@ func TestΔBTail(t *testing.T) {
...
@@ -1664,22 +1656,25 @@ func TestΔBTail(t *testing.T) {
// * `Tree -> ø -> Tree` (tree is deleted and then recreated)
// * `Tree -> ø -> Tree` (tree is deleted and then recreated)
DEL
,
DEL
,
// tree rotation
"T3/B2:b-B3:c,4:d"
,
"T5/T3-T7/B2:a-B3:a,4:a-B6:a-B8:a"
,
// found by AllStructs ([1] is not changed, but because B1 is
// found by AllStructs ([1] is not changed, but because B1 is
// unlinked and 1 migrates to other bucket, changes in that
// unlinked and 1 migrates to other bucket, changes in that
// other bucket must be included into δT)
// other bucket must be included into δT)
"T1,2/B0:e-B1:d-B2:g,3:a"
,
"T1,2/B0:e-B1:d-B2:g,3:a"
,
"T1/B0:d-B1:d,2:d"
,
"T1/B0:d-B1:d,2:d"
,
// ----//---- with depth=2
// XXX the same issue as ^^^ but with depth=2
"T1,2/T-T-T/B0:a-B1:b-B2:c,3:d"
,
"T1,2/T-T-T/B0:a-B1:b-B2:c,3:d"
,
"T1/T-T/B0:e-B1:b,2:f"
,
"T1/T-T/B0:e-B1:b,2:f"
,
// XXX depth=3 (to verify recursion and selecting which tree children to follow or not)
// XXX depth=3 (to verify recursion and selecting which tree children to follow or not)
// XXX more
// degenerate topology from ZODB tests
// degenerate topology from ZODB tests
// https://github.com/zopefoundation/ZODB/commit/6cd24e99f89b
// https://github.com/zopefoundation/BTrees/blob/4.7.2-1-g078ba60/BTrees/tests/testBTrees.py#L20-L57
"T4/T2-T/T-T-T6,10/B1:a-B3:b-T-T-T/T-B7:c-B11:d/B5:e"
,
"T4/T2-T/T-T-T6,10/B1:a-B3:b-T-T-T/T-B7:c-B11:d/B5:e"
,
"T/B1:e,5:d,7:c,8:b,11:a"
,
// -3 +8
"T/B1:e,5:d,7:c,8:b,11:a"
,
// -3 +8
...
@@ -1714,10 +1709,6 @@ func TestΔBTail(t *testing.T) {
...
@@ -1714,10 +1709,6 @@ func TestΔBTail(t *testing.T) {
"T4/T-T/B3:f-T/B4:a"
,
"T4/T-T/B3:f-T/B4:a"
,
// "T/T/T/B1:a,2:b",
// "T/T/B1:a",
// ---- found by AllStructs ----
// ---- found by AllStructs ----
// trackSet2 wrongly computed due to top not being tracked to tree root
// trackSet2 wrongly computed due to top not being tracked to tree root
...
@@ -1749,8 +1740,8 @@ func TestΔBTail(t *testing.T) {
...
@@ -1749,8 +1740,8 @@ func TestΔBTail(t *testing.T) {
"T/T1,3/T-T2-T4/B0:b-T-T-B3:g-B4:c/B1:b-B2:e"
,
"T/T1,3/T-T2-T4/B0:b-T-T-B3:g-B4:c/B1:b-B2:e"
,
"T1,4/T-T-T/T-T2-B4:f/T-T-T/B0:h-B1:b-B2:h,3:a"
,
"T1,4/T-T-T/T-T2-B4:f/T-T-T/B0:h-B1:b-B2:h,3:a"
,
// XXX TODO classify
"T2/B1:a-B7:g"
,
"T2
/B1:a-B7:g"
,
"T2
,8/B1:a-B7:g-B9:i"
,
"T2,8/B1:a-B7:g-B9:i"
,
"T2/B1:a-B2:b"
,
"T/B1:a,2:b"
,
"T2/B1:a-B2:b"
,
"T/B1:a,2:b"
,
"T2,3/B1:a-B2:b-B3:c"
,
"T/B1:a,2:b"
,
"T2,3/B1:a-B2:b-B3:c"
,
"T/B1:a,2:b"
,
...
@@ -1764,11 +1755,6 @@ func TestΔBTail(t *testing.T) {
...
@@ -1764,11 +1755,6 @@ func TestΔBTail(t *testing.T) {
3
:
K
(
3
,
99
,
oo
),
3
:
K
(
3
,
99
,
oo
),
99
:
K
(
3
,
99
,
oo
),
99
:
K
(
3
,
99
,
oo
),
oo
:
K
(
3
,
99
,
oo
)}),
oo
:
K
(
3
,
99
,
oo
)}),
// XXX --------
// tree rotation
"T3/B2:b-B3:c,4:d"
,
"T5/T3-T7/B2:a-B3:a,4:a-B6:a-B8:a"
,
}
}
// direct tree_i -> tree_{i+1} -> _{i+2} ... plus
// direct tree_i -> tree_{i+1} -> _{i+2} ... plus
// reverse ... tree_i <- _{i+1} <- _{i+2}
// reverse ... tree_i <- _{i+1} <- _{i+2}
...
@@ -1790,12 +1776,11 @@ func TestΔBTail(t *testing.T) {
...
@@ -1790,12 +1776,11 @@ func TestΔBTail(t *testing.T) {
}
}
// TestΔBTailAllStructs verifies ΔBtail on tree topologies generated by AllStructs.
var
(
var
(
verylongFlag
=
flag
.
Bool
(
"verylong"
,
false
,
`switch tests to run in "very long" mode`
)
verylongFlag
=
flag
.
Bool
(
"verylong"
,
false
,
`switch tests to run in "very long" mode`
)
randseedFlag
=
flag
.
Int64
(
"randseed"
,
-
1
,
`seed for random number generator`
)
randseedFlag
=
flag
.
Int64
(
"randseed"
,
-
1
,
`seed for random number generator`
)
)
)
// TestΔBTailAllStructs verifies ΔBtail on tree topologies generated by AllStructs.
func
TestΔBTailAllStructs
(
t
*
testing
.
T
)
{
func
TestΔBTailAllStructs
(
t
*
testing
.
T
)
{
X
:=
exc
.
Raiseif
X
:=
exc
.
Raiseif
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment