swarm/storage/localstore: add mock store option for chunk data

This commit is contained in:
Janos Guljas 2018-12-05 09:43:38 +01:00
parent 96409ff600
commit b782bfe464
7 changed files with 197 additions and 100 deletions

View file

@ -84,7 +84,7 @@ func New(path string) (s *Store, err error) {
value = append(b, fields.Data...) value = append(b, fields.Data...)
return value, nil return value, nil
}, },
DecodeValue: func(value []byte) (e shed.IndexItem, err error) { DecodeValue: func(keyItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8])) e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8]))
e.Data = value[8:] e.Data = value[8:]
return e, nil return e, nil
@ -108,7 +108,7 @@ func New(path string) (s *Store, err error) {
binary.BigEndian.PutUint64(b, uint64(fields.AccessTimestamp)) binary.BigEndian.PutUint64(b, uint64(fields.AccessTimestamp))
return b, nil return b, nil
}, },
DecodeValue: func(value []byte) (e shed.IndexItem, err error) { DecodeValue: func(keyItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
e.AccessTimestamp = int64(binary.BigEndian.Uint64(value)) e.AccessTimestamp = int64(binary.BigEndian.Uint64(value))
return e, nil return e, nil
}, },
@ -134,7 +134,7 @@ func New(path string) (s *Store, err error) {
EncodeValue: func(fields shed.IndexItem) (value []byte, err error) { EncodeValue: func(fields shed.IndexItem) (value []byte, err error) {
return nil, nil return nil, nil
}, },
DecodeValue: func(value []byte) (e shed.IndexItem, err error) { DecodeValue: func(keyItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
return e, nil return e, nil
}, },
}) })

View file

@ -77,7 +77,7 @@ type Index struct {
encodeKeyFunc func(fields IndexItem) (key []byte, err error) encodeKeyFunc func(fields IndexItem) (key []byte, err error)
decodeKeyFunc func(key []byte) (e IndexItem, err error) decodeKeyFunc func(key []byte) (e IndexItem, err error)
encodeValueFunc func(fields IndexItem) (value []byte, err error) encodeValueFunc func(fields IndexItem) (value []byte, err error)
decodeValueFunc func(value []byte) (e IndexItem, err error) decodeValueFunc func(keyFields IndexItem, value []byte) (e IndexItem, err error)
} }
// IndexFuncs structure defines functions for encoding and decoding // IndexFuncs structure defines functions for encoding and decoding
@ -86,7 +86,7 @@ type IndexFuncs struct {
EncodeKey func(fields IndexItem) (key []byte, err error) EncodeKey func(fields IndexItem) (key []byte, err error)
DecodeKey func(key []byte) (e IndexItem, err error) DecodeKey func(key []byte) (e IndexItem, err error)
EncodeValue func(fields IndexItem) (value []byte, err error) EncodeValue func(fields IndexItem) (value []byte, err error)
DecodeValue func(value []byte) (e IndexItem, err error) DecodeValue func(keyFields IndexItem, value []byte) (e IndexItem, err error)
} }
// NewIndex returns a new Index instance with defined name and // NewIndex returns a new Index instance with defined name and
@ -135,7 +135,7 @@ func (f Index) Get(keyFields IndexItem) (out IndexItem, err error) {
if err != nil { if err != nil {
return out, err return out, err
} }
out, err = f.decodeValueFunc(value) out, err = f.decodeValueFunc(keyFields, value)
if err != nil { if err != nil {
return out, err return out, err
} }
@ -210,15 +210,15 @@ func (f Index) IterateAll(fn IndexIterFunc) (err error) {
if key[0] != f.prefix[0] { if key[0] != f.prefix[0] {
break break
} }
keyIndexItem, err := f.decodeKeyFunc(key) keyItem, err := f.decodeKeyFunc(key)
if err != nil { if err != nil {
return err return err
} }
valueIndexItem, err := f.decodeValueFunc(it.Value()) valueItem, err := f.decodeValueFunc(keyItem, it.Value())
if err != nil { if err != nil {
return err return err
} }
stop, err := fn(keyIndexItem.Merge(valueIndexItem)) stop, err := fn(keyItem.Merge(valueItem))
if err != nil { if err != nil {
return err return err
} }
@ -244,15 +244,15 @@ func (f Index) IterateFrom(start IndexItem, fn IndexIterFunc) (err error) {
if key[0] != f.prefix[0] { if key[0] != f.prefix[0] {
break break
} }
keyIndexItem, err := f.decodeKeyFunc(key) keyItem, err := f.decodeKeyFunc(key)
if err != nil { if err != nil {
return err return err
} }
valueIndexItem, err := f.decodeValueFunc(it.Value()) valueItem, err := f.decodeValueFunc(keyItem, it.Value())
if err != nil { if err != nil {
return err return err
} }
stop, err := fn(keyIndexItem.Merge(valueIndexItem)) stop, err := fn(keyItem.Merge(valueItem))
if err != nil { if err != nil {
return err return err
} }

View file

@ -42,7 +42,7 @@ var retrievalIndexFuncs = IndexFuncs{
value = append(b, fields.Data...) value = append(b, fields.Data...)
return value, nil return value, nil
}, },
DecodeValue: func(value []byte) (e IndexItem, err error) { DecodeValue: func(keyItem IndexItem, value []byte) (e IndexItem, err error) {
e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8])) e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8]))
e.Data = value[8:] e.Data = value[8:]
return e, nil return e, nil

