100 lines
2.0 KiB
Go
100 lines
2.0 KiB
Go
|
package kvstore
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"math/rand"
|
||
|
"os"
|
||
|
"testing"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
func (kv *KV) waitForSeqNum(x uint64) {
|
||
|
for {
|
||
|
seqNum := kv.MaxSeqNum()
|
||
|
//log.Printf("%d/%d", seqNum, x)
|
||
|
if seqNum == x {
|
||
|
return
|
||
|
}
|
||
|
time.Sleep(100 * time.Millisecond)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (kv *KV) dump(collection string) map[uint64]string {
|
||
|
m := map[uint64]string{}
|
||
|
kv.Iterate(collection, func(id uint64, data []byte) {
|
||
|
m[id] = string(data)
|
||
|
})
|
||
|
return m
|
||
|
}
|
||
|
|
||
|
func (kv *KV) equals(collection string, expected map[uint64]string) error {
|
||
|
m := kv.dump(collection)
|
||
|
if len(m) != len(expected) {
|
||
|
return fmt.Errorf("Expected %d values but found %d", len(expected), len(m))
|
||
|
}
|
||
|
|
||
|
for key, exp := range expected {
|
||
|
val, ok := m[key]
|
||
|
if !ok {
|
||
|
return fmt.Errorf("Value for %d not found.", key)
|
||
|
}
|
||
|
if val != exp {
|
||
|
return fmt.Errorf("%d: Expected %s but found %s.", key, exp, val)
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (kv *KV) equalsKV(collection string, rhs *KV) error {
|
||
|
return kv.equals(collection, rhs.dump(collection))
|
||
|
}
|
||
|
|
||
|
// Collection one of ("a", "b", "c").
|
||
|
// ID one of [1,10]
|
||
|
var (
|
||
|
randCollections = []string{"a", "b", "c"}
|
||
|
randIDs = []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||
|
)
|
||
|
|
||
|
func (kv *KV) randAction() {
|
||
|
c := randCollections[rand.Intn(len(randCollections))]
|
||
|
id := randIDs[rand.Intn(len(randIDs))]
|
||
|
|
||
|
// Mostly stores.
|
||
|
if rand.Float64() < 0.9 {
|
||
|
kv.Store(c, id, randBytes())
|
||
|
} else {
|
||
|
kv.Delete(c, id)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
func TestKV(t *testing.T) {
|
||
|
run := func(name string, inner func(t *testing.T, kv *KV)) {
|
||
|
dir, _ := os.MkdirTemp("", "")
|
||
|
defer os.RemoveAll(dir)
|
||
|
kv := NewPrimary(dir)
|
||
|
defer kv.Close()
|
||
|
|
||
|
inner(t, kv)
|
||
|
}
|
||
|
|
||
|
run("simple", func(t *testing.T, kv *KV) {
|
||
|
kv.Store("a", 1, _b("Hello"))
|
||
|
kv.Store("a", 2, _b("World"))
|
||
|
|
||
|
kv.waitForSeqNum(2)
|
||
|
|
||
|
err := kv.equals("a", map[uint64]string{
|
||
|
1: "Hello",
|
||
|
2: "World",
|
||
|
})
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
})
|
||
|
}
|