veyron/runtimes/google/ipc/stream/benchmark: add ws throughput benchmark

* Add WS throughput benchmark and update the results.

Change-Id: Ia92dca53d32b75f82b7388da33f0e9b825065e72
diff --git a/runtimes/google/ipc/stream/benchmark/RESULTS.txt b/runtimes/google/ipc/stream/benchmark/RESULTS.txt
index b60e4ed..85c78ee 100644
--- a/runtimes/google/ipc/stream/benchmark/RESULTS.txt
+++ b/runtimes/google/ipc/stream/benchmark/RESULTS.txt
@@ -1,72 +1,82 @@
-Date: 01/06/2015
+Date: 01/30/2015
 Platform: Intel(R) Xeon(R) CPU E5-2689 0 @ 2.60GHz,  66114888KB Memory
 
 $ v23 go test -bench=. -cpu=1 -benchtime=5s \
   v.io/core/veyron/runtimes/google/ipc/stream/benchmark
 
-Benchmark_dial_VIF	  500000	     15356 ns/op
+Benchmark_dial_VIF	  500000	     14292 ns/op
 --- Histogram (unit: s)
-	Count: 500000  Min: 4  Max: 15644  Avg: 14.66
+	Count: 500000  Min: 4  Max: 16455  Avg: 13.58
 	------------------------------------------------------------
-	[    4,     5)   47181    9.4%    9.4%  #
-	[    5,     6)  314973   63.0%   72.4%  ######
-	[    6,     9)  123582   24.7%   97.1%  ##
-	[    9,    15)   10991    2.2%   99.3%  
-	[   15,    28)    2038    0.4%   99.8%  
-	[   28,    53)     129    0.0%   99.8%  
-	[   53,   100)      53    0.0%   99.8%  
-	[  100,   190)      12    0.0%   99.8%  
-	[  190,   362)       0    0.0%   99.8%  
-	[  362,   690)       1    0.0%   99.8%  
-	[  690,  1315)      38    0.0%   99.8%  
-	[ 1315,  2505)     165    0.0%   99.8%  
-	[ 2505,  4771)     487    0.1%   99.9%  
-	[ 4771,  9086)     326    0.1%  100.0%  
-	[ 9086, 17301)      24    0.0%  100.0%  
-	[17301, 32941)       0    0.0%  100.0%  
-	[32941,   inf)       0    0.0%  100.0%  
-Benchmark_dial_VIF_TLS	     500	  12681088 ns/op
+	[    4,     5)  139232   27.8%   27.8%  ###
+	[    5,     6)  257818   51.6%   79.4%  #####
+	[    6,     9)   92644   18.5%   97.9%  ##
+	[    9,    15)    5963    1.2%   99.1%  
+	[   15,    28)    3162    0.6%   99.8%  
+	[   28,    53)     171    0.0%   99.8%  
+	[   53,   101)      67    0.0%   99.8%  
+	[  101,   193)       1    0.0%   99.8%  
+	[  193,   370)       0    0.0%   99.8%  
+	[  370,   708)       0    0.0%   99.8%  
+	[  708,  1354)      57    0.0%   99.8%  
+	[ 1354,  2589)     152    0.0%   99.9%  
+	[ 2589,  4949)     393    0.1%   99.9%  
+	[ 4949,  9457)     322    0.1%  100.0%  
+	[ 9457, 18069)      18    0.0%  100.0%  
+	[18069, 34520)       0    0.0%  100.0%  
+	[34520,   inf)       0    0.0%  100.0%  
+Benchmark_dial_VIF_TLS	     500	  12594281 ns/op
 --- Histogram (unit: ms)
-	Count: 500  Min: 12  Max: 16  Avg: 12.31
+	Count: 500  Min: 12  Max: 14  Avg: 12.31
 	------------------------------------------------------------
