evio/doppio_test.go

127 lines
2.6 KiB
Go

package doppio
import (
"bufio"
"io"
"math/rand"
"net"
"os"
"strings"
"sync"
"testing"
"time"
)
func TestDoppio(t *testing.T) {
// start a server
// connect 10 clients
// each client will pipe random data for 1-3 seconds.
// the writes to the server will be random sizes. 0KB - 1MB.
// the server will echo back the data.
var wg sync.WaitGroup
wg.Add(4)
go func() {
testServer("tcp", ":9990", false, 10)
wg.Done()
}()
go func() {
testServer("tcp", ":9991", true, 10)
wg.Done()
}()
go func() {
testServer("tcp-stdlib", ":9992", false, 10)
wg.Done()
}()
go func() {
testServer("tcp-stdlib", ":9993", true, 10)
wg.Done()
}()
wg.Wait()
}
func testServer(network, addr string, unix bool, nclients int) {
var started bool
var connected int
var disconnected int
var events Events
events.Serving = func(wake func(id int) bool) (action Action) {
return
}
events.Opened = func(id int, addr string) (out []byte, opts Options, action Action) {
connected++
out = []byte("sweetness\r\n")
opts.TCPKeepAlive = time.Minute * 5
return
}
events.Closed = func(id int) (action Action) {
disconnected++
if connected == disconnected && disconnected == nclients {
action = Shutdown
}
return
}
events.Data = func(id int, in []byte) (out []byte, action Action) {
out = in
return
}
events.Tick = func() (delay time.Duration, action Action) {
if !started {
for i := 0; i < nclients; i++ {
go startClient(network, addr)
}
started = true
}
delay = time.Second / 5
return
}
var err error
if unix {
socket := strings.Replace(addr, ":", "socket", 1)
os.RemoveAll(socket)
defer os.RemoveAll(socket)
err = Serve(events, network+"://"+addr, "unix://"+socket)
} else {
err = Serve(events, network+"://"+addr)
}
if err != nil {
panic(err)
}
}
func startClient(network, addr string) {
network = strings.Replace(network, "-stdlib", "", -1)
rand.Seed(time.Now().UnixNano())
c, err := net.Dial(network, addr)
if err != nil {
panic(err)
}
defer c.Close()
rd := bufio.NewReader(c)
msg, err := rd.ReadBytes('\n')
if err != nil {
panic(err)
}
if string(msg) != "sweetness\r\n" {
panic("bad header")
}
duration := time.Duration((rand.Float64()*2 + 1) * float64(time.Second))
start := time.Now()
for time.Since(start) < duration {
sz := rand.Int() % (1024 * 1024)
data := make([]byte, sz)
if _, err := rand.Read(data); err != nil {
panic(err)
}
if _, err := c.Write(data); err != nil {
panic(err)
}
data2 := make([]byte, sz)
if _, err := io.ReadFull(rd, data2); err != nil {
panic(err)
}
if string(data) != string(data2) {
panic("mismatch")
}
}
}