Skip to content

Commit 1184855

Browse files
committed
statedb: Extend quick check to delete as well
Add deletion of objects to TestDB_Quick. Try to delete 33% of the time to keep the tree growing. Signed-off-by: Jussi Maki <[email protected]>
1 parent ab84043 commit 1184855

File tree

1 file changed

+93
-29
lines changed

1 file changed

+93
-29
lines changed

quick_test.go

Lines changed: 93 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,6 @@ import (
1515
"github.com/stretchr/testify/require"
1616
)
1717

18-
var quickConfig = &quick.Config{
19-
MaxCount: 5000,
20-
21-
// Make 1-8 byte long strings as input data. Keep the strings shorter
22-
// than the default quick value generation to hit the more interesting cases
23-
// often.
24-
Values: func(args []reflect.Value, rand *rand.Rand) {
25-
for i := range args {
26-
numBytes := 1 + rand.Intn(8)
27-
bs := make([]byte, numBytes)
28-
rand.Read(bs)
29-
args[i] = reflect.ValueOf(string(bs))
30-
}
31-
},
32-
}
33-
3418
// Use an object with strings for both primary and secondary
3519
// indexing. With non-unique indexes we'll create a composite
3620
// key out of them by concatenation and thus we need test that
@@ -118,24 +102,83 @@ func TestDB_Quick(t *testing.T) {
118102

119103
anyTable := AnyTable{table}
120104

121-
numExpected := 0
105+
values := map[string]string{}
106+
pickRandom := func() string {
107+
if len(values) == 0 || rand.Intn(10) == 0 {
108+
return "nonexisting"
109+
}
110+
n := rand.Intn(len(values))
111+
for a := range values {
112+
if n <= 0 {
113+
return a
114+
}
115+
n--
116+
}
117+
return ""
118+
}
119+
120+
numInserted, numRemoved := 0, 0
122121

123-
check := func(a, b string) bool {
122+
check := func(a, b string, remove bool) bool {
124123
txn := db.WriteTxn(table)
125-
_, hadOld, err := table.Insert(txn, quickObj{a, b})
124+
if remove {
125+
key := pickRandom()
126+
expected, found := values[key]
127+
actual, hadOld, err := table.Delete(txn, quickObj{A: key})
128+
if err != nil {
129+
t.Logf("delete error: %s", err)
130+
return false
131+
}
132+
if found {
133+
if !hadOld {
134+
t.Logf("object was inserted but not found when removing")
135+
return false
136+
}
137+
if actual.B != expected {
138+
t.Logf("removed object value mismatch %q vs %q", expected, actual.B)
139+
}
140+
delete(values, key)
141+
numRemoved++
142+
} else {
143+
if hadOld {
144+
t.Logf("object was removed when it should have not existed")
145+
return false
146+
}
147+
}
148+
txn.Commit()
149+
return true
150+
}
151+
152+
old, hadOld, err := table.Insert(txn, quickObj{a, b})
126153
require.NoError(t, err, "Insert")
127-
if !hadOld {
128-
numExpected++
154+
numInserted++
155+
156+
expected, found := values[a]
157+
if found {
158+
if !hadOld {
159+
t.Logf("object was updated but old value not returned")
160+
return false
161+
}
162+
if old.B != expected {
163+
t.Logf("insert returned wrong old object, %q vs %q", expected, old.B)
164+
}
165+
} else {
166+
if hadOld {
167+
t.Logf("insert returned old value when it should not have existed")
168+
return false
169+
}
129170
}
130-
if numExpected != table.NumObjects(txn) {
171+
values[a] = b
172+
173+
if len(values) != table.NumObjects(txn) {
131174
t.Logf("wrong object count")
132175
return false
133176
}
134177

135178
txn.Commit()
136179
rtxn := db.ReadTxn()
137180

138-
if numExpected != table.NumObjects(rtxn) {
181+
if len(values) != table.NumObjects(rtxn) {
139182
t.Logf("wrong object count")
140183
return false
141184
}
@@ -144,15 +187,15 @@ func TestDB_Quick(t *testing.T) {
144187
// Check queries against the primary index
145188
//
146189

147-
if numExpected != seqLen(table.All(rtxn)) {
190+
if len(values) != seqLen(table.All(rtxn)) {
148191
t.Logf("All() via aIndex wrong length")
149192
return false
150193
}
151-
if numExpected != seqLen(table.Prefix(rtxn, aIndex.Query(""))) {
194+
if len(values) != seqLen(table.Prefix(rtxn, aIndex.Query(""))) {
152195
t.Logf("Prefix() via aIndex wrong length")
153196
return false
154197
}
155-
if numExpected != seqLen(table.LowerBound(rtxn, aIndex.Query(""))) {
198+
if len(values) != seqLen(table.LowerBound(rtxn, aIndex.Query(""))) {
156199
t.Logf("LowerBound() via aIndex wrong length")
157200
return false
158201
}
@@ -212,12 +255,12 @@ func TestDB_Quick(t *testing.T) {
212255
//
213256

214257
// Non-unique indexes return the same number of objects as we've inserted.
215-
if numExpected != seqLen(table.Prefix(rtxn, bIndex.Query(""))) {
258+
if len(values) != seqLen(table.Prefix(rtxn, bIndex.Query(""))) {
216259
t.Logf("Prefix() via bIndex wrong length")
217260
return false
218261
}
219262

220-
if numExpected != seqLen(table.LowerBound(rtxn, bIndex.Query(""))) {
263+
if len(values) != seqLen(table.LowerBound(rtxn, bIndex.Query(""))) {
221264
t.Logf("LowerBound() via bIndex wrong length")
222265
return false
223266
}
@@ -305,7 +348,28 @@ func TestDB_Quick(t *testing.T) {
305348
return true
306349
}
307350

308-
require.NoError(t, quick.Check(check, quickConfig))
351+
require.NoError(t, quick.Check(check, &quick.Config{
352+
MaxCount: 5000,
353+
354+
// Make 1-8 byte long strings as input data. Keep the strings shorter
355+
// than the default quick value generation to hit the more interesting cases
356+
// often.
357+
Values: func(args []reflect.Value, rand *rand.Rand) {
358+
if len(args) != 3 {
359+
panic("unexpected args count")
360+
}
361+
for i := range args[:2] {
362+
numBytes := 1 + rand.Intn(8)
363+
bs := make([]byte, numBytes)
364+
rand.Read(bs)
365+
args[i] = reflect.ValueOf(string(bs))
366+
}
367+
// Remove 33% of the time
368+
args[2] = reflect.ValueOf(rand.Intn(3) == 1)
369+
},
370+
}))
371+
372+
t.Logf("%d objects after check, %d inserts, %d removals", len(values), numInserted, numRemoved)
309373
}
310374

311375
func Test_Quick_nonUniqueKey(t *testing.T) {

0 commit comments

Comments
 (0)