263 lines
5.3 KiB
Go
263 lines
5.3 KiB
Go
|
package test
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"reflect"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/blevesearch/bleve/index/store"
|
||
|
)
|
||
|
|
||
|
// tests which focus on the byte ownership
|
||
|
|
||
|
// CommonTestReaderOwnsGetBytes attempts to mutate the returned bytes
|
||
|
// first, while the reader is still open, second after that reader is
|
||
|
// closed, then the original key is read again, to ensure these
|
||
|
// modifications did not cause panic, or mutate the stored value
|
||
|
func CommonTestReaderOwnsGetBytes(t *testing.T, s store.KVStore) {
|
||
|
|
||
|
originalKey := []byte("key")
|
||
|
originalVal := []byte("val")
|
||
|
|
||
|
// open a writer
|
||
|
writer, err := s.Writer()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// write key/val
|
||
|
batch := writer.NewBatch()
|
||
|
batch.Set(originalKey, originalVal)
|
||
|
err = writer.ExecuteBatch(batch)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// close the writer
|
||
|
err = writer.Close()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// open a reader
|
||
|
reader, err := s.Reader()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// read key
|
||
|
returnedVal, err := reader.Get(originalKey)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// check that it is the expected value
|
||
|
if !reflect.DeepEqual(returnedVal, originalVal) {
|
||
|
t.Fatalf("expected value: %v for '%s', got %v", originalVal, originalKey, returnedVal)
|
||
|
}
|
||
|
|
||
|
// mutate the returned value with reader still open
|
||
|
for i := range returnedVal {
|
||
|
returnedVal[i] = '1'
|
||
|
}
|
||
|
|
||
|
// read the key again
|
||
|
returnedVal2, err := reader.Get(originalKey)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// check that it is the expected value
|
||
|
if !reflect.DeepEqual(returnedVal2, originalVal) {
|
||
|
t.Fatalf("expected value: %v for '%s', got %v", originalVal, originalKey, returnedVal2)
|
||
|
}
|
||
|
|
||
|
// close the reader
|
||
|
err = reader.Close()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// mutate the original returned value again
|
||
|
for i := range returnedVal {
|
||
|
returnedVal[i] = '2'
|
||
|
}
|
||
|
|
||
|
// open another reader
|
||
|
reader, err = s.Reader()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// read the key again
|
||
|
returnedVal3, err := reader.Get(originalKey)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// check that it is the expected value
|
||
|
if !reflect.DeepEqual(returnedVal3, originalVal) {
|
||
|
t.Fatalf("expected value: %v for '%s', got %v", originalVal, originalKey, returnedVal3)
|
||
|
}
|
||
|
|
||
|
// close the reader
|
||
|
err = reader.Close()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// finally check that the value we mutated still has what we set it to
|
||
|
for i := range returnedVal {
|
||
|
if returnedVal[i] != '2' {
|
||
|
t.Errorf("expected byte to be '2', got %v", returnedVal[i])
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func CommonTestWriterOwnsBytes(t *testing.T, s store.KVStore) {
|
||
|
|
||
|
keyBuffer := make([]byte, 5)
|
||
|
valBuffer := make([]byte, 5)
|
||
|
|
||
|
// open a writer
|
||
|
writer, err := s.Writer()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// write key/val pairs reusing same buffer
|
||
|
batch := writer.NewBatch()
|
||
|
for i := 0; i < 10; i++ {
|
||
|
keyBuffer[0] = 'k'
|
||
|
keyBuffer[1] = 'e'
|
||
|
keyBuffer[2] = 'y'
|
||
|
keyBuffer[3] = '-'
|
||
|
keyBuffer[4] = byte('0' + i)
|
||
|
valBuffer[0] = 'v'
|
||
|
valBuffer[1] = 'a'
|
||
|
valBuffer[2] = 'l'
|
||
|
valBuffer[3] = '-'
|
||
|
valBuffer[4] = byte('0' + i)
|
||
|
batch.Set(keyBuffer, valBuffer)
|
||
|
}
|
||
|
err = writer.ExecuteBatch(batch)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// close the writer
|
||
|
err = writer.Close()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// open a reader
|
||
|
reader, err := s.Reader()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// check that we can read back what we expect
|
||
|
allks := make([][]byte, 0)
|
||
|
allvs := make([][]byte, 0)
|
||
|
iter := reader.RangeIterator(nil, nil)
|
||
|
for iter.Valid() {
|
||
|
// if we want to keep bytes from iteration we must copy
|
||
|
k := iter.Key()
|
||
|
copyk := make([]byte, len(k))
|
||
|
copy(copyk, k)
|
||
|
allks = append(allks, copyk)
|
||
|
v := iter.Key()
|
||
|
copyv := make([]byte, len(v))
|
||
|
copy(copyv, v)
|
||
|
allvs = append(allvs, copyv)
|
||
|
iter.Next()
|
||
|
}
|
||
|
err = iter.Close()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if len(allks) != 10 {
|
||
|
t.Fatalf("expected 10 k/v pairs, got %d", len(allks))
|
||
|
}
|
||
|
for i, key := range allks {
|
||
|
val := allvs[i]
|
||
|
if !bytes.HasSuffix(key, []byte{byte('0' + i)}) {
|
||
|
t.Errorf("expected key %v to end in %d", key, []byte{byte('0' + i)})
|
||
|
}
|
||
|
if !bytes.HasSuffix(val, []byte{byte('0' + i)}) {
|
||
|
t.Errorf("expected val %v to end in %d", val, []byte{byte('0' + i)})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// close the reader
|
||
|
err = reader.Close()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// open a writer
|
||
|
writer, err = s.Writer()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// now delete using same approach
|
||
|
batch = writer.NewBatch()
|
||
|
for i := 0; i < 10; i++ {
|
||
|
keyBuffer[0] = 'k'
|
||
|
keyBuffer[1] = 'e'
|
||
|
keyBuffer[2] = 'y'
|
||
|
keyBuffer[3] = '-'
|
||
|
keyBuffer[4] = byte('0' + i)
|
||
|
batch.Delete(keyBuffer)
|
||
|
}
|
||
|
err = writer.ExecuteBatch(batch)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// close the writer
|
||
|
err = writer.Close()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// open a reader
|
||
|
reader, err = s.Reader()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// check that we can read back what we expect
|
||
|
allks = make([][]byte, 0)
|
||
|
iter = reader.RangeIterator(nil, nil)
|
||
|
for iter.Valid() {
|
||
|
// if we want to keep bytes from iteration we must copy
|
||
|
k := iter.Key()
|
||
|
copyk := make([]byte, len(k))
|
||
|
copy(copyk, k)
|
||
|
allks = append(allks, copyk)
|
||
|
v := iter.Key()
|
||
|
copyv := make([]byte, len(v))
|
||
|
copy(copyv, v)
|
||
|
allvs = append(allvs, copyv)
|
||
|
iter.Next()
|
||
|
}
|
||
|
err = iter.Close()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if len(allks) != 0 {
|
||
|
t.Fatalf("expected 0 k/v pairs remaining, got %d", len(allks))
|
||
|
}
|
||
|
|
||
|
// close the reader
|
||
|
err = reader.Close()
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
}
|