From: Mikio Hara Date: Tue, 21 Apr 2015 13:10:09 +0000 (+0900) Subject: net: replace server tests X-Git-Tag: go1.5beta1~967 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=15648d2e77fa8116edd51a13fb5233e8ce0e98b3;p=gostls13.git net: replace server tests This change replaces server tests with new ones that require features introduced after go1 release, such as runtime-integrated network poller, Dialer, etc. Change-Id: Icf1f94f08f33caacd499cfccbe74cda8d05eed30 Reviewed-on: https://go-review.googlesource.com/9195 Reviewed-by: Ian Lance Taylor --- diff --git a/src/net/server_test.go b/src/net/server_test.go index f064782783..d433ecfa4b 100644 --- a/src/net/server_test.go +++ b/src/net/server_test.go @@ -5,359 +5,384 @@ package net import ( - "io" "os" "testing" - "time" ) -var streamConnServerTests = []struct { - snet string // server side - saddr string - cnet string // client side - caddr string - empty bool // test with empty data +var tcpServerTests = []struct { + snet, saddr string // server endpoint + tnet, taddr string // target endpoint for client }{ - {snet: "tcp", saddr: ":0", cnet: "tcp", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "0.0.0.0:0", cnet: "tcp", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", cnet: "tcp", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "[::]:0", cnet: "tcp", caddr: "::1"}, + {snet: "tcp", saddr: ":0", tnet: "tcp", taddr: "127.0.0.1"}, + {snet: "tcp", saddr: "0.0.0.0:0", tnet: "tcp", taddr: "127.0.0.1"}, + {snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp", taddr: "127.0.0.1"}, + {snet: "tcp", saddr: "[::]:0", tnet: "tcp", taddr: "::1"}, - {snet: "tcp", saddr: ":0", cnet: "tcp", caddr: "::1"}, - {snet: "tcp", saddr: "0.0.0.0:0", cnet: "tcp", caddr: "::1"}, - {snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", cnet: "tcp", caddr: "::1"}, - {snet: "tcp", saddr: "[::]:0", cnet: "tcp", caddr: "127.0.0.1"}, + {snet: "tcp", saddr: ":0", tnet: "tcp", taddr: "::1"}, + {snet: "tcp", saddr: "0.0.0.0:0", tnet: "tcp", taddr: "::1"}, + {snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp", taddr: "::1"}, + {snet: "tcp", saddr: "[::]:0", tnet: "tcp", taddr: "127.0.0.1"}, - {snet: "tcp", saddr: ":0", cnet: "tcp4", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "0.0.0.0:0", cnet: "tcp4", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", cnet: "tcp4", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "[::]:0", cnet: "tcp6", caddr: "::1"}, + {snet: "tcp", saddr: ":0", tnet: "tcp4", taddr: "127.0.0.1"}, + {snet: "tcp", saddr: "0.0.0.0:0", tnet: "tcp4", taddr: "127.0.0.1"}, + {snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp4", taddr: "127.0.0.1"}, + {snet: "tcp", saddr: "[::]:0", tnet: "tcp6", taddr: "::1"}, - {snet: "tcp", saddr: ":0", cnet: "tcp6", caddr: "::1"}, - {snet: "tcp", saddr: "0.0.0.0:0", cnet: "tcp6", caddr: "::1"}, - {snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", cnet: "tcp6", caddr: "::1"}, - {snet: "tcp", saddr: "[::]:0", cnet: "tcp4", caddr: "127.0.0.1"}, + {snet: "tcp", saddr: ":0", tnet: "tcp6", taddr: "::1"}, + {snet: "tcp", saddr: "0.0.0.0:0", tnet: "tcp6", taddr: "::1"}, + {snet: "tcp", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp6", taddr: "::1"}, + {snet: "tcp", saddr: "[::]:0", tnet: "tcp4", taddr: "127.0.0.1"}, - {snet: "tcp", saddr: "127.0.0.1:0", cnet: "tcp", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "[::ffff:127.0.0.1]:0", cnet: "tcp", caddr: "127.0.0.1"}, - {snet: "tcp", saddr: "[::1]:0", cnet: "tcp", caddr: "::1"}, + {snet: "tcp", saddr: "127.0.0.1:0", tnet: "tcp", taddr: "127.0.0.1"}, + {snet: "tcp", saddr: "[::ffff:127.0.0.1]:0", tnet: "tcp", taddr: "127.0.0.1"}, + {snet: "tcp", saddr: "[::1]:0", tnet: "tcp", taddr: "::1"}, - {snet: "tcp4", saddr: ":0", cnet: "tcp4", caddr: "127.0.0.1"}, - {snet: "tcp4", saddr: "0.0.0.0:0", cnet: "tcp4", caddr: "127.0.0.1"}, - {snet: "tcp4", saddr: "[::ffff:0.0.0.0]:0", cnet: "tcp4", caddr: "127.0.0.1"}, + {snet: "tcp4", saddr: ":0", tnet: "tcp4", taddr: "127.0.0.1"}, + {snet: "tcp4", saddr: "0.0.0.0:0", tnet: "tcp4", taddr: "127.0.0.1"}, + {snet: "tcp4", saddr: "[::ffff:0.0.0.0]:0", tnet: "tcp4", taddr: "127.0.0.1"}, - {snet: "tcp4", saddr: "127.0.0.1:0", cnet: "tcp4", caddr: "127.0.0.1"}, + {snet: "tcp4", saddr: "127.0.0.1:0", tnet: "tcp4", taddr: "127.0.0.1"}, - {snet: "tcp6", saddr: ":0", cnet: "tcp6", caddr: "::1"}, - {snet: "tcp6", saddr: "[::]:0", cnet: "tcp6", caddr: "::1"}, + {snet: "tcp6", saddr: ":0", tnet: "tcp6", taddr: "::1"}, + {snet: "tcp6", saddr: "[::]:0", tnet: "tcp6", taddr: "::1"}, - {snet: "tcp6", saddr: "[::1]:0", cnet: "tcp6", caddr: "::1"}, - - {snet: "unix", saddr: testUnixAddr(), cnet: "unix", caddr: testUnixAddr()}, - {snet: "unix", saddr: "@gotest2/net", cnet: "unix", caddr: "@gotest2/net.local"}, + {snet: "tcp6", saddr: "[::1]:0", tnet: "tcp6", taddr: "::1"}, } -func TestStreamConnServer(t *testing.T) { - for _, tt := range streamConnServerTests { - if !testableListenArgs(tt.snet, tt.saddr, tt.caddr) { - t.Logf("skipping %s test", tt.snet+":"+tt.saddr+"->"+tt.caddr) +// TestTCPServer tests concurrent accept-read-write servers. +func TestTCPServer(t *testing.T) { + const N = 3 + + for i, tt := range tcpServerTests { + if !testableListenArgs(tt.snet, tt.saddr, tt.taddr) { + t.Logf("skipping %s test", tt.snet+":"+tt.saddr+"->"+tt.taddr) continue } - listening := make(chan string) - done := make(chan int) - switch tt.snet { - case "unix": - os.Remove(tt.saddr) - os.Remove(tt.caddr) + ln, err := Listen(tt.snet, tt.saddr) + if err != nil { + if perr := parseDialError(err); perr != nil { + t.Error(perr) + } + t.Fatal(err) } - go runStreamConnServer(t, tt.snet, tt.saddr, listening, done) - taddr := <-listening // wait for server to start - - switch tt.cnet { - case "tcp", "tcp4", "tcp6": - _, port, err := SplitHostPort(taddr) + var lss []*localServer + var tpchs []chan error + for i := 0; i < N; i++ { + ls, err := (&streamListener{Listener: ln}).newLocalServer() if err != nil { - t.Fatalf("SplitHostPort(%q) failed: %v", taddr, err) + t.Fatal(err) + } + lss = append(lss, ls) + tpchs = append(tpchs, make(chan error, 1)) + } + defer func() { + for _, ls := range lss { + ls.teardown() + } + }() + for i := 0; i < N; i++ { + ch := tpchs[i] + handler := func(ls *localServer, ln Listener) { transponder(ln, ch) } + if err := lss[i].buildup(handler); err != nil { + t.Fatal(err) } - taddr = JoinHostPort(tt.caddr, port) } - runStreamConnClient(t, tt.cnet, taddr, tt.empty) - <-done // make sure server stopped + var trchs []chan error + for i := 0; i < N; i++ { + _, port, err := SplitHostPort(lss[i].Listener.Addr().String()) + if err != nil { + t.Fatal(err) + } + d := Dialer{Timeout: someTimeout} + c, err := d.Dial(tt.tnet, JoinHostPort(tt.taddr, port)) + if err != nil { + if perr := parseDialError(err); perr != nil { + t.Error(perr) + } + t.Fatal(err) + } + defer c.Close() + trchs = append(trchs, make(chan error, 1)) + go transceiver(c, []byte("TCP SERVER TEST"), trchs[i]) + } - switch tt.snet { - case "unix": - os.Remove(tt.saddr) - os.Remove(tt.caddr) + for _, ch := range trchs { + for err := range ch { + t.Errorf("#%d: %v", i, err) + } + } + for _, ch := range tpchs { + for err := range ch { + t.Errorf("#%d: %v", i, err) + } } } } -var seqpacketConnServerTests = []struct { - net string - saddr string // server address - caddr string // client address - empty bool // test with empty data +var unixAndUnixpacketServerTests = []struct { + network, address string }{ - {net: "unixpacket", saddr: testUnixAddr(), caddr: testUnixAddr()}, - {net: "unixpacket", saddr: "@gotest4/net", caddr: "@gotest4/net.local"}, + {"unix", testUnixAddr()}, + {"unix", "@nettest/go/unix"}, + + {"unixpacket", testUnixAddr()}, + {"unixpacket", "@nettest/go/unixpacket"}, } -func TestSeqpacketConnServer(t *testing.T) { - for _, tt := range seqpacketConnServerTests { - if !testableListenArgs(tt.net, tt.saddr, tt.caddr) { - t.Logf("skipping %s test", tt.net+":"+tt.saddr+"->"+tt.caddr) +// TestUnixAndUnixpacketServer tests concurrent accept-read-write +// servers +func TestUnixAndUnixpacketServer(t *testing.T) { + const N = 3 + + for i, tt := range unixAndUnixpacketServerTests { + if !testableListenArgs(tt.network, tt.address, "") { + t.Logf("skipping %s test", tt.network+":"+tt.address+"->") continue } - listening := make(chan string) - done := make(chan int) - switch tt.net { - case "unixpacket": - os.Remove(tt.saddr) - os.Remove(tt.caddr) - } - - go runStreamConnServer(t, tt.net, tt.saddr, listening, done) - taddr := <-listening // wait for server to start - - runStreamConnClient(t, tt.net, taddr, tt.empty) - <-done // make sure server stopped - switch tt.net { - case "unixpacket": - os.Remove(tt.saddr) - os.Remove(tt.caddr) + ln, err := Listen(tt.network, tt.address) + if err != nil { + if perr := parseDialError(err); perr != nil { + t.Error(perr) + } + t.Fatal(err) } - } -} -func runStreamConnServer(t *testing.T, net, laddr string, listening chan<- string, done chan<- int) { - defer close(done) - l, err := Listen(net, laddr) - if err != nil { - t.Errorf("Listen(%q, %q) failed: %v", net, laddr, err) - listening <- "" - return - } - defer l.Close() - listening <- l.Addr().String() - - echo := func(rw io.ReadWriter, done chan<- int) { - buf := make([]byte, 1024) - for { - n, err := rw.Read(buf[0:]) - if err != nil || n == 0 || string(buf[:n]) == "END" { - break + var lss []*localServer + var tpchs []chan error + for i := 0; i < N; i++ { + ls, err := (&streamListener{Listener: ln}).newLocalServer() + if err != nil { + t.Fatal(err) } - rw.Write(buf[0:n]) + lss = append(lss, ls) + tpchs = append(tpchs, make(chan error, 1)) } - close(done) - } - -run: - for { - c, err := l.Accept() - if err != nil { - t.Logf("Accept failed: %v", err) - continue run + defer func() { + for _, ls := range lss { + ls.teardown() + } + }() + for i := 0; i < N; i++ { + ch := tpchs[i] + handler := func(ls *localServer, ln Listener) { transponder(ln, ch) } + if err := lss[i].buildup(handler); err != nil { + t.Fatal(err) + } } - echodone := make(chan int) - go echo(c, echodone) - <-echodone // make sure echo stopped - c.Close() - break run - } -} -func runStreamConnClient(t *testing.T, net, taddr string, isEmpty bool) { - c, err := Dial(net, taddr) - if err != nil { - t.Fatalf("Dial(%q, %q) failed: %v", net, taddr, err) - } - defer c.Close() - c.SetReadDeadline(time.Now().Add(1 * time.Second)) - - var wb []byte - if !isEmpty { - wb = []byte("StreamConnClient by Dial\n") - } - if n, err := c.Write(wb); err != nil || n != len(wb) { - t.Fatalf("Write failed: %v, %v; want %v, ", n, err, len(wb)) - } - - rb := make([]byte, 1024) - if n, err := c.Read(rb[0:]); err != nil || n != len(wb) { - t.Fatalf("Read failed: %v, %v; want %v, ", n, err, len(wb)) - } + var trchs []chan error + for i := 0; i < N; i++ { + d := Dialer{Timeout: someTimeout} + c, err := d.Dial(lss[i].Listener.Addr().Network(), lss[i].Listener.Addr().String()) + if err != nil { + if perr := parseDialError(err); perr != nil { + t.Error(perr) + } + t.Fatal(err) + } + defer os.Remove(c.LocalAddr().String()) + defer c.Close() + trchs = append(trchs, make(chan error, 1)) + go transceiver(c, []byte("UNIX AND UNIXPACKET SERVER TEST"), trchs[i]) + } - // Send explicit ending for unixpacket. - // Older Linux kernels do not stop reads on close. - switch net { - case "unixpacket": - c.Write([]byte("END")) + for _, ch := range trchs { + for err := range ch { + t.Errorf("#%d: %v", i, err) + } + } + for _, ch := range tpchs { + for err := range ch { + t.Errorf("#%d: %v", i, err) + } + } } } -var datagramPacketConnServerTests = []struct { - snet string // server side - saddr string - cnet string // client side - caddr string - dial bool // test with Dial or DialUnix - empty bool // test with empty data +var udpServerTests = []struct { + snet, saddr string // server endpoint + tnet, taddr string // target endpoint for client + dial bool // test with Dial }{ - {snet: "udp", saddr: ":0", cnet: "udp", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "0.0.0.0:0", cnet: "udp", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "[::ffff:0.0.0.0]:0", cnet: "udp", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "[::]:0", cnet: "udp", caddr: "::1"}, - - {snet: "udp", saddr: ":0", cnet: "udp", caddr: "::1"}, - {snet: "udp", saddr: "0.0.0.0:0", cnet: "udp", caddr: "::1"}, - {snet: "udp", saddr: "[::ffff:0.0.0.0]:0", cnet: "udp", caddr: "::1"}, - {snet: "udp", saddr: "[::]:0", cnet: "udp", caddr: "127.0.0.1"}, + {snet: "udp", saddr: ":0", tnet: "udp", taddr: "127.0.0.1"}, + {snet: "udp", saddr: "0.0.0.0:0", tnet: "udp", taddr: "127.0.0.1"}, + {snet: "udp", saddr: "[::ffff:0.0.0.0]:0", tnet: "udp", taddr: "127.0.0.1"}, + {snet: "udp", saddr: "[::]:0", tnet: "udp", taddr: "::1"}, - {snet: "udp", saddr: ":0", cnet: "udp4", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "0.0.0.0:0", cnet: "udp4", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "[::ffff:0.0.0.0]:0", cnet: "udp4", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "[::]:0", cnet: "udp6", caddr: "::1"}, + {snet: "udp", saddr: ":0", tnet: "udp", taddr: "::1"}, + {snet: "udp", saddr: "0.0.0.0:0", tnet: "udp", taddr: "::1"}, + {snet: "udp", saddr: "[::ffff:0.0.0.0]:0", tnet: "udp", taddr: "::1"}, + {snet: "udp", saddr: "[::]:0", tnet: "udp", taddr: "127.0.0.1"}, - {snet: "udp", saddr: ":0", cnet: "udp6", caddr: "::1"}, - {snet: "udp", saddr: "0.0.0.0:0", cnet: "udp6", caddr: "::1"}, - {snet: "udp", saddr: "[::ffff:0.0.0.0]:0", cnet: "udp6", caddr: "::1"}, - {snet: "udp", saddr: "[::]:0", cnet: "udp4", caddr: "127.0.0.1"}, + {snet: "udp", saddr: ":0", tnet: "udp4", taddr: "127.0.0.1"}, + {snet: "udp", saddr: "0.0.0.0:0", tnet: "udp4", taddr: "127.0.0.1"}, + {snet: "udp", saddr: "[::ffff:0.0.0.0]:0", tnet: "udp4", taddr: "127.0.0.1"}, + {snet: "udp", saddr: "[::]:0", tnet: "udp6", taddr: "::1"}, - {snet: "udp", saddr: "127.0.0.1:0", cnet: "udp", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "[::ffff:127.0.0.1]:0", cnet: "udp", caddr: "127.0.0.1"}, - {snet: "udp", saddr: "[::1]:0", cnet: "udp", caddr: "::1"}, + {snet: "udp", saddr: ":0", tnet: "udp6", taddr: "::1"}, + {snet: "udp", saddr: "0.0.0.0:0", tnet: "udp6", taddr: "::1"}, + {snet: "udp", saddr: "[::ffff:0.0.0.0]:0", tnet: "udp6", taddr: "::1"}, + {snet: "udp", saddr: "[::]:0", tnet: "udp4", taddr: "127.0.0.1"}, - {snet: "udp4", saddr: ":0", cnet: "udp4", caddr: "127.0.0.1"}, - {snet: "udp4", saddr: "0.0.0.0:0", cnet: "udp4", caddr: "127.0.0.1"}, - {snet: "udp4", saddr: "[::ffff:0.0.0.0]:0", cnet: "udp4", caddr: "127.0.0.1"}, + {snet: "udp", saddr: "127.0.0.1:0", tnet: "udp", taddr: "127.0.0.1"}, + {snet: "udp", saddr: "[::ffff:127.0.0.1]:0", tnet: "udp", taddr: "127.0.0.1"}, + {snet: "udp", saddr: "[::1]:0", tnet: "udp", taddr: "::1"}, - {snet: "udp4", saddr: "127.0.0.1:0", cnet: "udp4", caddr: "127.0.0.1"}, + {snet: "udp4", saddr: ":0", tnet: "udp4", taddr: "127.0.0.1"}, + {snet: "udp4", saddr: "0.0.0.0:0", tnet: "udp4", taddr: "127.0.0.1"}, + {snet: "udp4", saddr: "[::ffff:0.0.0.0]:0", tnet: "udp4", taddr: "127.0.0.1"}, - {snet: "udp6", saddr: ":0", cnet: "udp6", caddr: "::1"}, - {snet: "udp6", saddr: "[::]:0", cnet: "udp6", caddr: "::1"}, + {snet: "udp4", saddr: "127.0.0.1:0", tnet: "udp4", taddr: "127.0.0.1"}, - {snet: "udp6", saddr: "[::1]:0", cnet: "udp6", caddr: "::1"}, + {snet: "udp6", saddr: ":0", tnet: "udp6", taddr: "::1"}, + {snet: "udp6", saddr: "[::]:0", tnet: "udp6", taddr: "::1"}, - {snet: "udp", saddr: "127.0.0.1:0", cnet: "udp", caddr: "127.0.0.1", dial: true}, - {snet: "udp", saddr: "127.0.0.1:0", cnet: "udp", caddr: "127.0.0.1", empty: true}, - {snet: "udp", saddr: "127.0.0.1:0", cnet: "udp", caddr: "127.0.0.1", dial: true, empty: true}, + {snet: "udp6", saddr: "[::1]:0", tnet: "udp6", taddr: "::1"}, - {snet: "udp", saddr: "[::1]:0", cnet: "udp", caddr: "::1", dial: true}, - {snet: "udp", saddr: "[::1]:0", cnet: "udp", caddr: "::1", empty: true}, - {snet: "udp", saddr: "[::1]:0", cnet: "udp", caddr: "::1", dial: true, empty: true}, + {snet: "udp", saddr: "127.0.0.1:0", tnet: "udp", taddr: "127.0.0.1", dial: true}, - {snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr()}, - {snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr(), dial: true}, - {snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr(), empty: true}, - {snet: "unixgram", saddr: testUnixAddr(), cnet: "unixgram", caddr: testUnixAddr(), dial: true, empty: true}, - - {snet: "unixgram", saddr: "@gotest6/net", cnet: "unixgram", caddr: "@gotest6/net.local"}, + {snet: "udp", saddr: "[::1]:0", tnet: "udp", taddr: "::1", dial: true}, } -func runDatagramPacketConnServer(t *testing.T, net, laddr string, listening chan<- string, done chan<- int) { - c, err := ListenPacket(net, laddr) - if err != nil { - t.Errorf("ListenPacket(%q, %q) failed: %v", net, laddr, err) - listening <- "" - done <- 1 - return - } - defer c.Close() - listening <- c.LocalAddr().String() - - buf := make([]byte, 1024) -run: - for { - c.SetReadDeadline(time.Now().Add(10 * time.Millisecond)) - n, ra, err := c.ReadFrom(buf[0:]) - if nerr, ok := err.(Error); ok && nerr.Timeout() { - select { - case done <- 1: - break run - default: - continue run +func TestUDPServer(t *testing.T) { + for i, tt := range udpServerTests { + if !testableListenArgs(tt.snet, tt.saddr, tt.taddr) { + t.Logf("skipping %s test", tt.snet+":"+tt.saddr+"->"+tt.taddr) + continue + } + + c1, err := ListenPacket(tt.snet, tt.saddr) + if err != nil { + if perr := parseDialError(err); perr != nil { + t.Error(perr) } + t.Fatal(err) } + + ls, err := (&packetListener{PacketConn: c1}).newLocalServer() if err != nil { - break run + t.Fatal(err) } - if _, err = c.WriteTo(buf[0:n], ra); err != nil { - t.Errorf("WriteTo(%v) failed: %v", ra, err) - break run + defer ls.teardown() + tpch := make(chan error, 1) + handler := func(ls *localPacketServer, c PacketConn) { packetTransponder(c, tpch) } + if err := ls.buildup(handler); err != nil { + t.Fatal(err) } - } - done <- 1 -} -func runDatagramConnClient(t *testing.T, net, laddr, taddr string, isEmpty bool) { - var c Conn - var err error - switch net { - case "udp", "udp4", "udp6": - c, err = Dial(net, taddr) + trch := make(chan error, 1) + _, port, err := SplitHostPort(ls.PacketConn.LocalAddr().String()) if err != nil { - t.Fatalf("Dial(%q, %q) failed: %v", net, taddr, err) + t.Fatal(err) } - case "unixgram": - c, err = DialUnix(net, &UnixAddr{Name: laddr, Net: net}, &UnixAddr{Name: taddr, Net: net}) - if err != nil { - t.Fatalf("DialUnix(%q, {%q, %q}) failed: %v", net, laddr, taddr, err) + if tt.dial { + d := Dialer{Timeout: someTimeout} + c2, err := d.Dial(tt.tnet, JoinHostPort(tt.taddr, port)) + if err != nil { + if perr := parseDialError(err); perr != nil { + t.Error(perr) + } + t.Fatal(err) + } + defer c2.Close() + go transceiver(c2, []byte("UDP SERVER TEST"), trch) + } else { + c2, err := ListenPacket(tt.tnet, JoinHostPort(tt.taddr, "0")) + if err != nil { + if perr := parseDialError(err); perr != nil { + t.Error(perr) + } + t.Fatal(err) + } + defer c2.Close() + dst, err := ResolveUDPAddr(tt.tnet, JoinHostPort(tt.taddr, port)) + if err != nil { + t.Fatal(err) + } + go packetTransceiver(c2, []byte("UDP SERVER TEST"), dst, trch) } - } - defer c.Close() - c.SetReadDeadline(time.Now().Add(1 * time.Second)) - var wb []byte - if !isEmpty { - wb = []byte("DatagramConnClient by Dial\n") - } - if n, err := c.Write(wb[0:]); err != nil || n != len(wb) { - t.Fatalf("Write failed: %v, %v; want %v, ", n, err, len(wb)) + for err := range trch { + t.Errorf("#%d: %v", i, err) + } + for err := range tpch { + t.Errorf("#%d: %v", i, err) + } } +} - rb := make([]byte, 1024) - if n, err := c.Read(rb[0:]); err != nil || n != len(wb) { - t.Fatalf("Read failed: %v, %v; want %v, ", n, err, len(wb)) - } +var unixgramServerTests = []struct { + saddr string // server endpoint + caddr string // client endpoint + dial bool // test with Dial +}{ + {saddr: testUnixAddr(), caddr: testUnixAddr()}, + {saddr: testUnixAddr(), caddr: testUnixAddr(), dial: true}, + + {saddr: "@nettest/go/unixgram/server", caddr: "@nettest/go/unixgram/client"}, } -func runDatagramPacketConnClient(t *testing.T, net, laddr, taddr string, isEmpty bool) { - var ra Addr - var err error - switch net { - case "udp", "udp4", "udp6": - ra, err = ResolveUDPAddr(net, taddr) +func TestUnixgramServer(t *testing.T) { + for i, tt := range unixgramServerTests { + if !testableListenArgs("unixgram", tt.saddr, "") { + t.Logf("skipping %s test", "unixgram:"+tt.saddr+"->"+tt.caddr) + continue + } + + c1, err := ListenPacket("unixgram", tt.saddr) if err != nil { - t.Fatalf("ResolveUDPAddr(%q, %q) failed: %v", net, taddr, err) + if perr := parseDialError(err); perr != nil { + t.Error(perr) + } + t.Fatal(err) } - case "unixgram": - ra, err = ResolveUnixAddr(net, taddr) + + ls, err := (&packetListener{PacketConn: c1}).newLocalServer() if err != nil { - t.Fatalf("ResolveUxixAddr(%q, %q) failed: %v", net, taddr, err) + t.Fatal(err) + } + defer ls.teardown() + tpch := make(chan error, 1) + handler := func(ls *localPacketServer, c PacketConn) { packetTransponder(c, tpch) } + if err := ls.buildup(handler); err != nil { + t.Fatal(err) } - } - c, err := ListenPacket(net, laddr) - if err != nil { - t.Fatalf("ListenPacket(%q, %q) failed: %v", net, laddr, err) - } - defer c.Close() - c.SetReadDeadline(time.Now().Add(1 * time.Second)) - var wb []byte - if !isEmpty { - wb = []byte("DatagramPacketConnClient by ListenPacket\n") - } - if n, err := c.WriteTo(wb[0:], ra); err != nil || n != len(wb) { - t.Fatalf("WriteTo(%v) failed: %v, %v; want %v, ", ra, n, err, len(wb)) - } + trch := make(chan error, 1) + if tt.dial { + d := Dialer{Timeout: someTimeout, LocalAddr: &UnixAddr{Net: "unixgram", Name: tt.caddr}} + c2, err := d.Dial("unixgram", ls.PacketConn.LocalAddr().String()) + if err != nil { + if perr := parseDialError(err); perr != nil { + t.Error(perr) + } + t.Fatal(err) + } + defer os.Remove(c2.LocalAddr().String()) + defer c2.Close() + go transceiver(c2, []byte(c2.LocalAddr().String()), trch) + } else { + c2, err := ListenPacket("unixgram", tt.caddr) + if err != nil { + if perr := parseDialError(err); perr != nil { + t.Error(perr) + } + t.Fatal(err) + } + defer os.Remove(c2.LocalAddr().String()) + defer c2.Close() + go packetTransceiver(c2, []byte("UNIXGRAM SERVER TEST"), ls.PacketConn.LocalAddr(), trch) + } - rb := make([]byte, 1024) - if n, _, err := c.ReadFrom(rb[0:]); err != nil || n != len(wb) { - t.Fatalf("ReadFrom failed: %v, %v; want %v, ", n, err, len(wb)) + for err := range trch { + t.Errorf("#%d: %v", i, err) + } + for err := range tpch { + t.Errorf("#%d: %v", i, err) + } } } diff --git a/src/net/timeout_test.go b/src/net/timeout_test.go index 3ef22fa76f..c9a826e106 100644 --- a/src/net/timeout_test.go +++ b/src/net/timeout_test.go @@ -307,15 +307,14 @@ func TestTimeoutUDP(t *testing.T) { t.Skipf("skipping test on %q", runtime.GOOS) } - // set up a listener that won't talk back - listening := make(chan string) - done := make(chan int) - go runDatagramPacketConnServer(t, "udp", "127.0.0.1:0", listening, done) - addr := <-listening - - testTimeout(t, "udp", addr, false) - testTimeout(t, "udp", addr, true) - <-done + c, err := newLocalPacketListener("udp") // a listener that won't talk back + if err != nil { + t.Fatal(err) + } + + testTimeout(t, "udp", c.LocalAddr().String(), false) + testTimeout(t, "udp", c.LocalAddr().String(), true) + c.Close() } func TestTimeoutTCP(t *testing.T) { @@ -324,14 +323,25 @@ func TestTimeoutTCP(t *testing.T) { t.Skipf("skipping test on %q", runtime.GOOS) } - // set up a listener that won't talk back - listening := make(chan string) - done := make(chan int) - go runStreamConnServer(t, "tcp", "127.0.0.1:0", listening, done) - addr := <-listening + handler := func(ls *localServer, ln Listener) { // a listener that won't talk back + for { + c, err := ln.Accept() + if err != nil { + break + } + defer c.Close() + } + } + ls, err := newLocalServer("tcp") + if err != nil { + t.Fatal(err) + } + defer ls.teardown() + if err := ls.buildup(handler); err != nil { + t.Fatal(err) + } - testTimeout(t, "tcp", addr, false) - <-done + testTimeout(t, "tcp", ls.Listener.Addr().String(), false) } func TestDeadlineReset(t *testing.T) {