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  }