-	[ 12,  13)  357   71.4%   71.4%  #######
-	[ 13,  14)  133   26.6%   98.0%  ###
-	[ 14,  15)    7    1.4%   99.4%  
-	[ 15,  16)    2    0.4%   99.8%  
-	[ 16, inf)    1    0.2%  100.0%  
-Benchmark_dial_VC_TLS	     500	  16224331 ns/op
+	[ 12,  13)  352   70.4%   70.4%  #######
+	[ 13,  14)  141   28.2%   98.6%  ###
+	[ 14, inf)    7    1.4%  100.0%  
+Benchmark_dial_VC_TLS	     500	  16116072 ns/op
 --- Histogram (unit: ms)
-	Count: 500  Min: 15  Max: 22  Avg: 15.60
+	Count: 500  Min: 15  Max: 22  Avg: 15.53
 	------------------------------------------------------------
-	[ 15,  16)  279   55.8%   55.8%  ######
-	[ 16,  17)  152   30.4%   86.2%  ###
-	[ 17,  18)   62   12.4%   98.6%  #
-	[ 18,  19)    6    1.2%   99.8%  
-	[ 19,  20)    0    0.0%   99.8%  
+	[ 15,  16)  313   62.6%   62.6%  ######
+	[ 16,  17)  121   24.2%   86.8%  ##
+	[ 17,  18)   60   12.0%   98.8%  #
+	[ 18,  19)    3    0.6%   99.4%  
+	[ 19,  20)    2    0.4%   99.8%  
 	[ 20,  21)    0    0.0%   99.8%  
 	[ 21,  23)    1    0.2%  100.0%  
 	[ 23, inf)    0    0.0%  100.0%  
