diff --git a/consensus/common_test.go b/consensus/common_test.go index 953339c20..48a452de1 100644 --- a/consensus/common_test.go +++ b/consensus/common_test.go @@ -4,6 +4,7 @@ import ( "bytes" "context" "fmt" + "io" "io/ioutil" "os" "path/filepath" @@ -704,7 +705,10 @@ func randConsensusState( css := make([]*State, nValidators) logger := consensusLogger() + closeFuncs := make([]func() error, 0, nValidators) + configRootDirs := make([]string, 0, nValidators) + for i := 0; i < nValidators; i++ { stateDB := dbm.NewMemDB() // each state needs its own db stateStore := sm.NewStore(stateDB) @@ -719,6 +723,11 @@ func randConsensusState( ensureDir(filepath.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal app := appFunc() + + if appCloser, ok := app.(io.Closer); ok { + closeFuncs = append(closeFuncs, appCloser.Close) + } + vals := types.TM2PB.ValidatorUpdates(state.Validators) app.InitChain(abci.RequestInitChain{Validators: vals}) @@ -728,6 +737,9 @@ func randConsensusState( } return css, func() { + for _, closer := range closeFuncs { + _ = closer() + } for _, dir := range configRootDirs { os.RemoveAll(dir) } diff --git a/consensus/replay_file.go b/consensus/replay_file.go index 4bf7466ab..2244d868e 100644 --- a/consensus/replay_file.go +++ b/consensus/replay_file.go @@ -308,7 +308,7 @@ func newConsensusStateForReplay(config cfg.BaseConfig, csConfig *cfg.ConsensusCo } // Create proxyAppConn connection (consensus, mempool, query) - clientCreator := proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()) + clientCreator, _ := proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()) proxyApp := proxy.NewAppConns(clientCreator) err = proxyApp.Start() if err != nil { diff --git a/node/node.go b/node/node.go index 4b2b584ae..477b4ca9a 100644 --- a/node/node.go +++ b/node/node.go @@ -126,10 +126,12 @@ func DefaultNewNode(config *cfg.Config, logger log.Logger) (*Node, error) { } else { pval = nil } + + appClient, _ := proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()) return NewNode(config, pval, nodeKey, - proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()), + appClient, DefaultGenesisDocProviderFunc(config), DefaultDBProvider, DefaultMetricsProvider(config.Instrumentation), diff --git a/node/node_test.go b/node/node_test.go index d55a8d280..3290dbcd2 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -499,10 +499,12 @@ func TestNodeNewNodeCustomReactors(t *testing.T) { pval, err := privval.LoadOrGenFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile()) require.NoError(t, err) + appClient, closer := proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()) + t.Cleanup(func() { closer.Close() }) n, err := NewNode(config, pval, nodeKey, - proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()), + appClient, DefaultGenesisDocProviderFunc(config), DefaultDBProvider, DefaultMetricsProvider(config.Instrumentation), diff --git a/proxy/client.go b/proxy/client.go index 27baa9738..f57c603ca 100644 --- a/proxy/client.go +++ b/proxy/client.go @@ -2,6 +2,7 @@ package proxy import ( "fmt" + "io" abcicli "github.com/tendermint/tendermint/abci/client" "github.com/tendermint/tendermint/abci/example/counter" @@ -69,20 +70,28 @@ func (r *remoteClientCreator) NewABCIClient() (abcicli.Client, error) { // DefaultClientCreator returns a default ClientCreator, which will create a // local client if addr is one of: 'counter', 'counter_serial', 'kvstore', // 'persistent_kvstore' or 'noop', otherwise - a remote client. -func DefaultClientCreator(addr, transport, dbDir string) ClientCreator { +// +// The Closer is a noop except for persistent_kvstore applications, +// which will clean up the store. +func DefaultClientCreator(addr, transport, dbDir string) (ClientCreator, io.Closer) { switch addr { case "counter": - return NewLocalClientCreator(counter.NewApplication(false)) + return NewLocalClientCreator(counter.NewApplication(false)), noopCloser{} case "counter_serial": - return NewLocalClientCreator(counter.NewApplication(true)) + return NewLocalClientCreator(counter.NewApplication(true)), noopCloser{} case "kvstore": - return NewLocalClientCreator(kvstore.NewApplication()) + return NewLocalClientCreator(kvstore.NewApplication()), noopCloser{} case "persistent_kvstore": - return NewLocalClientCreator(kvstore.NewPersistentKVStoreApplication(dbDir)) + app := kvstore.NewPersistentKVStoreApplication(dbDir) + return NewLocalClientCreator(app), app case "noop": - return NewLocalClientCreator(types.NewBaseApplication()) + return NewLocalClientCreator(types.NewBaseApplication()), noopCloser{} default: mustConnect := false // loop retrying - return NewRemoteClientCreator(addr, transport, mustConnect) + return NewRemoteClientCreator(addr, transport, mustConnect), noopCloser{} } } + +type noopCloser struct{} + +func (noopCloser) Close() error { return nil } diff --git a/rpc/client/main_test.go b/rpc/client/main_test.go index c97311c81..cab8b7cdd 100644 --- a/rpc/client/main_test.go +++ b/rpc/client/main_test.go @@ -26,6 +26,7 @@ func TestMain(m *testing.M) { // and shut down proper at the end rpctest.StopTendermint(node) + app.Close() _ = os.RemoveAll(dir) os.Exit(code) }