aboutsummaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/iter.go
diff options
context:
space:
mode:
Diffstat (limited to 'Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/iter.go')
-rw-r--r--Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/iter.go327
1 files changed, 327 insertions, 0 deletions
diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/iter.go b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/iter.go
new file mode 100644
index 000000000..df6d9db6a
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/leveldb/testutil/iter.go
@@ -0,0 +1,327 @@
+// Copyright (c) 2014, Suryandaru Triandana <syndtr@gmail.com>
+// All rights reserved.
+//
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package testutil
+
+import (
+ "fmt"
+ "math/rand"
+
+ . "github.com/onsi/gomega"
+
+ "github.com/syndtr/goleveldb/leveldb/iterator"
+)
+
+type IterAct int
+
+func (a IterAct) String() string {
+ switch a {
+ case IterNone:
+ return "none"
+ case IterFirst:
+ return "first"
+ case IterLast:
+ return "last"
+ case IterPrev:
+ return "prev"
+ case IterNext:
+ return "next"
+ case IterSeek:
+ return "seek"
+ case IterSOI:
+ return "soi"
+ case IterEOI:
+ return "eoi"
+ }
+ return "unknown"
+}
+
+const (
+ IterNone IterAct = iota
+ IterFirst
+ IterLast
+ IterPrev
+ IterNext
+ IterSeek
+ IterSOI
+ IterEOI
+)
+
+type IteratorTesting struct {
+ KeyValue
+ Iter iterator.Iterator
+ Rand *rand.Rand
+ PostFn func(t *IteratorTesting)
+ Pos int
+ Act, LastAct IterAct
+
+ once bool
+}
+
+func (t *IteratorTesting) init() {
+ if !t.once {
+ t.Pos = -1
+ t.once = true
+ }
+}
+
+func (t *IteratorTesting) post() {
+ if t.PostFn != nil {
+ t.PostFn(t)
+ }
+}
+
+func (t *IteratorTesting) setAct(act IterAct) {
+ t.LastAct, t.Act = t.Act, act
+}
+
+func (t *IteratorTesting) text() string {
+ return fmt.Sprintf("at pos %d and last action was <%v> -> <%v>", t.Pos, t.LastAct, t.Act)
+}
+
+func (t *IteratorTesting) Text() string {
+ return "IteratorTesting is " + t.text()
+}
+
+func (t *IteratorTesting) IsFirst() bool {
+ t.init()
+ return t.Len() > 0 && t.Pos == 0
+}
+
+func (t *IteratorTesting) IsLast() bool {
+ t.init()
+ return t.Len() > 0 && t.Pos == t.Len()-1
+}
+
+func (t *IteratorTesting) TestKV() {
+ t.init()
+ key, value := t.Index(t.Pos)
+ Expect(t.Iter.Key()).NotTo(BeNil())
+ Expect(t.Iter.Key()).Should(Equal(key), "Key is invalid, %s", t.text())
+ Expect(t.Iter.Value()).Should(Equal(value), "Value for key %q, %s", key, t.text())
+}
+
+func (t *IteratorTesting) First() {
+ t.init()
+ t.setAct(IterFirst)
+
+ ok := t.Iter.First()
+ Expect(t.Iter.Error()).ShouldNot(HaveOccurred())
+ if t.Len() > 0 {
+ t.Pos = 0
+ Expect(ok).Should(BeTrue(), t.Text())
+ t.TestKV()
+ } else {
+ t.Pos = -1
+ Expect(ok).ShouldNot(BeTrue(), t.Text())
+ }
+ t.post()
+}
+
+func (t *IteratorTesting) Last() {
+ t.init()
+ t.setAct(IterLast)
+
+ ok := t.Iter.Last()
+ Expect(t.Iter.Error()).ShouldNot(HaveOccurred())
+ if t.Len() > 0 {
+ t.Pos = t.Len() - 1
+ Expect(ok).Should(BeTrue(), t.Text())
+ t.TestKV()
+ } else {
+ t.Pos = 0
+ Expect(ok).ShouldNot(BeTrue(), t.Text())
+ }
+ t.post()
+}
+
+func (t *IteratorTesting) Next() {
+ t.init()
+ t.setAct(IterNext)
+
+ ok := t.Iter.Next()
+ Expect(t.Iter.Error()).ShouldNot(HaveOccurred())
+ if t.Pos < t.Len()-1 {
+ t.Pos++
+ Expect(ok).Should(BeTrue(), t.Text())
+ t.TestKV()
+ } else {
+ t.Pos = t.Len()
+ Expect(ok).ShouldNot(BeTrue(), t.Text())
+ }
+ t.post()
+}
+
+func (t *IteratorTesting) Prev() {
+ t.init()
+ t.setAct(IterPrev)
+
+ ok := t.Iter.Prev()
+ Expect(t.Iter.Error()).ShouldNot(HaveOccurred())
+ if t.Pos > 0 {
+ t.Pos--
+ Expect(ok).Should(BeTrue(), t.Text())
+ t.TestKV()
+ } else {
+ t.Pos = -1
+ Expect(ok).ShouldNot(BeTrue(), t.Text())
+ }
+ t.post()
+}
+
+func (t *IteratorTesting) Seek(i int) {
+ t.init()
+ t.setAct(IterSeek)
+
+ key, _ := t.Index(i)
+ oldKey, _ := t.IndexOrNil(t.Pos)
+
+ ok := t.Iter.Seek(key)
+ Expect(t.Iter.Error()).ShouldNot(HaveOccurred())
+ Expect(ok).Should(BeTrue(), fmt.Sprintf("Seek from key %q to %q, to pos %d, %s", oldKey, key, i, t.text()))
+
+ t.Pos = i
+ t.TestKV()
+ t.post()
+}
+
+func (t *IteratorTesting) SeekInexact(i int) {
+ t.init()
+ t.setAct(IterSeek)
+ var key0 []byte
+ key1, _ := t.Index(i)
+ if i > 0 {
+ key0, _ = t.Index(i - 1)
+ }
+ key := BytesSeparator(key0, key1)
+ oldKey, _ := t.IndexOrNil(t.Pos)
+
+ ok := t.Iter.Seek(key)
+ Expect(t.Iter.Error()).ShouldNot(HaveOccurred())
+ Expect(ok).Should(BeTrue(), fmt.Sprintf("Seek from key %q to %q (%q), to pos %d, %s", oldKey, key, key1, i, t.text()))
+
+ t.Pos = i
+ t.TestKV()
+ t.post()
+}
+
+func (t *IteratorTesting) SeekKey(key []byte) {
+ t.init()
+ t.setAct(IterSeek)
+ oldKey, _ := t.IndexOrNil(t.Pos)
+ i := t.Search(key)
+
+ ok := t.Iter.Seek(key)
+ Expect(t.Iter.Error()).ShouldNot(HaveOccurred())
+ if i < t.Len() {
+ key_, _ := t.Index(i)
+ Expect(ok).Should(BeTrue(), fmt.Sprintf("Seek from key %q to %q (%q), to pos %d, %s", oldKey, key, key_, i, t.text()))
+ t.Pos = i
+ t.TestKV()
+ } else {
+ Expect(ok).ShouldNot(BeTrue(), fmt.Sprintf("Seek from key %q to %q, %s", oldKey, key, t.text()))
+ }
+
+ t.Pos = i
+ t.post()
+}
+
+func (t *IteratorTesting) SOI() {
+ t.init()
+ t.setAct(IterSOI)
+ Expect(t.Pos).Should(BeNumerically("<=", 0), t.Text())
+ for i := 0; i < 3; i++ {
+ t.Prev()
+ }
+ t.post()
+}
+
+func (t *IteratorTesting) EOI() {
+ t.init()
+ t.setAct(IterEOI)
+ Expect(t.Pos).Should(BeNumerically(">=", t.Len()-1), t.Text())
+ for i := 0; i < 3; i++ {
+ t.Next()
+ }
+ t.post()
+}
+
+func (t *IteratorTesting) WalkPrev(fn func(t *IteratorTesting)) {
+ t.init()
+ for old := t.Pos; t.Pos > 0; old = t.Pos {
+ fn(t)
+ Expect(t.Pos).Should(BeNumerically("<", old), t.Text())
+ }
+}
+
+func (t *IteratorTesting) WalkNext(fn func(t *IteratorTesting)) {
+ t.init()
+ for old := t.Pos; t.Pos < t.Len()-1; old = t.Pos {
+ fn(t)
+ Expect(t.Pos).Should(BeNumerically(">", old), t.Text())
+ }
+}
+
+func (t *IteratorTesting) PrevAll() {
+ t.WalkPrev(func(t *IteratorTesting) {
+ t.Prev()
+ })
+}
+
+func (t *IteratorTesting) NextAll() {
+ t.WalkNext(func(t *IteratorTesting) {
+ t.Next()
+ })
+}
+
+func DoIteratorTesting(t *IteratorTesting) {
+ if t.Rand == nil {
+ t.Rand = NewRand()
+ }
+ t.SOI()
+ t.NextAll()
+ t.First()
+ t.SOI()
+ t.NextAll()
+ t.EOI()
+ t.PrevAll()
+ t.Last()
+ t.EOI()
+ t.PrevAll()
+ t.SOI()
+
+ t.NextAll()
+ t.PrevAll()
+ t.NextAll()
+ t.Last()
+ t.PrevAll()
+ t.First()
+ t.NextAll()
+ t.EOI()
+
+ ShuffledIndex(t.Rand, t.Len(), 1, func(i int) {
+ t.Seek(i)
+ })
+
+ ShuffledIndex(t.Rand, t.Len(), 1, func(i int) {
+ t.SeekInexact(i)
+ })
+
+ ShuffledIndex(t.Rand, t.Len(), 1, func(i int) {
+ t.Seek(i)
+ if i%2 != 0 {
+ t.PrevAll()
+ t.SOI()
+ } else {
+ t.NextAll()
+ t.EOI()
+ }
+ })
+
+ for _, key := range []string{"", "foo", "bar", "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"} {
+ t.SeekKey([]byte(key))
+ }
+}