mirror of https://github.com/tidwall/evio.git
127 lines
2.6 KiB
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")
|
||
|
}
|
||
|
}
|
||
|
}
|