2008-09-17 14:49:23 -06:00
|
|
|
// Copyright 2009 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.
|
|
|
|
|
2008-12-18 16:42:39 -07:00
|
|
|
package net
|
2008-09-17 14:49:23 -06:00
|
|
|
|
|
|
|
import (
|
|
|
|
"io";
|
|
|
|
"net";
|
2009-04-16 21:52:37 -06:00
|
|
|
"os";
|
2009-06-17 22:44:26 -06:00
|
|
|
"strings";
|
2009-05-13 19:03:41 -06:00
|
|
|
"syscall";
|
2008-12-18 16:42:39 -07:00
|
|
|
"testing";
|
2008-09-17 14:49:23 -06:00
|
|
|
)
|
|
|
|
|
2009-05-08 12:22:57 -06:00
|
|
|
func runEcho(fd io.ReadWriter, done chan<- int) {
|
2008-09-17 14:49:23 -06:00
|
|
|
var buf [1024]byte;
|
|
|
|
|
|
|
|
for {
|
2009-04-15 21:27:45 -06:00
|
|
|
n, err := fd.Read(&buf);
|
2008-09-17 14:49:23 -06:00
|
|
|
if err != nil || n == 0 {
|
|
|
|
break;
|
|
|
|
}
|
2008-12-18 23:37:22 -07:00
|
|
|
fd.Write(buf[0:n])
|
2008-09-17 14:49:23 -06:00
|
|
|
}
|
|
|
|
done <- 1
|
|
|
|
}
|
|
|
|
|
2009-06-17 22:44:26 -06:00
|
|
|
func runServe(t *testing.T, network, addr string, listening chan<- string, done chan<- int) {
|
2008-09-17 14:49:23 -06:00
|
|
|
l, err := net.Listen(network, addr);
|
|
|
|
if err != nil {
|
2008-12-18 16:42:39 -07:00
|
|
|
t.Fatalf("net.Listen(%q, %q) = _, %v", network, addr, err);
|
2008-09-17 14:49:23 -06:00
|
|
|
}
|
2009-06-17 22:44:26 -06:00
|
|
|
listening <- l.Addr();
|
2008-09-17 14:49:23 -06:00
|
|
|
|
|
|
|
for {
|
|
|
|
fd, addr, err := l.Accept();
|
|
|
|
if err != nil {
|
|
|
|
break;
|
|
|
|
}
|
2009-01-06 16:19:02 -07:00
|
|
|
echodone := make(chan int);
|
2009-01-16 15:16:31 -07:00
|
|
|
go runEcho(fd, echodone);
|
2008-09-17 14:49:23 -06:00
|
|
|
<-echodone; // make sure Echo stops
|
|
|
|
l.Close();
|
|
|
|
}
|
|
|
|
done <- 1
|
|
|
|
}
|
|
|
|
|
2009-01-16 15:16:31 -07:00
|
|
|
func connect(t *testing.T, network, addr string) {
|
2008-09-17 14:49:23 -06:00
|
|
|
fd, err := net.Dial(network, "", addr);
|
|
|
|
if err != nil {
|
2008-12-18 16:42:39 -07:00
|
|
|
t.Fatalf("net.Dial(%q, %q, %q) = _, %v", network, "", addr, err);
|
2008-09-17 14:49:23 -06:00
|
|
|
}
|
|
|
|
|
2009-06-29 16:24:23 -06:00
|
|
|
b := strings.Bytes("hello, world\n");
|
2008-09-17 14:49:23 -06:00
|
|
|
var b1 [100]byte;
|
|
|
|
|
|
|
|
n, errno := fd.Write(b);
|
|
|
|
if n != len(b) {
|
2008-12-18 16:42:39 -07:00
|
|
|
t.Fatalf("fd.Write(%q) = %d, %v", b, n, errno);
|
2008-09-17 14:49:23 -06:00
|
|
|
}
|
|
|
|
|
2009-04-15 21:27:45 -06:00
|
|
|
n, errno = fd.Read(&b1);
|
2008-09-17 14:49:23 -06:00
|
|
|
if n != len(b) {
|
2008-12-18 16:42:39 -07:00
|
|
|
t.Fatalf("fd.Read() = %d, %v", n, errno);
|
2008-09-17 14:49:23 -06:00
|
|
|
}
|
|
|
|
fd.Close();
|
|
|
|
}
|
|
|
|
|
2009-01-16 15:16:31 -07:00
|
|
|
func doTest(t *testing.T, network, listenaddr, dialaddr string) {
|
2008-12-18 16:42:39 -07:00
|
|
|
t.Logf("Test %s %s %s\n", network, listenaddr, dialaddr);
|
2009-06-17 22:44:26 -06:00
|
|
|
listening := make(chan string);
|
2009-01-06 16:19:02 -07:00
|
|
|
done := make(chan int);
|
2009-06-17 22:44:26 -06:00
|
|
|
if network == "tcp" {
|
|
|
|
listenaddr += ":0"; // any available port
|
|
|
|
}
|
2009-01-16 15:16:31 -07:00
|
|
|
go runServe(t, network, listenaddr, listening, done);
|
2009-06-17 22:44:26 -06:00
|
|
|
addr := <-listening; // wait for server to start
|
|
|
|
if network == "tcp" {
|
|
|
|
dialaddr += addr[strings.LastIndex(addr, ":"):len(addr)];
|
|
|
|
}
|
2009-01-16 15:16:31 -07:00
|
|
|
connect(t, network, dialaddr);
|
2008-09-17 14:49:23 -06:00
|
|
|
<-done; // make sure server stopped
|
|
|
|
}
|
|
|
|
|
2009-01-20 15:40:40 -07:00
|
|
|
func TestTcpServer(t *testing.T) {
|
2009-06-17 22:44:26 -06:00
|
|
|
doTest(t, "tcp", "0.0.0.0", "127.0.0.1");
|
|
|
|
doTest(t, "tcp", "[::]", "[::ffff:127.0.0.1]");
|
|
|
|
doTest(t, "tcp", "[::]", "127.0.0.1");
|
|
|
|
doTest(t, "tcp", "", "127.0.0.1");
|
|
|
|
doTest(t, "tcp", "0.0.0.0", "[::ffff:127.0.0.1]");
|
2008-09-17 14:49:23 -06:00
|
|
|
}
|
|
|
|
|
2009-05-13 19:03:41 -06:00
|
|
|
func TestUnixServer(t *testing.T) {
|
|
|
|
doTest(t, "unix", "/tmp/gotest.net", "/tmp/gotest.net");
|
|
|
|
if syscall.OS == "linux" {
|
|
|
|
// Test abstract unix domain socket, a Linux-ism
|
|
|
|
doTest(t, "unix", "@gotest/net", "@gotest/net");
|
|
|
|
}
|
|
|
|
}
|