github.com/adoriasoft/tendermint@v0.34.0-dev1.0.20200722151356-96d84601a75a/tools/tm-signer-harness/internal/test_harness_test.go (about) 1 package internal 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "os" 7 "testing" 8 "time" 9 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 13 "github.com/tendermint/tendermint/crypto" 14 "github.com/tendermint/tendermint/crypto/ed25519" 15 "github.com/tendermint/tendermint/libs/log" 16 "github.com/tendermint/tendermint/privval" 17 "github.com/tendermint/tendermint/types" 18 ) 19 20 const ( 21 keyFileContents = `{ 22 "address": "D08FCA3BA74CF17CBFC15E64F9505302BB0E2748", 23 "pub_key": { 24 "type": "tendermint/PubKeyEd25519", 25 "value": "ZCsuTjaczEyon70nmKxwvwu+jqrbq5OH3yQjcK0SFxc=" 26 }, 27 "priv_key": { 28 "type": "tendermint/PrivKeyEd25519", 29 "value": "8O39AkQsoe1sBQwud/Kdul8lg8K9SFsql9aZvwXQSt1kKy5ONpzMTKifvSeYrHC/C76Oqturk4ffJCNwrRIXFw==" 30 } 31 }` 32 33 stateFileContents = `{ 34 "height": "0", 35 "round": 0, 36 "step": 0 37 }` 38 39 genesisFileContents = `{ 40 "genesis_time": "2019-01-15T11:56:34.8963Z", 41 "chain_id": "test-chain-0XwP5E", 42 "consensus_params": { 43 "block": { 44 "max_bytes": "22020096", 45 "max_gas": "-1", 46 "time_iota_ms": "1000" 47 }, 48 "evidence": { 49 "max_age_num_blocks": "100000", 50 "max_age_duration": "172800000000000", 51 "max_num": 50, 52 "proof_trial_period": "50000" 53 }, 54 "validator": { 55 "pub_key_types": [ 56 "ed25519" 57 ] 58 } 59 }, 60 "validators": [ 61 { 62 "address": "D08FCA3BA74CF17CBFC15E64F9505302BB0E2748", 63 "pub_key": { 64 "type": "tendermint/PubKeyEd25519", 65 "value": "ZCsuTjaczEyon70nmKxwvwu+jqrbq5OH3yQjcK0SFxc=" 66 }, 67 "power": "10", 68 "name": "" 69 } 70 ], 71 "app_hash": "" 72 }` 73 74 defaultConnDeadline = 100 75 ) 76 77 func TestRemoteSignerTestHarnessMaxAcceptRetriesReached(t *testing.T) { 78 cfg := makeConfig(t, 1, 2) 79 defer cleanup(cfg) 80 81 th, err := NewTestHarness(log.TestingLogger(), cfg) 82 require.NoError(t, err) 83 th.Run() 84 assert.Equal(t, ErrMaxAcceptRetriesReached, th.exitCode) 85 } 86 87 func TestRemoteSignerTestHarnessSuccessfulRun(t *testing.T) { 88 harnessTest( 89 t, 90 func(th *TestHarness) *privval.SignerServer { 91 return newMockSignerServer(t, th, th.fpv.Key.PrivKey, false, false) 92 }, 93 NoError, 94 ) 95 } 96 97 func TestRemoteSignerPublicKeyCheckFailed(t *testing.T) { 98 harnessTest( 99 t, 100 func(th *TestHarness) *privval.SignerServer { 101 return newMockSignerServer(t, th, ed25519.GenPrivKey(), false, false) 102 }, 103 ErrTestPublicKeyFailed, 104 ) 105 } 106 107 func TestRemoteSignerProposalSigningFailed(t *testing.T) { 108 harnessTest( 109 t, 110 func(th *TestHarness) *privval.SignerServer { 111 return newMockSignerServer(t, th, th.fpv.Key.PrivKey, true, false) 112 }, 113 ErrTestSignProposalFailed, 114 ) 115 } 116 117 func TestRemoteSignerVoteSigningFailed(t *testing.T) { 118 harnessTest( 119 t, 120 func(th *TestHarness) *privval.SignerServer { 121 return newMockSignerServer(t, th, th.fpv.Key.PrivKey, false, true) 122 }, 123 ErrTestSignVoteFailed, 124 ) 125 } 126 127 func newMockSignerServer( 128 t *testing.T, 129 th *TestHarness, 130 privKey crypto.PrivKey, 131 breakProposalSigning bool, 132 breakVoteSigning bool, 133 ) *privval.SignerServer { 134 mockPV := types.NewMockPVWithParams(privKey, breakProposalSigning, breakVoteSigning) 135 136 dialerEndpoint := privval.NewSignerDialerEndpoint( 137 th.logger, 138 privval.DialTCPFn( 139 th.addr, 140 time.Duration(defaultConnDeadline)*time.Millisecond, 141 ed25519.GenPrivKey(), 142 ), 143 ) 144 145 return privval.NewSignerServer(dialerEndpoint, th.chainID, mockPV) 146 } 147 148 // For running relatively standard tests. 149 func harnessTest(t *testing.T, signerServerMaker func(th *TestHarness) *privval.SignerServer, expectedExitCode int) { 150 cfg := makeConfig(t, 100, 3) 151 defer cleanup(cfg) 152 153 th, err := NewTestHarness(log.TestingLogger(), cfg) 154 require.NoError(t, err) 155 donec := make(chan struct{}) 156 go func() { 157 defer close(donec) 158 th.Run() 159 }() 160 161 ss := signerServerMaker(th) 162 require.NoError(t, ss.Start()) 163 assert.True(t, ss.IsRunning()) 164 defer ss.Stop() //nolint:errcheck // ignore for tests 165 166 <-donec 167 assert.Equal(t, expectedExitCode, th.exitCode) 168 } 169 170 func makeConfig(t *testing.T, acceptDeadline, acceptRetries int) TestHarnessConfig { 171 return TestHarnessConfig{ 172 BindAddr: privval.GetFreeLocalhostAddrPort(), 173 KeyFile: makeTempFile("tm-testharness-keyfile", keyFileContents), 174 StateFile: makeTempFile("tm-testharness-statefile", stateFileContents), 175 GenesisFile: makeTempFile("tm-testharness-genesisfile", genesisFileContents), 176 AcceptDeadline: time.Duration(acceptDeadline) * time.Millisecond, 177 ConnDeadline: time.Duration(defaultConnDeadline) * time.Millisecond, 178 AcceptRetries: acceptRetries, 179 SecretConnKey: ed25519.GenPrivKey(), 180 ExitWhenComplete: false, 181 } 182 } 183 184 func cleanup(cfg TestHarnessConfig) { 185 os.Remove(cfg.KeyFile) 186 os.Remove(cfg.StateFile) 187 os.Remove(cfg.GenesisFile) 188 } 189 190 func makeTempFile(name, content string) string { 191 tempFile, err := ioutil.TempFile("", fmt.Sprintf("%s-*", name)) 192 if err != nil { 193 panic(err) 194 } 195 if _, err := tempFile.Write([]byte(content)); err != nil { 196 tempFile.Close() 197 panic(err) 198 } 199 if err := tempFile.Close(); err != nil { 200 panic(err) 201 } 202 return tempFile.Name() 203 }