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