mirror of https://github.com/tidwall/evio.git
112 lines
2.3 KiB
Go
112 lines
2.3 KiB
Go
|
package shiny
|
||
|
|
||
|
import (
|
||
|
"bufio"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"math/rand"
|
||
|
"net"
|
||
|
"sync"
|
||
|
"testing"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
func TestShiny(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 - 100KB.
|
||
|
// the server will echo back the data.
|
||
|
var wg sync.WaitGroup
|
||
|
wg.Add(2)
|
||
|
go func() {
|
||
|
testServer(t, "tcp", 9990, 10)
|
||
|
wg.Done()
|
||
|
}()
|
||
|
go func() {
|
||
|
testServer(t, "tcp-compat", 9991, 10)
|
||
|
wg.Done()
|
||
|
}()
|
||
|
wg.Wait()
|
||
|
}
|
||
|
func testServer(t *testing.T, net string, port int, nclients int) {
|
||
|
var started bool
|
||
|
var connected int
|
||
|
var disconnected int
|
||
|
var shutdown bool
|
||
|
err := Serve(net, fmt.Sprintf(":%d", port),
|
||
|
func(id int, data []byte, ctx interface{}) (send []byte, keepopen bool) {
|
||
|
if shutdown {
|
||
|
return nil, false
|
||
|
}
|
||
|
return data, true
|
||
|
},
|
||
|
func(id int, addr string, wake func(), ctx interface{}) (send []byte, keepopen bool) {
|
||
|
if shutdown {
|
||
|
return nil, false
|
||
|
}
|
||
|
connected++
|
||
|
return []byte("sweetness\n"), true
|
||
|
},
|
||
|
func(id int, err error, ctx interface{}) {
|
||
|
if shutdown {
|
||
|
return
|
||
|
}
|
||
|
disconnected++
|
||
|
if connected == disconnected && disconnected == nclients {
|
||
|
shutdown = true
|
||
|
}
|
||
|
},
|
||
|
func(ctx interface{}) (keepserving bool) {
|
||
|
if shutdown {
|
||
|
return false
|
||
|
}
|
||
|
if !started {
|
||
|
for i := 0; i < nclients; i++ {
|
||
|
go startClient(t, port)
|
||
|
}
|
||
|
started = true
|
||
|
}
|
||
|
return true
|
||
|
}, "coolness")
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func startClient(t *testing.T, port int) {
|
||
|
rand.Seed(time.Now().UnixNano())
|
||
|
c, err := net.Dial("tcp", fmt.Sprintf(":%d", port))
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer c.Close()
|
||
|
rd := bufio.NewReader(c)
|
||
|
msg, err := rd.ReadBytes('\n')
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if string(msg) != "sweetness\n" {
|
||
|
t.Fatal("bad header")
|
||
|
}
|
||
|
duration := time.Duration((rand.Float64()*2 + 1) * float64(time.Second))
|
||
|
start := time.Now()
|
||
|
for time.Since(start) < duration {
|
||
|
sz := rand.Int() % (1024 * 100)
|
||
|
data := make([]byte, sz)
|
||
|
if _, err := rand.Read(data); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if _, err := c.Write(data); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
data2 := make([]byte, sz)
|
||
|
if _, err := io.ReadFull(rd, data2); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if string(data) != string(data2) {
|
||
|
t.Fatal("mismatch")
|
||
|
}
|
||
|
}
|
||
|
}
|