-Benchmark_throughput_TCP_1Conn	 1000000	     10963 ns/op	4669.96 MB/s
-Benchmark_throughput_TCP_2Conns	 1000000	      9739 ns/op	5257.14 MB/s
-Benchmark_throughput_TCP_4Conns	  500000	     11896 ns/op	4303.82 MB/s
-Benchmark_throughput_TCP_8Conns	  500000	     12867 ns/op	3979.12 MB/s
-Benchmark_throughput_Pipe_1Conn	  300000	     28233 ns/op	1813.43 MB/s
-Benchmark_throughput_Pipe_2Conns	  500000	     25339 ns/op	2020.60 MB/s
-Benchmark_throughput_Pipe_4Conns	  300000	     26626 ns/op	1922.90 MB/s
-Benchmark_throughput_Pipe_8Conns	  500000	     27340 ns/op	1872.67 MB/s
-Benchmark_throughput_Flow_1VIF_1VC_1Flow	  200000	     32590 ns/op	1571.02 MB/s
-Benchmark_throughput_Flow_1VIF_1VC_2Flow	  200000	     32731 ns/op	1564.24 MB/s
-Benchmark_throughput_Flow_1VIF_1VC_8Flow	  200000	     41289 ns/op	1240.03 MB/s
-Benchmark_throughput_Flow_1VIF_2VC_2Flow	  200000	     33878 ns/op	1511.30 MB/s
-Benchmark_throughput_Flow_1VIF_2VC_8Flow	  200000	     40923 ns/op	1251.10 MB/s
-Benchmark_throughput_Flow_2VIF_4VC_8Flow	  200000	     42293 ns/op	1210.60 MB/s
-Benchmark_throughput_TLS_1Conn	   20000	    426157 ns/op	 120.14 MB/s
-Benchmark_throughput_TLS_2Conns	   20000	    421319 ns/op	 121.52 MB/s
-Benchmark_throughput_TLS_4Conns	   20000	    425284 ns/op	 120.39 MB/s
-Benchmark_throughput_TLS_8Conns	   20000	    426533 ns/op	 120.04 MB/s
-Benchmark_throughput_Flow_1VIF_1VC_1FlowTLS	   20000	    474126 ns/op	 107.99 MB/s
-Benchmark_throughput_Flow_1VIF_1VC_2FlowTLS	   20000	    472005 ns/op	 108.47 MB/s
-Benchmark_throughput_Flow_1VIF_1VC_8FlowTLS	   20000	    484625 ns/op	 105.65 MB/s
-Benchmark_throughput_Flow_1VIF_2VC_2FlowTLS	   20000	    483762 ns/op	 105.84 MB/s
-Benchmark_throughput_Flow_1VIF_2VC_8FlowTLS	   20000	    485164 ns/op	 105.53 MB/s
-Benchmark_throughput_Flow_2VIF_4VC_8FlowTLS	   20000	    493864 ns/op	 103.67 MB/s
+Benchmark_throughput_TCP_1Conn	 1000000	      9197 ns/op	5566.89 MB/s
+Benchmark_throughput_TCP_2Conns	 1000000	      9083 ns/op	5636.56 MB/s
+Benchmark_throughput_TCP_4Conns	 1000000	      9855 ns/op	5194.81 MB/s
+Benchmark_throughput_TCP_8Conns	  500000	     12541 ns/op	4082.43 MB/s
+Benchmark_throughput_WS_1Conn	   30000	    206804 ns/op	 247.58 MB/s
+Benchmark_throughput_WS_2Conns	   30000	    211842 ns/op	 241.69 MB/s
+Benchmark_throughput_WS_4Conns	   30000	    209994 ns/op	 243.82 MB/s
+Benchmark_throughput_WS_8Conns	   30000	    217110 ns/op	 235.83 MB/s
+Benchmark_throughput_WSH_TCP_1Conn	 1000000	      9322 ns/op	5491.85 MB/s
+Benchmark_throughput_WSH_TCP_2Conns	 1000000	      9370 ns/op	5463.77 MB/s
+Benchmark_throughput_WSH_TCP_4Conns	 1000000	      9466 ns/op	5408.50 MB/s
+Benchmark_throughput_WSH_TCP_8Conns	  500000	     12526 ns/op	4087.22 MB/s
+Benchmark_throughput_WSH_WS_1Conn	   30000	    207833 ns/op	 246.35 MB/s
+Benchmark_throughput_WSH_WS_2Conns	   30000	    208567 ns/op	 245.48 MB/s
+Benchmark_throughput_WSH_WS_4Conns	   30000	    211562 ns/op	 242.01 MB/s
+Benchmark_throughput_WSH_WS_8Conns	   30000	    216454 ns/op	 236.54 MB/s
+Benchmark_throughput_Pipe_1Conn	  500000	     20169 ns/op	2538.54 MB/s
+Benchmark_throughput_Pipe_2Conns	  500000	     19935 ns/op	2568.29 MB/s
+Benchmark_throughput_Pipe_4Conns	  300000	     19893 ns/op	2573.76 MB/s
+Benchmark_throughput_Pipe_8Conns	 1000000	     20235 ns/op	2530.22 MB/s
+Benchmark_throughput_Flow_1VIF_1VC_1Flow	  300000	     28014 ns/op	1827.66 MB/s
+Benchmark_throughput_Flow_1VIF_1VC_2Flow	  300000	     27495 ns/op	1862.09 MB/s
+Benchmark_throughput_Flow_1VIF_1VC_8Flow	  200000	     35584 ns/op	1438.84 MB/s
+Benchmark_throughput_Flow_1VIF_2VC_2Flow	  300000	     27665 ns/op	1850.66 MB/s
+Benchmark_throughput_Flow_1VIF_2VC_8Flow	  200000	     34974 ns/op	1463.94 MB/s
+Benchmark_throughput_Flow_2VIF_4VC_8Flow	  200000	     37642 ns/op	1360.15 MB/s
+Benchmark_throughput_TLS_1Conn	   20000	    415149 ns/op	 123.33 MB/s
+Benchmark_throughput_TLS_2Conns	   20000	    416008 ns/op	 123.07 MB/s
+Benchmark_throughput_TLS_4Conns	   20000	    421083 ns/op	 121.59 MB/s
+Benchmark_throughput_TLS_8Conns	   20000	    423079 ns/op	 121.02 MB/s
+Benchmark_throughput_Flow_1VIF_1VC_1FlowTLS	   20000	    466212 ns/op	 109.82 MB/s
+Benchmark_throughput_Flow_1VIF_1VC_2FlowTLS	   20000	    466104 ns/op	 109.85 MB/s
+Benchmark_throughput_Flow_1VIF_1VC_8FlowTLS	   20000	    476604 ns/op	 107.43 MB/s
+Benchmark_throughput_Flow_1VIF_2VC_2FlowTLS	   20000	    466818 ns/op	 109.68 MB/s
+Benchmark_throughput_Flow_1VIF_2VC_8FlowTLS	   20000	    477094 ns/op	 107.32 MB/s
+Benchmark_throughput_Flow_2VIF_4VC_8FlowTLS	   20000	    476370 ns/op	 107.48 MB/s
diff --git a/runtimes/google/ipc/stream/benchmark/throughput_test.go b/runtimes/google/ipc/stream/benchmark/throughput_test.go
index 76ad57d..f97b6e9 100644
--- a/runtimes/google/ipc/stream/benchmark/throughput_test.go
+++ b/runtimes/google/ipc/stream/benchmark/throughput_test.go
@@ -7,6 +7,21 @@
 func Benchmark_throughput_TCP_4Conns(b *testing.B) { benchmarkTCP(b, 4) }
 func Benchmark_throughput_TCP_8Conns(b *testing.B) { benchmarkTCP(b, 8) }
 
