...

Source file src/google.golang.org/grpc/interop/http2/negative_http2_client.go

Documentation: google.golang.org/grpc/interop/http2

     1  /*
     2   *
     3   * Copyright 2016 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  // Binary http2 is used to test http2 error edge cases like GOAWAYs and
    20  // RST_STREAMs
    21  //
    22  // Documentation:
    23  // https://github.com/grpc/grpc/blob/master/doc/negative-http2-interop-test-descriptions.md
    24  package main
    25  
    26  import (
    27  	"context"
    28  	"flag"
    29  	"net"
    30  	"strconv"
    31  	"sync"
    32  	"time"
    33  
    34  	"google.golang.org/grpc"
    35  	"google.golang.org/grpc/codes"
    36  	"google.golang.org/grpc/credentials/insecure"
    37  	"google.golang.org/grpc/grpclog"
    38  	"google.golang.org/grpc/interop"
    39  	"google.golang.org/grpc/status"
    40  
    41  	testgrpc "google.golang.org/grpc/interop/grpc_testing"
    42  	testpb "google.golang.org/grpc/interop/grpc_testing"
    43  )
    44  
    45  var (
    46  	serverHost = flag.String("server_host", "localhost", "The server host name")
    47  	serverPort = flag.Int("server_port", 8080, "The server port number")
    48  	testCase   = flag.String("test_case", "goaway",
    49  		`Configure different test cases. Valid options are:
    50          goaway : client sends two requests, the server will send a goaway in between;
    51          rst_after_header : server will send rst_stream after it sends headers;
    52          rst_during_data : server will send rst_stream while sending data;
    53          rst_after_data : server will send rst_stream after sending data;
    54          ping : server will send pings between each http2 frame;
    55          max_streams : server will ensure that the max_concurrent_streams limit is upheld;`)
    56  	largeReqSize  = 271828
    57  	largeRespSize = 314159
    58  
    59  	logger = grpclog.Component("interop")
    60  )
    61  
    62  func largeSimpleRequest() *testpb.SimpleRequest {
    63  	pl := interop.ClientNewPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize)
    64  	return &testpb.SimpleRequest{
    65  		ResponseType: testpb.PayloadType_COMPRESSABLE,
    66  		ResponseSize: int32(largeRespSize),
    67  		Payload:      pl,
    68  	}
    69  }
    70  
    71  // sends two unary calls. The server asserts that the calls use different connections.
    72  func goaway(ctx context.Context, tc testgrpc.TestServiceClient) {
    73  	interop.DoLargeUnaryCall(ctx, tc)
    74  	// sleep to ensure that the client has time to recv the GOAWAY.
    75  	// TODO(ncteisen): make this less hacky.
    76  	time.Sleep(1 * time.Second)
    77  	interop.DoLargeUnaryCall(ctx, tc)
    78  }
    79  
    80  func rstAfterHeader(tc testgrpc.TestServiceClient) {
    81  	req := largeSimpleRequest()
    82  	reply, err := tc.UnaryCall(context.Background(), req)
    83  	if reply != nil {
    84  		logger.Fatal("Client received reply despite server sending rst stream after header")
    85  	}
    86  	if status.Code(err) != codes.Internal {
    87  		logger.Fatalf("%v.UnaryCall() = _, %v, want _, %v", tc, status.Code(err), codes.Internal)
    88  	}
    89  }
    90  
    91  func rstDuringData(tc testgrpc.TestServiceClient) {
    92  	req := largeSimpleRequest()
    93  	reply, err := tc.UnaryCall(context.Background(), req)
    94  	if reply != nil {
    95  		logger.Fatal("Client received reply despite server sending rst stream during data")
    96  	}
    97  	if status.Code(err) != codes.Unknown {
    98  		logger.Fatalf("%v.UnaryCall() = _, %v, want _, %v", tc, status.Code(err), codes.Unknown)
    99  	}
   100  }
   101  
   102  func rstAfterData(tc testgrpc.TestServiceClient) {
   103  	req := largeSimpleRequest()
   104  	reply, err := tc.UnaryCall(context.Background(), req)
   105  	if reply != nil {
   106  		logger.Fatal("Client received reply despite server sending rst stream after data")
   107  	}
   108  	if status.Code(err) != codes.Internal {
   109  		logger.Fatalf("%v.UnaryCall() = _, %v, want _, %v", tc, status.Code(err), codes.Internal)
   110  	}
   111  }
   112  
   113  func ping(ctx context.Context, tc testgrpc.TestServiceClient) {
   114  	// The server will assert that every ping it sends was ACK-ed by the client.
   115  	interop.DoLargeUnaryCall(ctx, tc)
   116  }
   117  
   118  func maxStreams(ctx context.Context, tc testgrpc.TestServiceClient) {
   119  	interop.DoLargeUnaryCall(ctx, tc)
   120  	var wg sync.WaitGroup
   121  	for i := 0; i < 15; i++ {
   122  		wg.Add(1)
   123  		go func() {
   124  			defer wg.Done()
   125  			interop.DoLargeUnaryCall(ctx, tc)
   126  		}()
   127  	}
   128  	wg.Wait()
   129  }
   130  
   131  func main() {
   132  	flag.Parse()
   133  	serverAddr := net.JoinHostPort(*serverHost, strconv.Itoa(*serverPort))
   134  	var opts []grpc.DialOption
   135  	opts = append(opts, grpc.WithTransportCredentials(insecure.NewCredentials()))
   136  	conn, err := grpc.Dial(serverAddr, opts...)
   137  	if err != nil {
   138  		logger.Fatalf("Fail to dial: %v", err)
   139  	}
   140  	defer conn.Close()
   141  	tc := testgrpc.NewTestServiceClient(conn)
   142  	ctx := context.Background()
   143  	switch *testCase {
   144  	case "goaway":
   145  		goaway(ctx, tc)
   146  		logger.Infoln("goaway done")
   147  	case "rst_after_header":
   148  		rstAfterHeader(tc)
   149  		logger.Infoln("rst_after_header done")
   150  	case "rst_during_data":
   151  		rstDuringData(tc)
   152  		logger.Infoln("rst_during_data done")
   153  	case "rst_after_data":
   154  		rstAfterData(tc)
   155  		logger.Infoln("rst_after_data done")
   156  	case "ping":
   157  		ping(ctx, tc)
   158  		logger.Infoln("ping done")
   159  	case "max_streams":
   160  		maxStreams(ctx, tc)
   161  		logger.Infoln("max_streams done")
   162  	default:
   163  		logger.Fatal("Unsupported test case: ", *testCase)
   164  	}
   165  }
   166  

View as plain text