github.com/vipernet-xyz/tm@v0.34.24/tools/tm-signer-harness/internal/test_harness_test.go (about)

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