+func Benchmark_throughput_WS_1Conn(b *testing.B)  { benchmarkWS(b, 1) }
+func Benchmark_throughput_WS_2Conns(b *testing.B) { benchmarkWS(b, 2) }
+func Benchmark_throughput_WS_4Conns(b *testing.B) { benchmarkWS(b, 4) }
+func Benchmark_throughput_WS_8Conns(b *testing.B) { benchmarkWS(b, 8) }
+
+func Benchmark_throughput_WSH_TCP_1Conn(b *testing.B)  { benchmarkWSH(b, "tcp", 1) }
+func Benchmark_throughput_WSH_TCP_2Conns(b *testing.B) { benchmarkWSH(b, "tcp", 2) }
+func Benchmark_throughput_WSH_TCP_4Conns(b *testing.B) { benchmarkWSH(b, "tcp", 4) }
+func Benchmark_throughput_WSH_TCP_8Conns(b *testing.B) { benchmarkWSH(b, "tcp", 8) }
+
+func Benchmark_throughput_WSH_WS_1Conn(b *testing.B)  { benchmarkWSH(b, "ws", 1) }
+func Benchmark_throughput_WSH_WS_2Conns(b *testing.B) { benchmarkWSH(b, "ws", 2) }
+func Benchmark_throughput_WSH_WS_4Conns(b *testing.B) { benchmarkWSH(b, "ws", 4) }
+func Benchmark_throughput_WSH_WS_8Conns(b *testing.B) { benchmarkWSH(b, "ws", 8) }
+
 func Benchmark_throughput_Pipe_1Conn(b *testing.B)  { benchmarkPipe(b, 1) }
 func Benchmark_throughput_Pipe_2Conns(b *testing.B) { benchmarkPipe(b, 2) }
 func Benchmark_throughput_Pipe_4Conns(b *testing.B) { benchmarkPipe(b, 4) }
