1/* 2 * 3 * Copyright 2014 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 client is an interop client. 20package main 21 22import ( 23 "flag" 24 "net" 25 "strconv" 26 27 "google.golang.org/grpc" 28 _ "google.golang.org/grpc/balancer/grpclb" 29 "google.golang.org/grpc/credentials" 30 "google.golang.org/grpc/credentials/alts" 31 "google.golang.org/grpc/credentials/google" 32 "google.golang.org/grpc/credentials/oauth" 33 "google.golang.org/grpc/grpclog" 34 "google.golang.org/grpc/interop" 35 testpb "google.golang.org/grpc/interop/grpc_testing" 36 "google.golang.org/grpc/resolver" 37 "google.golang.org/grpc/testdata" 38) 39 40const ( 41 googleDefaultCredsName = "google_default_credentials" 42 computeEngineCredsName = "compute_engine_channel_creds" 43) 44 45var ( 46 caFile = flag.String("ca_file", "", "The file containning the CA root cert file") 47 useTLS = flag.Bool("use_tls", false, "Connection uses TLS if true") 48 useALTS = flag.Bool("use_alts", false, "Connection uses ALTS if true (this option can only be used on GCP)") 49 customCredentialsType = flag.String("custom_credentials_type", "", "Custom creds to use, excluding TLS or ALTS") 50 altsHSAddr = flag.String("alts_handshaker_service_address", "", "ALTS handshaker gRPC service address") 51 testCA = flag.Bool("use_test_ca", false, "Whether to replace platform root CAs with test CA as the CA root") 52 serviceAccountKeyFile = flag.String("service_account_key_file", "", "Path to service account json key file") 53 oauthScope = flag.String("oauth_scope", "", "The scope for OAuth2 tokens") 54 defaultServiceAccount = flag.String("default_service_account", "", "Email of GCE default service account") 55 serverHost = flag.String("server_host", "localhost", "The server host name") 56 serverPort = flag.Int("server_port", 10000, "The server port number") 57 tlsServerName = flag.String("server_host_override", "", "The server name use to verify the hostname returned by TLS handshake if it is not empty. Otherwise, --server_host is used.") 58 testCase = flag.String("test_case", "large_unary", 59 `Configure different test cases. Valid options are: 60 empty_unary : empty (zero bytes) request and response; 61 large_unary : single request and (large) response; 62 client_streaming : request streaming with single response; 63 server_streaming : single request with response streaming; 64 ping_pong : full-duplex streaming; 65 empty_stream : full-duplex streaming with zero message; 66 timeout_on_sleeping_server: fullduplex streaming on a sleeping server; 67 compute_engine_creds: large_unary with compute engine auth; 68 service_account_creds: large_unary with service account auth; 69 jwt_token_creds: large_unary with jwt token auth; 70 per_rpc_creds: large_unary with per rpc token; 71 oauth2_auth_token: large_unary with oauth2 token auth; 72 google_default_credentials: large_unary with google default credentials 73 compute_engine_channel_credentials: large_unary with compute engine creds 74 cancel_after_begin: cancellation after metadata has been sent but before payloads are sent; 75 cancel_after_first_response: cancellation after receiving 1st message from the server; 76 status_code_and_message: status code propagated back to client; 77 special_status_message: Unicode and whitespace is correctly processed in status message; 78 custom_metadata: server will echo custom metadata; 79 unimplemented_method: client attempts to call unimplemented method; 80 unimplemented_service: client attempts to call unimplemented service; 81 pick_first_unary: all requests are sent to one server despite multiple servers are resolved.`) 82) 83 84type credsMode uint8 85 86const ( 87 credsNone credsMode = iota 88 credsTLS 89 credsALTS 90 credsGoogleDefaultCreds 91 credsComputeEngineCreds 92) 93 94func main() { 95 flag.Parse() 96 var useGDC bool // use google default creds 97 var useCEC bool // use compute engine creds 98 if *customCredentialsType != "" { 99 switch *customCredentialsType { 100 case googleDefaultCredsName: 101 useGDC = true 102 case computeEngineCredsName: 103 useCEC = true 104 default: 105 grpclog.Fatalf("If set, custom_credentials_type can only be set to one of %v or %v", 106 googleDefaultCredsName, computeEngineCredsName) 107 } 108 } 109 if (*useTLS && *useALTS) || (*useTLS && useGDC) || (*useALTS && useGDC) || (*useTLS && useCEC) || (*useALTS && useCEC) { 110 grpclog.Fatalf("only one of TLS, ALTS, google default creds, or compute engine creds can be used") 111 } 112 113 var credsChosen credsMode 114 switch { 115 case *useTLS: 116 credsChosen = credsTLS 117 case *useALTS: 118 credsChosen = credsALTS 119 case useGDC: 120 credsChosen = credsGoogleDefaultCreds 121 case useCEC: 122 credsChosen = credsComputeEngineCreds 123 } 124 125 resolver.SetDefaultScheme("dns") 126 serverAddr := net.JoinHostPort(*serverHost, strconv.Itoa(*serverPort)) 127 var opts []grpc.DialOption 128 switch credsChosen { 129 case credsTLS: 130 var sn string 131 if *tlsServerName != "" { 132 sn = *tlsServerName 133 } 134 var creds credentials.TransportCredentials 135 if *testCA { 136 var err error 137 if *caFile == "" { 138 *caFile = testdata.Path("ca.pem") 139 } 140 creds, err = credentials.NewClientTLSFromFile(*caFile, sn) 141 if err != nil { 142 grpclog.Fatalf("Failed to create TLS credentials %v", err) 143 } 144 } else { 145 creds = credentials.NewClientTLSFromCert(nil, sn) 146 } 147 opts = append(opts, grpc.WithTransportCredentials(creds)) 148 case credsALTS: 149 altsOpts := alts.DefaultClientOptions() 150 if *altsHSAddr != "" { 151 altsOpts.HandshakerServiceAddress = *altsHSAddr 152 } 153 altsTC := alts.NewClientCreds(altsOpts) 154 opts = append(opts, grpc.WithTransportCredentials(altsTC)) 155 case credsGoogleDefaultCreds: 156 opts = append(opts, grpc.WithCredentialsBundle(google.NewDefaultCredentials())) 157 case credsComputeEngineCreds: 158 opts = append(opts, grpc.WithCredentialsBundle(google.NewComputeEngineCredentials())) 159 case credsNone: 160 opts = append(opts, grpc.WithInsecure()) 161 default: 162 grpclog.Fatal("Invalid creds") 163 } 164 if credsChosen == credsTLS { 165 if *testCase == "compute_engine_creds" { 166 opts = append(opts, grpc.WithPerRPCCredentials(oauth.NewComputeEngine())) 167 } else if *testCase == "service_account_creds" { 168 jwtCreds, err := oauth.NewServiceAccountFromFile(*serviceAccountKeyFile, *oauthScope) 169 if err != nil { 170 grpclog.Fatalf("Failed to create JWT credentials: %v", err) 171 } 172 opts = append(opts, grpc.WithPerRPCCredentials(jwtCreds)) 173 } else if *testCase == "jwt_token_creds" { 174 jwtCreds, err := oauth.NewJWTAccessFromFile(*serviceAccountKeyFile) 175 if err != nil { 176 grpclog.Fatalf("Failed to create JWT credentials: %v", err) 177 } 178 opts = append(opts, grpc.WithPerRPCCredentials(jwtCreds)) 179 } else if *testCase == "oauth2_auth_token" { 180 opts = append(opts, grpc.WithPerRPCCredentials(oauth.NewOauthAccess(interop.GetToken(*serviceAccountKeyFile, *oauthScope)))) 181 } 182 } 183 opts = append(opts, grpc.WithBlock()) 184 conn, err := grpc.Dial(serverAddr, opts...) 185 if err != nil { 186 grpclog.Fatalf("Fail to dial: %v", err) 187 } 188 defer conn.Close() 189 tc := testpb.NewTestServiceClient(conn) 190 switch *testCase { 191 case "empty_unary": 192 interop.DoEmptyUnaryCall(tc) 193 grpclog.Infoln("EmptyUnaryCall done") 194 case "large_unary": 195 interop.DoLargeUnaryCall(tc) 196 grpclog.Infoln("LargeUnaryCall done") 197 case "client_streaming": 198 interop.DoClientStreaming(tc) 199 grpclog.Infoln("ClientStreaming done") 200 case "server_streaming": 201 interop.DoServerStreaming(tc) 202 grpclog.Infoln("ServerStreaming done") 203 case "ping_pong": 204 interop.DoPingPong(tc) 205 grpclog.Infoln("Pingpong done") 206 case "empty_stream": 207 interop.DoEmptyStream(tc) 208 grpclog.Infoln("Emptystream done") 209 case "timeout_on_sleeping_server": 210 interop.DoTimeoutOnSleepingServer(tc) 211 grpclog.Infoln("TimeoutOnSleepingServer done") 212 case "compute_engine_creds": 213 if credsChosen != credsTLS { 214 grpclog.Fatalf("TLS credentials need to be set for compute_engine_creds test case.") 215 } 216 interop.DoComputeEngineCreds(tc, *defaultServiceAccount, *oauthScope) 217 grpclog.Infoln("ComputeEngineCreds done") 218 case "service_account_creds": 219 if credsChosen != credsTLS { 220 grpclog.Fatalf("TLS credentials need to be set for service_account_creds test case.") 221 } 222 interop.DoServiceAccountCreds(tc, *serviceAccountKeyFile, *oauthScope) 223 grpclog.Infoln("ServiceAccountCreds done") 224 case "jwt_token_creds": 225 if credsChosen != credsTLS { 226 grpclog.Fatalf("TLS credentials need to be set for jwt_token_creds test case.") 227 } 228 interop.DoJWTTokenCreds(tc, *serviceAccountKeyFile) 229 grpclog.Infoln("JWTtokenCreds done") 230 case "per_rpc_creds": 231 if credsChosen != credsTLS { 232 grpclog.Fatalf("TLS credentials need to be set for per_rpc_creds test case.") 233 } 234 interop.DoPerRPCCreds(tc, *serviceAccountKeyFile, *oauthScope) 235 grpclog.Infoln("PerRPCCreds done") 236 case "oauth2_auth_token": 237 if credsChosen != credsTLS { 238 grpclog.Fatalf("TLS credentials need to be set for oauth2_auth_token test case.") 239 } 240 interop.DoOauth2TokenCreds(tc, *serviceAccountKeyFile, *oauthScope) 241 grpclog.Infoln("Oauth2TokenCreds done") 242 case "google_default_credentials": 243 if credsChosen != credsGoogleDefaultCreds { 244 grpclog.Fatalf("GoogleDefaultCredentials need to be set for google_default_credentials test case.") 245 } 246 interop.DoGoogleDefaultCredentials(tc, *defaultServiceAccount) 247 grpclog.Infoln("GoogleDefaultCredentials done") 248 case "compute_engine_channel_credentials": 249 if credsChosen != credsComputeEngineCreds { 250 grpclog.Fatalf("ComputeEngineCreds need to be set for compute_engine_channel_credentials test case.") 251 } 252 interop.DoComputeEngineChannelCredentials(tc, *defaultServiceAccount) 253 grpclog.Infoln("ComputeEngineChannelCredentials done") 254 case "cancel_after_begin": 255 interop.DoCancelAfterBegin(tc) 256 grpclog.Infoln("CancelAfterBegin done") 257 case "cancel_after_first_response": 258 interop.DoCancelAfterFirstResponse(tc) 259 grpclog.Infoln("CancelAfterFirstResponse done") 260 case "status_code_and_message": 261 interop.DoStatusCodeAndMessage(tc) 262 grpclog.Infoln("StatusCodeAndMessage done") 263 case "special_status_message": 264 interop.DoSpecialStatusMessage(tc) 265 grpclog.Infoln("SpecialStatusMessage done") 266 case "custom_metadata": 267 interop.DoCustomMetadata(tc) 268 grpclog.Infoln("CustomMetadata done") 269 case "unimplemented_method": 270 interop.DoUnimplementedMethod(conn) 271 grpclog.Infoln("UnimplementedMethod done") 272 case "unimplemented_service": 273 interop.DoUnimplementedService(testpb.NewUnimplementedServiceClient(conn)) 274 grpclog.Infoln("UnimplementedService done") 275 case "pick_first_unary": 276 interop.DoPickFirstUnary(tc) 277 grpclog.Infoln("PickFirstUnary done") 278 default: 279 grpclog.Fatal("Unsupported test case: ", *testCase) 280 } 281} 282