func BenchmarkClientServer(b *testing.B) { b.ReportAllocs() b.StopTimer() handler, err := NewHandler(func(in Ping, out *Pong) error { if in.Data != "ping" { b.Fatalf("expected ping, got %q", in.Data) } out.Data = "pong" return nil }) if err != nil { b.Fatalf("NewHandler: %v", err) } s := npctest.NewServer(handler) defer s.Close() c := NewClient([]string{s.Listener.Addr().String()}) defer c.Close() b.StartTimer() for i := 0; i < b.N; i++ { var pong Pong err = c.Call(Ping{"ping"}, &pong) if err != nil { b.Fatalf("Call: %v", err) } if pong.Data != "pong" { b.Fatalf("expected pong, got %q", pong.Data) } } }
func benchmarkClientServerParallel(b *testing.B, parallelism int) { b.ReportAllocs() b.StopTimer() handler, err := NewHandler(func(in Ping, out *Pong) error { if in.Data != "ping" { b.Fatalf("expected ping, got %q", in.Data) } out.Data = "pong" return nil }) if err != nil { b.Fatalf("NewHandler: %v", err) } s := npctest.NewServer(handler) defer s.Close() c := NewClient([]string{s.Listener.Addr().String()}) defer c.Close() b.SetParallelism(parallelism) b.StartTimer() b.RunParallel(func(pb *testing.PB) { for pb.Next() { var pong Pong err = c.Call(Ping{"ping"}, &pong) if err != nil { b.Fatalf("Call: %v", err) } if pong.Data != "pong" { b.Fatalf("expected pong, got %q", pong.Data) } } }) }
func TestServerPingPong(t *testing.T) { defer afterTest(t) s := npctest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { content, err := ioutil.ReadAll(r.Body) if string(content) != "ping" { t.Errorf("expected ping, got %s", string(content)) } if err != nil { t.Error(err) } w.Write([]byte("pong")) })) defer s.Close() for i := 0; i < 10; i++ { conn, err := net.Dial("tcp", s.Listener.Addr().String()) if err != nil { t.Fatalf("Dial: %v", err) } for j := 0; j < 10; j++ { req := NewRequest(strings.NewReader("ping")) if _, err := req.Write(conn); err != nil { t.Fatalf("Write: %v", err) } resp, err := ReadResponse(conn) if err != nil { t.Fatalf("ReadResponse: %v", err) } if string(resp.Body) != "pong" { t.Errorf("expected pong, got %s", string(resp.Body)) } } conn.Close() } }
func TestHandler(t *testing.T) { handler, err := NewHandler(func(in Ping, out *Pong) error { if in.Data != "ping" { t.Fatalf("expected ping, got %q", in.Data) } out.Data = "pong" return nil }) if err != nil { t.Fatalf("NewHandler: %v", err) } s := npctest.NewServer(handler) defer s.Close() c := NewClient([]string{s.Listener.Addr().String()}) defer c.Close() var pong Pong err = c.Call(Ping{"ping"}, &pong) if err != nil { t.Fatalf("Call: %v", err) } if pong.Data != "pong" { t.Fatalf("expected pong, got %q", pong.Data) } }
func TestClientWriteShutdown(t *testing.T) { defer afterTest(t) ts := npctest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {})) defer ts.Close() conn, err := net.Dial("tcp", ts.Listener.Addr().String()) if err != nil { t.Fatalf("Dial: %v", err) } err = conn.(*net.TCPConn).CloseWrite() if err != nil { t.Fatalf("Dial: %v", err) } donec := make(chan bool) go func() { defer close(donec) bs, err := ioutil.ReadAll(conn) if err != nil { t.Fatalf("ReadAll: %v", err) } got := string(bs) if got != "" { t.Errorf("read %q from server; want nothing", got) } }() select { case <-donec: case <-time.After(10 * time.Second): t.Fatalf("timeout") } }
// A benchmark for profiling the server without the client code. // The client code runs in a subprocess. // // For use like: // $ go test -c // $ ./npc.test -test.run=XX -test.bench=BenchmarkServer -test.benchtime=15s -test.cpuprofile=npc.prof // $ go tool pprof npc.test npc.prof // (pprof) web func BenchmarkServer(b *testing.B) { b.ReportAllocs() // Child process mode if addr := os.Getenv("TEST_BENCH_SERVER_ADDR"); addr != "" { c := NewClient([]string{addr}) defer c.Close() n, err := strconv.Atoi(os.Getenv("TEST_BENCH_CLIENT_N")) if err != nil { panic(err) } for i := 0; i < n; i++ { resp, err := c.Do(NewRequest(strings.NewReader("ping"))) if err != nil { log.Panicf("Do: %v", err) } body := string(resp.Body) if body != "pong" { log.Panicf("Got body: %v", resp.Body) } } os.Exit(0) return } b.StopTimer() ts := npctest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { fmt.Fprintf(w, "pong") })) defer ts.Close() b.StartTimer() cmd := exec.Command(os.Args[0], "-test.run=XXXX", "-test.bench=BenchmarkServer") cmd.Env = append([]string{ fmt.Sprintf("TEST_BENCH_CLIENT_N=%d", b.N), fmt.Sprintf("TEST_BENCH_SERVER_ADDR=%s", ts.Listener.Addr()), }, os.Environ()...) out, err := cmd.CombinedOutput() if err != nil { b.Errorf("Test failure: %v, with output: %s", err, out) } }
func xTestCloseNotifier(t *testing.T) { defer afterTest(t) gotReq := make(chan bool, 1) sawClose := make(chan bool, 1) ts := npctest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { gotReq <- true cc := w.(CloseNotifier).CloseNotify() <-cc sawClose <- true })) defer ts.Close() conn, err := net.DialTimeout("tcp", ts.Listener.Addr().String(), 10*time.Millisecond) if err != nil { t.Fatalf("Dial: %v", err) } diec := make(chan bool) go func() { _, err := NewRequest(strings.NewReader("ping")).Write(conn) if err != nil { t.Fatalf("Write: %v", err) } <-diec conn.Close() }() For: for { select { case <-gotReq: diec <- true case <-sawClose: break For case <-time.After(5 * time.Second): t.Fatal("timeout") } } }
func benchmarkClientServerParallel(b *testing.B, parallelism int) { b.ReportAllocs() ts := npctest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { fmt.Fprintf(w, "pong") })) defer ts.Close() c := NewClient([]string{ts.Listener.Addr().String()}) c.Timeout = 5 * time.Second defer c.Close() b.ResetTimer() b.SetParallelism(parallelism) b.RunParallel(func(pb *testing.PB) { for pb.Next() { resp, err := c.Do(NewRequest(strings.NewReader("ping"))) if err != nil { b.Fatalf("Do: %v", err) } body := string(resp.Body) if body != "pong" { b.Fatalf("Got body: %v, bodylen: %d", resp.Body, resp.Header.BodyLen) } } }) }
func xBenchmarkClientServer(b *testing.B) { b.ReportAllocs() b.StopTimer() ts := npctest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) { fmt.Fprintf(w, "pong") })) defer ts.Close() b.StartTimer() c := NewClient([]string{ts.Listener.Addr().String()}) defer c.Close() for i := 0; i < b.N; i++ { resp, err := c.Do(NewRequest(strings.NewReader("ping"))) if err != nil { b.Fatalf("Do: %v", err) } body := string(resp.Body) if body != "pong" { b.Fatalf("Got body: %v", resp.Body) } } b.StopTimer() }