mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-24 22:32:15 +00:00
* Close and recreate a RemoteSigner on err * Update changelog * Address Anton's comments / suggestions: - update changelog - restart TCPVal - shut down on `ErrUnexpectedResponse` * re-init remote signer client with fresh connection if Ping fails - add/update TODOs in secret connection - rename tcp.go -> tcp_client.go, same with ipc to clarify their purpose * account for `conn returned by waitConnection can be `nil` - also add TODO about RemoteSigner conn field * Tests for retrying: IPC / TCP - shorter info log on success - set conn and use it in tests to close conn * Tests for retrying: IPC / TCP - shorter info log on success - set conn and use it in tests to close conn - add rwmutex for conn field in IPC * comments and doc.go * fix ipc tests. fixes #2677 * use constants for tests * cleanup some error statements * fixes #2784, race in tests * remove print statement * minor fixes from review * update comment on sts spec * cosmetics * p2p/conn: add failing tests * p2p/conn: make SecretConnection thread safe * changelog * IPCVal signer refactor - use a .reset() method - don't use embedded RemoteSignerClient - guard RemoteSignerClient with mutex - drop the .conn - expose Close() on RemoteSignerClient * apply IPCVal refactor to TCPVal * remove mtx from RemoteSignerClient * consolidate IPCVal and TCPVal, fixes #3104 - done in tcp_client.go - now called SocketVal - takes a listener in the constructor - make tcpListener and unixListener contain all the differences * delete ipc files * introduce unix and tcp dialer for RemoteSigner * rename files - drop tcp_ prefix - rename priv_validator.go to file.go * bring back listener options * fix node * fix priv_val_server * fix node test * minor cleanup and comments
195 lines
4.8 KiB
Go
195 lines
4.8 KiB
Go
package node
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net"
|
|
"os"
|
|
"syscall"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/tendermint/tendermint/abci/example/kvstore"
|
|
cfg "github.com/tendermint/tendermint/config"
|
|
"github.com/tendermint/tendermint/crypto/ed25519"
|
|
cmn "github.com/tendermint/tendermint/libs/common"
|
|
"github.com/tendermint/tendermint/libs/log"
|
|
"github.com/tendermint/tendermint/p2p"
|
|
"github.com/tendermint/tendermint/privval"
|
|
sm "github.com/tendermint/tendermint/state"
|
|
"github.com/tendermint/tendermint/types"
|
|
tmtime "github.com/tendermint/tendermint/types/time"
|
|
"github.com/tendermint/tendermint/version"
|
|
)
|
|
|
|
func TestNodeStartStop(t *testing.T) {
|
|
config := cfg.ResetTestRoot("node_node_test")
|
|
|
|
// create & start node
|
|
n, err := DefaultNewNode(config, log.TestingLogger())
|
|
require.NoError(t, err)
|
|
err = n.Start()
|
|
require.NoError(t, err)
|
|
|
|
t.Logf("Started node %v", n.sw.NodeInfo())
|
|
|
|
// wait for the node to produce a block
|
|
blockCh := make(chan interface{})
|
|
err = n.EventBus().Subscribe(context.Background(), "node_test", types.EventQueryNewBlock, blockCh)
|
|
require.NoError(t, err)
|
|
select {
|
|
case <-blockCh:
|
|
case <-time.After(10 * time.Second):
|
|
t.Fatal("timed out waiting for the node to produce a block")
|
|
}
|
|
|
|
// stop the node
|
|
go func() {
|
|
n.Stop()
|
|
}()
|
|
|
|
select {
|
|
case <-n.Quit():
|
|
case <-time.After(5 * time.Second):
|
|
pid := os.Getpid()
|
|
p, err := os.FindProcess(pid)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
err = p.Signal(syscall.SIGABRT)
|
|
fmt.Println(err)
|
|
t.Fatal("timed out waiting for shutdown")
|
|
}
|
|
}
|
|
|
|
func TestSplitAndTrimEmpty(t *testing.T) {
|
|
testCases := []struct {
|
|
s string
|
|
sep string
|
|
cutset string
|
|
expected []string
|
|
}{
|
|
{"a,b,c", ",", " ", []string{"a", "b", "c"}},
|
|
{" a , b , c ", ",", " ", []string{"a", "b", "c"}},
|
|
{" a, b, c ", ",", " ", []string{"a", "b", "c"}},
|
|
{" a, ", ",", " ", []string{"a"}},
|
|
{" ", ",", " ", []string{}},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
assert.Equal(t, tc.expected, splitAndTrimEmpty(tc.s, tc.sep, tc.cutset), "%s", tc.s)
|
|
}
|
|
}
|
|
|
|
func TestNodeDelayedStop(t *testing.T) {
|
|
config := cfg.ResetTestRoot("node_delayed_node_test")
|
|
now := tmtime.Now()
|
|
|
|
// create & start node
|
|
n, err := DefaultNewNode(config, log.TestingLogger())
|
|
n.GenesisDoc().GenesisTime = now.Add(5 * time.Second)
|
|
require.NoError(t, err)
|
|
|
|
n.Start()
|
|
startTime := tmtime.Now()
|
|
assert.Equal(t, true, startTime.After(n.GenesisDoc().GenesisTime))
|
|
}
|
|
|
|
func TestNodeSetAppVersion(t *testing.T) {
|
|
config := cfg.ResetTestRoot("node_app_version_test")
|
|
|
|
// create & start node
|
|
n, err := DefaultNewNode(config, log.TestingLogger())
|
|
require.NoError(t, err)
|
|
|
|
// default config uses the kvstore app
|
|
var appVersion version.Protocol = kvstore.ProtocolVersion
|
|
|
|
// check version is set in state
|
|
state := sm.LoadState(n.stateDB)
|
|
assert.Equal(t, state.Version.Consensus.App, appVersion)
|
|
|
|
// check version is set in node info
|
|
assert.Equal(t, n.nodeInfo.(p2p.DefaultNodeInfo).ProtocolVersion.App, appVersion)
|
|
}
|
|
|
|
func TestNodeSetPrivValTCP(t *testing.T) {
|
|
addr := "tcp://" + testFreeAddr(t)
|
|
|
|
config := cfg.ResetTestRoot("node_priv_val_tcp_test")
|
|
config.BaseConfig.PrivValidatorListenAddr = addr
|
|
|
|
dialer := privval.DialTCPFn(addr, 100*time.Millisecond, ed25519.GenPrivKey())
|
|
pvsc := privval.NewRemoteSigner(
|
|
log.TestingLogger(),
|
|
config.ChainID(),
|
|
types.NewMockPV(),
|
|
dialer,
|
|
)
|
|
|
|
go func() {
|
|
err := pvsc.Start()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}()
|
|
defer pvsc.Stop()
|
|
|
|
n, err := DefaultNewNode(config, log.TestingLogger())
|
|
require.NoError(t, err)
|
|
assert.IsType(t, &privval.SocketVal{}, n.PrivValidator())
|
|
}
|
|
|
|
// address without a protocol must result in error
|
|
func TestPrivValidatorListenAddrNoProtocol(t *testing.T) {
|
|
addrNoPrefix := testFreeAddr(t)
|
|
|
|
config := cfg.ResetTestRoot("node_priv_val_tcp_test")
|
|
config.BaseConfig.PrivValidatorListenAddr = addrNoPrefix
|
|
|
|
_, err := DefaultNewNode(config, log.TestingLogger())
|
|
assert.Error(t, err)
|
|
}
|
|
|
|
func TestNodeSetPrivValIPC(t *testing.T) {
|
|
tmpfile := "/tmp/kms." + cmn.RandStr(6) + ".sock"
|
|
defer os.Remove(tmpfile) // clean up
|
|
|
|
config := cfg.ResetTestRoot("node_priv_val_tcp_test")
|
|
config.BaseConfig.PrivValidatorListenAddr = "unix://" + tmpfile
|
|
|
|
dialer := privval.DialUnixFn(tmpfile)
|
|
pvsc := privval.NewRemoteSigner(
|
|
log.TestingLogger(),
|
|
config.ChainID(),
|
|
types.NewMockPV(),
|
|
dialer,
|
|
)
|
|
|
|
done := make(chan struct{})
|
|
go func() {
|
|
defer close(done)
|
|
n, err := DefaultNewNode(config, log.TestingLogger())
|
|
require.NoError(t, err)
|
|
assert.IsType(t, &privval.SocketVal{}, n.PrivValidator())
|
|
}()
|
|
|
|
err := pvsc.Start()
|
|
require.NoError(t, err)
|
|
defer pvsc.Stop()
|
|
|
|
<-done
|
|
}
|
|
|
|
// testFreeAddr claims a free port so we don't block on listener being ready.
|
|
func testFreeAddr(t *testing.T) string {
|
|
ln, err := net.Listen("tcp", "127.0.0.1:0")
|
|
require.NoError(t, err)
|
|
defer ln.Close()
|
|
|
|
return fmt.Sprintf("127.0.0.1:%d", ln.Addr().(*net.TCPAddr).Port)
|
|
}
|