~ubuntu-branches/ubuntu/saucy/golang/saucy

« back to all changes in this revision

Viewing changes to src/pkg/net/dial_test.go

  • Committer: Package Import Robot
  • Author(s): Adam Conrad
  • Date: 2013-07-08 05:52:37 UTC
  • mfrom: (29.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20130708055237-at01839e0hp8z3ni
Tags: 2:1.1-1ubuntu1
016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
import (
8
8
        "flag"
9
9
        "fmt"
 
10
        "io"
 
11
        "os"
 
12
        "reflect"
10
13
        "regexp"
11
14
        "runtime"
12
15
        "testing"
25
28
}
26
29
 
27
30
func TestDialTimeout(t *testing.T) {
 
31
        origBacklog := listenerBacklog
 
32
        defer func() {
 
33
                listenerBacklog = origBacklog
 
34
        }()
 
35
        listenerBacklog = 1
 
36
 
28
37
        ln := newLocalListener(t)
29
38
        defer ln.Close()
30
39
 
31
40
        errc := make(chan error)
32
41
 
33
 
        numConns := listenerBacklog + 10
 
42
        numConns := listenerBacklog + 100
34
43
 
35
44
        // TODO(bradfitz): It's hard to test this in a portable
36
45
        // way. This is unfortunate, but works for now.
55
64
                // on our 386 builder, this Dial succeeds, connecting
56
65
                // to an IIS web server somewhere.  The data center
57
66
                // or VM or firewall must be stealing the TCP connection.
58
 
                // 
 
67
                //
59
68
                // IANA Service Name and Transport Protocol Port Number Registry
60
69
                // <http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml>
61
70
                go func() {
72
81
                // by default. FreeBSD likely works, but is untested.
73
82
                // TODO(rsc):
74
83
                // The timeout never happens on Windows.  Why?  Issue 3016.
75
 
                t.Logf("skipping test on %q; untested.", runtime.GOOS)
76
 
                return
 
84
                t.Skipf("skipping test on %q; untested.", runtime.GOOS)
77
85
        }
78
86
 
79
87
        connected := 0
105
113
func TestSelfConnect(t *testing.T) {
106
114
        if runtime.GOOS == "windows" {
107
115
                // TODO(brainman): do not know why it hangs.
108
 
                t.Logf("skipping known-broken test on windows")
109
 
                return
 
116
                t.Skip("skipping known-broken test on windows")
110
117
        }
111
118
        // Test that Dial does not honor self-connects.
112
119
        // See the comment in DialTCP.
130
137
                n = 1000
131
138
        }
132
139
        switch runtime.GOOS {
133
 
        case "darwin", "freebsd", "openbsd", "windows":
 
140
        case "darwin", "freebsd", "netbsd", "openbsd", "plan9", "windows":
134
141
                // Non-Linux systems take a long time to figure
135
142
                // out that there is nothing listening on localhost.
136
143
                n = 100
222
229
                }
223
230
        }
224
231
}
 
232
 
 
233
var invalidDialAndListenArgTests = []struct {
 
234
        net  string
 
235
        addr string
 
236
        err  error
 
237
}{
 
238
        {"foo", "bar", &OpError{Op: "dial", Net: "foo", Addr: nil, Err: UnknownNetworkError("foo")}},
 
239
        {"baz", "", &OpError{Op: "listen", Net: "baz", Addr: nil, Err: UnknownNetworkError("baz")}},
 
240
        {"tcp", "", &OpError{Op: "dial", Net: "tcp", Addr: nil, Err: errMissingAddress}},
 
241
}
 
242
 
 
243
func TestInvalidDialAndListenArgs(t *testing.T) {
 
244
        for _, tt := range invalidDialAndListenArgTests {
 
245
                var err error
 
246
                switch tt.err.(*OpError).Op {
 
247
                case "dial":
 
248
                        _, err = Dial(tt.net, tt.addr)
 
249
                case "listen":
 
250
                        _, err = Listen(tt.net, tt.addr)
 
251
                }
 
252
                if !reflect.DeepEqual(tt.err, err) {
 
253
                        t.Fatalf("got %#v; expected %#v", err, tt.err)
 
254
                }
 
255
        }
 
256
}
 
