You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
3.1 KiB

Close and retry a RemoteSigner on err (#2923) * Close and recreate a RemoteSigner on err * Update changelog * Address Anton's comments / suggestions: - update changelog - restart TCPVal - shut down on `ErrUnexpectedResponse` * re-init remote signer client with fresh connection if Ping fails - add/update TODOs in secret connection - rename tcp.go -> tcp_client.go, same with ipc to clarify their purpose * account for `conn returned by waitConnection can be `nil` - also add TODO about RemoteSigner conn field * Tests for retrying: IPC / TCP - shorter info log on success - set conn and use it in tests to close conn * Tests for retrying: IPC / TCP - shorter info log on success - set conn and use it in tests to close conn - add rwmutex for conn field in IPC * comments and doc.go * fix ipc tests. fixes #2677 * use constants for tests * cleanup some error statements * fixes #2784, race in tests * remove print statement * minor fixes from review * update comment on sts spec * cosmetics * p2p/conn: add failing tests * p2p/conn: make SecretConnection thread safe * changelog * IPCVal signer refactor - use a .reset() method - don't use embedded RemoteSignerClient - guard RemoteSignerClient with mutex - drop the .conn - expose Close() on RemoteSignerClient * apply IPCVal refactor to TCPVal * remove mtx from RemoteSignerClient * consolidate IPCVal and TCPVal, fixes #3104 - done in tcp_client.go - now called SocketVal - takes a listener in the constructor - make tcpListener and unixListener contain all the differences * delete ipc files * introduce unix and tcp dialer for RemoteSigner * rename files - drop tcp_ prefix - rename priv_validator.go to file.go * bring back listener options * fix node * fix priv_val_server * fix node test * minor cleanup and comments
6 years ago
Close and retry a RemoteSigner on err (#2923) * Close and recreate a RemoteSigner on err * Update changelog * Address Anton's comments / suggestions: - update changelog - restart TCPVal - shut down on `ErrUnexpectedResponse` * re-init remote signer client with fresh connection if Ping fails - add/update TODOs in secret connection - rename tcp.go -> tcp_client.go, same with ipc to clarify their purpose * account for `conn returned by waitConnection can be `nil` - also add TODO about RemoteSigner conn field * Tests for retrying: IPC / TCP - shorter info log on success - set conn and use it in tests to close conn * Tests for retrying: IPC / TCP - shorter info log on success - set conn and use it in tests to close conn - add rwmutex for conn field in IPC * comments and doc.go * fix ipc tests. fixes #2677 * use constants for tests * cleanup some error statements * fixes #2784, race in tests * remove print statement * minor fixes from review * update comment on sts spec * cosmetics * p2p/conn: add failing tests * p2p/conn: make SecretConnection thread safe * changelog * IPCVal signer refactor - use a .reset() method - don't use embedded RemoteSignerClient - guard RemoteSignerClient with mutex - drop the .conn - expose Close() on RemoteSignerClient * apply IPCVal refactor to TCPVal * remove mtx from RemoteSignerClient * consolidate IPCVal and TCPVal, fixes #3104 - done in tcp_client.go - now called SocketVal - takes a listener in the constructor - make tcpListener and unixListener contain all the differences * delete ipc files * introduce unix and tcp dialer for RemoteSigner * rename files - drop tcp_ prefix - rename priv_validator.go to file.go * bring back listener options * fix node * fix priv_val_server * fix node test * minor cleanup and comments
6 years ago
  1. package privval
  2. import (
  3. "io/ioutil"
  4. "net"
  5. "os"
  6. "testing"
  7. "time"
  8. "github.com/tendermint/tendermint/crypto/ed25519"
  9. )
  10. //-------------------------------------------
  11. // helper funcs
  12. func newPrivKey() ed25519.PrivKeyEd25519 {
  13. return ed25519.GenPrivKey()
  14. }
  15. //-------------------------------------------
  16. // tests
  17. type listenerTestCase struct {
  18. description string // For test reporting purposes.
  19. listener net.Listener
  20. dialer Dialer
  21. }
  22. // testUnixAddr will attempt to obtain a platform-independent temporary file
  23. // name for a Unix socket
  24. func testUnixAddr() (string, error) {
  25. f, err := ioutil.TempFile("", "tendermint-privval-test-*")
  26. if err != nil {
  27. return "", err
  28. }
  29. addr := f.Name()
  30. f.Close()
  31. os.Remove(addr)
  32. return addr, nil
  33. }
  34. func tcpListenerTestCase(t *testing.T, acceptDeadline, connectDeadline time.Duration) listenerTestCase {
  35. ln, err := net.Listen("tcp", "127.0.0.1:0")
  36. if err != nil {
  37. t.Fatal(err)
  38. }
  39. tcpLn := NewTCPListener(ln, newPrivKey())
  40. TCPListenerAcceptDeadline(acceptDeadline)(tcpLn)
  41. TCPListenerConnDeadline(connectDeadline)(tcpLn)
  42. return listenerTestCase{
  43. description: "TCP",
  44. listener: tcpLn,
  45. dialer: DialTCPFn(ln.Addr().String(), testConnDeadline, newPrivKey()),
  46. }
  47. }
  48. func unixListenerTestCase(t *testing.T, acceptDeadline, connectDeadline time.Duration) listenerTestCase {
  49. addr, err := testUnixAddr()
  50. if err != nil {
  51. t.Fatal(err)
  52. }
  53. ln, err := net.Listen("unix", addr)
  54. if err != nil {
  55. t.Fatal(err)
  56. }
  57. unixLn := NewUnixListener(ln)
  58. UnixListenerAcceptDeadline(acceptDeadline)(unixLn)
  59. UnixListenerConnDeadline(connectDeadline)(unixLn)
  60. return listenerTestCase{
  61. description: "Unix",
  62. listener: unixLn,
  63. dialer: DialUnixFn(addr),
  64. }
  65. }
  66. func listenerTestCases(t *testing.T, acceptDeadline, connectDeadline time.Duration) []listenerTestCase {
  67. return []listenerTestCase{
  68. tcpListenerTestCase(t, acceptDeadline, connectDeadline),
  69. unixListenerTestCase(t, acceptDeadline, connectDeadline),
  70. }
  71. }
  72. func TestListenerAcceptDeadlines(t *testing.T) {
  73. for _, tc := range listenerTestCases(t, time.Millisecond, time.Second) {
  74. _, err := tc.listener.Accept()
  75. opErr, ok := err.(*net.OpError)
  76. if !ok {
  77. t.Fatalf("for %s listener, have %v, want *net.OpError", tc.description, err)
  78. }
  79. if have, want := opErr.Op, "accept"; have != want {
  80. t.Errorf("for %s listener, have %v, want %v", tc.description, have, want)
  81. }
  82. }
  83. }
  84. func TestListenerConnectDeadlines(t *testing.T) {
  85. for _, tc := range listenerTestCases(t, time.Second, time.Millisecond) {
  86. readyc := make(chan struct{})
  87. donec := make(chan struct{})
  88. go func(ln net.Listener) {
  89. defer close(donec)
  90. c, err := ln.Accept()
  91. if err != nil {
  92. t.Fatal(err)
  93. }
  94. <-readyc
  95. time.Sleep(2 * time.Millisecond)
  96. msg := make([]byte, 200)
  97. _, err = c.Read(msg)
  98. opErr, ok := err.(*net.OpError)
  99. if !ok {
  100. t.Fatalf("for %s listener, have %v, want *net.OpError", tc.description, err)
  101. }
  102. if have, want := opErr.Op, "read"; have != want {
  103. t.Errorf("for %s listener, have %v, want %v", tc.description, have, want)
  104. }
  105. }(tc.listener)
  106. _, err := tc.dialer()
  107. if err != nil {
  108. t.Fatal(err)
  109. }
  110. close(readyc)
  111. <-donec
  112. }
  113. }