Plan 9 from Bell Labs’s /usr/web/sources/contrib/ericvh/go-plan9/src/pkg/net/server_test.go

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


// 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.

package net

import (
	"flag";
	"io";
	"os";
	"strings";
	"syscall";
	"testing";
)

// Do not test empty datagrams by default.
// It causes unexplained timeouts on some systems,
// including Snow Leopard.  I think that the kernel
// doesn't quite expect them.
var testEmptyDatagrams = flag.Bool("empty_datagrams", false, "whether to test empty datagrams")

func runEcho(fd io.ReadWriter, done chan<- int) {
	var buf [1024]byte;

	for {
		n, err := fd.Read(&buf);
		if err != nil || n == 0 {
			break
		}
		fd.Write(buf[0:n]);
	}
	done <- 1;
}

func runServe(t *testing.T, network, addr string, listening chan<- string, done chan<- int) {
	l, err := Listen(network, addr);
	if err != nil {
		t.Fatalf("net.Listen(%q, %q) = _, %v", network, addr, err)
	}
	listening <- l.Addr().String();

	for {
		fd, err := l.Accept();
		if err != nil {
			break
		}
		echodone := make(chan int);
		go runEcho(fd, echodone);
		<-echodone;	// make sure Echo stops
		l.Close();
	}
	done <- 1;
}

func connect(t *testing.T, network, addr string, isEmpty bool) {
	var laddr string;
	if network == "unixgram" {
		laddr = addr + ".local"
	}
	fd, err := Dial(network, laddr, addr);
	if err != nil {
		t.Fatalf("net.Dial(%q, %q, %q) = _, %v", network, laddr, addr, err)
	}
	fd.SetReadTimeout(1e9);	// 1s

	var b []byte;
	if !isEmpty {
		b = strings.Bytes("hello, world\n")
	}
	var b1 [100]byte;

	n, err := fd.Write(b);
	if n != len(b) {
		t.Fatalf("fd.Write(%q) = %d, %v", b, n, err)
	}

	n, err = fd.Read(&b1);
	if n != len(b) || err != nil {
		t.Fatalf("fd.Read() = %d, %v (want %d, nil)", n, err, len(b))
	}
	fd.Close();
}

func doTest(t *testing.T, network, listenaddr, dialaddr string) {
	t.Logf("Test %s %s %s\n", network, listenaddr, dialaddr);
	listening := make(chan string);
	done := make(chan int);
	if network == "tcp" {
		listenaddr += ":0"	// any available port
	}
	go runServe(t, network, listenaddr, listening, done);
	addr := <-listening;	// wait for server to start
	if network == "tcp" {
		dialaddr += addr[strings.LastIndex(addr, ":"):]
	}
	connect(t, network, dialaddr, false);
	<-done;	// make sure server stopped
}

func TestTCPServer(t *testing.T) {
	doTest(t, "tcp", "0.0.0.0", "127.0.0.1");
	doTest(t, "tcp", "", "127.0.0.1");
	if kernelSupportsIPv6() {
		doTest(t, "tcp", "[::]", "[::ffff:127.0.0.1]");
		doTest(t, "tcp", "[::]", "127.0.0.1");
		doTest(t, "tcp", "0.0.0.0", "[::ffff:127.0.0.1]");
	}
}

func TestUnixServer(t *testing.T) {
	os.Remove("/tmp/gotest.net");
	doTest(t, "unix", "/tmp/gotest.net", "/tmp/gotest.net");
	os.Remove("/tmp/gotest.net");
	if syscall.OS == "linux" {
		// Test abstract unix domain socket, a Linux-ism
		doTest(t, "unix", "@gotest/net", "@gotest/net")
	}
}

func runPacket(t *testing.T, network, addr string, listening chan<- string, done chan<- int) {
	c, err := ListenPacket(network, addr);
	if err != nil {
		t.Fatalf("net.ListenPacket(%q, %q) = _, %v", network, addr, err)
	}
	listening <- c.LocalAddr().String();
	c.SetReadTimeout(10e6);	// 10ms
	var buf [1000]byte;
	for {
		n, addr, err := c.ReadFrom(&buf);
		if isEAGAIN(err) {
			if done <- 1 {
				break
			}
			continue;
		}
		if err != nil {
			break
		}
		if _, err = c.WriteTo(buf[0:n], addr); err != nil {
			t.Fatalf("WriteTo %v: %v", addr, err)
		}
	}
	c.Close();
	done <- 1;
}

func doTestPacket(t *testing.T, network, listenaddr, dialaddr string, isEmpty bool) {
	t.Logf("TestPacket %s %s %s\n", network, listenaddr, dialaddr);
	listening := make(chan string);
	done := make(chan int);
	if network == "udp" {
		listenaddr += ":0"	// any available port
	}
	go runPacket(t, network, listenaddr, listening, done);
	addr := <-listening;	// wait for server to start
	if network == "udp" {
		dialaddr += addr[strings.LastIndex(addr, ":"):]
	}
	connect(t, network, dialaddr, isEmpty);
	<-done;	// tell server to stop
	<-done;	// wait for stop
}

func TestUDPServer(t *testing.T) {
	for _, isEmpty := range []bool{false, *testEmptyDatagrams} {
		doTestPacket(t, "udp", "0.0.0.0", "127.0.0.1", isEmpty);
		doTestPacket(t, "udp", "", "127.0.0.1", isEmpty);
		if kernelSupportsIPv6() {
			doTestPacket(t, "udp", "[::]", "[::ffff:127.0.0.1]", isEmpty);
			doTestPacket(t, "udp", "[::]", "127.0.0.1", isEmpty);
			doTestPacket(t, "udp", "0.0.0.0", "[::ffff:127.0.0.1]", isEmpty);
		}
	}
}

func TestUnixDatagramServer(t *testing.T) {
	for _, isEmpty := range []bool{false, *testEmptyDatagrams} {
		os.Remove("/tmp/gotest1.net");
		os.Remove("/tmp/gotest1.net.local");
		doTestPacket(t, "unixgram", "/tmp/gotest1.net", "/tmp/gotest1.net", isEmpty);
		os.Remove("/tmp/gotest1.net");
		os.Remove("/tmp/gotest1.net.local");
		if syscall.OS == "linux" {
			// Test abstract unix domain socket, a Linux-ism
			doTestPacket(t, "unixgram", "@gotest1/net", "@gotest1/net", isEmpty)
		}
	}
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.