257
 
 
258
func TestDialTimeoutFDLeak(t *testing.T) {
 
259
        if runtime.GOOS != "linux" {
 
260
                // TODO(bradfitz): test on other platforms
 
261
                t.Skipf("skipping test on %q", runtime.GOOS)
 
262
        }
 
263
 
 
264
        ln := newLocalListener(t)
 
265
        defer ln.Close()
 
266
 
 
267
        type connErr struct {
 
268
                conn Conn
 
269
                err  error
 
270
        }
 
271
        dials := listenerBacklog + 100
 
272
        // used to be listenerBacklog + 5, but was found to be unreliable, issue 4384.
 
273
        maxGoodConnect := listenerBacklog + runtime.NumCPU()*10
 
274
        resc := make(chan connErr)
 
275
        for i := 0; i < dials; i++ {
 
276
                go func() {
 
277
                        conn, err := DialTimeout("tcp", ln.Addr().String(), 500*time.Millisecond)
 
278
                        resc <- connErr{conn, err}
 
279
                }()
 
280
        }
 
281
 
 
282
        var firstErr string
 
283
        var ngood int
 
284
        var toClose []io.Closer
 
285
        for i := 0; i < dials; i++ {
 
286
                ce := <-resc
 
287
                if ce.err == nil {
 
288
                        ngood++
 
289
                        if ngood > maxGoodConnect {
 
290
                                t.Errorf("%d good connects; expected at most %d", ngood, maxGoodConnect)
 
291
                        }
 
292
                        toClose = append(toClose, ce.conn)
 
293
                        continue
 
294
                }
 
295
                err := ce.err
 
296
                if firstErr == "" {
 
297
                        firstErr = err.Error()
 
298
                } else if err.Error() != firstErr {
 
299
                        t.Fatalf("inconsistent error messages: first was %q, then later %q", firstErr, err)
 
300
                }
 
301
        }
 
302
        for _, c := range toClose {
 
303
                c.Close()
 
304
        }
 
305
        for i := 0; i < 100; i++ {
 
306
                if got := numFD(); got < dials {
 
307
                        // Test passes.
 
308
                        return
 
309
                }
 
310
                time.Sleep(10 * time.Millisecond)
 
311
        }
 
312
        if got := numFD(); got >= dials {
 
313
                t.Errorf("num fds after %d timeouts = %d; want <%d", dials, got, dials)
 
314
        }
 
315
}
 
316
 
 
317
func numFD() int {
 
318
        if runtime.GOOS == "linux" {
 
319
                f, err := os.Open("/proc/self/fd")
 
320
                if err != nil {
 
321
                        panic(err)
 
322
                }
 
323
                defer f.Close()
 
324
                names, err := f.Readdirnames(0)
 
325
                if err != nil {
 
326
                        panic(err)
 
327
                }
 
328
                return len(names)
 
329
        }
 
330
        // All tests using this should be skipped anyway, but:
 
331
        panic("numFDs not implemented on " + runtime.GOOS)
 
332
}
 
333
 
 
334
var testPoller = flag.Bool("poller", false, "platform supports runtime-integrated poller")
 
335
 
 
336
// Assert that a failed Dial attempt does not leak
 
337
// runtime.PollDesc structures
 
338
func TestDialFailPDLeak(t *testing.T) {
 
339
        if !*testPoller {
 
340
                t.Skip("test disabled; use -poller to enable")
 
341
        }
 
342
 
 
343
        const loops = 10
 
344
        const count = 20000
 
345
        var old runtime.MemStats // used by sysdelta
 
346
        runtime.ReadMemStats(&old)
 
347
        sysdelta := func() uint64 {
 
348
                var new runtime.MemStats
 
349
                runtime.ReadMemStats(&new)
 
350
                delta := old.Sys - new.Sys
 
351
                old = new
 
352
                return delta
 
353
        }
 
354
        d := &Dialer{Timeout: time.Nanosecond} // don't bother TCP with handshaking
 
355
        failcount := 0
 
356
        for i := 0; i < loops; i++ {
 
357
                for i := 0; i < count; i++ {
 
358
                        conn, err := d.Dial("tcp", "127.0.0.1:1")
 
359
                        if err == nil {
 
360
                                t.Error("dial should not succeed")
 
361
                                conn.Close()
 
362
                                t.FailNow()
 
363
                        }
 
364
                }
 
365
                if delta := sysdelta(); delta > 0 {
 
366
                        failcount++
 
367
                }
 
368
                // there are always some allocations on the first loop
 
369
                if failcount > 3 {
 
370
                        t.Error("detected possible memory leak in runtime")
 
371
                        t.FailNow()
 
372
                }
 
373
        }
 
374
}
 
375
 
 
376
func TestDialer(t *testing.T) {
 
377
        ln, err := Listen("tcp4", "127.0.0.1:0")
 
378
        if err != nil {
 
379
                t.Fatalf("Listen failed: %v", err)
 
380
        }
 
381
        defer ln.Close()
 
382
        ch := make(chan error, 1)
 
383
        go func() {
 
384
                var err error
 
385
                c, err := ln.Accept()
 
386
                if err != nil {
 
387
                        ch <- fmt.Errorf("Accept failed: %v", err)
 
388
                        return
 
389
                }
 
390
                defer c.Close()
 
391
                ch <- nil
 
392
        }()
 
393
 
 
394
        laddr, err := ResolveTCPAddr("tcp4", "127.0.0.1:0")
 
395
        if err != nil {
 
396
                t.Fatalf("ResolveTCPAddr failed: %v", err)
 
397
        }
 
398
        d := &Dialer{LocalAddr: laddr}
 
399
        c, err := d.Dial("tcp4", ln.Addr().String())
 
400
        if err != nil {
 
401
                t.Fatalf("Dial failed: %v", err)
 
402
        }
 
403
        defer c.Close()
 
404
        c.Read(make([]byte, 1))
 
405
        err = <-ch
 
406
        if err != nil {
 
407
                t.Error(err)
 
408
        }
 
409
}