From 91e00b362013436ec8f693983bd73e1b3b6e55bb Mon Sep 17 00:00:00 2001 From: Juan Leni Date: Mon, 4 Mar 2019 19:36:12 +0100 Subject: [PATCH] Improve tests --- .gitignore | 2 + privval/file_deprecated_test.go | 8 +- privval/file_test.go | 6 +- privval/signer_listener_endpoint_test.go | 207 ++++++----------------- privval/signer_remote_test.go | 36 ++++ 5 files changed, 98 insertions(+), 161 deletions(-) diff --git a/.gitignore b/.gitignore index 1cf9cdb90..12eb789f5 100644 --- a/.gitignore +++ b/.gitignore @@ -42,3 +42,5 @@ terraform.tfstate.backup terraform.tfstate.d .vscode + +profile\.out diff --git a/privval/file_deprecated_test.go b/privval/file_deprecated_test.go index 46391a3fe..e678bfc09 100644 --- a/privval/file_deprecated_test.go +++ b/privval/file_deprecated_test.go @@ -67,11 +67,11 @@ func assertEqualPV(t *testing.T, oldPV *privval.OldFilePV, newPV *privval.FilePV } func initTmpOldFile(t *testing.T) string { - tmpfile, err := ioutil.TempFile("", "priv_validator_*.json") + tmpFile, err := ioutil.TempFile("", "priv_validator_*.json") require.NoError(t, err) - t.Logf("created test file %s", tmpfile.Name()) - _, err = tmpfile.WriteString(oldPrivvalContent) + t.Logf("created test file %s", tmpFile.Name()) + _, err = tmpFile.WriteString(oldPrivvalContent) require.NoError(t, err) - return tmpfile.Name() + return tmpFile.Name() } diff --git a/privval/file_test.go b/privval/file_test.go index 9ece30ede..3b9c3b614 100644 --- a/privval/file_test.go +++ b/privval/file_test.go @@ -162,8 +162,8 @@ func TestSignVote(t *testing.T) { privVal := GenFilePV(tempKeyFile.Name(), tempStateFile.Name()) - block1 := types.BlockID{[]byte{1, 2, 3}, types.PartSetHeader{}} - block2 := types.BlockID{[]byte{3, 2, 1}, types.PartSetHeader{}} + block1 := types.BlockID{Hash: []byte{1, 2, 3}} + block2 := types.BlockID{Hash: []byte{3, 2, 1}} height, round := int64(10), 1 voteType := byte(types.PrevoteType) @@ -277,7 +277,7 @@ func TestDifferByTimestamp(t *testing.T) { // test vote { voteType := byte(types.PrevoteType) - blockID := types.BlockID{[]byte{1, 2, 3}, types.PartSetHeader{}} + blockID := types.BlockID{Hash: []byte{1, 2, 3}} vote := newVote(privVal.Key.Address, 0, height, round, voteType, blockID) err := privVal.SignVote("mychainid", vote) assert.NoError(t, err, "expected no error signing vote") diff --git a/privval/signer_listener_endpoint_test.go b/privval/signer_listener_endpoint_test.go index 1f1a292bb..57c29bd1e 100644 --- a/privval/signer_listener_endpoint_test.go +++ b/privval/signer_listener_endpoint_test.go @@ -44,7 +44,6 @@ func TestSignerRemoteRetryTCPOnly(t *testing.T) { go func(ln net.Listener, attemptCh chan<- int) { attempts := 0 - for { conn, err := ln.Accept() require.NoError(t, err) @@ -82,151 +81,59 @@ func TestSignerRemoteRetryTCPOnly(t *testing.T) { } } -//func TestSocketPVDeadline(t *testing.T) { -// for _, tc := range getTestCases(t) { -// func() { -// var ( -// listenc = make(chan struct{}) -// thisConnTimeout = 100 * time.Millisecond -// validatorEndpoint = newSignerValidatorEndpoint(log.TestingLogger(), tc.addr, thisConnTimeout) -// ) -// -// go func(sc *SignerListenerEndpoint) { -// defer close(listenc) -// -// // Note: the TCP connection times out at the accept() phase, -// // whereas the Unix domain sockets connection times out while -// // attempting to fetch the remote signer's public key. -// assert.True(t, IsConnTimeout(sc.Start())) -// -// assert.False(t, sc.IsRunning()) -// }(validatorEndpoint) -// -// for { -// _, err := common.Connect(tc.addr) -// if err == nil { -// break -// } -// } -// -// <-listenc -// }() -// } -//} - -//func TestErrUnexpectedResponse(t *testing.T) { -// for _, tc := range getTestCases(t) { -// func() { -// var ( -// logger = log.TestingLogger() -// chainID = common.RandStr(12) -// readyCh = make(chan struct{}) -// errCh = make(chan error, 1) -// -// serviceEndpoint = NewSignerDialerEndpoint( -// logger, -// chainID, -// types.NewMockPV(), -// tc.dialer, -// ) -// -// validatorEndpoint = newSignerValidatorEndpoint( -// logger, -// tc.addr, -// testTimeoutReadWrite) -// ) -// -// getStartEndpoint(t, readyCh, validatorEndpoint) -// defer validatorEndpoint.Stop() -// SignerServiceEndpointTimeoutReadWrite(time.Millisecond)(serviceEndpoint) -// SignerServiceEndpointConnRetries(100)(serviceEndpoint) -// // we do not want to Start() the remote signer here and instead use the connection to -// // reply with intentionally wrong replies below: -// rsConn, err := serviceEndpoint.connect() -// defer rsConn.Close() -// require.NoError(t, err) -// require.NotNil(t, rsConn) -// // send over public key to get the remote signer running: -// go testReadWriteResponse(t, &PubKeyResponse{}, rsConn) -// <-readyCh -// -// // Proposal: -// go func(errc chan error) { -// errc <- validatorEndpoint.SignProposal(chainID, &types.Proposal{}) -// }(errCh) -// -// // read request and write wrong response: -// go testReadWriteResponse(t, &SignedVoteResponse{}, rsConn) -// err = <-errCh -// require.Error(t, err) -// require.Equal(t, err, ErrUnexpectedResponse) -// -// // Vote: -// go func(errc chan error) { -// errc <- validatorEndpoint.SignVote(chainID, &types.Vote{}) -// }(errCh) -// // read request and write wrong response: -// go testReadWriteResponse(t, &SignedProposalResponse{}, rsConn) -// err = <-errCh -// require.Error(t, err) -// require.Equal(t, err, ErrUnexpectedResponse) -// }() -// } -//} -// -//func TestRetryConnToRemoteSigner(t *testing.T) { -// for _, tc := range getTestCases(t) { -// func() { -// var ( -// logger = log.TestingLogger() -// chainID = common.RandStr(12) -// readyCh = make(chan struct{}) -// -// serviceEndpoint = NewSignerDialerEndpoint( -// logger, -// chainID, -// types.NewMockPV(), -// tc.dialer, -// ) -// thisConnTimeout = testTimeoutReadWrite -// validatorEndpoint = newSignerValidatorEndpoint(logger, tc.addr, thisConnTimeout) -// ) -// // Ping every: -// SignerValidatorEndpointSetHeartbeat(testTimeoutHeartbeat)(validatorEndpoint) -// -// SignerServiceEndpointTimeoutReadWrite(testTimeoutReadWrite)(serviceEndpoint) -// SignerServiceEndpointConnRetries(10)(serviceEndpoint) -// -// getStartEndpoint(t, readyCh, validatorEndpoint) -// defer validatorEndpoint.Stop() -// require.NoError(t, serviceEndpoint.Start()) -// assert.True(t, serviceEndpoint.IsRunning()) -// -// <-readyCh -// time.Sleep(testTimeoutHeartbeat * 2) -// -// serviceEndpoint.Stop() -// rs2 := NewSignerDialerEndpoint( -// logger, -// chainID, -// types.NewMockPV(), -// tc.dialer, -// ) -// // let some pings pass -// time.Sleep(testTimeoutHeartbeat3o2) -// require.NoError(t, rs2.Start()) -// assert.True(t, rs2.IsRunning()) -// defer rs2.Stop() -// -// // give the client some time to re-establish the conn to the remote signer -// // should see sth like this in the logs: -// // -// // E[10016-01-10|17:12:46.128] Ping err="remote signer timed out" -// // I[10016-01-10|17:16:42.447] Re-created connection to remote signer impl=SocketVal -// time.Sleep(testTimeoutReadWrite * 2) -// }() -// } -//} +func TestRetryConnToRemoteSigner(t *testing.T) { + for _, tc := range getDialerTestCases(t) { + func() { + var ( + logger = log.TestingLogger() + chainID = common.RandStr(12) + readyCh = make(chan struct{}) + + serviceEndpoint = NewSignerDialerEndpoint( + logger, + chainID, + types.NewMockPV(), + tc.dialer, + ) + thisConnTimeout = testTimeoutReadWrite + validatorEndpoint = newSignerValidatorEndpoint(logger, tc.addr, thisConnTimeout) + ) + // Ping every: + SignerValidatorEndpointSetHeartbeat(testTimeoutHeartbeat)(validatorEndpoint) + + SignerServiceEndpointTimeoutReadWrite(testTimeoutReadWrite)(serviceEndpoint) + SignerServiceEndpointConnRetries(10)(serviceEndpoint) + + getStartEndpoint(t, readyCh, validatorEndpoint) + defer validatorEndpoint.Stop() + require.NoError(t, serviceEndpoint.Start()) + assert.True(t, serviceEndpoint.IsRunning()) + + <-readyCh + time.Sleep(testTimeoutHeartbeat * 2) + + serviceEndpoint.Stop() + rs2 := NewSignerDialerEndpoint( + logger, + chainID, + types.NewMockPV(), + tc.dialer, + ) + // let some pings pass + time.Sleep(testTimeoutHeartbeat3o2) + require.NoError(t, rs2.Start()) + assert.True(t, rs2.IsRunning()) + defer rs2.Stop() + + // give the client some time to re-establish the conn to the remote signer + // should see sth like this in the logs: + // + // E[10016-01-10|17:12:46.128] Ping err="remote signer timed out" + // I[10016-01-10|17:16:42.447] Re-created connection to remote signer impl=SocketVal + time.Sleep(testTimeoutReadWrite * 2) + }() + } +} /////////////////////////////////// @@ -299,11 +206,3 @@ func getMockEndpoints( return validatorEndpoint, serviceEndpoint } - -//func testReadWriteResponse(t *testing.T, resp RemoteSignerMsg, rsConn net.Conn) { -// _, err := readMessage(rsConn) -// require.NoError(t, err) -// -// err = writeMessage(rsConn, resp) -// require.NoError(t, err) -//} diff --git a/privval/signer_remote_test.go b/privval/signer_remote_test.go index cec37a617..d8ca81600 100644 --- a/privval/signer_remote_test.go +++ b/privval/signer_remote_test.go @@ -195,6 +195,7 @@ func TestSignerSignVoteErrors(t *testing.T) { ts := time.Now() vote := &types.Vote{Timestamp: ts, Type: types.PrecommitType} + // Replace signer service privval with one that always fails tc.signerService.privVal = types.NewErroringMockPV() tc.mockPV = types.NewErroringMockPV() @@ -212,3 +213,38 @@ func TestSignerSignVoteErrors(t *testing.T) { }() } } + +type BrokenSignerDialerEndpoint struct { + SignerDialerEndpoint +} + +func (ss *BrokenSignerDialerEndpoint) writeMessage(msg RemoteSignerMsg) (err error) { + _, err = cdc.MarshalBinaryLengthPrefixedWriter(ss.conn, PingResponse{}) + return +} + +func TestSignerUnexpectedResponse(t *testing.T) { + for _, tc := range getSignerTestCases(t) { + func() { + // TODO: This test is actually not working. Fails for a different reason + + tc.signerService.privVal = types.NewErroringMockPV() + tc.mockPV = types.NewErroringMockPV() + + // Replace signer service with a broken one + tc.signerService.OnStop() + tmp := BrokenSignerDialerEndpoint{*tc.signerService} + tmp.OnStart() + + defer tmp.OnStop() + defer tc.signer.Close() + + ts := time.Now() + want := &types.Vote{Timestamp: ts, Type: types.PrecommitType} + + e := tc.signer.SignVote(tc.chainID, want) + println(e.Error()) + require.Error(t, e) + }() + } +}