diff --git a/network/dag/consistency_test.go b/network/dag/consistency_test.go index 4f3a172486..09f9614cf9 100644 --- a/network/dag/consistency_test.go +++ b/network/dag/consistency_test.go @@ -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" ) @@ -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() { diff --git a/network/dag/notifier_test.go b/network/dag/notifier_test.go index aab56d505c..cf61bb0439 100644 --- a/network/dag/notifier_test.go +++ b/network/dag/notifier_test.go @@ -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" @@ -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 @@ -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) }) @@ -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 { @@ -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() @@ -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) @@ -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{ @@ -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() @@ -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() @@ -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} @@ -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) @@ -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() @@ -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() @@ -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 diff --git a/network/dag/state_test.go b/network/dag/state_test.go index a7317470e0..6d8beb38ae 100644 --- a/network/dag/state_test.go +++ b/network/dag/state_test.go @@ -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" @@ -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) diff --git a/network/network_test.go b/network/network_test.go index cfa478b66c..02f849b1d0 100644 --- a/network/network_test.go +++ b/network/network_test.go @@ -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)) @@ -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() }) diff --git a/network/test.go b/network/test.go index 1e2fcc0ed8..6ea1af8d06 100644 --- a/network/test.go +++ b/network/test.go @@ -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 { diff --git a/network/transport/v2/protocol_integration_test.go b/network/transport/v2/protocol_integration_test.go index ac2f2f2328..7109421f11 100644 --- a/network/transport/v2/protocol_integration_test.go +++ b/network/transport/v2/protocol_integration_test.go @@ -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) diff --git a/storage/bbolt.go b/storage/bbolt.go index 37bfda7ed2..f2b8fdcc88 100644 --- a/storage/bbolt.go +++ b/storage/bbolt.go @@ -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 @@ -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) } diff --git a/storage/engine_test.go b/storage/engine_test.go index 5a4edb660a..6b010bea1b 100644 --- a/storage/engine_test.go +++ b/storage/engine_test.go @@ -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" @@ -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 diff --git a/storage/test.go b/storage/test.go index 029ca50a58..43fa707bd0 100644 --- a/storage/test.go +++ b/storage/test.go @@ -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 } diff --git a/vcr/test.go b/vcr/test.go index 9a04492446..ea3bd1fc79 100644 --- a/vcr/test.go +++ b/vcr/test.go @@ -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) @@ -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) @@ -105,6 +105,8 @@ 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, @@ -112,7 +114,7 @@ func NewTestVCRInstanceInDir(t *testing.T, testDirectory string) *vcr { network.NewTestNetworkInstance(t), jsonld.NewTestJSONLDManager(t), events.NewTestManager(t), - storage.NewTestStorageEngine(testDirectory), + storageEngine, pki.New(), nil, ).(*vcr) @@ -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 diff --git a/vcr/vcr_test.go b/vcr/vcr_test.go index 94887563d1..987e2ef7e7 100644 --- a/vcr/vcr_test.go +++ b/vcr/vcr_test.go @@ -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") @@ -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})) @@ -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})) @@ -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 { @@ -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 diff --git a/vdr/didstore/test.go b/vdr/didstore/test.go index 29239dc2a4..861b9c5b5e 100644 --- a/vdr/didstore/test.go +++ b/vdr/didstore/test.go @@ -20,13 +20,11 @@ package didstore import ( "encoding/json" - "path" "testing" "time" "github.com/nuts-foundation/nuts-node/core" "github.com/nuts-foundation/nuts-node/storage" - "github.com/nuts-foundation/nuts-node/test/io" "github.com/stretchr/testify/require" "github.com/nuts-foundation/nuts-node/crypto/hash" @@ -44,7 +42,7 @@ var testServiceA = did.Service{ID: ssi.MustParseURI("did:nuts:service:a"), Servi var testServiceB = did.Service{ID: ssi.MustParseURI("did:nuts:service:b"), ServiceEndpoint: []interface{}{"http://b"}} func NewTestStore(t *testing.T) *store { - s := New(storage.NewTestStorageEngine(path.Join(io.TestDirectory(t))).GetProvider(moduleName)).(*store) + s := New(storage.NewTestStorageEngine(t).GetProvider(moduleName)).(*store) err := s.Configure(core.ServerConfig{}) require.NoError(t, err) return s