diff --git a/runtimes/google/ipc/stream/benchmark/throughput_ws.go b/runtimes/google/ipc/stream/benchmark/throughput_ws.go
new file mode 100644
index 0000000..aa07582
--- /dev/null
+++ b/runtimes/google/ipc/stream/benchmark/throughput_ws.go
@@ -0,0 +1,60 @@
+package benchmark
+
+import (
+	"io"
+	"net"
+	"testing"
+
+	"v.io/core/veyron/lib/websocket"
+)
+
+// benchmarkWS sets up nConns WS connections and measures throughput.
+func benchmarkWS(b *testing.B, nConns int) {
+	rchan := make(chan net.Conn, nConns)
+	wchan := make(chan net.Conn, nConns)
+	ln, err := websocket.Listener("ws", "127.0.0.1:0")
+	if err != nil {
+		b.Fatalf("websocket.Listener failed: %v", err)
+		return
+	}
+	defer ln.Close()
+	// One goroutine to dial nConns connections.
+	go func() {
+		for i := 0; i < nConns; i++ {
+			conn, err := websocket.Dial("ws", ln.Addr().String(), 0)
+			if err != nil {
+				b.Fatalf("websocket.Dial(%q, %q) failed: %v", "ws", ln.Addr(), err)
+				wchan <- nil
+				return
+			}
+			wchan <- conn
+		}
+		close(wchan)
+	}()
+	// One goroutine to accept nConns connections.
+	go func() {
+		for i := 0; i < nConns; i++ {
+			conn, err := ln.Accept()
+			if err != nil {
+				b.Fatalf("Accept failed: %v", err)
+				rchan <- nil
+				return
+			}
+			rchan <- conn
+		}
+		close(rchan)
+	}()
+
+	var readers []io.ReadCloser
+	var writers []io.WriteCloser
+	for r := range rchan {
+		readers = append(readers, r)
+	}
+	for w := range wchan {
+		writers = append(writers, w)
+	}
+	if b.Failed() {
+		return
+	}
+	(&throughputTester{b: b, readers: readers, writers: writers}).Run()
+}
diff --git a/runtimes/google/ipc/stream/benchmark/throughput_wsh.go b/runtimes/google/ipc/stream/benchmark/throughput_wsh.go
new file mode 100644
index 0000000..58066a9
--- /dev/null
+++ b/runtimes/google/ipc/stream/benchmark/throughput_wsh.go
@@ -0,0 +1,75 @@
+package benchmark
+
+import (
+	"io"
+	"net"
+	"testing"
+
+	"v.io/core/veyron/lib/websocket"
+)
+
+// benchmarkWS sets up nConns WS connections and measures throughput.
+func benchmarkWSH(b *testing.B, protocol string, nConns int) {
+	rchan := make(chan net.Conn, nConns)
+	wchan := make(chan net.Conn, nConns)
+	ln, err := websocket.HybridListener("wsh", "127.0.0.1:0")
+	if err != nil {
+		b.Fatalf("websocket.HybridListener failed: %v", err)
+		return
+	}
+	defer ln.Close()
+	// One goroutine to dial nConns connections.
+	go func() {
+		for i := 0; i < nConns; i++ {
+			var conn net.Conn
+			var err error
+			switch protocol {
+			case "tcp":
+				conn, err = net.Dial("tcp", ln.Addr().String())
+			case "ws":
+				conn, err = websocket.Dial("ws", ln.Addr().String(), 0)
+			}
+			if err != nil {
+				b.Fatalf("Dial(%q, %q) failed: %v", protocol, ln.Addr(), err)
+				wchan <- nil
+				return
+			}
+			if protocol == "tcp" {
+				// Write a dummy byte since wsh waits for magic byte forever.
+				conn.Write([]byte("."))
+			}
+			wchan <- conn
+		}
+		close(wchan)
+	}()
+	// One goroutine to accept nConns connections.
+	go func() {
+		for i := 0; i < nConns; i++ {
+			conn, err := ln.Accept()
+			if err != nil {
+				b.Fatalf("Accept failed: %v", err)
+				rchan <- nil
+				return
+			}
+			if protocol == "tcp" {
+				// Read a dummy byte.
+				conn.Read(make([]byte, 1))
+			}
+			rchan <- conn
+		}
+		close(rchan)
+	}()
+
+	var readers []io.ReadCloser
+	var writers []io.WriteCloser
+	for r := range rchan {
+		readers = append(readers, r)
+	}
+	for w := range wchan {
+		writers = append(writers, w)
+	}
+	if b.Failed() {
+		return
+	}
+	(&throughputTester{b: b, readers: readers, writers: writers}).Run()
+}