1 /* 2 * Copyright 2014 The gRPC Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package io.grpc.testing.integration; 18 19 import com.google.common.annotations.VisibleForTesting; 20 import com.google.common.io.Files; 21 import io.grpc.ChannelCredentials; 22 import io.grpc.ClientInterceptor; 23 import io.grpc.Grpc; 24 import io.grpc.InsecureChannelCredentials; 25 import io.grpc.InsecureServerCredentials; 26 import io.grpc.LoadBalancerProvider; 27 import io.grpc.LoadBalancerRegistry; 28 import io.grpc.ManagedChannel; 29 import io.grpc.ManagedChannelBuilder; 30 import io.grpc.Metadata; 31 import io.grpc.ServerBuilder; 32 import io.grpc.TlsChannelCredentials; 33 import io.grpc.alts.AltsChannelCredentials; 34 import io.grpc.alts.ComputeEngineChannelCredentials; 35 import io.grpc.alts.GoogleDefaultChannelCredentials; 36 import io.grpc.internal.GrpcUtil; 37 import io.grpc.internal.JsonParser; 38 import io.grpc.netty.InsecureFromHttp1ChannelCredentials; 39 import io.grpc.netty.InternalNettyChannelBuilder; 40 import io.grpc.netty.NettyChannelBuilder; 41 import io.grpc.okhttp.InternalOkHttpChannelBuilder; 42 import io.grpc.okhttp.OkHttpChannelBuilder; 43 import io.grpc.stub.MetadataUtils; 44 import io.grpc.testing.TlsTesting; 45 import java.io.File; 46 import java.io.FileInputStream; 47 import java.nio.charset.Charset; 48 import java.util.Map; 49 import java.util.concurrent.TimeUnit; 50 import javax.annotation.Nullable; 51 52 /** 53 * Application that starts a client for the {@link TestServiceGrpc.TestServiceImplBase} and runs 54 * through a series of tests. 55 */ 56 public class TestServiceClient { 57 58 private static final Charset UTF_8 = Charset.forName("UTF-8"); 59 60 /** 61 * The main application allowing this client to be launched from the command line. 62 */ main(String[] args)63 public static void main(String[] args) throws Exception { 64 final TestServiceClient client = new TestServiceClient(); 65 client.parseArgs(args); 66 customBackendMetricsLoadBalancerProvider = new CustomBackendMetricsLoadBalancerProvider(); 67 LoadBalancerRegistry.getDefaultRegistry().register(customBackendMetricsLoadBalancerProvider); 68 client.setUp(); 69 70 try { 71 client.run(); 72 } finally { 73 client.tearDown(); 74 } 75 } 76 77 private String serverHost = "localhost"; 78 private String serverHostOverride; 79 private int serverPort = 8080; 80 private String testCase = "empty_unary"; 81 private int numTimes = 1; 82 private boolean useTls = true; 83 private boolean useAlts = false; 84 private boolean useH2cUpgrade = false; 85 private String customCredentialsType; 86 private boolean useTestCa; 87 private boolean useOkHttp; 88 private String defaultServiceAccount; 89 private String serviceAccountKeyFile; 90 private String oauthScope; 91 private boolean fullStreamDecompression; 92 private int localHandshakerPort = -1; 93 private Map<String, ?> serviceConfig = null; 94 private int soakIterations = 10; 95 private int soakMaxFailures = 0; 96 private int soakPerIterationMaxAcceptableLatencyMs = 1000; 97 private int soakMinTimeMsBetweenRpcs = 0; 98 private int soakOverallTimeoutSeconds = 99 soakIterations * soakPerIterationMaxAcceptableLatencyMs / 1000; 100 private String additionalMetadata = ""; 101 private static LoadBalancerProvider customBackendMetricsLoadBalancerProvider; 102 103 private Tester tester = new Tester(); 104 105 @VisibleForTesting parseArgs(String[] args)106 void parseArgs(String[] args) throws Exception { 107 boolean usage = false; 108 for (String arg : args) { 109 if (!arg.startsWith("--")) { 110 System.err.println("All arguments must start with '--': " + arg); 111 usage = true; 112 break; 113 } 114 String[] parts = arg.substring(2).split("=", 2); 115 String key = parts[0]; 116 if ("help".equals(key)) { 117 usage = true; 118 break; 119 } 120 if (parts.length != 2) { 121 System.err.println("All arguments must be of the form --arg=value"); 122 usage = true; 123 break; 124 } 125 String value = parts[1]; 126 if ("server_host".equals(key)) { 127 serverHost = value; 128 } else if ("server_host_override".equals(key)) { 129 serverHostOverride = value; 130 } else if ("server_port".equals(key)) { 131 serverPort = Integer.parseInt(value); 132 } else if ("test_case".equals(key)) { 133 testCase = value; 134 } else if ("num_times".equals(key)) { 135 numTimes = Integer.parseInt(value); 136 } else if ("use_tls".equals(key)) { 137 useTls = Boolean.parseBoolean(value); 138 } else if ("use_upgrade".equals(key)) { 139 useH2cUpgrade = Boolean.parseBoolean(value); 140 } else if ("use_alts".equals(key)) { 141 useAlts = Boolean.parseBoolean(value); 142 } else if ("custom_credentials_type".equals(key)) { 143 customCredentialsType = value; 144 } else if ("use_test_ca".equals(key)) { 145 useTestCa = Boolean.parseBoolean(value); 146 } else if ("use_okhttp".equals(key)) { 147 useOkHttp = Boolean.parseBoolean(value); 148 } else if ("grpc_version".equals(key)) { 149 if (!"2".equals(value)) { 150 System.err.println("Only grpc version 2 is supported"); 151 usage = true; 152 break; 153 } 154 } else if ("default_service_account".equals(key)) { 155 defaultServiceAccount = value; 156 } else if ("service_account_key_file".equals(key)) { 157 serviceAccountKeyFile = value; 158 } else if ("oauth_scope".equals(key)) { 159 oauthScope = value; 160 } else if ("full_stream_decompression".equals(key)) { 161 fullStreamDecompression = Boolean.parseBoolean(value); 162 } else if ("local_handshaker_port".equals(key)) { 163 localHandshakerPort = Integer.parseInt(value); 164 } else if ("service_config_json".equals(key)) { 165 @SuppressWarnings("unchecked") 166 Map<String, ?> map = (Map<String, ?>) JsonParser.parse(value); 167 serviceConfig = map; 168 } else if ("soak_iterations".equals(key)) { 169 soakIterations = Integer.parseInt(value); 170 } else if ("soak_max_failures".equals(key)) { 171 soakMaxFailures = Integer.parseInt(value); 172 } else if ("soak_per_iteration_max_acceptable_latency_ms".equals(key)) { 173 soakPerIterationMaxAcceptableLatencyMs = Integer.parseInt(value); 174 } else if ("soak_min_time_ms_between_rpcs".equals(key)) { 175 soakMinTimeMsBetweenRpcs = Integer.parseInt(value); 176 } else if ("soak_overall_timeout_seconds".equals(key)) { 177 soakOverallTimeoutSeconds = Integer.parseInt(value); 178 } else if ("additional_metadata".equals(key)) { 179 additionalMetadata = value; 180 } else { 181 System.err.println("Unknown argument: " + key); 182 usage = true; 183 break; 184 } 185 } 186 if (useAlts || useH2cUpgrade) { 187 useTls = false; 188 } 189 if (usage) { 190 TestServiceClient c = new TestServiceClient(); 191 System.out.println( 192 "Usage: [ARGS...]" 193 + "\n" 194 + "\n --server_host=HOST Server to connect to. Default " + c.serverHost 195 + "\n --server_host_override=HOST Claimed identification expected of server." 196 + "\n Defaults to server host" 197 + "\n --server_port=PORT Port to connect to. Default " + c.serverPort 198 + "\n --test_case=TESTCASE Test case to run. Default " + c.testCase 199 + "\n Valid options:" 200 + validTestCasesHelpText() 201 + "\n --num_times=INT Number of times to run the test case. Default: " 202 + c.numTimes 203 + "\n --use_tls=true|false Whether to use TLS. Default " + c.useTls 204 + "\n --use_alts=true|false Whether to use ALTS. Enable ALTS will disable TLS." 205 + "\n Default " + c.useAlts 206 + "\n --local_handshaker_port=PORT" 207 + "\n Use local ALTS handshaker service on the specified " 208 + "\n port for testing. Only effective when --use_alts=true." 209 + "\n --use_upgrade=true|false Whether to use the h2c Upgrade mechanism." 210 + "\n Enabling h2c Upgrade will disable TLS." 211 + "\n Default " + c.useH2cUpgrade 212 + "\n --custom_credentials_type Custom credentials type to use. Default " 213 + c.customCredentialsType 214 + "\n --use_test_ca=true|false Whether to trust our fake CA. Requires --use_tls=true " 215 + "\n to have effect. Default " + c.useTestCa 216 + "\n --use_okhttp=true|false Whether to use OkHttp instead of Netty. Default " 217 + c.useOkHttp 218 + "\n --default_service_account Email of GCE default service account. Default " 219 + c.defaultServiceAccount 220 + "\n --service_account_key_file Path to service account json key file." 221 + c.serviceAccountKeyFile 222 + "\n --oauth_scope Scope for OAuth tokens. Default " + c.oauthScope 223 + "\n --full_stream_decompression Enable full-stream decompression. Default " 224 + c.fullStreamDecompression 225 + "\n --service_config_json=SERVICE_CONFIG_JSON" 226 + "\n Disables service config lookups and sets the provided " 227 + "\n string as the default service config." 228 + "\n --soak_iterations The number of iterations to use for the two soak " 229 + "\n tests: rpc_soak and channel_soak. Default " 230 + c.soakIterations 231 + "\n --soak_max_failures The number of iterations in soak tests that are " 232 + "\n allowed to fail (either due to non-OK status code or " 233 + "\n exceeding the per-iteration max acceptable latency). " 234 + "\n Default " + c.soakMaxFailures 235 + "\n --soak_per_iteration_max_acceptable_latency_ms " 236 + "\n The number of milliseconds a single iteration in the " 237 + "\n two soak tests (rpc_soak and channel_soak) should " 238 + "\n take. Default " 239 + c.soakPerIterationMaxAcceptableLatencyMs 240 + "\n --soak_min_time_ms_between_rpcs " 241 + "\n The minimum time in milliseconds between consecutive " 242 + "\n RPCs in a soak test (rpc_soak or channel_soak), " 243 + "\n useful for limiting QPS. Default: " 244 + c.soakMinTimeMsBetweenRpcs 245 + "\n --soak_overall_timeout_seconds " 246 + "\n The overall number of seconds after which a soak test " 247 + "\n should stop and fail, if the desired number of " 248 + "\n iterations have not yet completed. Default " 249 + c.soakOverallTimeoutSeconds 250 + "\n --additional_metadata " 251 + "\n Additional metadata to send in each request, as a " 252 + "\n semicolon-separated list of key:value pairs. Default " 253 + c.additionalMetadata 254 ); 255 System.exit(1); 256 } 257 } 258 259 @VisibleForTesting setUp()260 void setUp() { 261 tester.setUp(); 262 } 263 tearDown()264 private synchronized void tearDown() { 265 try { 266 tester.tearDown(); 267 if (customBackendMetricsLoadBalancerProvider != null) { 268 LoadBalancerRegistry.getDefaultRegistry() 269 .deregister(customBackendMetricsLoadBalancerProvider); 270 } 271 } catch (RuntimeException ex) { 272 throw ex; 273 } catch (Exception ex) { 274 throw new RuntimeException(ex); 275 } 276 } 277 run()278 private void run() { 279 System.out.println("Running test " + testCase); 280 try { 281 for (int i = 0; i < numTimes; i++) { 282 runTest(TestCases.fromString(testCase)); 283 } 284 } catch (RuntimeException ex) { 285 throw ex; 286 } catch (Exception ex) { 287 throw new RuntimeException(ex); 288 } 289 System.out.println("Test completed."); 290 } 291 runTest(TestCases testCase)292 private void runTest(TestCases testCase) throws Exception { 293 switch (testCase) { 294 case EMPTY_UNARY: 295 tester.emptyUnary(); 296 break; 297 298 case CACHEABLE_UNARY: { 299 tester.cacheableUnary(); 300 break; 301 } 302 303 case LARGE_UNARY: 304 tester.largeUnary(); 305 break; 306 307 case CLIENT_COMPRESSED_UNARY: 308 tester.clientCompressedUnary(true); 309 break; 310 311 case CLIENT_COMPRESSED_UNARY_NOPROBE: 312 tester.clientCompressedUnary(false); 313 break; 314 315 case SERVER_COMPRESSED_UNARY: 316 tester.serverCompressedUnary(); 317 break; 318 319 case CLIENT_STREAMING: 320 tester.clientStreaming(); 321 break; 322 323 case CLIENT_COMPRESSED_STREAMING: 324 tester.clientCompressedStreaming(true); 325 break; 326 327 case CLIENT_COMPRESSED_STREAMING_NOPROBE: 328 tester.clientCompressedStreaming(false); 329 break; 330 331 case SERVER_STREAMING: 332 tester.serverStreaming(); 333 break; 334 335 case SERVER_COMPRESSED_STREAMING: 336 tester.serverCompressedStreaming(); 337 break; 338 339 case PING_PONG: 340 tester.pingPong(); 341 break; 342 343 case EMPTY_STREAM: 344 tester.emptyStream(); 345 break; 346 347 case COMPUTE_ENGINE_CREDS: 348 tester.computeEngineCreds(defaultServiceAccount, oauthScope); 349 break; 350 351 case COMPUTE_ENGINE_CHANNEL_CREDENTIALS: { 352 ManagedChannelBuilder<?> builder; 353 if (serverPort == 0) { 354 builder = Grpc.newChannelBuilder(serverHost, ComputeEngineChannelCredentials.create()); 355 } else { 356 builder = 357 Grpc.newChannelBuilderForAddress( 358 serverHost, serverPort, ComputeEngineChannelCredentials.create()); 359 } 360 if (serviceConfig != null) { 361 builder.disableServiceConfigLookUp(); 362 builder.defaultServiceConfig(serviceConfig); 363 } 364 ManagedChannel channel = builder.build(); 365 try { 366 TestServiceGrpc.TestServiceBlockingStub computeEngineStub = 367 TestServiceGrpc.newBlockingStub(channel); 368 tester.computeEngineChannelCredentials(defaultServiceAccount, computeEngineStub); 369 } finally { 370 channel.shutdownNow(); 371 channel.awaitTermination(5, TimeUnit.SECONDS); 372 } 373 break; 374 } 375 376 case SERVICE_ACCOUNT_CREDS: { 377 String jsonKey = Files.asCharSource(new File(serviceAccountKeyFile), UTF_8).read(); 378 FileInputStream credentialsStream = new FileInputStream(new File(serviceAccountKeyFile)); 379 tester.serviceAccountCreds(jsonKey, credentialsStream, oauthScope); 380 break; 381 } 382 383 case JWT_TOKEN_CREDS: { 384 FileInputStream credentialsStream = new FileInputStream(new File(serviceAccountKeyFile)); 385 tester.jwtTokenCreds(credentialsStream); 386 break; 387 } 388 389 case OAUTH2_AUTH_TOKEN: { 390 String jsonKey = Files.asCharSource(new File(serviceAccountKeyFile), UTF_8).read(); 391 FileInputStream credentialsStream = new FileInputStream(new File(serviceAccountKeyFile)); 392 tester.oauth2AuthToken(jsonKey, credentialsStream, oauthScope); 393 break; 394 } 395 396 case PER_RPC_CREDS: { 397 String jsonKey = Files.asCharSource(new File(serviceAccountKeyFile), UTF_8).read(); 398 FileInputStream credentialsStream = new FileInputStream(new File(serviceAccountKeyFile)); 399 tester.perRpcCreds(jsonKey, credentialsStream, oauthScope); 400 break; 401 } 402 403 case GOOGLE_DEFAULT_CREDENTIALS: { 404 ManagedChannelBuilder<?> builder; 405 if (serverPort == 0) { 406 builder = Grpc.newChannelBuilder(serverHost, GoogleDefaultChannelCredentials.create()); 407 } else { 408 builder = 409 Grpc.newChannelBuilderForAddress( 410 serverHost, serverPort, GoogleDefaultChannelCredentials.create()); 411 } 412 if (serviceConfig != null) { 413 builder.disableServiceConfigLookUp(); 414 builder.defaultServiceConfig(serviceConfig); 415 } 416 ManagedChannel channel = builder.build(); 417 try { 418 TestServiceGrpc.TestServiceBlockingStub googleDefaultStub = 419 TestServiceGrpc.newBlockingStub(channel); 420 tester.googleDefaultCredentials(defaultServiceAccount, googleDefaultStub); 421 } finally { 422 channel.shutdownNow(); 423 } 424 break; 425 } 426 427 case CUSTOM_METADATA: { 428 tester.customMetadata(); 429 break; 430 } 431 432 case STATUS_CODE_AND_MESSAGE: { 433 tester.statusCodeAndMessage(); 434 break; 435 } 436 437 case SPECIAL_STATUS_MESSAGE: 438 tester.specialStatusMessage(); 439 break; 440 441 case UNIMPLEMENTED_METHOD: { 442 tester.unimplementedMethod(); 443 break; 444 } 445 446 case UNIMPLEMENTED_SERVICE: { 447 tester.unimplementedService(); 448 break; 449 } 450 451 case CANCEL_AFTER_BEGIN: { 452 tester.cancelAfterBegin(); 453 break; 454 } 455 456 case CANCEL_AFTER_FIRST_RESPONSE: { 457 tester.cancelAfterFirstResponse(); 458 break; 459 } 460 461 case TIMEOUT_ON_SLEEPING_SERVER: { 462 tester.timeoutOnSleepingServer(); 463 break; 464 } 465 466 case VERY_LARGE_REQUEST: { 467 tester.veryLargeRequest(); 468 break; 469 } 470 471 case PICK_FIRST_UNARY: { 472 tester.pickFirstUnary(); 473 break; 474 } 475 476 case RPC_SOAK: { 477 tester.performSoakTest( 478 serverHost, 479 false /* resetChannelPerIteration */, 480 soakIterations, 481 soakMaxFailures, 482 soakPerIterationMaxAcceptableLatencyMs, 483 soakMinTimeMsBetweenRpcs, 484 soakOverallTimeoutSeconds); 485 break; 486 } 487 488 case CHANNEL_SOAK: { 489 tester.performSoakTest( 490 serverHost, 491 true /* resetChannelPerIteration */, 492 soakIterations, 493 soakMaxFailures, 494 soakPerIterationMaxAcceptableLatencyMs, 495 soakMinTimeMsBetweenRpcs, 496 soakOverallTimeoutSeconds); 497 break; 498 499 } 500 501 case ORCA_PER_RPC: { 502 tester.testOrcaPerRpc(); 503 break; 504 } 505 506 case ORCA_OOB: { 507 tester.testOrcaOob(); 508 break; 509 } 510 511 default: 512 throw new IllegalArgumentException("Unknown test case: " + testCase); 513 } 514 } 515 516 /* Parses input string as a semi-colon-separated list of colon-separated key/value pairs. 517 * Allow any character but semicolons in values. 518 * If the string is emtpy, return null. 519 * Otherwise, return a client interceptor which inserts the provided metadata. 520 */ 521 @Nullable maybeCreateAdditionalMetadataInterceptor( String additionalMd)522 private ClientInterceptor maybeCreateAdditionalMetadataInterceptor( 523 String additionalMd) 524 throws IllegalArgumentException { 525 if (additionalMd.length() == 0) { 526 return null; 527 } 528 Metadata metadata = new Metadata(); 529 String[] pairs = additionalMd.split(";", -1); 530 for (String pair : pairs) { 531 String[] parts = pair.split(":", 2); 532 if (parts.length != 2) { 533 throw new IllegalArgumentException( 534 "error parsing --additional_metadata string, expected k:v pairs separated by ;"); 535 } 536 Metadata.Key<String> key = Metadata.Key.of(parts[0], Metadata.ASCII_STRING_MARSHALLER); 537 metadata.put(key, parts[1]); 538 } 539 return MetadataUtils.newAttachHeadersInterceptor(metadata); 540 } 541 542 private class Tester extends AbstractInteropTest { 543 @Override createChannelBuilder()544 protected ManagedChannelBuilder<?> createChannelBuilder() { 545 boolean useGeneric = false; 546 ChannelCredentials channelCredentials; 547 if (customCredentialsType != null) { 548 useGeneric = true; // Retain old behavior; avoids erroring if incompatible 549 if (customCredentialsType.equals("google_default_credentials")) { 550 channelCredentials = GoogleDefaultChannelCredentials.create(); 551 } else if (customCredentialsType.equals("compute_engine_channel_creds")) { 552 channelCredentials = ComputeEngineChannelCredentials.create(); 553 } else { 554 throw new IllegalArgumentException( 555 "Unknown custom credentials: " + customCredentialsType); 556 } 557 558 } else if (useAlts) { 559 useGeneric = true; // Retain old behavior; avoids erroring if incompatible 560 if (localHandshakerPort > -1) { 561 channelCredentials = AltsChannelCredentials.newBuilder() 562 .enableUntrustedAltsForTesting() 563 .setHandshakerAddressForTesting("localhost:" + localHandshakerPort).build(); 564 } else { 565 channelCredentials = AltsChannelCredentials.create(); 566 } 567 568 } else if (useTls) { 569 if (!useTestCa) { 570 channelCredentials = TlsChannelCredentials.create(); 571 } else { 572 try { 573 channelCredentials = TlsChannelCredentials.newBuilder() 574 .trustManager(TlsTesting.loadCert("ca.pem")) 575 .build(); 576 } catch (Exception ex) { 577 throw new RuntimeException(ex); 578 } 579 } 580 581 } else { 582 if (useH2cUpgrade) { 583 if (useOkHttp) { 584 throw new IllegalArgumentException("OkHttp does not support HTTP/1 upgrade"); 585 } else { 586 channelCredentials = InsecureFromHttp1ChannelCredentials.create(); 587 } 588 } else { 589 channelCredentials = InsecureChannelCredentials.create(); 590 } 591 } 592 ClientInterceptor addMdInterceptor = maybeCreateAdditionalMetadataInterceptor( 593 additionalMetadata); 594 if (useGeneric) { 595 ManagedChannelBuilder<?> channelBuilder; 596 if (serverPort == 0) { 597 channelBuilder = Grpc.newChannelBuilder(serverHost, channelCredentials); 598 } else { 599 channelBuilder = 600 Grpc.newChannelBuilderForAddress(serverHost, serverPort, channelCredentials); 601 } 602 if (serverHostOverride != null) { 603 channelBuilder.overrideAuthority(serverHostOverride); 604 } 605 if (serviceConfig != null) { 606 channelBuilder.disableServiceConfigLookUp(); 607 channelBuilder.defaultServiceConfig(serviceConfig); 608 } 609 if (addMdInterceptor != null) { 610 channelBuilder.intercept(addMdInterceptor); 611 } 612 return channelBuilder; 613 } 614 if (!useOkHttp) { 615 NettyChannelBuilder nettyBuilder; 616 if (serverPort == 0) { 617 nettyBuilder = NettyChannelBuilder.forTarget(serverHost, channelCredentials); 618 } else { 619 nettyBuilder = NettyChannelBuilder.forAddress(serverHost, serverPort, channelCredentials); 620 } 621 nettyBuilder.flowControlWindow(AbstractInteropTest.TEST_FLOW_CONTROL_WINDOW); 622 if (serverHostOverride != null) { 623 nettyBuilder.overrideAuthority(serverHostOverride); 624 } 625 if (fullStreamDecompression) { 626 nettyBuilder.enableFullStreamDecompression(); 627 } 628 // Disable the default census stats interceptor, use testing interceptor instead. 629 InternalNettyChannelBuilder.setStatsEnabled(nettyBuilder, false); 630 if (serviceConfig != null) { 631 nettyBuilder.disableServiceConfigLookUp(); 632 nettyBuilder.defaultServiceConfig(serviceConfig); 633 } 634 if (addMdInterceptor != null) { 635 nettyBuilder.intercept(addMdInterceptor); 636 } 637 return nettyBuilder.intercept(createCensusStatsClientInterceptor()); 638 } 639 640 OkHttpChannelBuilder okBuilder; 641 if (serverPort == 0) { 642 okBuilder = OkHttpChannelBuilder.forTarget(serverHost, channelCredentials); 643 } else { 644 okBuilder = OkHttpChannelBuilder.forAddress(serverHost, serverPort, channelCredentials); 645 } 646 if (serverHostOverride != null) { 647 // Force the hostname to match the cert the server uses. 648 okBuilder.overrideAuthority( 649 GrpcUtil.authorityFromHostAndPort(serverHostOverride, serverPort)); 650 } 651 if (fullStreamDecompression) { 652 okBuilder.enableFullStreamDecompression(); 653 } 654 // Disable the default census stats interceptor, use testing interceptor instead. 655 InternalOkHttpChannelBuilder.setStatsEnabled(okBuilder, false); 656 if (serviceConfig != null) { 657 okBuilder.disableServiceConfigLookUp(); 658 okBuilder.defaultServiceConfig(serviceConfig); 659 } 660 if (addMdInterceptor != null) { 661 okBuilder.intercept(addMdInterceptor); 662 } 663 return okBuilder.intercept(createCensusStatsClientInterceptor()); 664 } 665 666 @Override metricsExpected()667 protected boolean metricsExpected() { 668 // Exact message size doesn't match when testing with Go servers: 669 // https://github.com/grpc/grpc-go/issues/1572 670 // TODO(zhangkun83): remove this override once the said issue is fixed. 671 return false; 672 } 673 674 @Override 675 @Nullable getHandshakerServerBuilder()676 protected ServerBuilder<?> getHandshakerServerBuilder() { 677 if (localHandshakerPort > -1) { 678 return Grpc.newServerBuilderForPort(localHandshakerPort, 679 InsecureServerCredentials.create()) 680 .addService(new AltsHandshakerTestService()); 681 } else { 682 return null; 683 } 684 } 685 686 @Override operationTimeoutMillis()687 protected int operationTimeoutMillis() { 688 return 15000; 689 } 690 } 691 validTestCasesHelpText()692 private static String validTestCasesHelpText() { 693 StringBuilder builder = new StringBuilder(); 694 for (TestCases testCase : TestCases.values()) { 695 String strTestcase = testCase.name().toLowerCase(); 696 builder.append("\n ") 697 .append(strTestcase) 698 .append(": ") 699 .append(testCase.description()); 700 } 701 return builder.toString(); 702 } 703 } 704