Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

node tests: Use in memory badger in unit tests #347

Merged
merged 6 commits into from
May 20, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion libs/db/badgerdb/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"path/filepath"

"github.com/dgraph-io/badger/v3"
"github.com/dgraph-io/badger/v3/options"

"github.com/lazyledger/lazyledger-core/libs/db"
)
Expand All @@ -22,7 +23,8 @@ func NewDB(dbName, dir string) (*BadgerDB, error) {
}
opts := badger.DefaultOptions(path)
opts.SyncWrites = false // note that we have Sync methods
opts.Logger = nil // badger is too chatty by default
// TODO(ismail): investigate if we don't want a logger here at least for errors though:
opts.Logger = nil // badger is too chatty by default
return NewDBWithOptions(opts)
}

Expand All @@ -37,6 +39,22 @@ func NewDBWithOptions(opts badger.Options) (*BadgerDB, error) {
return &BadgerDB{db: db}, nil
}

// NewInMemoryDB creates a light weight in-memory BadgerDB.
// Mainly useful for unit-tests.
func NewInMemoryDB() (*BadgerDB, error) {
opts := badger.DefaultOptions("")
opts.InMemory = true
liamsi marked this conversation as resolved.
Show resolved Hide resolved
opts.NumCompactors = 2 // minimize number of go-routines
opts.Compression = options.None // this is supposed to be short-lived
opts.ZSTDCompressionLevel = 0 // this is supposed to be short-lived
opts.Logger = nil // there is not much that can go wrong in-memory
db, err := badger.Open(opts)
if err != nil {
return nil, err
}
return &BadgerDB{db: db}, nil
}

type BadgerDB struct {
db *badger.DB
}
Expand Down
5 changes: 5 additions & 0 deletions node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ func DefaultDBProvider(ctx *DBContext) (dbm.DB, error) {
return badgerdb.NewDB(ctx.ID, ctx.Config.DBDir())
}

// InMemDBProvider provides an in-memory DB.
func InMemDBProvider(ctx *DBContext) (dbm.DB, error) {
return badgerdb.NewInMemoryDB()
}

// GenesisDocProvider returns a GenesisDoc.
// It allows the GenesisDoc to be pulled from sources other than the
// filesystem, for instance from a distributed key-value store cluster.
Expand Down
42 changes: 33 additions & 9 deletions node/node_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,35 @@ import (
tmtime "github.com/lazyledger/lazyledger-core/types/time"
)

func defaultNewTestNode(config *cfg.Config, logger log.Logger) (*Node, error) {
nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile())
if err != nil {
return nil, fmt.Errorf("failed to load or gen node key %s: %w", config.NodeKeyFile(), err)
}

pval, err := privval.LoadOrGenFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile())
if err != nil {
return nil, err
}
liamsi marked this conversation as resolved.
Show resolved Hide resolved

return NewNode(config,
pval,
nodeKey,
proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()),
DefaultGenesisDocProviderFunc(config),
InMemDBProvider,
ipfs.Mock(),
DefaultMetricsProvider(config.Instrumentation),
logger,
)
}

