github.com/noirx94/tendermintmp@v0.0.1/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/tendermint/tendermint/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  }