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 }