note about encryption and why it must be test datastore now using same settings as seed badger options extracted from storage for test and other uses one place it was missing all using badger/v3 now peer database entry count implemented fixed stray incorrect refactorings added expiry to interface, now propagates correctly eliminated type switch with extending of interface Access to badger View and Update now in Engine Datastore now available via Listener
179 lines
4.2 KiB
Go
179 lines
4.2 KiB
Go
package pstoreds
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
pstore "github.com/libp2p/go-libp2p/core/peerstore"
|
|
pt "github.com/libp2p/go-libp2p/p2p/host/peerstore/test"
|
|
|
|
mockClock "github.com/benbjohnson/clock"
|
|
badger "github.com/indra-labs/go-ds-badger3"
|
|
ds "github.com/ipfs/go-datastore"
|
|
leveldb "github.com/ipfs/go-ds-leveldb"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
type datastoreFactory func(tb testing.TB) (ds.Batching, func())
|
|
|
|
var dstores = map[string]datastoreFactory{
|
|
// "Badger": badgerStore,
|
|
"Leveldb": leveldbStore,
|
|
}
|
|
|
|
func TestDsPeerstore(t *testing.T) {
|
|
for name, dsFactory := range dstores {
|
|
t.Run(name, func(t *testing.T) {
|
|
pt.TestPeerstore(t, peerstoreFactory(t, dsFactory, DefaultOpts()))
|
|
})
|
|
|
|
t.Run("protobook limits", func(t *testing.T) {
|
|
const limit = 10
|
|
opts := DefaultOpts()
|
|
opts.MaxProtocols = limit
|
|
ds, close := dsFactory(t)
|
|
defer close()
|
|
ps, err := NewPeerstore(context.Background(), ds, opts)
|
|
require.NoError(t, err)
|
|
defer ps.Close()
|
|
pt.TestPeerstoreProtoStoreLimits(t, ps, limit)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDsAddrBook(t *testing.T) {
|
|
for name, dsFactory := range dstores {
|
|
t.Run(name+" Cacheful", func(t *testing.T) {
|
|
opts := DefaultOpts()
|
|
opts.GCPurgeInterval = 1 * time.Second
|
|
opts.CacheSize = 1024
|
|
clk := mockClock.NewMock()
|
|
opts.Clock = clk
|
|
|
|
pt.TestAddrBook(t, addressBookFactory(t, dsFactory, opts), clk)
|
|
})
|
|
|
|
t.Run(name+" Cacheless", func(t *testing.T) {
|
|
opts := DefaultOpts()
|
|
opts.GCPurgeInterval = 1 * time.Second
|
|
opts.CacheSize = 0
|
|
clk := mockClock.NewMock()
|
|
opts.Clock = clk
|
|
|
|
pt.TestAddrBook(t, addressBookFactory(t, dsFactory, opts), clk)
|
|
})
|
|
}
|
|
}
|
|
|
|
// func TestDsKeyBook(t *testing.T) {
|
|
// for name, dsFactory := range dstores {
|
|
// t.Run(name, func(t *testing.T) {
|
|
// pt.TestKeyBook(t, keyBookFactory(t, dsFactory, DefaultOpts()))
|
|
// })
|
|
// }
|
|
// }
|
|
|
|
func BenchmarkDsKeyBook(b *testing.B) {
|
|
for name, dsFactory := range dstores {
|
|
b.Run(name, func(b *testing.B) {
|
|
pt.BenchmarkKeyBook(b, keyBookFactory(b, dsFactory, DefaultOpts()))
|
|
})
|
|
}
|
|
}
|
|
|
|
func BenchmarkDsPeerstore(b *testing.B) {
|
|
caching := DefaultOpts()
|
|
caching.CacheSize = 1024
|
|
|
|
cacheless := DefaultOpts()
|
|
cacheless.CacheSize = 0
|
|
|
|
for name, dsFactory := range dstores {
|
|
b.Run(name, func(b *testing.B) {
|
|
pt.BenchmarkPeerstore(b, peerstoreFactory(b, dsFactory, caching),
|
|
"Caching")
|
|
})
|
|
b.Run(name, func(b *testing.B) {
|
|
pt.BenchmarkPeerstore(b, peerstoreFactory(b, dsFactory, cacheless),
|
|
"Cacheless")
|
|
})
|
|
}
|
|
}
|
|
|
|
// Doesn't work on 32bit because badger.
|
|
//
|
|
//lint:ignore U1000 disabled for now
|
|
func badgerStore(tb testing.TB) (ds.Batching, func()) {
|
|
dataPath, err := os.MkdirTemp(os.TempDir(), "badger")
|
|
if err != nil {
|
|
tb.Fatal(err)
|
|
}
|
|
store, err := badger.NewDatastore(dataPath, nil)
|
|
if err != nil {
|
|
tb.Fatal(err)
|
|
}
|
|
closer := func() {
|
|
store.Close()
|
|
os.RemoveAll(dataPath)
|
|
}
|
|
return store, closer
|
|
}
|
|
|
|
func leveldbStore(tb testing.TB) (ds.Batching, func()) {
|
|
// Intentionally test in-memory because disks suck, especially in CI.
|
|
store, err := leveldb.NewDatastore("", nil)
|
|
if err != nil {
|
|
tb.Fatal(err)
|
|
}
|
|
closer := func() {
|
|
store.Close()
|
|
}
|
|
return store, closer
|
|
}
|
|
|
|
func peerstoreFactory(tb testing.TB, storeFactory datastoreFactory,
|
|
opts Options) pt.PeerstoreFactory {
|
|
return func() (pstore.Peerstore, func()) {
|
|
store, storeCloseFn := storeFactory(tb)
|
|
ps, err := NewPeerstore(context.Background(), store, opts)
|
|
if err != nil {
|
|
tb.Fatal(err)
|
|
}
|
|
closer := func() {
|
|
ps.Close()
|
|
storeCloseFn()
|
|
}
|
|
return ps, closer
|
|
}
|
|
}
|
|
|
|
func addressBookFactory(tb testing.TB, storeFactory datastoreFactory,
|
|
opts Options) pt.AddrBookFactory {
|
|
return func() (pstore.AddrBook, func()) {
|
|
store, closeFunc := storeFactory(tb)
|
|
ab, err := NewAddrBook(context.Background(), store, opts)
|
|
if err != nil {
|
|
tb.Fatal(err)
|
|
}
|
|
closer := func() {
|
|
ab.Close()
|
|
closeFunc()
|
|
}
|
|
return ab, closer
|
|
}
|
|
}
|
|
|
|
func keyBookFactory(tb testing.TB, storeFactory datastoreFactory,
|
|
opts Options) pt.KeyBookFactory {
|
|
return func() (pstore.KeyBook, func()) {
|
|
store, storeCloseFn := storeFactory(tb)
|
|
kb, err := NewKeyBook(context.Background(), store, opts)
|
|
if err != nil {
|
|
tb.Fatal(err)
|
|
}
|
|
return kb, storeCloseFn
|
|
}
|
|
}
|