github.com/lazyledger/lazyledger-core@v0.35.0-dev.0.20210613111200-4c651f053571/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/lazyledger/lazyledger-core/crypto"
    14  	"github.com/lazyledger/lazyledger-core/crypto/ed25519"
    15  	"github.com/lazyledger/lazyledger-core/libs/log"
    16  	"github.com/lazyledger/lazyledger-core/privval"
    17  	"github.com/lazyledger/lazyledger-core/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  		},
    53  		"validator": {
    54  			"pub_key_types": [
    55  				"ed25519"
    56  			]
    57  		}
    58  	},
    59  	"validators": [
    60  		{
    61  		"address": "D08FCA3BA74CF17CBFC15E64F9505302BB0E2748",
    62  		"pub_key": {
    63  			"type": "tendermint/PubKeyEd25519",
    64  			"value": "ZCsuTjaczEyon70nmKxwvwu+jqrbq5OH3yQjcK0SFxc="
    65  		},
    66  		"power": "10",
    67  		"name": ""
    68  		}
    69  	],
    70  	"app_hash": ""
    71  }`
    72  
    73  	defaultConnDeadline = 100
    74  )
    75  
    76  func TestRemoteSignerTestHarnessMaxAcceptRetriesReached(t *testing.T) {
    77  	cfg := makeConfig(t, 1, 2)
    78  	defer cleanup(cfg)
    79  
    80  	th, err := NewTestHarness(log.TestingLogger(), cfg)
    81  	require.NoError(t, err)
    82  	th.Run()
    83  	assert.Equal(t, ErrMaxAcceptRetriesReached, th.exitCode)
    84  }
    85  
    86  func TestRemoteSignerTestHarnessSuccessfulRun(t *testing.T) {
    87  	harnessTest(
    88  		t,
    89  		func(th *TestHarness) *privval.SignerServer {
    90  			return newMockSignerServer(t, th, th.fpv.Key.PrivKey, false, false)
    91  		},
    92  		NoError,
    93  	)
    94  }
    95  
    96  func TestRemoteSignerPublicKeyCheckFailed(t *testing.T) {
    97  	harnessTest(
    98  		t,
    99  		func(th *TestHarness) *privval.SignerServer {
   100  			return newMockSignerServer(t, th, ed25519.GenPrivKey(), false, false)
   101  		},
   102  		ErrTestPublicKeyFailed,
   103  	)
   104  }
   105  
   106  func TestRemoteSignerProposalSigningFailed(t *testing.T) {
   107  	harnessTest(
   108  		t,
   109  		func(th *TestHarness) *privval.SignerServer {
   110  			return newMockSignerServer(t, th, th.fpv.Key.PrivKey, true, false)
   111  		},
   112  		ErrTestSignProposalFailed,
   113  	)
   114  }
   115  
   116  func TestRemoteSignerVoteSigningFailed(t *testing.T) {
   117  	harnessTest(
   118  		t,
   119  		func(th *TestHarness) *privval.SignerServer {
   120  			return newMockSignerServer(t, th, th.fpv.Key.PrivKey, false, true)
   121  		},
   122  		ErrTestSignVoteFailed,
   123  	)
   124  }
   125  
   126  func newMockSignerServer(
   127  	t *testing.T,
   128  	th *TestHarness,
   129  	privKey crypto.PrivKey,
   130  	breakProposalSigning bool,
   131  	breakVoteSigning bool,
   132  ) *privval.SignerServer {
   133  	mockPV := types.NewMockPVWithParams(privKey, breakProposalSigning, breakVoteSigning)
   134  
   135  	dialerEndpoint := privval.NewSignerDialerEndpoint(
   136  		th.logger,
   137  		privval.DialTCPFn(
   138  			th.addr,
   139  			time.Duration(defaultConnDeadline)*time.Millisecond,
   140  			ed25519.GenPrivKey(),
   141  		),
   142  	)
   143  
   144  	return privval.NewSignerServer(dialerEndpoint, th.chainID, mockPV)
   145  }
   146  
   147  // For running relatively standard tests.
   148  func harnessTest(t *testing.T, signerServerMaker func(th *TestHarness) *privval.SignerServer, expectedExitCode int) {
   149  	cfg := makeConfig(t, 100, 3)
   150  	defer cleanup(cfg)
   151  
   152  	th, err := NewTestHarness(log.TestingLogger(), cfg)
   153  	require.NoError(t, err)
   154  	donec := make(chan struct{})
   155  	go func() {
   156  		defer close(donec)
   157  		th.Run()
   158  	}()
   159  
   160  	ss := signerServerMaker(th)
   161  	require.NoError(t, ss.Start())
   162  	assert.True(t, ss.IsRunning())
   163  	defer ss.Stop() //nolint:errcheck // ignore for tests
   164  
   165  	<-donec
   166  	assert.Equal(t, expectedExitCode, th.exitCode)
   167  }
   168  
   169  func makeConfig(t *testing.T, acceptDeadline, acceptRetries int) TestHarnessConfig {
   170  	return TestHarnessConfig{
   171  		BindAddr:         privval.GetFreeLocalhostAddrPort(),
   172  		KeyFile:          makeTempFile("tm-testharness-keyfile", keyFileContents),
   173  		StateFile:        makeTempFile("tm-testharness-statefile", stateFileContents),
   174  		GenesisFile:      makeTempFile("tm-testharness-genesisfile", genesisFileContents),
   175  		AcceptDeadline:   time.Duration(acceptDeadline) * time.Millisecond,
   176  		ConnDeadline:     time.Duration(defaultConnDeadline) * time.Millisecond,
   177  		AcceptRetries:    acceptRetries,
   178  		SecretConnKey:    ed25519.GenPrivKey(),
   179  		ExitWhenComplete: false,
   180  	}
   181  }
   182  
   183  func cleanup(cfg TestHarnessConfig) {
   184  	os.Remove(cfg.KeyFile)
   185  	os.Remove(cfg.StateFile)
   186  	os.Remove(cfg.GenesisFile)
   187  }
   188  
   189  func makeTempFile(name, content string) string {
   190  	tempFile, err := ioutil.TempFile("", fmt.Sprintf("%s-*", name))
   191  	if err != nil {
   192  		panic(err)
   193  	}
   194  	if _, err := tempFile.Write([]byte(content)); err != nil {
   195  		tempFile.Close()
   196  		panic(err)
   197  	}
   198  	if err := tempFile.Close(); err != nil {
   199  		panic(err)
   200  	}
   201  	return tempFile.Name()
   202  }