- package privval
-
- import (
- "io/ioutil"
- "net"
- "os"
- "testing"
- "time"
-
- "github.com/tendermint/tendermint/crypto/ed25519"
- )
-
- //-------------------------------------------
- // helper funcs
-
- func newPrivKey() ed25519.PrivKey {
- return ed25519.GenPrivKey()
- }
-
- //-------------------------------------------
- // tests
-
- type listenerTestCase struct {
- description string // For test reporting purposes.
- listener net.Listener
- dialer SocketDialer
- }
-
- // testUnixAddr will attempt to obtain a platform-independent temporary file
- // name for a Unix socket
- func testUnixAddr() (string, error) {
- f, err := ioutil.TempFile("", "tendermint-privval-test-*")
- if err != nil {
- return "", err
- }
- addr := f.Name()
- f.Close()
- os.Remove(addr)
- return addr, nil
- }
-
- func tcpListenerTestCase(t *testing.T, timeoutAccept, timeoutReadWrite time.Duration) listenerTestCase {
- ln, err := net.Listen("tcp", "127.0.0.1:0")
- if err != nil {
- t.Fatal(err)
- }
-
- tcpLn := NewTCPListener(ln, newPrivKey())
- TCPListenerTimeoutAccept(timeoutAccept)(tcpLn)
- TCPListenerTimeoutReadWrite(timeoutReadWrite)(tcpLn)
- return listenerTestCase{
- description: "TCP",
- listener: tcpLn,
- dialer: DialTCPFn(ln.Addr().String(), testTimeoutReadWrite, newPrivKey()),
- }
- }
-
- func unixListenerTestCase(t *testing.T, timeoutAccept, timeoutReadWrite time.Duration) listenerTestCase {
- addr, err := testUnixAddr()
- if err != nil {
- t.Fatal(err)
- }
- ln, err := net.Listen("unix", addr)
- if err != nil {
- t.Fatal(err)
- }
-
- unixLn := NewUnixListener(ln)
- UnixListenerTimeoutAccept(timeoutAccept)(unixLn)
- UnixListenerTimeoutReadWrite(timeoutReadWrite)(unixLn)
- return listenerTestCase{
- description: "Unix",
- listener: unixLn,
- dialer: DialUnixFn(addr),
- }
- }
-
- func listenerTestCases(t *testing.T, timeoutAccept, timeoutReadWrite time.Duration) []listenerTestCase {
- return []listenerTestCase{
- tcpListenerTestCase(t, timeoutAccept, timeoutReadWrite),
- unixListenerTestCase(t, timeoutAccept, timeoutReadWrite),
- }
- }
-
- func TestListenerTimeoutAccept(t *testing.T) {
- for _, tc := range listenerTestCases(t, time.Millisecond, time.Second) {
- _, err := tc.listener.Accept()
- opErr, ok := err.(*net.OpError)
- if !ok {
- t.Fatalf("for %s listener, have %v, want *net.OpError", tc.description, err)
- }
-
- if have, want := opErr.Op, "accept"; have != want {
- t.Errorf("for %s listener, have %v, want %v", tc.description, have, want)
- }
- }
- }
-
- func TestListenerTimeoutReadWrite(t *testing.T) {
- const (
- // This needs to be long enough s.t. the Accept will definitely succeed:
- timeoutAccept = time.Second
- // This can be really short but in the TCP case, the accept can
- // also trigger a timeoutReadWrite. Hence, we need to give it some time.
- // Note: this controls how long this test actually runs.
- timeoutReadWrite = 10 * time.Millisecond
- )
- for _, tc := range listenerTestCases(t, timeoutAccept, timeoutReadWrite) {
- go func(dialer SocketDialer) {
- _, err := dialer()
- if err != nil {
- panic(err)
- }
- }(tc.dialer)
-
- c, err := tc.listener.Accept()
- if err != nil {
- t.Fatal(err)
- }
-
- // this will timeout because we don't write anything:
- msg := make([]byte, 200)
- _, err = c.Read(msg)
- opErr, ok := err.(*net.OpError)
- if !ok {
- t.Fatalf("for %s listener, have %v, want *net.OpError", tc.description, err)
- }
-
- if have, want := opErr.Op, "read"; have != want {
- t.Errorf("for %s listener, have %v, want %v", tc.description, have, want)
- }
-
- if !opErr.Timeout() {
- t.Errorf("for %s listener, got unexpected error: have %v, want Timeout error", tc.description, opErr)
- }
- }
- }
|