1
2
3
4
5
6
7 package testutil
8
9 import (
10 "fmt"
11 "math/rand"
12
13 . "github.com/onsi/ginkgo"
14 . "github.com/onsi/gomega"
15
16 "github.com/syndtr/goleveldb/leveldb/errors"
17 "github.com/syndtr/goleveldb/leveldb/util"
18 )
19
20 func TestFind(db Find, kv KeyValue) {
21 ShuffledIndex(nil, kv.Len(), 1, func(i int) {
22 key_, key, value := kv.IndexInexact(i)
23
24
25 rkey, rvalue, err := db.TestFind(key)
26 Expect(err).ShouldNot(HaveOccurred(), "Error for exact key %q", key)
27 Expect(rkey).Should(Equal(key), "Key")
28 Expect(rvalue).Should(Equal(value), "Value for exact key %q", key)
29
30
31 rkey, rvalue, err = db.TestFind(key_)
32 Expect(err).ShouldNot(HaveOccurred(), "Error for inexact key %q (%q)", key_, key)
33 Expect(rkey).Should(Equal(key), "Key for inexact key %q (%q)", key_, key)
34 Expect(rvalue).Should(Equal(value), "Value for inexact key %q (%q)", key_, key)
35 })
36 }
37
38 func TestFindAfterLast(db Find, kv KeyValue) {
39 var key []byte
40 if kv.Len() > 0 {
41 key_, _ := kv.Index(kv.Len() - 1)
42 key = BytesAfter(key_)
43 }
44 rkey, _, err := db.TestFind(key)
45 Expect(err).Should(HaveOccurred(), "Find for key %q yield key %q", key, rkey)
46 Expect(err).Should(Equal(errors.ErrNotFound))
47 }
48
49 func TestGet(db Get, kv KeyValue) {
50 ShuffledIndex(nil, kv.Len(), 1, func(i int) {
51 key_, key, value := kv.IndexInexact(i)
52
53
54 rvalue, err := db.TestGet(key)
55 Expect(err).ShouldNot(HaveOccurred(), "Error for key %q", key)
56 Expect(rvalue).Should(Equal(value), "Value for key %q", key)
57
58
59 if len(key_) > 0 {
60 _, err = db.TestGet(key_)
61 Expect(err).Should(HaveOccurred(), "Error for key %q", key_)
62 Expect(err).Should(Equal(errors.ErrNotFound))
63 }
64 })
65 }
66
67 func TestHas(db Has, kv KeyValue) {
68 ShuffledIndex(nil, kv.Len(), 1, func(i int) {
69 key_, key, _ := kv.IndexInexact(i)
70
71
72 ret, err := db.TestHas(key)
73 Expect(err).ShouldNot(HaveOccurred(), "Error for key %q", key)
74 Expect(ret).Should(BeTrue(), "False for key %q", key)
75
76
77 if len(key_) > 0 {
78 ret, err = db.TestHas(key_)
79 Expect(err).ShouldNot(HaveOccurred(), "Error for key %q", key_)
80 Expect(ret).ShouldNot(BeTrue(), "True for key %q", key)
81 }
82 })
83 }
84
85 func TestIter(db NewIterator, r *util.Range, kv KeyValue) {
86 iter := db.TestNewIterator(r)
87 Expect(iter.Error()).ShouldNot(HaveOccurred())
88
89 t := IteratorTesting{
90 KeyValue: kv,
91 Iter: iter,
92 }
93
94 DoIteratorTesting(&t)
95 iter.Release()
96 }
97
98 func KeyValueTesting(rnd *rand.Rand, kv KeyValue, p DB, setup func(KeyValue) DB, teardown func(DB)) {
99 if rnd == nil {
100 rnd = NewRand()
101 }
102
103 if p == nil {
104 BeforeEach(func() {
105 p = setup(kv)
106 })
107 if teardown != nil {
108 AfterEach(func() {
109 teardown(p)
110 })
111 }
112 }
113
114 It("Should find all keys with Find", func() {
115 if db, ok := p.(Find); ok {
116 TestFind(db, kv)
117 }
118 })
119
120 It("Should return error if Find on key after the last", func() {
121 if db, ok := p.(Find); ok {
122 TestFindAfterLast(db, kv)
123 }
124 })
125
126 It("Should only find exact key with Get", func() {
127 if db, ok := p.(Get); ok {
128 TestGet(db, kv)
129 }
130 })
131
132 It("Should only find present key with Has", func() {
133 if db, ok := p.(Has); ok {
134 TestHas(db, kv)
135 }
136 })
137
138 It("Should iterates and seeks correctly", func(done Done) {
139 if db, ok := p.(NewIterator); ok {
140 TestIter(db, nil, kv.Clone())
141 }
142 done <- true
143 }, 30.0)
144
145 It("Should iterates and seeks slice correctly", func(done Done) {
146 if db, ok := p.(NewIterator); ok {
147 RandomIndex(rnd, kv.Len(), Min(kv.Len(), 50), func(i int) {
148 type slice struct {
149 r *util.Range
150 start, limit int
151 }
152
153 key_, _, _ := kv.IndexInexact(i)
154 for _, x := range []slice{
155 {&util.Range{Start: key_, Limit: nil}, i, kv.Len()},
156 {&util.Range{Start: nil, Limit: key_}, 0, i},
157 } {
158 By(fmt.Sprintf("Random index of %d .. %d", x.start, x.limit), func() {
159 TestIter(db, x.r, kv.Slice(x.start, x.limit))
160 })
161 }
162 })
163 }
164 done <- true
165 }, 200.0)
166
167 It("Should iterates and seeks slice correctly", func(done Done) {
168 if db, ok := p.(NewIterator); ok {
169 RandomRange(rnd, kv.Len(), Min(kv.Len(), 50), func(start, limit int) {
170 By(fmt.Sprintf("Random range of %d .. %d", start, limit), func() {
171 r := kv.Range(start, limit)
172 TestIter(db, &r, kv.Slice(start, limit))
173 })
174 })
175 }
176 done <- true
177 }, 200.0)
178 }
179
180 func AllKeyValueTesting(rnd *rand.Rand, body, setup func(KeyValue) DB, teardown func(DB)) {
181 Test := func(kv *KeyValue) func() {
182 return func() {
183 var p DB
184 if setup != nil {
185 Defer("setup", func() {
186 p = setup(*kv)
187 })
188 }
189 if teardown != nil {
190 Defer("teardown", func() {
191 teardown(p)
192 })
193 }
194 if body != nil {
195 p = body(*kv)
196 }
197 KeyValueTesting(rnd, *kv, p, func(KeyValue) DB {
198 return p
199 }, nil)
200 }
201 }
202
203 Describe("with no key/value (empty)", Test(&KeyValue{}))
204 Describe("with empty key", Test(KeyValue_EmptyKey()))
205 Describe("with empty value", Test(KeyValue_EmptyValue()))
206 Describe("with one key/value", Test(KeyValue_OneKeyValue()))
207 Describe("with big value", Test(KeyValue_BigValue()))
208 Describe("with special key", Test(KeyValue_SpecialKey()))
209 Describe("with multiple key/value", Test(KeyValue_MultipleKeyValue()))
210 Describe("with generated key/value 2-incr", Test(KeyValue_Generate(nil, 120, 2, 1, 50, 10, 120)))
211 Describe("with generated key/value 3-incr", Test(KeyValue_Generate(nil, 120, 3, 1, 50, 10, 120)))
212 }
213
View as plain text