Skip to content

Commit

Permalink
Use in-memory BBolt storage for test Storage Engines (#2385)
Browse files Browse the repository at this point in the history
  • Loading branch information
reinkrul authored Jul 31, 2023
1 parent 37283bf commit f6c703e
Show file tree
Hide file tree
Showing 12 changed files with 51 additions and 53 deletions.
10 changes: 3 additions & 7 deletions network/dag/consistency_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,14 @@ import (
"context"
"encoding/binary"
"github.com/magiconair/properties/assert"
"github.com/nuts-foundation/go-stoabs"
"github.com/nuts-foundation/go-stoabs/bbolt"
"github.com/nuts-foundation/nuts-node/crypto/hash"
"github.com/nuts-foundation/nuts-node/network/dag/tree"
"github.com/nuts-foundation/nuts-node/storage"
"github.com/nuts-foundation/nuts-node/test"
"github.com/nuts-foundation/nuts-node/test/io"
"github.com/stretchr/testify/require"
"go.uber.org/goleak"
"path/filepath"
"path"
"testing"
"time"
)
Expand Down Expand Up @@ -139,10 +138,7 @@ func createXorTreeRepairState(t testing.TB, tx Transaction) *state {

func createStoppedState(t testing.TB) *state {
testDir := io.TestDirectory(t)
bboltStore, err := bbolt.CreateBBoltStore(filepath.Join(testDir, "test_state"), stoabs.WithNoSync())
if err != nil {
t.Fatal("failed to create store: ", err)
}
bboltStore := storage.CreateTestBBoltStore(t, path.Join(testDir, "test.db"))
s, err := NewState(bboltStore)
require.NoError(t, err)
t.Cleanup(func() {
Expand Down
33 changes: 15 additions & 18 deletions network/dag/notifier_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import (
"encoding/json"
"errors"
"github.com/nuts-foundation/go-stoabs"
"github.com/nuts-foundation/go-stoabs/bbolt"
"github.com/nuts-foundation/nuts-node/crypto/hash"
"github.com/nuts-foundation/nuts-node/storage"
"github.com/nuts-foundation/nuts-node/test"
"github.com/nuts-foundation/nuts-node/test/io"
"github.com/prometheus/client_golang/prometheus"
Expand Down Expand Up @@ -123,7 +123,7 @@ func TestNotifier_Save(t *testing.T) {
}
persistentSubscriber := func(t *testing.T, additionalOptions ...NotifierOption) (*notifier, stoabs.KVStore) {
filePath := io.TestDirectory(t)
kvStore, _ := bbolt.CreateBBoltStore(path.Join(filePath, "test.db"))
kvStore := storage.CreateTestBBoltStore(t, path.Join(filePath, "test.db"))
options := append(additionalOptions, WithPersistency(kvStore))
s := NewNotifier(t.Name(), dummyFunc, options...)
return s.(*notifier), kvStore
Expand Down Expand Up @@ -154,12 +154,9 @@ func TestNotifier_Save(t *testing.T) {
s, _ := persistentSubscriber(t)

testDir := io.TestDirectory(t)
dummyDB, err := bbolt.CreateBBoltStore(path.Join(testDir, "test.db"))
if err != nil {
t.Fatal(err)
}
dummyDB := storage.CreateTestBBoltStore(t, path.Join(testDir, "test.db"))

err = dummyDB.Write(ctx, func(tx stoabs.WriteTx) error {
err := dummyDB.Write(ctx, func(tx stoabs.WriteTx) error {
return s.Save(tx, event)
})

Expand All @@ -168,7 +165,7 @@ func TestNotifier_Save(t *testing.T) {

t.Run("Not stored if no persistency", func(t *testing.T) {
filePath := io.TestDirectory(t)
kvStore, _ := bbolt.CreateBBoltStore(path.Join(filePath, "test.db"))
kvStore := storage.CreateTestBBoltStore(t, path.Join(filePath, "test.db"))
s := NewNotifier(t.Name(), dummyFunc)

err := kvStore.Write(ctx, func(tx stoabs.WriteTx) error {
Expand Down Expand Up @@ -306,7 +303,7 @@ func TestNotifier_Notify(t *testing.T) {
t.Run("OK - updates DB", func(t *testing.T) {
filePath := io.TestDirectory(t)
transaction, _, _ := CreateTestTransaction(0)
kvStore, _ := bbolt.CreateBBoltStore(path.Join(filePath, "test.db"))
kvStore := storage.CreateTestBBoltStore(t, path.Join(filePath, "test.db"))
counter := callbackCounter{}
event := Event{Hash: hash.EmptyHash(), Transaction: transaction}
now := time.Now()
Expand Down Expand Up @@ -341,7 +338,7 @@ func TestNotifier_Notify(t *testing.T) {
t.Run("OK - stops when no longer available in DB", func(t *testing.T) {
filePath := io.TestDirectory(t)
transaction, _, _ := CreateTestTransaction(0)
kvStore, _ := bbolt.CreateBBoltStore(path.Join(filePath, "test.db"))
kvStore := storage.CreateTestBBoltStore(t, path.Join(filePath, "test.db"))
counter := callbackCounter{}
event := Event{Hash: hash.EmptyHash(), Transaction: transaction}
s := NewNotifier(t.Name(), counter.callback, WithPersistency(kvStore), WithRetryDelay(time.Millisecond)).(*notifier)
Expand All @@ -363,7 +360,7 @@ func TestNotifier_Run(t *testing.T) {
ctx := context.Background()
filePath := io.TestDirectory(t)
transaction, _, _ := CreateTestTransaction(0)
kvStore, _ := bbolt.CreateBBoltStore(path.Join(filePath, "test.db"))
kvStore := storage.CreateTestBBoltStore(t, path.Join(filePath, "test.db"))
counter := callbackCounter{}
payload := "payload"
event := Event{
Expand Down Expand Up @@ -393,7 +390,7 @@ func TestNotifier_VariousFlows(t *testing.T) {
event := Event{Hash: hash.EmptyHash(), Transaction: transaction}
t.Run("Happy flow", func(t *testing.T) {
filePath := io.TestDirectory(t)
kvStore, _ := bbolt.CreateBBoltStore(path.Join(filePath, "test.db"))
kvStore := storage.CreateTestBBoltStore(t, path.Join(filePath, "test.db"))
counter := callbackCounter{}
s := NewNotifier(t.Name(), counter.callback, WithPersistency(kvStore), WithRetryDelay(10*time.Millisecond)).(*notifier)
defer s.Close()
Expand All @@ -420,7 +417,7 @@ func TestNotifier_VariousFlows(t *testing.T) {

t.Run("notifier marks event as finished", func(t *testing.T) {
filePath := io.TestDirectory(t)
kvStore, _ := bbolt.CreateBBoltStore(path.Join(filePath, "test.db"))
kvStore := storage.CreateTestBBoltStore(t, path.Join(filePath, "test.db"))
counter := callbackCounter{}
s := NewNotifier(t.Name(), counter.callbackFinished, WithPersistency(kvStore), WithRetryDelay(10*time.Millisecond)).(*notifier)
defer s.Close()
Expand All @@ -444,7 +441,7 @@ func TestNotifier_VariousFlows(t *testing.T) {

t.Run("fails and stops at max attempts", func(t *testing.T) {
filePath := io.TestDirectory(t)
kvStore, _ := bbolt.CreateBBoltStore(path.Join(filePath, "test.db"))
kvStore := storage.CreateTestBBoltStore(t, path.Join(filePath, "test.db"))
counter := callbackCounter{}
notifiedCounter := &prometheusCounter{}
event := Event{Hash: hash.EmptyHash(), Transaction: transaction, Retries: 95}
Expand Down Expand Up @@ -478,7 +475,7 @@ func TestNotifier_VariousFlows(t *testing.T) {

t.Run("fails on fatal event before scheduling retry ", func(t *testing.T) {
filePath := io.TestDirectory(t)
kvStore, _ := bbolt.CreateBBoltStore(path.Join(filePath, "test.db"))
kvStore := storage.CreateTestBBoltStore(t, path.Join(filePath, "test.db"))
counter := callbackCounter{}
counter.setCallbackError(EventFatal{errors.New("fatal error")})
s := NewNotifier(t.Name(), counter.callbackFailure, WithPersistency(kvStore), WithRetryDelay(time.Nanosecond)).(*notifier)
Expand Down Expand Up @@ -510,7 +507,7 @@ func TestNotifier_VariousFlows(t *testing.T) {

t.Run("fails on fatal event while retrying", func(t *testing.T) {
filePath := io.TestDirectory(t)
kvStore, _ := bbolt.CreateBBoltStore(path.Join(filePath, "test.db"))
kvStore := storage.CreateTestBBoltStore(t, path.Join(filePath, "test.db"))
counter := callbackCounter{}
s := NewNotifier(t.Name(), counter.callbackFailure, WithPersistency(kvStore), WithRetryDelay(time.Millisecond)).(*notifier)
defer s.Close()
Expand Down Expand Up @@ -544,7 +541,7 @@ func TestNotifier_VariousFlows(t *testing.T) {

t.Run("OK - incomplete event logs error", func(t *testing.T) {
counter := callbackCounter{}
kvStore, _ := bbolt.CreateBBoltStore(path.Join(t.TempDir(), "test.db"))
kvStore := storage.CreateTestBBoltStore(t, path.Join(t.TempDir(), "test.db"))
s := NewNotifier(t.Name(), counter.callback, WithRetryDelay(time.Millisecond), WithPersistency(kvStore)).(*notifier)
defer s.Close()

Expand All @@ -571,7 +568,7 @@ func TestNotifier_VariousFlows(t *testing.T) {
assert.Equal(t, errEventIncomplete.Error(), events[0].Error)
})
t.Run("OK - completed event does not cause an error", func(t *testing.T) {
kvStore, _ := bbolt.CreateBBoltStore(path.Join(t.TempDir(), "test.db"))
kvStore := storage.CreateTestBBoltStore(t, path.Join(t.TempDir(), "test.db"))
s := NewNotifier(t.Name(), nil, WithPersistency(kvStore)).(*notifier)

// event is missing from kvStore, this should be interpreted as the event is completed
Expand Down
9 changes: 3 additions & 6 deletions network/dag/state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,19 @@ import (
"errors"
"fmt"
"github.com/nuts-foundation/go-stoabs"
"github.com/nuts-foundation/nuts-node/storage"
"github.com/nuts-foundation/nuts-node/test"
io_prometheus_client "github.com/prometheus/client_model/go"
"github.com/stretchr/testify/require"
"go.uber.org/atomic"
"go.uber.org/mock/gomock"
"math"
"path/filepath"
"path"
"sort"
"strings"
"testing"
"time"

"github.com/nuts-foundation/go-stoabs/bbolt"
"github.com/nuts-foundation/nuts-node/crypto/hash"
"github.com/nuts-foundation/nuts-node/network/dag/tree"
"github.com/nuts-foundation/nuts-node/test/io"
Expand Down Expand Up @@ -460,10 +460,7 @@ func Test_createStore(t *testing.T) {

func createState(t testing.TB, verifier ...Verifier) State {
testDir := io.TestDirectory(t)
bboltStore, err := bbolt.CreateBBoltStore(filepath.Join(testDir, "test_state"), stoabs.WithNoSync())
if err != nil {
t.Fatal("failed to create store: ", err)
}
bboltStore := storage.CreateTestBBoltStore(t, path.Join(testDir, "test.db"))
s, err := NewState(bboltStore, verifier...)
if err != nil {
t.Fatal("failed to create store: ", err)
Expand Down
4 changes: 2 additions & 2 deletions network/network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,7 @@ func TestNetwork_Subscribers(t *testing.T) {
func TestNetwork_CleanupSubscriberEvents(t *testing.T) {
ctrl := gomock.NewController(t)
cxt := createNetwork(t, ctrl)
kvStore, _ := storage.NewTestStorageEngine(t.TempDir()).GetProvider("test").GetKVStore("test", storage.PersistentStorageClass)
kvStore, _ := storage.NewTestStorageEngine(t).GetProvider("test").GetKVStore("test", storage.PersistentStorageClass)
notifier := dag.NewNotifier("test", func(event dag.Event) (bool, error) {
return true, nil
}, dag.WithPersistency(kvStore))
Expand Down Expand Up @@ -1323,7 +1323,7 @@ func createNetwork(t *testing.T, ctrl *gomock.Controller, cfgFn ...func(config *
docFinder := vdrTypes.NewMockDocFinder(ctrl)
didStore := didstore.NewMockStore(ctrl)
eventPublisher := events.NewMockEvent(ctrl)
storageEngine := storage.NewTestStorageEngine(io.TestDirectory(t))
storageEngine := storage.NewTestStorageEngine(t)
t.Cleanup(func() {
_ = storageEngine.Shutdown()
})
Expand Down
2 changes: 1 addition & 1 deletion network/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func NewTestNetworkInstance(t *testing.T) *Network {
store,
cryptoInstance,
eventPublisher,
storage.NewTestStorageEngine(testDirectory).GetProvider(ModuleName),
storage.NewTestStorageEngine(t).GetProvider(ModuleName),
pkiMock,
)
if err := newInstance.Configure(core.TestServerConfig(core.ServerConfig{Datadir: testDirectory})); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion network/transport/v2/protocol_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func startNode(t *testing.T, name string, configurers ...func(config *Config)) *
mux: &sync.Mutex{},
}

storageClient := storage.NewTestStorageEngine(testDirectory)
storageClient := storage.NewTestStorageEngine(t)
bboltStore, err := storageClient.GetProvider("network").GetKVStore("data", storage.PersistentStorageClass)
if err != nil {
t.Fatal(err)
Expand Down
6 changes: 5 additions & 1 deletion storage/bbolt.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ import (
const fileMode = 0640
const bboltDbExtension = ".db"

var DefaultBBoltOptions = []stoabs.Option{
stoabs.WithLockAcquireTimeout(lockAcquireTimeout),
}

type bboltDatabase struct {
datadir string
config BBoltConfig
Expand Down Expand Up @@ -80,7 +84,7 @@ func (b bboltDatabase) createStore(moduleName string, storeName string) (stoabs.
WithField(core.LogFieldStore, fullStoreName).
Debug("Creating BBolt store")
databasePath := path.Join(b.datadir, fullStoreName) + bboltDbExtension
store, err := bbolt.CreateBBoltStore(databasePath, stoabs.WithLockAcquireTimeout(lockAcquireTimeout))
store, err := bbolt.CreateBBoltStore(databasePath, DefaultBBoltOptions...)
if store != nil {
b.startBackup(fullStoreName, store)
}
Expand Down
3 changes: 1 addition & 2 deletions storage/engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
"errors"
"github.com/nuts-foundation/go-stoabs"
"github.com/nuts-foundation/nuts-node/core"
"github.com/nuts-foundation/nuts-node/test/io"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/mock/gomock"
Expand All @@ -38,7 +37,7 @@ func Test_engine_Name(t *testing.T) {
}

func Test_engine_lifecycle(t *testing.T) {
sut := NewTestStorageEngine(io.TestDirectory(t))
sut := NewTestStorageEngine(t)
err := sut.Start()
require.NoError(t, err)
// Get a KV store so there's something to shut down
Expand Down
10 changes: 8 additions & 2 deletions storage/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,18 @@ import (
"github.com/nuts-foundation/go-stoabs"
"github.com/nuts-foundation/go-stoabs/bbolt"
"github.com/nuts-foundation/nuts-node/core"
"github.com/nuts-foundation/nuts-node/test/io"
"testing"
)

func NewTestStorageEngine(testDirectory string) Engine {
func NewTestStorageEngine(t *testing.T) Engine {
oldOpts := append(DefaultBBoltOptions[:])
t.Cleanup(func() {
DefaultBBoltOptions = oldOpts
})
DefaultBBoltOptions = append(DefaultBBoltOptions, stoabs.WithNoSync())
result := New()
_ = result.Configure(core.TestServerConfig(core.ServerConfig{Datadir: testDirectory + "/data"}))
_ = result.Configure(core.TestServerConfig(core.ServerConfig{Datadir: io.TestDirectory(t) + "/data"}))
return result
}

Expand Down
10 changes: 6 additions & 4 deletions vcr/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func NewTestVCRContext(t *testing.T, keyStore crypto.KeyStore) TestVCRContext {
network.NewTestNetworkInstance(t),
jsonld.NewTestJSONLDManager(t),
events.NewTestManager(t),
storage.NewTestStorageEngine(testDirectory),
storage.NewTestStorageEngine(t),
pki.New(), nil,
).(*vcr)

Expand All @@ -90,7 +90,7 @@ func NewTestVCRInstance(t *testing.T) *vcr {
network.NewTestNetworkInstance(t),
jsonld.NewTestJSONLDManager(t),
events.NewTestManager(t),
storage.NewTestStorageEngine(testDirectory),
storage.NewTestStorageEngine(t),
pki.New(), nil,
).(*vcr)

Expand All @@ -105,14 +105,16 @@ func NewTestVCRInstance(t *testing.T) *vcr {
}

func NewTestVCRInstanceInDir(t *testing.T, testDirectory string) *vcr {
storageEngine := storage.New()
_ = storageEngine.Configure(core.TestServerConfig(core.ServerConfig{Datadir: path.Join(testDirectory, "data")}))
// give network a subdirectory to avoid duplicate networks in tests
newInstance := NewVCRInstance(
nil,
nil,
network.NewTestNetworkInstance(t),
jsonld.NewTestJSONLDManager(t),
events.NewTestManager(t),
storage.NewTestStorageEngine(testDirectory),
storageEngine,
pki.New(), nil,
).(*vcr)

Expand Down Expand Up @@ -149,7 +151,7 @@ func newMockContext(t *testing.T) mockContext {
serviceResolver := types.NewMockServiceResolver(ctrl)
jsonldManager := jsonld.NewTestJSONLDManager(t)
eventManager := events.NewTestManager(t)
storageClient := storage.NewTestStorageEngine(testDir)
storageClient := storage.NewTestStorageEngine(t)
cryptoInstance := crypto.NewMemoryCryptoInstance()
vcr := NewVCRInstance(cryptoInstance, nil, tx, jsonldManager, eventManager, storageClient, pki.New(), nil).(*vcr)
vcr.serviceResolver = serviceResolver
Expand Down
11 changes: 5 additions & 6 deletions vcr/vcr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ import (

func TestVCR_Configure(t *testing.T) {
t.Run("error - creating issuer store", func(t *testing.T) {
testDirectory := io.TestDirectory(t)
instance := NewVCRInstance(nil, nil, nil, jsonld.NewTestJSONLDManager(t), nil, storage.NewTestStorageEngine(testDirectory), pki.New(), nil).(*vcr)
instance := NewVCRInstance(nil, nil, nil, jsonld.NewTestJSONLDManager(t), nil, storage.NewTestStorageEngine(t), pki.New(), nil).(*vcr)

err := instance.Configure(core.TestServerConfig(core.ServerConfig{Datadir: "test"}))
assert.EqualError(t, err, "failed to create leiaIssuerStore: mkdir test/vcr: not a directory")
Expand All @@ -67,7 +66,7 @@ func TestVCR_Configure(t *testing.T) {
ctrl := gomock.NewController(t)
pkiProvider := pki.NewMockProvider(ctrl)
pkiProvider.EXPECT().CreateTLSConfig(gomock.Any()).Return(nil, nil).AnyTimes()
instance := NewVCRInstance(nil, nil, nil, jsonld.NewTestJSONLDManager(t), nil, storage.NewTestStorageEngine(testDirectory), pkiProvider, nil).(*vcr)
instance := NewVCRInstance(nil, nil, nil, jsonld.NewTestJSONLDManager(t), nil, storage.NewTestStorageEngine(t), pkiProvider, nil).(*vcr)
instance.config.OpenID4VCI.Enabled = true

err := instance.Configure(core.TestServerConfig(core.ServerConfig{Datadir: testDirectory}))
Expand All @@ -88,7 +87,7 @@ func TestVCR_Configure(t *testing.T) {
localWalletResolver.EXPECT().Resolve(issuerDID).Return("https://example.com", nil).AnyTimes()
documentOwner := types.NewMockDocumentOwner(ctrl)
documentOwner.EXPECT().IsOwner(gomock.Any(), gomock.Any()).Return(true, nil).AnyTimes()
instance := NewVCRInstance(nil, nil, nil, jsonld.NewTestJSONLDManager(t), nil, storage.NewTestStorageEngine(testDirectory), pkiProvider, documentOwner).(*vcr)
instance := NewVCRInstance(nil, nil, nil, jsonld.NewTestJSONLDManager(t), nil, storage.NewTestStorageEngine(t), pkiProvider, documentOwner).(*vcr)
instance.config.OpenID4VCI.Enabled = true

err := instance.Configure(core.TestServerConfig(core.ServerConfig{Datadir: testDirectory, Strictmode: true}))
Expand Down Expand Up @@ -120,7 +119,7 @@ func TestVCR_Start(t *testing.T) {
network.NewTestNetworkInstance(t),
jsonld.NewTestJSONLDManager(t),
events.NewTestManager(t),
storage.NewTestStorageEngine(testDirectory),
storage.NewTestStorageEngine(t),
pki.New(), nil,
).(*vcr)
if err := instance.Configure(core.TestServerConfig(core.ServerConfig{Datadir: testDirectory})); err != nil {
Expand Down Expand Up @@ -167,7 +166,7 @@ func TestVCR_Diagnostics(t *testing.T) {
network.NewTestNetworkInstance(t),
jsonld.NewTestJSONLDManager(t),
events.NewTestManager(t),
storage.NewTestStorageEngine(testDirectory),
storage.NewTestStorageEngine(t),
pki.New(), nil,
).(*vcr)
instance.config.OpenID4VCI.Enabled = false
Expand Down
Loading

0 comments on commit f6c703e

Please sign in to comment.