View file

@ -19,30 +19,74 @@ package localstore
import ( import (
"bytes" "bytes"
"context" "context"
"io/ioutil"
"testing" "testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/swarm/storage" "github.com/ethereum/go-ethereum/swarm/storage"
"github.com/ethereum/go-ethereum/swarm/storage/mock"
"github.com/ethereum/go-ethereum/swarm/storage/mock/mem"
) )
// TestAccessors tests most basic Put and Get functionalities // TestAccessors tests most basic Put and Get functionalities
// for different accessors. // for different accessors.
func TestAccessors(t *testing.T) { func TestAccessors(t *testing.T) {
db, cleanupFunc := newTestDB(t) db, cleanupFunc := newTestDB(t, nil)
defer cleanupFunc() defer cleanupFunc()
testAccessors(t, db) testAccessors(t, db)
} }
// TestAccessors_withRetrievalCompositeIndex tests most basic // TestAccessors_useRetrievalCompositeIndex tests most basic
// Put and Get functionalities for different accessors // Put and Get functionalities for different accessors
// by using retrieval composite index. // by using retrieval composite index.
func TestAccessors_withRetrievalCompositeIndex(t *testing.T) { func TestAccessors_useRetrievalCompositeIndex(t *testing.T) {
db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(true)) db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
defer cleanupFunc() defer cleanupFunc()
testAccessors(t, db) testAccessors(t, db)
} }
// TestAccessors_mockStore tests most basic Put and Get
// functionalities for different accessors with the mock store
// as the storage for chunk data.
func TestAccessors_mockStore(t *testing.T) {
globalStore := mem.NewGlobalStore()
addr := common.BytesToAddress(make([]byte, 32))
db, cleanupFunc := newTestDB(t, &Options{
MockStore: globalStore.NewNodeStore(addr),
})
defer cleanupFunc()
testAccessors(t, db)
// testAccessors leaves 5 chunks in global store
checkGlobalStoreChunkCount(t, globalStore, 5)
}
// TestAccessors_mockStore_useRetrievalCompositeIndex tests
// most basic Put and Get functionalities for different accessors
// with the mock store as the storage for chunk data and by using
// retrieval composite index.
func TestAccessors_mockStore_useRetrievalCompositeIndex(t *testing.T) {
globalStore := mem.NewGlobalStore()
addr := common.BytesToAddress(make([]byte, 32))
db, cleanupFunc := newTestDB(t, &Options{
MockStore: globalStore.NewNodeStore(addr),
UseRetrievalCompositeIndex: true,
})
defer cleanupFunc()
testAccessors(t, db)
// testAccessors leaves 5 chunks in global store
checkGlobalStoreChunkCount(t, globalStore, 5)
}
// testAccessors tests most basic Put and Get functionalities // testAccessors tests most basic Put and Get functionalities
// for different accessors. This test validates that the chunk // for different accessors. This test validates that the chunk
// is retrievable from the database, not if all indexes are set // is retrievable from the database, not if all indexes are set
@ -153,3 +197,17 @@ func testAccessors(t *testing.T, db *DB) {
} }
}) })
} }
// checkGlobalStoreChunkCount counts the number of chunks
// in a global mock store to validate it against the expected value.
func checkGlobalStoreChunkCount(t *testing.T, s mock.ImportExporter, want int) {
t.Helper()
n, err := s.Export(ioutil.Discard)
if err != nil {
t.Fatal(err)
}
if n != want {
t.Errorf("got %v chunks, want %v", n, want)
}
}

