github.com/blixtra/rkt@v0.8.1-0.20160204105720-ab0d1add1a43/Godeps/_workspace/src/google.golang.org/grpc/interop/test_utils.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  package interop
    35  
    36  import (
    37  	"fmt"
    38  	"io"
    39  	"io/ioutil"
    40  	"strings"
    41  	"time"
    42  
    43  	"github.com/golang/protobuf/proto"
    44  	"golang.org/x/net/context"
    45  	"golang.org/x/oauth2"
    46  	"golang.org/x/oauth2/google"
    47  	"google.golang.org/grpc"
    48  	"google.golang.org/grpc/codes"
    49  	"google.golang.org/grpc/grpclog"
    50  	testpb "google.golang.org/grpc/interop/grpc_testing"
    51  	"google.golang.org/grpc/metadata"
    52  )
    53  
    54  var (
    55  	reqSizes      = []int{27182, 8, 1828, 45904}
    56  	respSizes     = []int{31415, 9, 2653, 58979}
    57  	largeReqSize  = 271828
    58  	largeRespSize = 314159
    59  )
    60  
    61  func clientNewPayload(t testpb.PayloadType, size int) *testpb.Payload {
    62  	if size < 0 {
    63  		grpclog.Fatalf("Requested a response with invalid length %d", size)
    64  	}
    65  	body := make([]byte, size)
    66  	switch t {
    67  	case testpb.PayloadType_COMPRESSABLE:
    68  	case testpb.PayloadType_UNCOMPRESSABLE:
    69  		grpclog.Fatalf("PayloadType UNCOMPRESSABLE is not supported")
    70  	default:
    71  		grpclog.Fatalf("Unsupported payload type: %d", t)
    72  	}
    73  	return &testpb.Payload{
    74  		Type: t.Enum(),
    75  		Body: body,
    76  	}
    77  }
    78  
    79  // DoEmptyUnaryCall performs a unary RPC with empty request and response messages.
    80  func DoEmptyUnaryCall(tc testpb.TestServiceClient) {
    81  	reply, err := tc.EmptyCall(context.Background(), &testpb.Empty{})
    82  	if err != nil {
    83  		grpclog.Fatal("/TestService/EmptyCall RPC failed: ", err)
    84  	}
    85  	if !proto.Equal(&testpb.Empty{}, reply) {
    86  		grpclog.Fatalf("/TestService/EmptyCall receives %v, want %v", reply, testpb.Empty{})
    87  	}
    88  	grpclog.Println("EmptyUnaryCall done")
    89  }
    90  
    91  // DoLargeUnaryCall performs a unary RPC with large payload in the request and response.
    92  func DoLargeUnaryCall(tc testpb.TestServiceClient) {
    93  	pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize)
    94  	req := &testpb.SimpleRequest{
    95  		ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(),
    96  		ResponseSize: proto.Int32(int32(largeRespSize)),
    97  		Payload:      pl,
    98  	}
    99  	reply, err := tc.UnaryCall(context.Background(), req)
   100  	if err != nil {
   101  		grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err)
   102  	}
   103  	t := reply.GetPayload().GetType()
   104  	s := len(reply.GetPayload().GetBody())
   105  	if t != testpb.PayloadType_COMPRESSABLE || s != largeRespSize {
   106  		grpclog.Fatalf("Got the reply with type %d len %d; want %d, %d", t, s, testpb.PayloadType_COMPRESSABLE, largeRespSize)
   107  	}
   108  	grpclog.Println("LargeUnaryCall done")
   109  }
   110  
   111  // DoClientStreaming performs a client streaming RPC.
   112  func DoClientStreaming(tc testpb.TestServiceClient) {
   113  	stream, err := tc.StreamingInputCall(context.Background())
   114  	if err != nil {
   115  		grpclog.Fatalf("%v.StreamingInputCall(_) = _, %v", tc, err)
   116  	}
   117  	var sum int
   118  	for _, s := range reqSizes {
   119  		pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, s)
   120  		req := &testpb.StreamingInputCallRequest{
   121  			Payload: pl,
   122  		}
   123  		if err := stream.Send(req); err != nil {
   124  			grpclog.Fatalf("%v.Send(%v) = %v", stream, req, err)
   125  		}
   126  		sum += s
   127  		grpclog.Printf("Sent a request of size %d, aggregated size %d", s, sum)
   128  
   129  	}
   130  	reply, err := stream.CloseAndRecv()
   131  	if err != nil {
   132  		grpclog.Fatalf("%v.CloseAndRecv() got error %v, want %v", stream, err, nil)
   133  	}
   134  	if reply.GetAggregatedPayloadSize() != int32(sum) {
   135  		grpclog.Fatalf("%v.CloseAndRecv().GetAggregatePayloadSize() = %v; want %v", stream, reply.GetAggregatedPayloadSize(), sum)
   136  	}
   137  	grpclog.Println("ClientStreaming done")
   138  }
   139  
   140  // DoServerStreaming performs a server streaming RPC.
   141  func DoServerStreaming(tc testpb.TestServiceClient) {
   142  	respParam := make([]*testpb.ResponseParameters, len(respSizes))
   143  	for i, s := range respSizes {
   144  		respParam[i] = &testpb.ResponseParameters{
   145  			Size: proto.Int32(int32(s)),
   146  		}
   147  	}
   148  	req := &testpb.StreamingOutputCallRequest{
   149  		ResponseType:       testpb.PayloadType_COMPRESSABLE.Enum(),
   150  		ResponseParameters: respParam,
   151  	}
   152  	stream, err := tc.StreamingOutputCall(context.Background(), req)
   153  	if err != nil {
   154  		grpclog.Fatalf("%v.StreamingOutputCall(_) = _, %v", tc, err)
   155  	}
   156  	var rpcStatus error
   157  	var respCnt int
   158  	var index int
   159  	for {
   160  		reply, err := stream.Recv()
   161  		if err != nil {
   162  			rpcStatus = err
   163  			break
   164  		}
   165  		t := reply.GetPayload().GetType()
   166  		if t != testpb.PayloadType_COMPRESSABLE {
   167  			grpclog.Fatalf("Got the reply of type %d, want %d", t, testpb.PayloadType_COMPRESSABLE)
   168  		}
   169  		size := len(reply.GetPayload().GetBody())
   170  		if size != int(respSizes[index]) {
   171  			grpclog.Fatalf("Got reply body of length %d, want %d", size, respSizes[index])
   172  		}
   173  		index++
   174  		respCnt++
   175  	}
   176  	if rpcStatus != io.EOF {
   177  		grpclog.Fatalf("Failed to finish the server streaming rpc: %v", err)
   178  	}
   179  	if respCnt != len(respSizes) {
   180  		grpclog.Fatalf("Got %d reply, want %d", len(respSizes), respCnt)
   181  	}
   182  	grpclog.Println("ServerStreaming done")
   183  }
   184  
   185  // DoPingPong performs ping-pong style bi-directional streaming RPC.
   186  func DoPingPong(tc testpb.TestServiceClient) {
   187  	stream, err := tc.FullDuplexCall(context.Background())
   188  	if err != nil {
   189  		grpclog.Fatalf("%v.FullDuplexCall(_) = _, %v", tc, err)
   190  	}
   191  	var index int
   192  	for index < len(reqSizes) {
   193  		respParam := []*testpb.ResponseParameters{
   194  			{
   195  				Size: proto.Int32(int32(respSizes[index])),
   196  			},
   197  		}
   198  		pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, reqSizes[index])
   199  		req := &testpb.StreamingOutputCallRequest{
   200  			ResponseType:       testpb.PayloadType_COMPRESSABLE.Enum(),
   201  			ResponseParameters: respParam,
   202  			Payload:            pl,
   203  		}
   204  		if err := stream.Send(req); err != nil {
   205  			grpclog.Fatalf("%v.Send(%v) = %v", stream, req, err)
   206  		}
   207  		reply, err := stream.Recv()
   208  		if err != nil {
   209  			grpclog.Fatalf("%v.Recv() = %v", stream, err)
   210  		}
   211  		t := reply.GetPayload().GetType()
   212  		if t != testpb.PayloadType_COMPRESSABLE {
   213  			grpclog.Fatalf("Got the reply of type %d, want %d", t, testpb.PayloadType_COMPRESSABLE)
   214  		}
   215  		size := len(reply.GetPayload().GetBody())
   216  		if size != int(respSizes[index]) {
   217  			grpclog.Fatalf("Got reply body of length %d, want %d", size, respSizes[index])
   218  		}
   219  		index++
   220  	}
   221  	if err := stream.CloseSend(); err != nil {
   222  		grpclog.Fatalf("%v.CloseSend() got %v, want %v", stream, err, nil)
   223  	}
   224  	if _, err := stream.Recv(); err != io.EOF {
   225  		grpclog.Fatalf("%v failed to complele the ping pong test: %v", stream, err)
   226  	}
   227  	grpclog.Println("Pingpong done")
   228  }
   229  
   230  // DoEmptyStream sets up a bi-directional streaming with zero message.
   231  func DoEmptyStream(tc testpb.TestServiceClient) {
   232  	stream, err := tc.FullDuplexCall(context.Background())
   233  	if err != nil {
   234  		grpclog.Fatalf("%v.FullDuplexCall(_) = _, %v", tc, err)
   235  	}
   236  	if err := stream.CloseSend(); err != nil {
   237  		grpclog.Fatalf("%v.CloseSend() got %v, want %v", stream, err, nil)
   238  	}
   239  	if _, err := stream.Recv(); err != io.EOF {
   240  		grpclog.Fatalf("%v failed to complete the empty stream test: %v", stream, err)
   241  	}
   242  	grpclog.Println("Emptystream done")
   243  }
   244  
   245  // DoTimeoutOnSleepingServer performs an RPC on a sleep server which causes RPC timeout.
   246  func DoTimeoutOnSleepingServer(tc testpb.TestServiceClient) {
   247  	ctx, _ := context.WithTimeout(context.Background(), 1*time.Millisecond)
   248  	stream, err := tc.FullDuplexCall(ctx)
   249  	if err != nil {
   250  		if grpc.Code(err) == codes.DeadlineExceeded {
   251  			grpclog.Println("TimeoutOnSleepingServer done")
   252  			return
   253  		}
   254  		grpclog.Fatalf("%v.FullDuplexCall(_) = _, %v", tc, err)
   255  	}
   256  	pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, 27182)
   257  	req := &testpb.StreamingOutputCallRequest{
   258  		ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(),
   259  		Payload:      pl,
   260  	}
   261  	if err := stream.Send(req); err != nil {
   262  		grpclog.Fatalf("%v.Send(%v) = %v", stream, req, err)
   263  	}
   264  	if _, err := stream.Recv(); grpc.Code(err) != codes.DeadlineExceeded {
   265  		grpclog.Fatalf("%v.Recv() = _, %v, want error code %d", stream, err, codes.DeadlineExceeded)
   266  	}
   267  	grpclog.Println("TimeoutOnSleepingServer done")
   268  }
   269  
   270  // DoComputeEngineCreds performs a unary RPC with compute engine auth.
   271  func DoComputeEngineCreds(tc testpb.TestServiceClient, serviceAccount, oauthScope string) {
   272  	pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize)
   273  	req := &testpb.SimpleRequest{
   274  		ResponseType:   testpb.PayloadType_COMPRESSABLE.Enum(),
   275  		ResponseSize:   proto.Int32(int32(largeRespSize)),
   276  		Payload:        pl,
   277  		FillUsername:   proto.Bool(true),
   278  		FillOauthScope: proto.Bool(true),
   279  	}
   280  	reply, err := tc.UnaryCall(context.Background(), req)
   281  	if err != nil {
   282  		grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err)
   283  	}
   284  	user := reply.GetUsername()
   285  	scope := reply.GetOauthScope()
   286  	if user != serviceAccount {
   287  		grpclog.Fatalf("Got user name %q, want %q.", user, serviceAccount)
   288  	}
   289  	if !strings.Contains(oauthScope, scope) {
   290  		grpclog.Fatalf("Got OAuth scope %q which is NOT a substring of %q.", scope, oauthScope)
   291  	}
   292  	grpclog.Println("ComputeEngineCreds done")
   293  }
   294  
   295  func getServiceAccountJSONKey(keyFile string) []byte {
   296  	jsonKey, err := ioutil.ReadFile(keyFile)
   297  	if err != nil {
   298  		grpclog.Fatalf("Failed to read the service account key file: %v", err)
   299  	}
   300  	return jsonKey
   301  }
   302  
   303  // DoServiceAccountCreds performs a unary RPC with service account auth.
   304  func DoServiceAccountCreds(tc testpb.TestServiceClient, serviceAccountKeyFile, oauthScope string) {
   305  	pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize)
   306  	req := &testpb.SimpleRequest{
   307  		ResponseType:   testpb.PayloadType_COMPRESSABLE.Enum(),
   308  		ResponseSize:   proto.Int32(int32(largeRespSize)),
   309  		Payload:        pl,
   310  		FillUsername:   proto.Bool(true),
   311  		FillOauthScope: proto.Bool(true),
   312  	}
   313  	reply, err := tc.UnaryCall(context.Background(), req)
   314  	if err != nil {
   315  		grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err)
   316  	}
   317  	jsonKey := getServiceAccountJSONKey(serviceAccountKeyFile)
   318  	user := reply.GetUsername()
   319  	scope := reply.GetOauthScope()
   320  	if !strings.Contains(string(jsonKey), user) {
   321  		grpclog.Fatalf("Got user name %q which is NOT a substring of %q.", user, jsonKey)
   322  	}
   323  	if !strings.Contains(oauthScope, scope) {
   324  		grpclog.Fatalf("Got OAuth scope %q which is NOT a substring of %q.", scope, oauthScope)
   325  	}
   326  	grpclog.Println("ServiceAccountCreds done")
   327  }
   328  
   329  // DoJWTTokenCreds performs a unary RPC with JWT token auth.
   330  func DoJWTTokenCreds(tc testpb.TestServiceClient, serviceAccountKeyFile string) {
   331  	pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize)
   332  	req := &testpb.SimpleRequest{
   333  		ResponseType: testpb.PayloadType_COMPRESSABLE.Enum(),
   334  		ResponseSize: proto.Int32(int32(largeRespSize)),
   335  		Payload:      pl,
   336  		FillUsername: proto.Bool(true),
   337  	}
   338  	reply, err := tc.UnaryCall(context.Background(), req)
   339  	if err != nil {
   340  		grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err)
   341  	}
   342  	jsonKey := getServiceAccountJSONKey(serviceAccountKeyFile)
   343  	user := reply.GetUsername()
   344  	if !strings.Contains(string(jsonKey), user) {
   345  		grpclog.Fatalf("Got user name %q which is NOT a substring of %q.", user, jsonKey)
   346  	}
   347  	grpclog.Println("JWTtokenCreds done")
   348  }
   349  
   350  // GetToken obtains an OAUTH token from the input.
   351  func GetToken(serviceAccountKeyFile string, oauthScope string) *oauth2.Token {
   352  	jsonKey := getServiceAccountJSONKey(serviceAccountKeyFile)
   353  	config, err := google.JWTConfigFromJSON(jsonKey, oauthScope)
   354  	if err != nil {
   355  		grpclog.Fatalf("Failed to get the config: %v", err)
   356  	}
   357  	token, err := config.TokenSource(context.Background()).Token()
   358  	if err != nil {
   359  		grpclog.Fatalf("Failed to get the token: %v", err)
   360  	}
   361  	return token
   362  }
   363  
   364  // DoOauth2TokenCreds performs a unary RPC with OAUTH2 token auth.
   365  func DoOauth2TokenCreds(tc testpb.TestServiceClient, serviceAccountKeyFile, oauthScope string) {
   366  	pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize)
   367  	req := &testpb.SimpleRequest{
   368  		ResponseType:   testpb.PayloadType_COMPRESSABLE.Enum(),
   369  		ResponseSize:   proto.Int32(int32(largeRespSize)),
   370  		Payload:        pl,
   371  		FillUsername:   proto.Bool(true),
   372  		FillOauthScope: proto.Bool(true),
   373  	}
   374  	reply, err := tc.UnaryCall(context.Background(), req)
   375  	if err != nil {
   376  		grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err)
   377  	}
   378  	jsonKey := getServiceAccountJSONKey(serviceAccountKeyFile)
   379  	user := reply.GetUsername()
   380  	scope := reply.GetOauthScope()
   381  	if !strings.Contains(string(jsonKey), user) {
   382  		grpclog.Fatalf("Got user name %q which is NOT a substring of %q.", user, jsonKey)
   383  	}
   384  	if !strings.Contains(oauthScope, scope) {
   385  		grpclog.Fatalf("Got OAuth scope %q which is NOT a substring of %q.", scope, oauthScope)
   386  	}
   387  	grpclog.Println("Oauth2TokenCreds done")
   388  }
   389  
   390  // DoPerRPCCreds performs a unary RPC with per RPC OAUTH2 token.
   391  func DoPerRPCCreds(tc testpb.TestServiceClient, serviceAccountKeyFile, oauthScope string) {
   392  	jsonKey := getServiceAccountJSONKey(serviceAccountKeyFile)
   393  	pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize)
   394  	req := &testpb.SimpleRequest{
   395  		ResponseType:   testpb.PayloadType_COMPRESSABLE.Enum(),
   396  		ResponseSize:   proto.Int32(int32(largeRespSize)),
   397  		Payload:        pl,
   398  		FillUsername:   proto.Bool(true),
   399  		FillOauthScope: proto.Bool(true),
   400  	}
   401  	token := GetToken(serviceAccountKeyFile, oauthScope)
   402  	kv := map[string]string{"authorization": token.TokenType + " " + token.AccessToken}
   403  	ctx := metadata.NewContext(context.Background(), metadata.MD{"authorization": []string{kv["authorization"]}})
   404  	reply, err := tc.UnaryCall(ctx, req)
   405  	if err != nil {
   406  		grpclog.Fatal("/TestService/UnaryCall RPC failed: ", err)
   407  	}
   408  	user := reply.GetUsername()
   409  	scope := reply.GetOauthScope()
   410  	if !strings.Contains(string(jsonKey), user) {
   411  		grpclog.Fatalf("Got user name %q which is NOT a substring of %q.", user, jsonKey)
   412  	}
   413  	if !strings.Contains(oauthScope, scope) {
   414  		grpclog.Fatalf("Got OAuth scope %q which is NOT a substring of %q.", scope, oauthScope)
   415  	}
   416  	grpclog.Println("PerRPCCreds done")
   417  }
   418  
   419  var (
   420  	testMetadata = metadata.MD{
   421  		"key1": []string{"value1"},
   422  		"key2": []string{"value2"},
   423  	}
   424  )
   425  
   426  // DoCancelAfterBegin cancels the RPC after metadata has been sent but before payloads are sent.
   427  func DoCancelAfterBegin(tc testpb.TestServiceClient) {
   428  	ctx, cancel := context.WithCancel(metadata.NewContext(context.Background(), testMetadata))
   429  	stream, err := tc.StreamingInputCall(ctx)
   430  	if err != nil {
   431  		grpclog.Fatalf("%v.StreamingInputCall(_) = _, %v", tc, err)
   432  	}
   433  	cancel()
   434  	_, err = stream.CloseAndRecv()
   435  	if grpc.Code(err) != codes.Canceled {
   436  		grpclog.Fatalf("%v.CloseAndRecv() got error code %d, want %d", stream, grpc.Code(err), codes.Canceled)
   437  	}
   438  	grpclog.Println("CancelAfterBegin done")
   439  }
   440  
   441  // DoCancelAfterFirstResponse cancels the RPC after receiving the first message from the server.
   442  func DoCancelAfterFirstResponse(tc testpb.TestServiceClient) {
   443  	ctx, cancel := context.WithCancel(context.Background())
   444  	stream, err := tc.FullDuplexCall(ctx)
   445  	if err != nil {
   446  		grpclog.Fatalf("%v.FullDuplexCall(_) = _, %v", tc, err)
   447  	}
   448  	respParam := []*testpb.ResponseParameters{
   449  		{
   450  			Size: proto.Int32(31415),
   451  		},
   452  	}
   453  	pl := clientNewPayload(testpb.PayloadType_COMPRESSABLE, 27182)
   454  	req := &testpb.StreamingOutputCallRequest{
   455  		ResponseType:       testpb.PayloadType_COMPRESSABLE.Enum(),
   456  		ResponseParameters: respParam,
   457  		Payload:            pl,
   458  	}
   459  	if err := stream.Send(req); err != nil {
   460  		grpclog.Fatalf("%v.Send(%v) = %v", stream, req, err)
   461  	}
   462  	if _, err := stream.Recv(); err != nil {
   463  		grpclog.Fatalf("%v.Recv() = %v", stream, err)
   464  	}
   465  	cancel()
   466  	if _, err := stream.Recv(); grpc.Code(err) != codes.Canceled {
   467  		grpclog.Fatalf("%v compleled with error code %d, want %d", stream, grpc.Code(err), codes.Canceled)
   468  	}
   469  	grpclog.Println("CancelAfterFirstResponse done")
   470  }
   471  
   472  type testServer struct {
   473  }
   474  
   475  // NewTestServer creates a test server for test service.
   476  func NewTestServer() testpb.TestServiceServer {
   477  	return &testServer{}
   478  }
   479  
   480  func (s *testServer) EmptyCall(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) {
   481  	return new(testpb.Empty), nil
   482  }
   483  
   484  func serverNewPayload(t testpb.PayloadType, size int32) (*testpb.Payload, error) {
   485  	if size < 0 {
   486  		return nil, fmt.Errorf("requested a response with invalid length %d", size)
   487  	}
   488  	body := make([]byte, size)
   489  	switch t {
   490  	case testpb.PayloadType_COMPRESSABLE:
   491  	case testpb.PayloadType_UNCOMPRESSABLE:
   492  		return nil, fmt.Errorf("payloadType UNCOMPRESSABLE is not supported")
   493  	default:
   494  		return nil, fmt.Errorf("unsupported payload type: %d", t)
   495  	}
   496  	return &testpb.Payload{
   497  		Type: t.Enum(),
   498  		Body: body,
   499  	}, nil
   500  }
   501  
   502  func (s *testServer) UnaryCall(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) {
   503  	pl, err := serverNewPayload(in.GetResponseType(), in.GetResponseSize())
   504  	if err != nil {
   505  		return nil, err
   506  	}
   507  	return &testpb.SimpleResponse{
   508  		Payload: pl,
   509  	}, nil
   510  }
   511  
   512  func (s *testServer) StreamingOutputCall(args *testpb.StreamingOutputCallRequest, stream testpb.TestService_StreamingOutputCallServer) error {
   513  	cs := args.GetResponseParameters()
   514  	for _, c := range cs {
   515  		if us := c.GetIntervalUs(); us > 0 {
   516  			time.Sleep(time.Duration(us) * time.Microsecond)
   517  		}
   518  		pl, err := serverNewPayload(args.GetResponseType(), c.GetSize())
   519  		if err != nil {
   520  			return err
   521  		}
   522  		if err := stream.Send(&testpb.StreamingOutputCallResponse{
   523  			Payload: pl,
   524  		}); err != nil {
   525  			return err
   526  		}
   527  	}
   528  	return nil
   529  }
   530  
   531  func (s *testServer) StreamingInputCall(stream testpb.TestService_StreamingInputCallServer) error {
   532  	var sum int
   533  	for {
   534  		in, err := stream.Recv()
   535  		if err == io.EOF {
   536  			return stream.SendAndClose(&testpb.StreamingInputCallResponse{
   537  				AggregatedPayloadSize: proto.Int32(int32(sum)),
   538  			})
   539  		}
   540  		if err != nil {
   541  			return err
   542  		}
   543  		p := in.GetPayload().GetBody()
   544  		sum += len(p)
   545  	}
   546  }
   547  
   548  func (s *testServer) FullDuplexCall(stream testpb.TestService_FullDuplexCallServer) error {
   549  	for {
   550  		in, err := stream.Recv()
   551  		if err == io.EOF {
   552  			// read done.
   553  			return nil
   554  		}
   555  		if err != nil {
   556  			return err
   557  		}
   558  		cs := in.GetResponseParameters()
   559  		for _, c := range cs {
   560  			if us := c.GetIntervalUs(); us > 0 {
   561  				time.Sleep(time.Duration(us) * time.Microsecond)
   562  			}
   563  			pl, err := serverNewPayload(in.GetResponseType(), c.GetSize())
   564  			if err != nil {
   565  				return err
   566  			}
   567  			if err := stream.Send(&testpb.StreamingOutputCallResponse{
   568  				Payload: pl,
   569  			}); err != nil {
   570  				return err
   571  			}
   572  		}
   573  	}
   574  }
   575  
   576  func (s *testServer) HalfDuplexCall(stream testpb.TestService_HalfDuplexCallServer) error {
   577  	var msgBuf []*testpb.StreamingOutputCallRequest
   578  	for {
   579  		in, err := stream.Recv()
   580  		if err == io.EOF {
   581  			// read done.
   582  			break
   583  		}
   584  		if err != nil {
   585  			return err
   586  		}
   587  		msgBuf = append(msgBuf, in)
   588  	}
   589  	for _, m := range msgBuf {
   590  		cs := m.GetResponseParameters()
   591  		for _, c := range cs {
   592  			if us := c.GetIntervalUs(); us > 0 {
   593  				time.Sleep(time.Duration(us) * time.Microsecond)
   594  			}
   595  			pl, err := serverNewPayload(m.GetResponseType(), c.GetSize())
   596  			if err != nil {
   597  				return err
   598  			}
   599  			if err := stream.Send(&testpb.StreamingOutputCallResponse{
   600  				Payload: pl,
   601  			}); err != nil {
   602  				return err
   603  			}
   604  		}
   605  	}
   606  	return nil
   607  }