blob: c29f942e6a24df0e31a648807680086aef46e72a [file] [log] [blame]
Jungho Ahnfa7a31f2015-01-07 17:34:12 -08001package benchmark
Robin Thellendcafaa492014-06-24 13:58:25 -07002
3import (
4 "bytes"
5 "fmt"
Jungho Ahnbc6ffa22014-12-10 17:55:35 -08006 "testing"
Robin Thellendcafaa492014-06-24 13:58:25 -07007 "time"
8
Jungho Ahnfa7a31f2015-01-07 17:34:12 -08009 "v.io/core/veyron/lib/testutil/benchmark"
Jungho Ahnbc6ffa22014-12-10 17:55:35 -080010
Jiri Simsa764efb72014-12-25 20:57:03 -080011 "v.io/core/veyron2/context"
12 "v.io/core/veyron2/vlog"
Robin Thellendcafaa492014-06-24 13:58:25 -070013)
14
Jungho Ahnfa7a31f2015-01-07 17:34:12 -080015// CallEcho calls 'Echo' method 'iterations' times with the given payload size.
16func CallEcho(b *testing.B, ctx *context.T, address string, iterations, payloadSize int, stats *benchmark.Stats) {
Jungho Ahnbc6ffa22014-12-10 17:55:35 -080017 stub := BenchmarkClient(address)
Robin Thellendcafaa492014-06-24 13:58:25 -070018 payload := make([]byte, payloadSize)
Jungho Ahnbc6ffa22014-12-10 17:55:35 -080019 for i := range payload {
Robin Thellendcafaa492014-06-24 13:58:25 -070020 payload[i] = byte(i & 0xff)
21 }
22
Jungho Ahnbc6ffa22014-12-10 17:55:35 -080023 b.SetBytes(int64(payloadSize) * 2) // 2 for round trip of each payload.
24 b.ResetTimer() // Exclude setup time from measurement.
25
Robin Thellendcafaa492014-06-24 13:58:25 -070026 for i := 0; i < iterations; i++ {
Jungho Ahnbc6ffa22014-12-10 17:55:35 -080027 b.StartTimer()
Robin Thellendcafaa492014-06-24 13:58:25 -070028 start := time.Now()
Jungho Ahnbc6ffa22014-12-10 17:55:35 -080029
30 r, err := stub.Echo(ctx, payload)
31
Robin Thellendcafaa492014-06-24 13:58:25 -070032 elapsed := time.Since(start)
Jungho Ahnbc6ffa22014-12-10 17:55:35 -080033 b.StopTimer()
34
Robin Thellendcafaa492014-06-24 13:58:25 -070035 if err != nil {
36 vlog.Fatalf("Echo failed: %v", err)
37 }
Jungho Ahnbc6ffa22014-12-10 17:55:35 -080038 if !bytes.Equal(r, payload) {
39 vlog.Fatalf("Echo returned %v, but expected %v", r, payload)
Robin Thellendcafaa492014-06-24 13:58:25 -070040 }
Jungho Ahnbc6ffa22014-12-10 17:55:35 -080041
Jungho Ahnfa7a31f2015-01-07 17:34:12 -080042 stats.Add(elapsed)
Robin Thellendcafaa492014-06-24 13:58:25 -070043 }
44}
45
Jungho Ahnfa7a31f2015-01-07 17:34:12 -080046// CallEchoStream calls 'EchoStream' method 'iterations' times. Each iteration sends
47// 'chunkCnt' chunks on the stream and receives the same number of chunks back. Each
48// chunk has the given payload size.
49func CallEchoStream(b *testing.B, ctx *context.T, address string, iterations, chunkCnt, payloadSize int, stats *benchmark.Stats) {
Jungho Ahnbc6ffa22014-12-10 17:55:35 -080050 done, _ := StartEchoStream(b, ctx, address, iterations, chunkCnt, payloadSize, stats)
51 <-done
52}
53
Jungho Ahnfa7a31f2015-01-07 17:34:12 -080054// StartEchoStream starts to call 'EchoStream' method 'iterations' times. This does
55// not block, and returns a channel that will receive the number of iterations when
56// it's done. It also returns a callback function to stop the streaming. Each iteration
57// requests 'chunkCnt' chunks on the stream and receives that number of chunks back.
58// Each chunk has the given payload size. Zero 'iterations' means unlimited.
59func StartEchoStream(b *testing.B, ctx *context.T, address string, iterations, chunkCnt, payloadSize int, stats *benchmark.Stats) (<-chan int, func()) {
Jungho Ahnbc6ffa22014-12-10 17:55:35 -080060 stub := BenchmarkClient(address)
Robin Thellendcafaa492014-06-24 13:58:25 -070061 payload := make([]byte, payloadSize)
Jungho Ahnbc6ffa22014-12-10 17:55:35 -080062 for i := range payload {
Robin Thellendcafaa492014-06-24 13:58:25 -070063 payload[i] = byte(i & 0xff)
64 }
65
Jungho Ahnfa7a31f2015-01-07 17:34:12 -080066 stop := make(chan struct{})
Jungho Ahnbc6ffa22014-12-10 17:55:35 -080067 stopped := func() bool {
68 select {
69 case <-stop:
70 return true
71 default:
72 return false
Robin Thellendcafaa492014-06-24 13:58:25 -070073 }
Jungho Ahnbc6ffa22014-12-10 17:55:35 -080074 }
Jungho Ahnfa7a31f2015-01-07 17:34:12 -080075 done := make(chan int, 1)
Jungho Ahnbc6ffa22014-12-10 17:55:35 -080076
77 if b.N > 0 {
78 // 2 for round trip of each payload.
79 b.SetBytes(int64((iterations*chunkCnt/b.N)*payloadSize) * 2)
80 }
81 b.ResetTimer() // Exclude setup time from measurement.
82
83 go func() {
84 defer close(done)
85
86 n := 0
87 for ; !stopped() && (iterations == 0 || n < iterations); n++ {
88 b.StartTimer()
89 start := time.Now()
90
91 stream, err := stub.EchoStream(ctx)
92 if err != nil {
93 vlog.Fatalf("EchoStream failed: %v", err)
Robin Thellendcafaa492014-06-24 13:58:25 -070094 }
Shyam Jayaramanc4aed6e2014-07-22 14:25:06 -070095
Jungho Ahnbc6ffa22014-12-10 17:55:35 -080096 rDone := make(chan error, 1)
97 go func() {
98 defer close(rDone)
99
100 rStream := stream.RecvStream()
101 i := 0
102 for ; rStream.Advance(); i++ {
103 r := rStream.Value()
104 if !bytes.Equal(r, payload) {
105 rDone <- fmt.Errorf("EchoStream returned %v, but expected %v", r, payload)
106 return
107 }
108 }
109 if i != chunkCnt {
Jungho Ahnb2657b22015-02-04 09:10:04 -0800110 rDone <- fmt.Errorf("EchoStream returned %d chunks, but expected %d", i, chunkCnt)
Jungho Ahnbc6ffa22014-12-10 17:55:35 -0800111 return
112 }
113 rDone <- rStream.Err()
114 }()
115
116 sStream := stream.SendStream()
117 for i := 0; i < chunkCnt; i++ {
118 if err = sStream.Send(payload); err != nil {
119 vlog.Fatalf("EchoStream Send failed: %v", err)
120 }
121 }
122 if err = sStream.Close(); err != nil {
123 vlog.Fatalf("EchoStream Send failed: %v", err)
124 }
125
126 if err = <-rDone; err != nil {
127 vlog.Fatalf("%v", err)
128 }
129
130 if err = stream.Finish(); err != nil {
131 vlog.Fatalf("Finish failed: %v", err)
132 }
133
134 elapsed := time.Since(start)
135 b.StopTimer()
136
Jungho Ahnfa7a31f2015-01-07 17:34:12 -0800137 stats.Add(elapsed)
Robin Thellendcafaa492014-06-24 13:58:25 -0700138 }
Robin Thellendcafaa492014-06-24 13:58:25 -0700139
Jungho Ahnbc6ffa22014-12-10 17:55:35 -0800140 done <- n
141 }()
142
143 return done, func() {
144 close(stop)
145 <-done
Robin Thellendcafaa492014-06-24 13:58:25 -0700146 }
147}