github.com/DFWallet/tendermint-cosmos@v0.0.2/privval/socket_listeners_test.go (about) 1 package privval 2 3 import ( 4 "io/ioutil" 5 "net" 6 "os" 7 "testing" 8 "time" 9 10 "github.com/DFWallet/tendermint-cosmos/crypto/ed25519" 11 ) 12 13 //------------------------------------------- 14 // helper funcs 15 16 func newPrivKey() ed25519.PrivKey { 17 return ed25519.GenPrivKey() 18 } 19 20 //------------------------------------------- 21 // tests 22 23 type listenerTestCase struct { 24 description string // For test reporting purposes. 25 listener net.Listener 26 dialer SocketDialer 27 } 28 29 // testUnixAddr will attempt to obtain a platform-independent temporary file 30 // name for a Unix socket 31 func testUnixAddr() (string, error) { 32 f, err := ioutil.TempFile("", "tendermint-privval-test-*") 33 if err != nil { 34 return "", err 35 } 36 addr := f.Name() 37 f.Close() 38 os.Remove(addr) 39 return addr, nil 40 } 41 42 func tcpListenerTestCase(t *testing.T, timeoutAccept, timeoutReadWrite time.Duration) listenerTestCase { 43 ln, err := net.Listen("tcp", "127.0.0.1:0") 44 if err != nil { 45 t.Fatal(err) 46 } 47 48 tcpLn := NewTCPListener(ln, newPrivKey()) 49 TCPListenerTimeoutAccept(timeoutAccept)(tcpLn) 50 TCPListenerTimeoutReadWrite(timeoutReadWrite)(tcpLn) 51 return listenerTestCase{ 52 description: "TCP", 53 listener: tcpLn, 54 dialer: DialTCPFn(ln.Addr().String(), testTimeoutReadWrite, newPrivKey()), 55 } 56 } 57 58 func unixListenerTestCase(t *testing.T, timeoutAccept, timeoutReadWrite time.Duration) listenerTestCase { 59 addr, err := testUnixAddr() 60 if err != nil { 61 t.Fatal(err) 62 } 63 ln, err := net.Listen("unix", addr) 64 if err != nil { 65 t.Fatal(err) 66 } 67 68 unixLn := NewUnixListener(ln) 69 UnixListenerTimeoutAccept(timeoutAccept)(unixLn) 70 UnixListenerTimeoutReadWrite(timeoutReadWrite)(unixLn) 71 return listenerTestCase{ 72 description: "Unix", 73 listener: unixLn, 74 dialer: DialUnixFn(addr), 75 } 76 } 77 78 func listenerTestCases(t *testing.T, timeoutAccept, timeoutReadWrite time.Duration) []listenerTestCase { 79 return []listenerTestCase{ 80 tcpListenerTestCase(t, timeoutAccept, timeoutReadWrite), 81 unixListenerTestCase(t, timeoutAccept, timeoutReadWrite), 82 } 83 } 84 85 func TestListenerTimeoutAccept(t *testing.T) { 86 for _, tc := range listenerTestCases(t, time.Millisecond, time.Second) { 87 _, err := tc.listener.Accept() 88 opErr, ok := err.(*net.OpError) 89 if !ok { 90 t.Fatalf("for %s listener, have %v, want *net.OpError", tc.description, err) 91 } 92 93 if have, want := opErr.Op, "accept"; have != want { 94 t.Errorf("for %s listener, have %v, want %v", tc.description, have, want) 95 } 96 } 97 } 98 99 func TestListenerTimeoutReadWrite(t *testing.T) { 100 const ( 101 // This needs to be long enough s.t. the Accept will definitely succeed: 102 timeoutAccept = time.Second 103 // This can be really short but in the TCP case, the accept can 104 // also trigger a timeoutReadWrite. Hence, we need to give it some time. 105 // Note: this controls how long this test actually runs. 106 timeoutReadWrite = 10 * time.Millisecond 107 ) 108 for _, tc := range listenerTestCases(t, timeoutAccept, timeoutReadWrite) { 109 go func(dialer SocketDialer) { 110 _, err := dialer() 111 if err != nil { 112 panic(err) 113 } 114 }(tc.dialer) 115 116 c, err := tc.listener.Accept() 117 if err != nil { 118 t.Fatal(err) 119 } 120 121 // this will timeout because we don't write anything: 122 msg := make([]byte, 200) 123 _, err = c.Read(msg) 124 opErr, ok := err.(*net.OpError) 125 if !ok { 126 t.Fatalf("for %s listener, have %v, want *net.OpError", tc.description, err) 127 } 128 129 if have, want := opErr.Op, "read"; have != want { 130 t.Errorf("for %s listener, have %v, want %v", tc.description, have, want) 131 } 132 133 if !opErr.Timeout() { 134 t.Errorf("for %s listener, got unexpected error: have %v, want Timeout error", tc.description, opErr) 135 } 136 } 137 }