@@ -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
311375func Test_Quick_nonUniqueKey (t * testing.T ) {
0 commit comments