View file

@ -24,6 +24,7 @@ import (
"github.com/ethereum/go-ethereum/swarm/shed" "github.com/ethereum/go-ethereum/swarm/shed"
"github.com/ethereum/go-ethereum/swarm/storage" "github.com/ethereum/go-ethereum/swarm/storage"
"github.com/ethereum/go-ethereum/swarm/storage/mock"
) )
const ( const (
@ -73,36 +74,26 @@ type DB struct {
close chan struct{} // closed on Close, signals other goroutines to terminate close chan struct{} // closed on Close, signals other goroutines to terminate
} }
// Option is a function that sets optional field values on DB. // Options struct holds optional parameters for configuring DB.
// It is used as a variadic parameter to New constructor. type Options struct {
type Option func(*DB) UseRetrievalCompositeIndex bool
MockStore *mock.NodeStore
// WithRetrievalCompositeIndex is the optional variadic parameter to New constructor
// to use the single retrieval composite index instead two separate for data
// and access timestamp. This option is used for benchmarking this two types of
// retrieval schemas for performance. Composite retrieval index performes less seeks
// on retrieval as it has two times less key/value pairs then alternative approach,
// but it needs to write chunk data on every access timestamp change.
func WithRetrievalCompositeIndex(use bool) Option {
return func(db *DB) {
db.useRetrievalCompositeIndex = use
}
} }
// New returns a new DB. All fields and indexes are initialized // New returns a new DB. All fields and indexes are initialized
// and possible conflicts with schema from existing database is checked. // and possible conflicts with schema from existing database is checked.
// One goroutine for writing batches is created. // One goroutine for writing batches is created.
func New(path string, baseKey []byte, opts ...Option) (db *DB, err error) { func New(path string, baseKey []byte, o *Options) (db *DB, err error) {
db = &DB{ if o == nil {
baseKey: baseKey, o = new(Options)
batch: newBatch(),
writeTrigger: make(chan struct{}, 1),
close: make(chan struct{}),
writeDone: make(chan struct{}),
} }
db = &DB{
for _, o := range opts { baseKey: baseKey,
o(db) useRetrievalCompositeIndex: o.UseRetrievalCompositeIndex,
batch: newBatch(),
writeTrigger: make(chan struct{}, 1),
close: make(chan struct{}),
writeDone: make(chan struct{}),
} }
db.shed, err = shed.NewDB(path) db.shed, err = shed.NewDB(path)
@ -119,6 +110,42 @@ func New(path string, baseKey []byte, opts ...Option) (db *DB, err error) {
return nil, err return nil, err
} }
if db.useRetrievalCompositeIndex { if db.useRetrievalCompositeIndex {
var (
encodeValueFunc func(fields shed.IndexItem) (value []byte, err error)
decodeValueFunc func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error)
)
if o.MockStore != nil {
encodeValueFunc = func(fields shed.IndexItem) (value []byte, err error) {
b := make([]byte, 16)
binary.BigEndian.PutUint64(b[:8], uint64(fields.StoreTimestamp))
binary.BigEndian.PutUint64(b[8:16], uint64(fields.AccessTimestamp))
err = o.MockStore.Put(fields.Address, fields.Data)
if err != nil {
return nil, err
}
return b, nil
}
decodeValueFunc = func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8]))
e.AccessTimestamp = int64(binary.BigEndian.Uint64(value[8:16]))
e.Data, err = o.MockStore.Get(keyIndexItem.Address)
return e, err
}
} else {
encodeValueFunc = func(fields shed.IndexItem) (value []byte, err error) {
b := make([]byte, 16)
binary.BigEndian.PutUint64(b[:8], uint64(fields.StoreTimestamp))
binary.BigEndian.PutUint64(b[8:16], uint64(fields.AccessTimestamp))
value = append(b, fields.Data...)
return value, nil
}
decodeValueFunc = func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8]))
e.AccessTimestamp = int64(binary.BigEndian.Uint64(value[8:16]))
e.Data = value[16:]
return e, nil
}
}
// Index storing chunk data with stored and access timestamps. // Index storing chunk data with stored and access timestamps.
db.retrievalCompositeIndex, err = db.shed.NewIndex("Hash->StoredTimestamp|AccessTimestamp|Data", shed.IndexFuncs{ db.retrievalCompositeIndex, err = db.shed.NewIndex("Hash->StoredTimestamp|AccessTimestamp|Data", shed.IndexFuncs{
EncodeKey: func(fields shed.IndexItem) (key []byte, err error) { EncodeKey: func(fields shed.IndexItem) (key []byte, err error) {
@ -128,24 +155,45 @@ func New(path string, baseKey []byte, opts ...Option) (db *DB, err error) {
e.Address = key e.Address = key
return e, nil return e, nil
}, },
EncodeValue: func(fields shed.IndexItem) (value []byte, err error) { EncodeValue: encodeValueFunc,
b := make([]byte, 16) DecodeValue: decodeValueFunc,
binary.BigEndian.PutUint64(b[:8], uint64(fields.StoreTimestamp))
binary.BigEndian.PutUint64(b[8:16], uint64(fields.AccessTimestamp))
value = append(b, fields.Data...)
return value, nil
},
DecodeValue: func(value []byte) (e shed.IndexItem, err error) {
e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8]))
e.AccessTimestamp = int64(binary.BigEndian.Uint64(value[8:16]))
e.Data = value[16:]
return e, nil
},
}) })
if err != nil { if err != nil {
return nil, err return nil, err
} }
} else { } else {
var (
encodeValueFunc func(fields shed.IndexItem) (value []byte, err error)
decodeValueFunc func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error)
)
if o.MockStore != nil {
encodeValueFunc = func(fields shed.IndexItem) (value []byte, err error) {
b := make([]byte, 8)
binary.BigEndian.PutUint64(b, uint64(fields.StoreTimestamp))
err = o.MockStore.Put(fields.Address, fields.Data)
if err != nil {
return nil, err
}
return b, nil
}
decodeValueFunc = func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8]))
e.Data, err = o.MockStore.Get(keyIndexItem.Address)
return e, err
}
} else {
encodeValueFunc = func(fields shed.IndexItem) (value []byte, err error) {
b := make([]byte, 8)
binary.BigEndian.PutUint64(b, uint64(fields.StoreTimestamp))
value = append(b, fields.Data...)
return value, nil
}
decodeValueFunc = func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8]))
e.Data = value[8:]
return e, nil
}
}
// Index storing actual chunk address, data and store timestamp. // Index storing actual chunk address, data and store timestamp.
db.retrievalDataIndex, err = db.shed.NewIndex("Address->StoreTimestamp|Data", shed.IndexFuncs{ db.retrievalDataIndex, err = db.shed.NewIndex("Address->StoreTimestamp|Data", shed.IndexFuncs{
EncodeKey: func(fields shed.IndexItem) (key []byte, err error) { EncodeKey: func(fields shed.IndexItem) (key []byte, err error) {
@ -155,17 +203,8 @@ func New(path string, baseKey []byte, opts ...Option) (db *DB, err error) {
e.Address = key e.Address = key
return e, nil return e, nil
}, },
EncodeValue: func(fields shed.IndexItem) (value []byte, err error) { EncodeValue: encodeValueFunc,
b := make([]byte, 8) DecodeValue: decodeValueFunc,
binary.BigEndian.PutUint64(b, uint64(fields.StoreTimestamp))
value = append(b, fields.Data...)
return value, nil
},
DecodeValue: func(value []byte) (e shed.IndexItem, err error) {
e.StoreTimestamp = int64(binary.BigEndian.Uint64(value[:8]))
e.Data = value[8:]
return e, nil
},
}) })
if err != nil { if err != nil {
return nil, err return nil, err
@ -185,7 +224,7 @@ func New(path string, baseKey []byte, opts ...Option) (db *DB, err error) {
binary.BigEndian.PutUint64(b, uint64(fields.AccessTimestamp)) binary.BigEndian.PutUint64(b, uint64(fields.AccessTimestamp))
return b, nil return b, nil
}, },
DecodeValue: func(value []byte) (e shed.IndexItem, err error) { DecodeValue: func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
e.AccessTimestamp = int64(binary.BigEndian.Uint64(value)) e.AccessTimestamp = int64(binary.BigEndian.Uint64(value))
return e, nil return e, nil
}, },
@ -211,7 +250,7 @@ func New(path string, baseKey []byte, opts ...Option) (db *DB, err error) {
EncodeValue: func(fields shed.IndexItem) (value []byte, err error) { EncodeValue: func(fields shed.IndexItem) (value []byte, err error) {
return nil, nil return nil, nil
}, },
DecodeValue: func(value []byte) (e shed.IndexItem, err error) { DecodeValue: func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
return e, nil return e, nil
}, },
}) })
@ -234,7 +273,7 @@ func New(path string, baseKey []byte, opts ...Option) (db *DB, err error) {
EncodeValue: func(fields shed.IndexItem) (value []byte, err error) { EncodeValue: func(fields shed.IndexItem) (value []byte, err error) {
return nil, nil return nil, nil
}, },
DecodeValue: func(value []byte) (e shed.IndexItem, err error) { DecodeValue: func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
return e, nil return e, nil
}, },
}) })
@ -259,7 +298,7 @@ func New(path string, baseKey []byte, opts ...Option) (db *DB, err error) {
EncodeValue: func(fields shed.IndexItem) (value []byte, err error) { EncodeValue: func(fields shed.IndexItem) (value []byte, err error) {
return nil, nil return nil, nil
}, },
DecodeValue: func(value []byte) (e shed.IndexItem, err error) { DecodeValue: func(keyIndexItem shed.IndexItem, value []byte) (e shed.IndexItem, err error) {
return e, nil return e, nil
}, },
}) })