func TestNodeStartStop(t *testing.T) {
config := cfg.ResetTestRoot("node_node_test")
defer os.RemoveAll(config.RootDir)

// create & start node
n, err := DefaultNewNode(config, ipfs.Mock(), log.TestingLogger())
n, err := defaultNewTestNode(config, log.TestingLogger())
require.NoError(t, err)
err = n.Start()
require.NoError(t, err)
Expand Down Expand Up @@ -103,7 +126,7 @@ func TestNodeDelayedStart(t *testing.T) {
now := tmtime.Now()

// create & start node
n, err := DefaultNewNode(config, ipfs.Mock(), log.TestingLogger())
liamsi marked this conversation as resolved.
Show resolved Hide resolved
n, err := defaultNewTestNode(config, log.TestingLogger())
n.GenesisDoc().GenesisTime = now.Add(2 * time.Second)
require.NoError(t, err)

Expand All @@ -120,7 +143,7 @@ func TestNodeSetAppVersion(t *testing.T) {
defer os.RemoveAll(config.RootDir)

// create & start node
n, err := DefaultNewNode(config, ipfs.Mock(), log.TestingLogger())
n, err := defaultNewTestNode(config, log.TestingLogger())
require.NoError(t, err)

// default config uses the kvstore app
Expand All @@ -136,18 +159,19 @@ func TestNodeSetAppVersion(t *testing.T) {
}

func TestNodeSetPrivValTCP(t *testing.T) {
t.Skip("TODO(ismail): Mock these conns using net.Pipe instead")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not fully understand why this fails more often now. But IMHO, this should not really dial tcp://" + testFreeAddr(t) but instead use net.Pipe() or sth similar. This would require some changes in the node code so it can deal with the pipe connection too. Either way, this code is highly orthogonal and we can come back to it (much) later. For now, it is just a timesink ...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is an actual fix and inmemdb does have any effect?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inmemdb helps with some timeouts, too. And tests will be a tiny bit faster ...

addr := "tcp://" + testFreeAddr(t)

config := cfg.ResetTestRoot("node_priv_val_tcp_test")
defer os.RemoveAll(config.RootDir)
config.BaseConfig.PrivValidatorListenAddr = addr

dialer := privval.DialTCPFn(addr, 100*time.Millisecond, ed25519.GenPrivKey())
dialer := privval.DialTCPFn(addr, 250*time.Millisecond, ed25519.GenPrivKey())
liamsi marked this conversation as resolved.
Show resolved Hide resolved
dialerEndpoint := privval.NewSignerDialerEndpoint(
log.TestingLogger(),
dialer,
)
privval.SignerDialerEndpointTimeoutReadWrite(100 * time.Millisecond)(dialerEndpoint)
privval.SignerDialerEndpointTimeoutReadWrite(250 * time.Millisecond)(dialerEndpoint)
liamsi marked this conversation as resolved.
Show resolved Hide resolved

signerServer := privval.NewSignerServer(
dialerEndpoint,
Expand All @@ -164,7 +188,7 @@ func TestNodeSetPrivValTCP(t *testing.T) {
defer signerServer.Stop() //nolint:errcheck // ignore for tests

logger := log.TestingLogger()
n, err := DefaultNewNode(config, ipfs.Mock(), logger)
n, err := defaultNewTestNode(config, logger)
require.NoError(t, err)
assert.IsType(t, &privval.RetrySignerClient{}, n.PrivValidator())
}
Expand All @@ -177,7 +201,7 @@ func TestPrivValidatorListenAddrNoProtocol(t *testing.T) {
defer os.RemoveAll(config.RootDir)
config.BaseConfig.PrivValidatorListenAddr = addrNoPrefix

_, err := DefaultNewNode(config, ipfs.Mock(), log.TestingLogger())
_, err := defaultNewTestNode(config, log.TestingLogger())
assert.Error(t, err)
}

Expand Down Expand Up @@ -209,7 +233,7 @@ func TestNodeSetPrivValIPC(t *testing.T) {
defer pvsc.Stop() //nolint:errcheck // ignore for tests

logger := log.TestingLogger()
n, err := DefaultNewNode(config, ipfs.Mock(), logger)
n, err := defaultNewTestNode(config, logger)
require.NoError(t, err)
assert.IsType(t, &privval.RetrySignerClient{}, n.PrivValidator())
}
Expand Down Expand Up @@ -514,7 +538,7 @@ func TestNodeNewNodeCustomReactors(t *testing.T) {
nodeKey,
proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()),
DefaultGenesisDocProviderFunc(config),
DefaultDBProvider,
InMemDBProvider,
ipfs.Mock(),
DefaultMetricsProvider(config.Instrumentation),
log.TestingLogger(),
Expand Down
4 changes: 2 additions & 2 deletions p2p/transport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ func TestTransportHandshake(t *testing.T) {
t.Fatal(err)
}

ni, err := handshake(c, 20*time.Millisecond, emptyNodeInfo())
ni, err := handshake(c, 100*time.Millisecond, emptyNodeInfo())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that a failed attempt to fix?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, that was flaky too and it helped.

if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -651,7 +651,7 @@ func testSetupMultiplexTransport(t *testing.T) *MultiplexTransport {
}

// give the listener some time to get ready
time.Sleep(20 * time.Millisecond)
time.Sleep(100 * time.Millisecond)

return mt
}
Expand Down
2 changes: 1 addition & 1 deletion rpc/test/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ func NewTendermint(app abci.Application, opts *Options) *nm.Node {

node, err := nm.NewNode(config, pv, nodeKey, papp,
nm.DefaultGenesisDocProviderFunc(config),
nm.DefaultDBProvider,
nm.InMemDBProvider,
ipfs.Mock(),
nm.DefaultMetricsProvider(config.Instrumentation),
logger,
Expand Down