1 /*
2  * Copyright 2015 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 static org.junit.Assert.assertTrue;
20 
21 import io.grpc.ManagedChannel;
22 import io.grpc.StatusRuntimeException;
23 import io.grpc.netty.NegotiationType;
24 import io.grpc.netty.NettyChannelBuilder;
25 import io.grpc.okhttp.OkHttpChannelBuilder;
26 import io.grpc.testing.integration.EmptyProtos.Empty;
27 import io.grpc.testing.integration.Messages.ReconnectInfo;
28 
29 /**
30  * Verifies the client is reconnecting the server with correct backoffs
31  *
32  * <p>See the <a href="https://github.com/grpc/grpc/blob/master/doc/connection-backoff-interop-test-description.md">Test Spec</a>.
33  */
34 public class ReconnectTestClient {
35   private static final int TEST_TIME_MS = 540 * 1000;
36 
37   private int serverControlPort = 8080;
38   private int serverRetryPort = 8081;
39   private boolean useOkhttp = false;
40   private ManagedChannel controlChannel;
41   private ManagedChannel retryChannel;
42   private ReconnectServiceGrpc.ReconnectServiceBlockingStub controlStub;
43   private ReconnectServiceGrpc.ReconnectServiceBlockingStub retryStub;
44 
parseArgs(String[] args)45   private void parseArgs(String[] args) {
46     for (String arg : args) {
47       if (!arg.startsWith("--")) {
48         System.err.println("All arguments must start with '--': " + arg);
49         System.exit(1);
50       }
51       String[] parts = arg.substring(2).split("=", 2);
52       String key = parts[0];
53       String value = parts[1];
54       if ("server_control_port".equals(key)) {
55         serverControlPort = Integer.parseInt(value);
56       } else if ("server_retry_port".equals(key)) {
57         serverRetryPort = Integer.parseInt(value);
58       } else if ("use_okhttp".equals(key)) {
59         useOkhttp = Boolean.parseBoolean(value);
60       } else {
61         System.err.println("Unknown argument: " + key);
62         System.exit(1);
63       }
64     }
65   }
66 
runTest()67   private void runTest() throws Exception {
68     try {
69       controlChannel = NettyChannelBuilder.forAddress("127.0.0.1", serverControlPort)
70           .negotiationType(NegotiationType.PLAINTEXT).build();
71       controlStub = ReconnectServiceGrpc.newBlockingStub(controlChannel);
72       if (useOkhttp) {
73         retryChannel =
74             OkHttpChannelBuilder.forAddress("127.0.0.1", serverRetryPort)
75                 .useTransportSecurity()
76                 .build();
77       } else {
78         retryChannel = NettyChannelBuilder.forAddress("127.0.0.1", serverRetryPort)
79             .negotiationType(NegotiationType.TLS).build();
80       }
81       retryStub = ReconnectServiceGrpc.newBlockingStub(retryChannel);
82       controlStub.start(Empty.getDefaultInstance());
83 
84       long startTimeStamp = System.currentTimeMillis();
85       while ((System.currentTimeMillis() - startTimeStamp) < TEST_TIME_MS) {
86         try {
87           retryStub.start(Empty.getDefaultInstance());
88         } catch (StatusRuntimeException expected) {
89           // Make CheckStyle happy.
90         }
91         Thread.sleep(50);
92       }
93       ReconnectInfo info = controlStub.stop(Empty.getDefaultInstance());
94       assertTrue(info.getPassed());
95     } finally {
96       controlChannel.shutdownNow();
97       retryChannel.shutdownNow();
98     }
99   }
100 
101   /**
102    * The main application allowing this client to be launched from the command line.
103    */
main(String[] args)104   public static void main(String[] args) {
105     ReconnectTestClient client = new ReconnectTestClient();
106     client.parseArgs(args);
107     System.out.println("Starting test:");
108     try {
109       client.runTest();
110       System.out.println("Finished successfully");
111       System.exit(0);
112     } catch (Throwable e) {
113       e.printStackTrace();
114       System.err.println("Test failed!");
115       System.exit(1);
116     }
117   }
118 }
119