func doBenchmarkRPCData(b *testing.B, buffered bool) { b.StopTimer() plen := b.N * 1024 // N kB b.SetBytes(int64(plen) * 2) // both directions payload := string(vbytes.RandBytes(plen)) inconn, outconn := vtesting.SelfConnection() ins, outs, err := MuxPairs(inconn, outconn, 2, buffered) if err != nil { b.Fatal("MuxPairs failed: ", err) } clients, err := SetupRPC(ins, outs) if err != nil { b.Fatal("SetupRPC failed: ", err) } rpayload1 := "" rpayload2 := "" retch := make(chan *rpc.Call, 2) b.StartTimer() clients[0].Go("RPCRecv.Echo", &payload, &rpayload1, retch) clients[1].Go("RPCRecv.Echo", &payload, &rpayload2, retch) <-retch <-retch b.StopTimer() if rpayload1 != payload || rpayload2 != payload { b.Fatal("Bigdata failed") } }
func doBenchmarkRPCCalls(b *testing.B, buffered bool) { b.StopTimer() payload := string([]byte{11, 23, 5}) // payload sent b.N times in two directions b.SetBytes(int64(len(payload) * b.N * 2)) inconn, outconn := vtesting.SelfConnection() ins, outs, err := MuxPairs(inconn, outconn, 2, buffered) if err != nil { b.Fatal("MuxPairs failed: ", err) } clients, err := SetupRPC(ins, outs) if err != nil { b.Fatal("SetupRPC failed: ", err) } retch := make(chan *rpc.Call, b.N*2) rpayload := "" b.StartTimer() for i := 0; i < b.N; i++ { clients[0].Go("RPCRecv.Echo", &payload, &rpayload, retch) clients[1].Go("RPCRecv.Echo", &payload, &rpayload, retch) } for i := 0; i < b.N*2; i++ { <-retch } b.StopTimer() }
func TestCascadedMuxConn(t *testing.T) { inconn, outconn := vtesting.SelfConnection() for i := 0; i < 10; i++ { ins, outs, err := MuxPairs(inconn, outconn, 2, false) if err != nil { t.Fatal("Could not set up cascade") } ins[0].Close() outs[0].Close() inconn = ins[1] outconn = outs[1] } srv := rpc.NewServer() srv.Register(new(vtesting.RPCRecv)) go srv.ServeConn(inconn) client := rpc.NewClient(outconn) sdata := "abc" rdata := "" err := client.Call("RPCRecv.Echo", &sdata, &rdata) if err != nil || sdata != rdata { t.Error("Cascaded RPC call failed: ", err) } client.Close() }
func TestConnection(t *testing.T) { inconn, outconn := vtesting.SelfConnection() defer inconn.Close() defer outconn.Close() data := make([]byte, 2) data[0] = 0 data[1] = 1 outconn.Write(data) rdata := make([]byte, 2) inconn.Read(rdata) if data[0] != rdata[0] || data[1] != rdata[1] { t.Error("Basic socket comms failed") } enc := gob.NewEncoder(outconn) dec := gob.NewDecoder(inconn) sstr := "hello" go func() { enc.Encode(sstr) }() var rstr string dec.Decode(&rstr) if rstr != sstr { t.Error("Encoder over socket failed") } }
func TestClose(t *testing.T) { inconn, outconn := vtesting.SelfConnection() ins, outs, err := MuxPairs(inconn, outconn, 2, false) if err != nil { t.Fatal("MuxPairs failed: ", err) } // Close one mux, should be able to read from the other ins[0].Close() sdata := []byte{11, 23, 5} go func() { ins[1].Write(sdata) }() rdata := make([]byte, 3) outs[1].Read(rdata) if !bytes.Equal(sdata, rdata) { t.Error("Half-closed connection: bytes don't match") } // Close other mux, reads should return io.EOF ins[1].Close() _, err0 := ins[0].Read(rdata) _, err1 := ins[1].Read(rdata) if err0 != io.EOF || err1 != io.EOF { t.Error("Bad error codes on closed muxed conn:", err0, err1) } }
func TestRPCDropServerConn(t *testing.T) { inconn, outconn := vtesting.SelfConnection() ins, outs, err := MuxPairs(inconn, outconn, 2, false) if err != nil { t.Error("MuxPairs failed: ", err) } ins[0].Close() outs[0].Close() srv := rpc.NewServer() srv.Register(new(vtesting.RPCRecv)) go srv.ServeConn(ins[1]) client := rpc.NewClient(outs[1]) sdata := "abc" rdata := "" err = client.Call("RPCRecv.Echo", &sdata, &rdata) if err != nil { t.Error("Regular RPC call failed: ", err) } // TODO: test closing the muxconn instead of the underlying connection once // muxconn handles read-after-close errors // ins[1].Close() outconn.Close() inconn.Close() err = client.Call("RPCRecv.Echo", &sdata, &rdata) if err != io.EOF { t.Error("RPC call on closed MuxConn server did not fail with io.EOF", err) } }
func TestSplitReceiver(t *testing.T) { inconn, outconn := vtesting.SelfConnection() outchannels, err := Split(outconn, 2) if err != nil { t.Error("Split failed: ", err) } out := outchannels[1] chno := uint(1) sdata := []byte("hello") sdatalen := len(sdata) enc := gob.NewEncoder(inconn) go func() { err := enc.Encode(chno) if err != nil { t.Error("Split conn write chno failed") } err = enc.Encode(sdatalen) if err != nil { t.Error("Split conn write sdatalen failed") } err = enc.Encode(sdata) if err != nil { t.Error("Split conn write sdata failed") } }() rdata := make([]byte, len(sdata)) n, err := out.Read(rdata) if n != len(sdata) || err != nil || !bytes.Equal(rdata, sdata) { t.Error("Split receive failed: ", rdata) } }
func TestXRPC(t *testing.T) { inconn, outconn := vtesting.SelfConnection() ins, outs, err := MuxPairs(inconn, outconn, 2, false) if err != nil { t.Error("MuxPairs failed: ", err) } type pair struct { In net.Conn Out net.Conn } pairs := make([]pair, 2) pairs[0].In = ins[0] pairs[1].In = ins[1] pairs[0].Out = outs[0] pairs[1].Out = outs[1] for _, p := range pairs { if p.In.LocalAddr().String() != p.Out.RemoteAddr().String() && p.In.LocalAddr().String() != "" { t.Error("Address mismatch: ", p.In.LocalAddr(), " != ", p.Out.RemoteAddr()) } if p.In.RemoteAddr().String() != p.Out.LocalAddr().String() && p.In.RemoteAddr().String() != "" { t.Error("Address mismatch: ", p.In.RemoteAddr(), " != ", p.Out.LocalAddr()) } } srv := rpc.NewServer() srv.Register(new(vtesting.RPCRecv)) go srv.ServeConn(pairs[0].In) go srv.ServeConn(pairs[1].Out) client1 := rpc.NewClient(pairs[0].Out) defer client1.Close() client2 := rpc.NewClient(pairs[1].In) defer client2.Close() sdata1 := "abc" sdata2 := "123" rdata1 := "" rdata2 := "" call1 := client1.Go("RPCRecv.Echo", &sdata1, &rdata1, nil) call2 := client2.Go("RPCRecv.Echo", &sdata2, &rdata2, nil) <-call2.Done <-call1.Done if sdata1 != rdata1 || sdata2 != rdata2 { t.Error("XRPC failed") } }
func TestRPC(t *testing.T) { inconn, outconn := vtesting.SelfConnection() ins, outs, err := MuxPairs(inconn, outconn, 2, false) if err != nil { t.Error("MuxPairs failed: ", err) } recv := new(vtesting.RPCRecv) rpc.Register(recv) go rpc.ServeConn(ins[0]) client := rpc.NewClient(outs[0]) sdata := "hello" rdata := "" err = client.Call("RPCRecv.Echo", &sdata, &rdata) if err != nil { t.Error("RPC call failed: ", err) } if sdata != rdata { t.Error("RPC Echo failed") } }
func TestSplitSender(t *testing.T) { inconn, outconn := vtesting.SelfConnection() defer outconn.Close() // Use inconn as a sender inchannels, err := Split(inconn, 2) if err != nil { t.Error("Split failed: ", err) } in := inchannels[1] defer inchannels[0].Close() sdata := []byte("hello") go func() { in.Write(sdata) in.Close() }() dec := gob.NewDecoder(outconn) var rchno uint var rdatalen int err = dec.Decode(&rchno) if err != nil || rchno != 1 { t.Error("Split conn chno failed") } err = dec.Decode(&rdatalen) if err != nil || rdatalen != len(sdata) { t.Error("Split conn rdatalen failed") } rdata := make([]byte, rdatalen) err = dec.Decode(&rdata) if err != nil { t.Error("Split conn rdata failed") } if !bytes.Equal(rdata, sdata) { t.Error("Split send failed: ", sdata, " != ", rdata) } }
func TestRPCDropClientConn(t *testing.T) { inconn, outconn := vtesting.SelfConnection() ins, outs, err := MuxPairs(inconn, outconn, 2, false) if err != nil { t.Fatal("MuxPairs failed: ", err) } srv := rpc.NewServer() srv.Register(new(vtesting.RPCRecv)) go srv.ServeConn(ins[0]) client := rpc.NewClient(outs[0]) sdata := "abc" rdata := "" err = client.Call("RPCRecv.Echo", &sdata, &rdata) if err != nil { t.Error("Regular RPC call failed: ", err) } outconn.Close() err = client.Call("RPCRecv.Echo", &sdata, &rdata) if err != io.EOF { t.Error("RPC call on closed MuxConn client did not fail with io.EOF") } }
// Stress test with many muxes func TestNMuxes(t *testing.T) { var n int if testing.Short() { n = 100 } else { n = 10000 } inconn, outconn := vtesting.SelfConnection() ins, outs, err := MuxPairs(inconn, outconn, n, false) if err != nil { t.Fatal("MuxPairs failed: ", err) } // in --> out sdata := []byte{11, 23, 5} go func() { for _, c := range ins { c.Write(sdata) } }() rch := make(chan []byte) for _, c := range outs { go func(c net.Conn) { rdata := make([]byte, len(sdata)) c.Read(rdata) rch <- rdata }(c) } for i := 0; i < n; i++ { if !bytes.Equal(sdata, <-rch) { t.Error("Failed on channel ", i) } } }