1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
package tcplisten
import (
"fmt"
"io/ioutil"
"net"
"testing"
"time"
)
func TestConfigDeferAccept(t *testing.T) {
testConfig(t, Config{DeferAccept: true})
}
func TestConfigReusePort(t *testing.T) {
testConfig(t, Config{ReusePort: true})
}
func TestConfigFastOpen(t *testing.T) {
testConfig(t, Config{FastOpen: true})
}
func TestConfigAll(t *testing.T) {
cfg := Config{
ReusePort: true,
DeferAccept: true,
FastOpen: true,
}
testConfig(t, cfg)
}
func TestConfigBacklog(t *testing.T) {
cfg := Config{
Backlog: 32,
}
testConfig(t, cfg)
}
func testConfig(t *testing.T, cfg Config) {
testConfigV(t, cfg, "tcp4", "127.0.0.1:10081")
testConfigV(t, cfg, "tcp6", "[::1]:10081")
}
func testConfigV(t *testing.T, cfg Config, network, addr string) {
const requestsCount = 1000
var serversCount = 1
if cfg.ReusePort {
serversCount = 10
}
doneCh := make(chan struct{}, serversCount)
var lns []net.Listener
for i := 0; i < serversCount; i++ {
ln, err := cfg.NewListener(network, addr)
if err != nil {
t.Fatalf("cannot create listener %d using Config %#v: %s", i, &cfg, err)
}
go func() {
serveEcho(t, ln)
doneCh <- struct{}{}
}()
lns = append(lns, ln)
}
for i := 0; i < requestsCount; i++ {
c, err := net.Dial(network, addr)
if err != nil {
t.Fatalf("%d. unexpected error when dialing: %s", i, err)
}
req := fmt.Sprintf("request number %d", i)
if _, err = c.Write([]byte(req)); err != nil {
t.Fatalf("%d. unexpected error when writing request: %s", i, err)
}
if err = c.(*net.TCPConn).CloseWrite(); err != nil {
t.Fatalf("%d. unexpected error when closing write end of the connection: %s", i, err)
}
var resp []byte
ch := make(chan struct{})
go func() {
if resp, err = ioutil.ReadAll(c); err != nil {
t.Fatalf("%d. unexpected error when reading response: %s", i, err)
}
close(ch)
}()
select {
case <-ch:
case <-time.After(200 * time.Millisecond):
t.Fatalf("%d. timeout when waiting for response: %s", i, err)
}
if string(resp) != req {
t.Fatalf("%d. unexpected response %q. Expecting %q", i, resp, req)
}
if err = c.Close(); err != nil {
t.Fatalf("%d. unexpected error when closing connection: %s", i, err)
}
}
for _, ln := range lns {
if err := ln.Close(); err != nil {
t.Fatalf("unexpected error when closing listener: %s", err)
}
}
for i := 0; i < serversCount; i++ {
select {
case <-doneCh:
case <-time.After(time.Second):
t.Fatalf("timeout when waiting for servers to be closed")
}
}
}
func serveEcho(t *testing.T, ln net.Listener) {
for {
c, err := ln.Accept()
if err != nil {
break
}
req, err := ioutil.ReadAll(c)
if err != nil {
t.Fatalf("unepxected error when reading request: %s", err)
}
if _, err = c.Write(req); err != nil {
t.Fatalf("unexpected error when writing response: %s", err)
}
if err = c.Close(); err != nil {
t.Fatalf("unexpected error when closing connection: %s", err)
}
}
}
|