From 5f93220c614c349d0018bb6728da31aa37cb24e3 Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Mon, 14 Jan 2019 11:41:09 +0200 Subject: [PATCH 1/3] Adds tests for Unix sockets As per #3115, adds simple Unix socket connect/accept deadline tests in pretty much the same way as the TCP connect/accept deadline tests work. --- privval/socket_test.go | 88 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/privval/socket_test.go b/privval/socket_test.go index 0c05fa3a0..808a57aee 100644 --- a/privval/socket_test.go +++ b/privval/socket_test.go @@ -1,7 +1,9 @@ package privval import ( + "io/ioutil" "net" + "os" "testing" "time" @@ -82,3 +84,89 @@ func TestTCPListenerConnDeadline(t *testing.T) { close(readyc) <-donec } + +// 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 TestUnixListenerAcceptDeadline(t *testing.T) { + addr, err := testUnixAddr() + if err != nil { + t.Fatal(err) + } + ln, err := net.Listen("unix", addr) + if err != nil { + t.Fatal(err) + } + + unixLn := NewUnixListener(ln) + UnixListenerAcceptDeadline(time.Millisecond)(unixLn) + UnixListenerConnDeadline(time.Second)(unixLn) + + _, err = unixLn.Accept() + opErr, ok := err.(*net.OpError) + if !ok { + t.Fatalf("have %v, want *net.OpError", err) + } + + if have, want := opErr.Op, "accept"; have != want { + t.Errorf("have %v, want %v", have, want) + } +} + +func TestUnixListenerConnDeadline(t *testing.T) { + addr, err := testUnixAddr() + if err != nil { + t.Fatal(err) + } + ln, err := net.Listen("unix", addr) + if err != nil { + t.Fatal(err) + } + + unixLn := NewUnixListener(ln) + UnixListenerAcceptDeadline(time.Second)(unixLn) + UnixListenerConnDeadline(time.Millisecond)(unixLn) + + readyc := make(chan struct{}) + donec := make(chan struct{}) + go func(ln net.Listener) { + defer close(donec) + + c, err := ln.Accept() + if err != nil { + t.Fatal(err) + } + <-readyc + + time.Sleep(2 * time.Millisecond) + + msg := make([]byte, 200) + _, err = c.Read(msg) + opErr, ok := err.(*net.OpError) + if !ok { + t.Fatalf("have %v, want *net.OpError", err) + } + + if have, want := opErr.Op, "read"; have != want { + t.Errorf("have %v, want %v", have, want) + } + }(unixLn) + + dialer := DialUnixFn(addr) + _, err = dialer() + if err != nil { + t.Fatal(err) + } + close(readyc) + <-donec +} From ca00cd6a78be56884873257ed4bd5f61f3210d5b Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Tue, 15 Jan 2019 10:14:41 +0200 Subject: [PATCH 2/3] Make privval listener testing generic This cuts out two tests by constructing test cases and iterating through them, rather than having separate sets of tests for TCP and Unix listeners. This is as per the feedback from #3121. --- privval/socket_test.go | 183 ++++++++++++++++------------------------- 1 file changed, 72 insertions(+), 111 deletions(-) diff --git a/privval/socket_test.go b/privval/socket_test.go index 808a57aee..88d9ef8e5 100644 --- a/privval/socket_test.go +++ b/privval/socket_test.go @@ -20,74 +20,15 @@ func newPrivKey() ed25519.PrivKeyEd25519 { //------------------------------------------- // tests -func TestTCPListenerAcceptDeadline(t *testing.T) { - ln, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - t.Fatal(err) - } - - tcpLn := NewTCPListener(ln, newPrivKey()) - TCPListenerAcceptDeadline(time.Millisecond)(tcpLn) - TCPListenerConnDeadline(time.Second)(tcpLn) - - _, err = tcpLn.Accept() - opErr, ok := err.(*net.OpError) - if !ok { - t.Fatalf("have %v, want *net.OpError", err) - } - - if have, want := opErr.Op, "accept"; have != want { - t.Errorf("have %v, want %v", have, want) - } -} - -func TestTCPListenerConnDeadline(t *testing.T) { - ln, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - t.Fatal(err) - } - - tcpLn := NewTCPListener(ln, newPrivKey()) - TCPListenerAcceptDeadline(time.Second)(tcpLn) - TCPListenerConnDeadline(time.Millisecond)(tcpLn) - - readyc := make(chan struct{}) - donec := make(chan struct{}) - go func(ln net.Listener) { - defer close(donec) - - c, err := ln.Accept() - if err != nil { - t.Fatal(err) - } - <-readyc - - time.Sleep(2 * time.Millisecond) - - msg := make([]byte, 200) - _, err = c.Read(msg) - opErr, ok := err.(*net.OpError) - if !ok { - t.Fatalf("have %v, want *net.OpError", err) - } - - if have, want := opErr.Op, "read"; have != want { - t.Errorf("have %v, want %v", have, want) - } - }(tcpLn) - - dialer := DialTCPFn(ln.Addr().String(), testConnDeadline, newPrivKey()) - _, err = dialer() - if err != nil { - t.Fatal(err) - } - close(readyc) - <-donec +type listenerTestCase struct { + description string // For test reporting purposes. + listener net.Listener + dialer Dialer } -// testUnixAddr will attempt to obtain a platform-independent temporary file +// getTestUnixAddr will attempt to obtain a platform-independent temporary file // name for a Unix socket -func testUnixAddr() (string, error) { +func getTestUnixAddr() (string, error) { f, err := ioutil.TempFile("", "tendermint-privval-test") if err != nil { return "", err @@ -98,33 +39,24 @@ func testUnixAddr() (string, error) { return addr, nil } -func TestUnixListenerAcceptDeadline(t *testing.T) { - addr, err := testUnixAddr() - if err != nil { - t.Fatal(err) - } - ln, err := net.Listen("unix", addr) +func constructTCPListenerTestCase(t *testing.T, acceptDeadline, connectDeadline time.Duration) listenerTestCase { + ln, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } - unixLn := NewUnixListener(ln) - UnixListenerAcceptDeadline(time.Millisecond)(unixLn) - UnixListenerConnDeadline(time.Second)(unixLn) - - _, err = unixLn.Accept() - opErr, ok := err.(*net.OpError) - if !ok { - t.Fatalf("have %v, want *net.OpError", err) - } - - if have, want := opErr.Op, "accept"; have != want { - t.Errorf("have %v, want %v", have, want) + tcpLn := NewTCPListener(ln, newPrivKey()) + TCPListenerAcceptDeadline(acceptDeadline)(tcpLn) + TCPListenerConnDeadline(connectDeadline)(tcpLn) + return listenerTestCase{ + description: "TCP", + listener: tcpLn, + dialer: DialTCPFn(ln.Addr().String(), testConnDeadline, newPrivKey()), } } -func TestUnixListenerConnDeadline(t *testing.T) { - addr, err := testUnixAddr() +func constructUnixListenerTestCase(t *testing.T, acceptDeadline, connectDeadline time.Duration) listenerTestCase { + addr, err := getTestUnixAddr() if err != nil { t.Fatal(err) } @@ -134,39 +66,68 @@ func TestUnixListenerConnDeadline(t *testing.T) { } unixLn := NewUnixListener(ln) - UnixListenerAcceptDeadline(time.Second)(unixLn) - UnixListenerConnDeadline(time.Millisecond)(unixLn) - - readyc := make(chan struct{}) - donec := make(chan struct{}) - go func(ln net.Listener) { - defer close(donec) - - c, err := ln.Accept() - if err != nil { - t.Fatal(err) - } - <-readyc + UnixListenerAcceptDeadline(acceptDeadline)(unixLn) + UnixListenerConnDeadline(connectDeadline)(unixLn) + return listenerTestCase{ + description: "Unix", + listener: unixLn, + dialer: DialUnixFn(addr), + } +} - time.Sleep(2 * time.Millisecond) +func constructListenerTestCases(t *testing.T, acceptDeadline, connectDeadline time.Duration) []listenerTestCase { + return []listenerTestCase{ + constructTCPListenerTestCase(t, acceptDeadline, connectDeadline), + constructUnixListenerTestCase(t, acceptDeadline, connectDeadline), + } +} - msg := make([]byte, 200) - _, err = c.Read(msg) +func TestListenerAcceptDeadlines(t *testing.T) { + for _, tc := range constructListenerTestCases(t, time.Millisecond, time.Second) { + _, err := tc.listener.Accept() opErr, ok := err.(*net.OpError) if !ok { - t.Fatalf("have %v, want *net.OpError", err) + t.Fatalf("for %s listener, have %v, want *net.OpError", tc.description, err) } - if have, want := opErr.Op, "read"; have != want { - t.Errorf("have %v, want %v", have, want) + if have, want := opErr.Op, "accept"; have != want { + t.Errorf("for %s listener, have %v, want %v", tc.description, have, want) } - }(unixLn) + } +} - dialer := DialUnixFn(addr) - _, err = dialer() - if err != nil { - t.Fatal(err) +func TestListenerConnectDeadlines(t *testing.T) { + for _, tc := range constructListenerTestCases(t, time.Second, time.Millisecond) { + readyc := make(chan struct{}) + donec := make(chan struct{}) + go func(ln net.Listener) { + defer close(donec) + + c, err := ln.Accept() + if err != nil { + t.Fatal(err) + } + <-readyc + + time.Sleep(2 * time.Millisecond) + + 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) + } + }(tc.listener) + + _, err := tc.dialer() + if err != nil { + t.Fatal(err) + } + close(readyc) + <-donec } - close(readyc) - <-donec } From 3191ee8badde5a815da252dbcd77b641dd417521 Mon Sep 17 00:00:00 2001 From: Thane Thomson Date: Tue, 15 Jan 2019 18:06:57 +0200 Subject: [PATCH 3/3] Dropping "construct" prefix as per #3121 --- privval/socket_test.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/privval/socket_test.go b/privval/socket_test.go index 88d9ef8e5..dfce45b57 100644 --- a/privval/socket_test.go +++ b/privval/socket_test.go @@ -26,9 +26,9 @@ type listenerTestCase struct { dialer Dialer } -// getTestUnixAddr will attempt to obtain a platform-independent temporary file +// testUnixAddr will attempt to obtain a platform-independent temporary file // name for a Unix socket -func getTestUnixAddr() (string, error) { +func testUnixAddr() (string, error) { f, err := ioutil.TempFile("", "tendermint-privval-test") if err != nil { return "", err @@ -39,7 +39,7 @@ func getTestUnixAddr() (string, error) { return addr, nil } -func constructTCPListenerTestCase(t *testing.T, acceptDeadline, connectDeadline time.Duration) listenerTestCase { +func tcpListenerTestCase(t *testing.T, acceptDeadline, connectDeadline time.Duration) listenerTestCase { ln, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) @@ -55,8 +55,8 @@ func constructTCPListenerTestCase(t *testing.T, acceptDeadline, connectDeadline } } -func constructUnixListenerTestCase(t *testing.T, acceptDeadline, connectDeadline time.Duration) listenerTestCase { - addr, err := getTestUnixAddr() +func unixListenerTestCase(t *testing.T, acceptDeadline, connectDeadline time.Duration) listenerTestCase { + addr, err := testUnixAddr() if err != nil { t.Fatal(err) } @@ -75,15 +75,15 @@ func constructUnixListenerTestCase(t *testing.T, acceptDeadline, connectDeadline } } -func constructListenerTestCases(t *testing.T, acceptDeadline, connectDeadline time.Duration) []listenerTestCase { +func listenerTestCases(t *testing.T, acceptDeadline, connectDeadline time.Duration) []listenerTestCase { return []listenerTestCase{ - constructTCPListenerTestCase(t, acceptDeadline, connectDeadline), - constructUnixListenerTestCase(t, acceptDeadline, connectDeadline), + tcpListenerTestCase(t, acceptDeadline, connectDeadline), + unixListenerTestCase(t, acceptDeadline, connectDeadline), } } func TestListenerAcceptDeadlines(t *testing.T) { - for _, tc := range constructListenerTestCases(t, time.Millisecond, time.Second) { + for _, tc := range listenerTestCases(t, time.Millisecond, time.Second) { _, err := tc.listener.Accept() opErr, ok := err.(*net.OpError) if !ok { @@ -97,7 +97,7 @@ func TestListenerAcceptDeadlines(t *testing.T) { } func TestListenerConnectDeadlines(t *testing.T) { - for _, tc := range constructListenerTestCases(t, time.Second, time.Millisecond) { + for _, tc := range listenerTestCases(t, time.Second, time.Millisecond) { readyc := make(chan struct{}) donec := make(chan struct{}) go func(ln net.Listener) {