summaryrefslogtreecommitdiff
path: root/src/pkg/net/dial_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/net/dial_test.go')
-rw-r--r--src/pkg/net/dial_test.go114
1 files changed, 108 insertions, 6 deletions
diff --git a/src/pkg/net/dial_test.go b/src/pkg/net/dial_test.go
index 7212087fe..2303e8fa4 100644
--- a/src/pkg/net/dial_test.go
+++ b/src/pkg/net/dial_test.go
@@ -7,6 +7,9 @@ package net
import (
"flag"
"fmt"
+ "io"
+ "os"
+ "reflect"
"regexp"
"runtime"
"testing"
@@ -55,7 +58,7 @@ func TestDialTimeout(t *testing.T) {
// on our 386 builder, this Dial succeeds, connecting
// to an IIS web server somewhere. The data center
// or VM or firewall must be stealing the TCP connection.
- //
+ //
// IANA Service Name and Transport Protocol Port Number Registry
// <http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml>
go func() {
@@ -72,8 +75,7 @@ func TestDialTimeout(t *testing.T) {
// by default. FreeBSD likely works, but is untested.
// TODO(rsc):
// The timeout never happens on Windows. Why? Issue 3016.
- t.Logf("skipping test on %q; untested.", runtime.GOOS)
- return
+ t.Skipf("skipping test on %q; untested.", runtime.GOOS)
}
connected := 0
@@ -105,8 +107,7 @@ func TestDialTimeout(t *testing.T) {
func TestSelfConnect(t *testing.T) {
if runtime.GOOS == "windows" {
// TODO(brainman): do not know why it hangs.
- t.Logf("skipping known-broken test on windows")
- return
+ t.Skip("skipping known-broken test on windows")
}
// Test that Dial does not honor self-connects.
// See the comment in DialTCP.
@@ -130,7 +131,7 @@ func TestSelfConnect(t *testing.T) {
n = 1000
}
switch runtime.GOOS {
- case "darwin", "freebsd", "openbsd", "windows":
+ case "darwin", "freebsd", "netbsd", "openbsd", "plan9", "windows":
// Non-Linux systems take a long time to figure
// out that there is nothing listening on localhost.
n = 100
@@ -222,3 +223,104 @@ func TestDialError(t *testing.T) {
}
}
}
+
+var invalidDialAndListenArgTests = []struct {
+ net string
+ addr string
+ err error
+}{
+ {"foo", "bar", &OpError{Op: "dial", Net: "foo", Addr: nil, Err: UnknownNetworkError("foo")}},
+ {"baz", "", &OpError{Op: "listen", Net: "baz", Addr: nil, Err: UnknownNetworkError("baz")}},
+ {"tcp", "", &OpError{Op: "dial", Net: "tcp", Addr: nil, Err: errMissingAddress}},
+}
+
+func TestInvalidDialAndListenArgs(t *testing.T) {
+ for _, tt := range invalidDialAndListenArgTests {
+ var err error
+ switch tt.err.(*OpError).Op {
+ case "dial":
+ _, err = Dial(tt.net, tt.addr)
+ case "listen":
+ _, err = Listen(tt.net, tt.addr)
+ }
+ if !reflect.DeepEqual(tt.err, err) {
+ t.Fatalf("got %#v; expected %#v", err, tt.err)
+ }
+ }
+}
+
+func TestDialTimeoutFDLeak(t *testing.T) {
+ if runtime.GOOS != "linux" {
+ // TODO(bradfitz): test on other platforms
+ t.Skipf("skipping test on %q", runtime.GOOS)
+ }
+
+ ln := newLocalListener(t)
+ defer ln.Close()
+
+ type connErr struct {
+ conn Conn
+ err error
+ }
+ dials := listenerBacklog + 100
+ // used to be listenerBacklog + 5, but was found to be unreliable, issue 4384.
+ maxGoodConnect := listenerBacklog + runtime.NumCPU()*10
+ resc := make(chan connErr)
+ for i := 0; i < dials; i++ {
+ go func() {
+ conn, err := DialTimeout("tcp", ln.Addr().String(), 500*time.Millisecond)
+ resc <- connErr{conn, err}
+ }()
+ }
+
+ var firstErr string
+ var ngood int
+ var toClose []io.Closer
+ for i := 0; i < dials; i++ {
+ ce := <-resc
+ if ce.err == nil {
+ ngood++
+ if ngood > maxGoodConnect {
+ t.Errorf("%d good connects; expected at most %d", ngood, maxGoodConnect)
+ }
+ toClose = append(toClose, ce.conn)
+ continue
+ }
+ err := ce.err
+ if firstErr == "" {
+ firstErr = err.Error()
+ } else if err.Error() != firstErr {
+ t.Fatalf("inconsistent error messages: first was %q, then later %q", firstErr, err)
+ }
+ }
+ for _, c := range toClose {
+ c.Close()
+ }
+ for i := 0; i < 100; i++ {
+ if got := numFD(); got < dials {
+ // Test passes.
+ return
+ }
+ time.Sleep(10 * time.Millisecond)
+ }
+ if got := numFD(); got >= dials {
+ t.Errorf("num fds after %d timeouts = %d; want <%d", dials, got, dials)
+ }
+}
+
+func numFD() int {
+ if runtime.GOOS == "linux" {
+ f, err := os.Open("/proc/self/fd")
+ if err != nil {
+ panic(err)
+ }
+ defer f.Close()
+ names, err := f.Readdirnames(0)
+ if err != nil {
+ panic(err)
+ }
+ return len(names)
+ }
+ // All tests using this should be skipped anyway, but:
+ panic("numFDs not implemented on " + runtime.GOOS)
+}