github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/interop/http2/negative_http2_client.go (about)

     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  	grpc "github.com/hxx258456/ccgo/grpc"
    35  	"github.com/hxx258456/ccgo/grpc/codes"
    36  	"github.com/hxx258456/ccgo/grpc/grpclog"
    37  	"github.com/hxx258456/ccgo/grpc/interop"
    38  	"github.com/hxx258456/ccgo/grpc/status"
    39  
    40  	testgrpc "github.com/hxx258456/ccgo/grpc/interop/grpc_testing"
    41  	testpb "github.com/hxx258456/ccgo/grpc/interop/grpc_testing"
    42  )
    43  
    44  var (
    45  	serverHost = flag.String("server_host", "localhost", "The server host name")
    46  	serverPort = flag.Int("server_port", 8080, "The server port number")
    47  	testCase   = flag.String("test_case", "goaway",
    48  		`Configure different test cases. Valid options are:
    49          goaway : client sends two requests, the server will send a goaway in between;
    50          rst_after_header : server will send rst_stream after it sends headers;
    51          rst_during_data : server will send rst_stream while sending data;
    52          rst_after_data : server will send rst_stream after sending data;
    53          ping : server will send pings between each http2 frame;
    54          max_streams : server will ensure that the max_concurrent_streams limit is upheld;`)
    55  	largeReqSize  = 271828
    56  	largeRespSize = 314159
    57  
    58  	logger = grpclog.Component("interop")
    59  )
    60  
    61  func largeSimpleRequest() *testpb.SimpleRequest {
    62  	pl := interop.ClientNewPayload(testpb.PayloadType_COMPRESSABLE, largeReqSize)
    63  	return &testpb.SimpleRequest{
    64  		ResponseType: testpb.PayloadType_COMPRESSABLE,
    65  		ResponseSize: int32(largeRespSize),
    66  		Payload:      pl,
    67  	}
    68  }
    69  
    70  // sends two unary calls. The server asserts that the calls use different connections.
    71  func goaway(tc testgrpc.TestServiceClient) {
    72  	interop.DoLargeUnaryCall(tc)
    73  	// sleep to ensure that the client has time to recv the GOAWAY.
    74  	// TODO(ncteisen): make this less hacky.
    75  	time.Sleep(1 * time.Second)
    76  	interop.DoLargeUnaryCall(tc)
    77  }
    78  
    79  func rstAfterHeader(tc testgrpc.TestServiceClient) {
    80  	req := largeSimpleRequest()
    81  	reply, err := tc.UnaryCall(context.Background(), req)
    82  	if reply != nil {
    83  		logger.Fatalf("Client received reply despite server sending rst stream after header")
    84  	}
    85  	if status.Code(err) != codes.Internal {
    86  		logger.Fatalf("%v.UnaryCall() = _, %v, want _, %v", tc, status.Code(err), codes.Internal)
    87  	}
    88  }
    89  
    90  func rstDuringData(tc testgrpc.TestServiceClient) {
    91  	req := largeSimpleRequest()
    92  	reply, err := tc.UnaryCall(context.Background(), req)
    93  	if reply != nil {
    94  		logger.Fatalf("Client received reply despite server sending rst stream during data")
    95  	}
    96  	if status.Code(err) != codes.Unknown {
    97  		logger.Fatalf("%v.UnaryCall() = _, %v, want _, %v", tc, status.Code(err), codes.Unknown)
    98  	}
    99  }
   100  
   101  func rstAfterData(tc testgrpc.TestServiceClient) {
   102  	req := largeSimpleRequest()
   103  	reply, err := tc.UnaryCall(context.Background(), req)
   104  	if reply != nil {
   105  		logger.Fatalf("Client received reply despite server sending rst stream after data")
   106  	}
   107  	if status.Code(err) != codes.Internal {
   108  		logger.Fatalf("%v.UnaryCall() = _, %v, want _, %v", tc, status.Code(err), codes.Internal)
   109  	}
   110  }
   111  
   112  func ping(tc testgrpc.TestServiceClient) {
   113  	// The server will assert that every ping it sends was ACK-ed by the client.
   114  	interop.DoLargeUnaryCall(tc)
   115  }
   116  
   117  func maxStreams(tc testgrpc.TestServiceClient) {
   118  	interop.DoLargeUnaryCall(tc)
   119  	var wg sync.WaitGroup
   120  	for i := 0; i < 15; i++ {
   121  		wg.Add(1)
   122  		go func() {
   123  			defer wg.Done()
   124  			interop.DoLargeUnaryCall(tc)
   125  		}()
   126  	}
   127  	wg.Wait()
   128  }
   129  
   130  func main() {
   131  	flag.Parse()
   132  	serverAddr := net.JoinHostPort(*serverHost, strconv.Itoa(*serverPort))
   133  	var opts []grpc.DialOption
   134  	opts = append(opts, grpc.WithInsecure())
   135  	conn, err := grpc.Dial(serverAddr, opts...)
   136  	if err != nil {
   137  		logger.Fatalf("Fail to dial: %v", err)
   138  	}
   139  	defer conn.Close()
   140  	tc := testgrpc.NewTestServiceClient(conn)
   141  	switch *testCase {
   142  	case "goaway":
   143  		goaway(tc)
   144  		logger.Infoln("goaway done")
   145  	case "rst_after_header":
   146  		rstAfterHeader(tc)
   147  		logger.Infoln("rst_after_header done")
   148  	case "rst_during_data":
   149  		rstDuringData(tc)
   150  		logger.Infoln("rst_during_data done")
   151  	case "rst_after_data":
   152  		rstAfterData(tc)
   153  		logger.Infoln("rst_after_data done")
   154  	case "ping":
   155  		ping(tc)
   156  		logger.Infoln("ping done")
   157  	case "max_streams":
   158  		maxStreams(tc)
   159  		logger.Infoln("max_streams done")
   160  	default:
   161  		logger.Fatal("Unsupported test case: ", *testCase)
   162  	}
   163  }