View file

@ -26,12 +26,12 @@ import (
"github.com/ethereum/go-ethereum/swarm/storage" "github.com/ethereum/go-ethereum/swarm/storage"
) )
// TestWithRetrievalCompositeIndex checks if optional argument // TestDB_useRetrievalCompositeIndex checks if optional argument
// WithRetrievalCompositeIndex to New constructor is setting the // WithRetrievalCompositeIndex to New constructor is setting the
// correct state. // correct state.
func TestWithRetrievalCompositeIndex(t *testing.T) { func TestDB_useRetrievalCompositeIndex(t *testing.T) {
t.Run("set true", func(t *testing.T) { t.Run("set true", func(t *testing.T) {
db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(true)) db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
defer cleanupFunc() defer cleanupFunc()
if !db.useRetrievalCompositeIndex { if !db.useRetrievalCompositeIndex {
@ -39,7 +39,7 @@ func TestWithRetrievalCompositeIndex(t *testing.T) {
} }
}) })
t.Run("set false", func(t *testing.T) { t.Run("set false", func(t *testing.T) {
db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(false)) db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: false})
defer cleanupFunc() defer cleanupFunc()
if db.useRetrievalCompositeIndex { if db.useRetrievalCompositeIndex {
@ -47,7 +47,7 @@ func TestWithRetrievalCompositeIndex(t *testing.T) {
} }
}) })
t.Run("unset", func(t *testing.T) { t.Run("unset", func(t *testing.T) {
db, cleanupFunc := newTestDB(t) db, cleanupFunc := newTestDB(t, nil)
defer cleanupFunc() defer cleanupFunc()
if db.useRetrievalCompositeIndex { if db.useRetrievalCompositeIndex {
@ -59,7 +59,7 @@ func TestWithRetrievalCompositeIndex(t *testing.T) {
// newTestDB is a helper function that constructs a // newTestDB is a helper function that constructs a
// temporary database and returns a cleanup function that must // temporary database and returns a cleanup function that must
// be called to remove the data. // be called to remove the data.
func newTestDB(t *testing.T, opts ...Option) (db *DB, cleanupFunc func()) { func newTestDB(t *testing.T, o *Options) (db *DB, cleanupFunc func()) {
t.Helper() t.Helper()
dir, err := ioutil.TempDir("", "shed-test") dir, err := ioutil.TempDir("", "shed-test")
@ -71,7 +71,7 @@ func newTestDB(t *testing.T, opts ...Option) (db *DB, cleanupFunc func()) {
if _, err := rand.Read(baseKey); err != nil { if _, err := rand.Read(baseKey); err != nil {
t.Fatal(err) t.Fatal(err)
} }
db, err = New(dir, baseKey, opts...) db, err = New(dir, baseKey, o)
if err != nil { if err != nil {
cleanupFunc() cleanupFunc()
t.Fatal(err) t.Fatal(err)

View file

@ -31,17 +31,17 @@ import (
// TestModeSyncing validates internal data operations and state // TestModeSyncing validates internal data operations and state
// for ModeSyncing on DB with default configuration. // for ModeSyncing on DB with default configuration.
func TestModeSyncing(t *testing.T) { func TestModeSyncing(t *testing.T) {
db, cleanupFunc := newTestDB(t) db, cleanupFunc := newTestDB(t, nil)
defer cleanupFunc() defer cleanupFunc()
testModeSyncingValues(t, db) testModeSyncingValues(t, db)
} }
// TestModeSyncing_withRetrievalCompositeIndex validates internal // TestModeSyncing_useRetrievalCompositeIndex validates internal
// data operations and state for ModeSyncing on DB with // data operations and state for ModeSyncing on DB with
// retrieval composite index enabled. // retrieval composite index enabled.
func TestModeSyncing_withRetrievalCompositeIndex(t *testing.T) { func TestModeSyncing_useRetrievalCompositeIndex(t *testing.T) {
db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(true)) db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
defer cleanupFunc() defer cleanupFunc()
testModeSyncingValues(t, db) testModeSyncingValues(t, db)
@ -81,17 +81,17 @@ func testModeSyncingValues(t *testing.T, db *DB) {
// TestModeUpload validates internal data operations and state // TestModeUpload validates internal data operations and state
// for ModeUpload on DB with default configuration. // for ModeUpload on DB with default configuration.
func TestModeUpload(t *testing.T) { func TestModeUpload(t *testing.T) {
db, cleanupFunc := newTestDB(t) db, cleanupFunc := newTestDB(t, nil)
defer cleanupFunc() defer cleanupFunc()
testModeUploadValues(t, db) testModeUploadValues(t, db)
} }
// TestModeUpload_withRetrievalCompositeIndex validates internal // TestModeUpload_useRetrievalCompositeIndex validates internal
// data operations and state for ModeUpload on DB with // data operations and state for ModeUpload on DB with
// retrieval composite index enabled. // retrieval composite index enabled.
func TestModeUpload_withRetrievalCompositeIndex(t *testing.T) { func TestModeUpload_useRetrievalCompositeIndex(t *testing.T) {
db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(true)) db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
defer cleanupFunc() defer cleanupFunc()
testModeUploadValues(t, db) testModeUploadValues(t, db)
@ -133,17 +133,17 @@ func testModeUploadValues(t *testing.T, db *DB) {
// TestModeRequest validates internal data operations and state // TestModeRequest validates internal data operations and state
// for ModeRequest on DB with default configuration. // for ModeRequest on DB with default configuration.
func TestModeRequest(t *testing.T) { func TestModeRequest(t *testing.T) {
db, cleanupFunc := newTestDB(t) db, cleanupFunc := newTestDB(t, nil)
defer cleanupFunc() defer cleanupFunc()
testModeRequestValues(t, db) testModeRequestValues(t, db)
} }
// TestModeRequest_withRetrievalCompositeIndex validates internal // TestModeRequest_useRetrievalCompositeIndex validates internal
// data operations and state for ModeRequest on DB with // data operations and state for ModeRequest on DB with
// retrieval composite index enabled. // retrieval composite index enabled.
func TestModeRequest_withRetrievalCompositeIndex(t *testing.T) { func TestModeRequest_useRetrievalCompositeIndex(t *testing.T) {
db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(true)) db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
defer cleanupFunc() defer cleanupFunc()
testModeRequestValues(t, db) testModeRequestValues(t, db)
@ -174,17 +174,17 @@ func testModeRequestValues(t *testing.T, db *DB) {
// TestModeSynced validates internal data operations and state // TestModeSynced validates internal data operations and state
// for ModeSynced on DB with default configuration. // for ModeSynced on DB with default configuration.
func TestModeSynced(t *testing.T) { func TestModeSynced(t *testing.T) {
db, cleanupFunc := newTestDB(t) db, cleanupFunc := newTestDB(t, nil)
defer cleanupFunc() defer cleanupFunc()
testModeSyncedValues(t, db) testModeSyncedValues(t, db)
} }
// TestModeSynced_withRetrievalCompositeIndex validates internal // TestModeSynced_useRetrievalCompositeIndex validates internal
// data operations and state for ModeSynced on DB with // data operations and state for ModeSynced on DB with
// retrieval composite index enabled. // retrieval composite index enabled.
func TestModeSynced_withRetrievalCompositeIndex(t *testing.T) { func TestModeSynced_useRetrievalCompositeIndex(t *testing.T) {
db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(true)) db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
defer cleanupFunc() defer cleanupFunc()
testModeSyncedValues(t, db) testModeSyncedValues(t, db)
@ -224,17 +224,17 @@ func testModeSyncedValues(t *testing.T, db *DB) {
// TestModeAccess validates internal data operations and state // TestModeAccess validates internal data operations and state
// for ModeAccess on DB with default configuration. // for ModeAccess on DB with default configuration.
func TestModeAccess(t *testing.T) { func TestModeAccess(t *testing.T) {
db, cleanupFunc := newTestDB(t) db, cleanupFunc := newTestDB(t, nil)
defer cleanupFunc() defer cleanupFunc()
testModeAccessValues(t, db) testModeAccessValues(t, db)
} }
// TestModeAccess_withRetrievalCompositeIndex validates internal // TestModeAccess_useRetrievalCompositeIndex validates internal
// data operations and state for ModeAccess on DB with // data operations and state for ModeAccess on DB with
// retrieval composite index enabled. // retrieval composite index enabled.
func TestModeAccess_withRetrievalCompositeIndex(t *testing.T) { func TestModeAccess_useRetrievalCompositeIndex(t *testing.T) {
db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(true)) db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
defer cleanupFunc() defer cleanupFunc()
testModeAccessValues(t, db) testModeAccessValues(t, db)
@ -310,17 +310,17 @@ func testModeAccessValues(t *testing.T, db *DB) {
// TestModeRemoval validates internal data operations and state // TestModeRemoval validates internal data operations and state
// for ModeRemoval on DB with default configuration. // for ModeRemoval on DB with default configuration.
func TestModeRemoval(t *testing.T) { func TestModeRemoval(t *testing.T) {
db, cleanupFunc := newTestDB(t) db, cleanupFunc := newTestDB(t, nil)
defer cleanupFunc() defer cleanupFunc()
testModeRemovalValues(t, db) testModeRemovalValues(t, db)
} }
// TestModeRemoval_withRetrievalCompositeIndex validates internal // TestModeRemoval_useRetrievalCompositeIndex validates internal
// data operations and state for ModeRemoval on DB with // data operations and state for ModeRemoval on DB with
// retrieval composite index enabled. // retrieval composite index enabled.
func TestModeRemoval_withRetrievalCompositeIndex(t *testing.T) { func TestModeRemoval_useRetrievalCompositeIndex(t *testing.T) {
db, cleanupFunc := newTestDB(t, WithRetrievalCompositeIndex(true)) db, cleanupFunc := newTestDB(t, &Options{UseRetrievalCompositeIndex: true})
defer cleanupFunc() defer cleanupFunc()
testModeRemovalValues(t, db) testModeRemovalValues(t, db)