github.com/stackdocker/rkt@v0.10.1-0.20151109095037-1aa827478248/Godeps/_workspace/src/google.golang.org/grpc/benchmark/benchmark.go (about) 1 /* 2 * 3 * Copyright 2014, Google Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above 13 * copyright notice, this list of conditions and the following disclaimer 14 * in the documentation and/or other materials provided with the 15 * distribution. 16 * * Neither the name of Google Inc. nor the names of its 17 * contributors may be used to endorse or promote products derived from 18 * this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 */ 33 34 /* 35 Package benchmark implements the building blocks to setup end-to-end gRPC benchmarks. 36 */ 37 package benchmark 38 39 import ( 40 "io" 41 "math" 42 "net" 43 44 "github.com/coreos/rkt/Godeps/_workspace/src/golang.org/x/net/context" 45 "github.com/coreos/rkt/Godeps/_workspace/src/google.golang.org/grpc" 46 testpb "github.com/coreos/rkt/Godeps/_workspace/src/google.golang.org/grpc/benchmark/grpc_testing" 47 "github.com/coreos/rkt/Godeps/_workspace/src/google.golang.org/grpc/grpclog" 48 ) 49 50 func newPayload(t testpb.PayloadType, size int) *testpb.Payload { 51 if size < 0 { 52 grpclog.Fatalf("Requested a response with invalid length %d", size) 53 } 54 body := make([]byte, size) 55 switch t { 56 case testpb.PayloadType_COMPRESSABLE: 57 case testpb.PayloadType_UNCOMPRESSABLE: 58 grpclog.Fatalf("PayloadType UNCOMPRESSABLE is not supported") 59 default: 60 grpclog.Fatalf("Unsupported payload type: %d", t) 61 } 62 return &testpb.Payload{ 63 Type: t, 64 Body: body, 65 } 66 } 67 68 type testServer struct { 69 } 70 71 func (s *testServer) UnaryCall(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) { 72 return &testpb.SimpleResponse{ 73 Payload: newPayload(in.ResponseType, int(in.ResponseSize)), 74 }, nil 75 } 76 77 func (s *testServer) StreamingCall(stream testpb.TestService_StreamingCallServer) error { 78 for { 79 in, err := stream.Recv() 80 if err == io.EOF { 81 // read done. 82 return nil 83 } 84 if err != nil { 85 return err 86 } 87 if err := stream.Send(&testpb.SimpleResponse{ 88 Payload: newPayload(in.ResponseType, int(in.ResponseSize)), 89 }); err != nil { 90 return err 91 } 92 } 93 } 94 95 // StartServer starts a gRPC server serving a benchmark service on the given 96 // address, which may be something like "localhost:0". It returns its listen 97 // address and a function to stop the server. 98 func StartServer(addr string) (string, func()) { 99 lis, err := net.Listen("tcp", addr) 100 if err != nil { 101 grpclog.Fatalf("Failed to listen: %v", err) 102 } 103 s := grpc.NewServer(grpc.MaxConcurrentStreams(math.MaxUint32)) 104 testpb.RegisterTestServiceServer(s, &testServer{}) 105 go s.Serve(lis) 106 return lis.Addr().String(), func() { 107 s.Stop() 108 } 109 } 110 111 // DoUnaryCall performs an unary RPC with given stub and request and response sizes. 112 func DoUnaryCall(tc testpb.TestServiceClient, reqSize, respSize int) { 113 pl := newPayload(testpb.PayloadType_COMPRESSABLE, reqSize) 114 req := &testpb.SimpleRequest{ 115 ResponseType: pl.Type, 116 ResponseSize: int32(respSize), 117 Payload: pl, 118 } 119 if _, err := tc.UnaryCall(context.Background(), req); err != nil { 120 grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err) 121 } 122 } 123 124 // DoStreamingRoundTrip performs a round trip for a single streaming rpc. 125 func DoStreamingRoundTrip(tc testpb.TestServiceClient, stream testpb.TestService_StreamingCallClient, reqSize, respSize int) { 126 pl := newPayload(testpb.PayloadType_COMPRESSABLE, reqSize) 127 req := &testpb.SimpleRequest{ 128 ResponseType: pl.Type, 129 ResponseSize: int32(respSize), 130 Payload: pl, 131 } 132 if err := stream.Send(req); err != nil { 133 grpclog.Fatalf("StreamingCall(_).Send: %v", err) 134 } 135 if _, err := stream.Recv(); err != nil { 136 grpclog.Fatalf("StreamingCall(_).Recv: %v", err) 137 } 138 } 139 140 // NewClientConn creates a gRPC client connection to addr. 141 func NewClientConn(addr string) *grpc.ClientConn { 142 conn, err := grpc.Dial(addr, grpc.WithInsecure()) 143 if err != nil { 144 grpclog.Fatalf("NewClientConn(%q) failed to create a ClientConn %v", addr, err) 145 } 146 return conn 147 }