diff options
Diffstat (limited to 'src/pkg/net/dial_test.go')
-rw-r--r-- | src/pkg/net/dial_test.go | 114 |
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) +} |