This repository has been archived on 2022-07-30. You can view files and clone it, but cannot push or open issues/pull-requests.
mdb/kvstore/store_test.go

118 lines
2.3 KiB
Go

package kvstore
import (
"fmt"
"math/rand"
"os"
"reflect"
"testing"
"time"
)
// ----------------------------------------------------------------------------
func (kv *KV) waitForSeqNum(x uint64) {
for {
seqNum := kv.MaxSeqNum()
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 {
l1 := []record{}
kv.replay(0, func(rec record) error {
l1 = append(l1, rec)
return nil
})
idx := -1
err := rhs.replay(0, func(rec record) error {
idx++
if !reflect.DeepEqual(rec, l1[idx]) {
return fmt.Errorf("Records not equal: %d %v %v", idx, rec, l1[idx])
}
return nil
})
if err != nil {
return err
}
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, 11, 12, 13, 14, 15, 16}
)
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)
}
})
}