diff options
Diffstat (limited to 'src/net/conn_test.go')
-rw-r--r-- | src/net/conn_test.go | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/src/net/conn_test.go b/src/net/conn_test.go new file mode 100644 index 000000000..9c9d1a805 --- /dev/null +++ b/src/net/conn_test.go @@ -0,0 +1,124 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This file implements API tests across platforms and will never have a build +// tag. + +package net + +import ( + "os" + "runtime" + "testing" + "time" +) + +var connTests = []struct { + net string + addr string +}{ + {"tcp", "127.0.0.1:0"}, + {"unix", testUnixAddr()}, + {"unixpacket", testUnixAddr()}, +} + +// someTimeout is used just to test that net.Conn implementations +// don't explode when their SetFooDeadline methods are called. +// It isn't actually used for testing timeouts. +const someTimeout = 10 * time.Second + +func TestConnAndListener(t *testing.T) { + for _, tt := range connTests { + switch tt.net { + case "unix": + switch runtime.GOOS { + case "nacl", "plan9", "windows": + continue + } + case "unixpacket": + switch runtime.GOOS { + case "android", "darwin", "nacl", "openbsd", "plan9", "windows": + continue + case "freebsd": // FreeBSD 8 doesn't support unixpacket + continue + } + } + + ln, err := Listen(tt.net, tt.addr) + if err != nil { + t.Fatalf("Listen failed: %v", err) + } + defer func(ln Listener, net, addr string) { + ln.Close() + switch net { + case "unix", "unixpacket": + os.Remove(addr) + } + }(ln, tt.net, tt.addr) + if ln.Addr().Network() != tt.net { + t.Fatalf("got %v; expected %v", ln.Addr().Network(), tt.net) + } + + done := make(chan int) + go transponder(t, ln, done) + + c, err := Dial(tt.net, ln.Addr().String()) + if err != nil { + t.Fatalf("Dial failed: %v", err) + } + defer c.Close() + if c.LocalAddr().Network() != tt.net || c.LocalAddr().Network() != tt.net { + t.Fatalf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), tt.net, tt.net) + } + c.SetDeadline(time.Now().Add(someTimeout)) + c.SetReadDeadline(time.Now().Add(someTimeout)) + c.SetWriteDeadline(time.Now().Add(someTimeout)) + + if _, err := c.Write([]byte("CONN TEST")); err != nil { + t.Fatalf("Conn.Write failed: %v", err) + } + rb := make([]byte, 128) + if _, err := c.Read(rb); err != nil { + t.Fatalf("Conn.Read failed: %v", err) + } + + <-done + } +} + +func transponder(t *testing.T, ln Listener, done chan<- int) { + defer func() { done <- 1 }() + + switch ln := ln.(type) { + case *TCPListener: + ln.SetDeadline(time.Now().Add(someTimeout)) + case *UnixListener: + ln.SetDeadline(time.Now().Add(someTimeout)) + } + c, err := ln.Accept() + if err != nil { + t.Errorf("Listener.Accept failed: %v", err) + return + } + defer c.Close() + network := ln.Addr().Network() + if c.LocalAddr().Network() != network || c.LocalAddr().Network() != network { + t.Errorf("got %v->%v; expected %v->%v", c.LocalAddr().Network(), c.RemoteAddr().Network(), network, network) + return + } + c.SetDeadline(time.Now().Add(someTimeout)) + c.SetReadDeadline(time.Now().Add(someTimeout)) + c.SetWriteDeadline(time.Now().Add(someTimeout)) + + b := make([]byte, 128) + n, err := c.Read(b) + if err != nil { + t.Errorf("Conn.Read failed: %v", err) + return + } + if _, err := c.Write(b[:n]); err != nil { + t.Errorf("Conn.Write failed: %v", err) + return + } +} |