Skip to content

Commit 6239965

Browse files
committed
Improve test client for real cert
The test client can now be used against a server that has properly configured certificates, instead of just the test server. To reach the test server, the client needs these arguments: --use_test_ca=true --server_host_override=foo.test.google.fr Client no longer has any required arguments, although for any given setup needing to specify at least one argument is highly likely. The arguments have been improved in general to hopefully be more orthogonal and match those of other language's test clients.
1 parent f681eff commit 6239965

File tree

1 file changed

+132
-143
lines changed

1 file changed

+132
-143
lines changed

integration-testing/src/main/java/com/google/net/stubby/testing/integration/TestServiceClient.java

Lines changed: 132 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@
3131

3232
package com.google.net.stubby.testing.integration;
3333

34-
import com.google.common.base.Preconditions;
35-
import com.google.common.collect.Maps;
3634
import com.google.net.stubby.ChannelImpl;
3735
import com.google.net.stubby.transport.netty.NegotiationType;
3836
import com.google.net.stubby.transport.netty.NettyChannelBuilder;
@@ -44,7 +42,6 @@
4442
import java.net.InetAddress;
4543
import java.net.InetSocketAddress;
4644
import java.net.UnknownHostException;
47-
import java.util.Map;
4845

4946
import javax.net.ssl.SSLException;
5047

@@ -53,166 +50,135 @@
5350
* series of tests.
5451
*/
5552
public class TestServiceClient {
56-
private static final String SERVER_HOST_ARG = "--server_host";
57-
private static final String SERVER_PORT_ARG = "--server_port";
58-
private static final String TRANSPORT_ARG = "--transport";
59-
private static final String TEST_CASE_ARG = "--test_case";
60-
private static final String GRPC_VERSION_ARG = "--grpc_version";
61-
62-
private enum Transport {
63-
NETTY {
64-
@Override
65-
public ChannelImpl createChannel(String serverHost, int serverPort) {
66-
return NettyChannelBuilder.forAddress(serverHost, serverPort)
67-
.negotiationType(NegotiationType.PLAINTEXT).build();
68-
}
69-
},
70-
NETTY_TLS {
71-
@Override
72-
public ChannelImpl createChannel(String serverHost, int serverPort) {
73-
InetAddress address;
74-
try {
75-
address = InetAddress.getByName(serverHost);
76-
// Force the hostname to match the cert the server uses.
77-
address = InetAddress.getByAddress("foo.test.google.fr", address.getAddress());
78-
} catch (UnknownHostException ex) {
79-
throw new RuntimeException(ex);
80-
}
81-
SslContext sslContext;
82-
try {
83-
String dir = "integration-testing/certs";
84-
sslContext = SslContext.newClientContext(
85-
new File(dir + "/ca.pem"));
86-
} catch (SSLException ex) {
87-
throw new RuntimeException(ex);
88-
}
89-
return NettyChannelBuilder.forAddress(new InetSocketAddress(address, serverPort))
90-
.negotiationType(NegotiationType.TLS)
91-
.sslContext(sslContext)
92-
.build();
93-
}
94-
},
95-
OKHTTP {
96-
@Override
97-
public ChannelImpl createChannel(String serverHost, int serverPort) {
98-
return OkHttpChannelBuilder.forAddress(serverHost, serverPort).build();
99-
}
100-
},
101-
;
102-
103-
public abstract ChannelImpl createChannel(String serverHost, int serverPort);
104-
}
105-
10653
/**
107-
* The main application allowing this client to be launched from the command line. Accepts the
108-
* following arguments:
109-
* <p>
110-
* --transport=NETTY|NETTY_TLS|OKHTTP Identifies the concrete implementation of the
111-
* transport. <br>
112-
* --serverHost=The host of the remote server.<br>
113-
* --serverPort=$port_number The port of the remote server.<br>
114-
* --test_case=empty_unary|server_streaming The client test to run.<br>
54+
* The main application allowing this client to be launched from the command line.
11555
*/
11656
public static void main(String[] args) throws Exception {
117-
Map<String, String> argMap = parseArgs(args);
118-
Transport transport = getTransport(argMap);
119-
String serverHost = getServerHost(argMap);
120-
int serverPort = getPort(argMap);
121-
String testCase = getTestCase(argMap);
122-
123-
// TODO(user): Remove. Ideally stop passing the arg in scripts first.
124-
if (getGrpcVersion(argMap) != 2) {
125-
System.err.println("Only grpc_version=2 is supported");
126-
System.exit(1);
127-
}
57+
final TestServiceClient client = new TestServiceClient();
58+
client.parseArgs(args);
59+
client.setup();
12860

129-
final Tester tester = new Tester(transport, serverHost, serverPort);
13061
Runtime.getRuntime().addShutdownHook(new Thread() {
13162
@Override
13263
public void run() {
13364
System.out.println("Shutting down");
13465
try {
135-
tester.teardown();
66+
client.teardown();
13667
} catch (Exception e) {
13768
e.printStackTrace();
13869
}
13970
}
14071
});
14172

142-
tester.setup();
143-
System.out.println("Running test " + testCase);
14473
try {
145-
runTest(tester, testCase);
146-
} catch (Exception ex) {
147-
ex.printStackTrace();
148-
tester.teardown();
149-
System.exit(1);
74+
client.run();
75+
} finally {
76+
client.teardown();
15077
}
151-
System.out.println("Test completed.");
152-
tester.teardown();
15378
}
15479

155-
private static Transport getTransport(Map<String, String> argMap) {
156-
String value = argMap.get(TRANSPORT_ARG.toLowerCase());
157-
Preconditions.checkNotNull(value, "%s argument must be provided.", TRANSPORT_ARG);
158-
Transport transport = Transport.valueOf(value.toUpperCase().trim());
159-
System.out.println(TRANSPORT_ARG + " set to: " + transport);
160-
return transport;
161-
}
80+
private String serverHost = "localhost";
81+
private String serverHostOverride;
82+
private int serverPort = 8080;
83+
private String testCase = "empty_unary";
84+
private boolean useTls = true;
85+
private boolean useTestCa;
86+
private boolean useOkHttp;
16287

163-
private static String getServerHost(Map<String, String> argMap) {
164-
String value = argMap.get(SERVER_HOST_ARG.toLowerCase());
165-
if (value == null) {
166-
throw new IllegalArgumentException(
167-
"Must provide " + SERVER_HOST_ARG + " command-line argument");
168-
}
169-
System.out.println(SERVER_HOST_ARG + " set to: " + value);
170-
return value;
171-
}
88+
private Tester tester = new Tester();
17289

173-
private static int getPort(Map<String, String> argMap) {
174-
String value = argMap.get(SERVER_PORT_ARG.toLowerCase());
175-
if (value == null) {
176-
throw new IllegalArgumentException(
177-
"Must provide numeric " + SERVER_PORT_ARG + " command-line argument");
90+
private void parseArgs(String[] args) {
91+
boolean usage = false;
92+
for (String arg : args) {
93+
if (!arg.startsWith("--")) {
94+
System.err.println("All arguments must start with '--': " + arg);
95+
usage = true;
96+
break;
97+
}
98+
String[] parts = arg.substring(2).split("=", 2);
99+
String key = parts[0];
100+
if ("help".equals(key)) {
101+
usage = true;
102+
break;
103+
}
104+
if (parts.length != 2) {
105+
System.err.println("All arguments must be of the form --arg=value");
106+
usage = true;
107+
break;
108+
}
109+
String value = parts[1];
110+
if ("server_host".equals(key)) {
111+
serverHost = value;
112+
} else if ("server_host_override".equals(key)) {
113+
serverHostOverride = value;
114+
} else if ("server_port".equals(key)) {
115+
serverPort = Integer.parseInt(value);
116+
} else if ("test_case".equals(key)) {
117+
testCase = value;
118+
} else if ("use_tls".equals(key)) {
119+
useTls = Boolean.parseBoolean(value);
120+
} else if ("use_test_ca".equals(key)) {
121+
useTestCa = Boolean.parseBoolean(value);
122+
} else if ("use_okhttp".equals(key)) {
123+
useOkHttp = Boolean.parseBoolean(value);
124+
} else if ("grpc_version".equals(key)) {
125+
if (!"2".equals(value)) {
126+
System.err.println("Only grpc version 2 is supported");
127+
usage = true;
128+
break;
129+
}
130+
} else {
131+
System.err.println("Unknown argument: " + key);
132+
usage = true;
133+
break;
134+
}
135+
}
136+
if (usage) {
137+
TestServiceClient c = new TestServiceClient();
138+
System.out.println(
139+
"Usage: [ARGS...]"
140+
+ "\n"
141+
+ "\n --server_host=HOST Server to connect to. Default " + c.serverHost
142+
+ "\n --server_host_override=HOST Claimed identification expected of server."
143+
+ "\n Defaults to server host"
144+
+ "\n --server_port=PORT Port to connect to. Default " + c.serverPort
145+
+ "\n --test_case=TESTCASE Test case to run. Default " + c.testCase
146+
+ "\n --use_tls=true|false Whether to use TLS. Default " + c.useTls
147+
+ "\n --use_test_ca=true|false Whether to trust our fake CA. Default " + c.useTestCa
148+
+ "\n --use_okhttp=true|false Whether to use OkHttp instead of Netty. Default "
149+
+ c.useOkHttp
150+
);
151+
System.exit(1);
178152
}
179-
int port = Integer.parseInt(value);
180-
System.out.println(SERVER_PORT_ARG + " set to port: " + port);
181-
return port;
182153
}
183154

184-
private static String getTestCase(Map<String, String> argMap) {
185-
String value = argMap.get(TEST_CASE_ARG);
186-
if (value == null) {
187-
throw new IllegalArgumentException(
188-
"Must provide " + TEST_CASE_ARG + " command-line argument");
189-
}
190-
System.out.println(TEST_CASE_ARG + " set to: " + value);
191-
return value;
155+
private void setup() {
156+
tester.setup();
192157
}
193158

194-
private static int getGrpcVersion(Map<String, String> argMap) {
195-
String value = argMap.get(GRPC_VERSION_ARG.toLowerCase());
196-
if (value == null) {
197-
return 2;
159+
private synchronized void teardown() {
160+
try {
161+
tester.teardown();
162+
} catch (RuntimeException ex) {
163+
throw ex;
164+
} catch (Exception ex) {
165+
throw new RuntimeException(ex);
198166
}
199-
int version = Integer.parseInt(value);
200-
System.out.println(GRPC_VERSION_ARG + " set to version: " + version);
201-
return version;
202167
}
203168

204-
private static Map<String, String> parseArgs(String[] args) {
205-
Map<String, String> argMap = Maps.newHashMap();
206-
for (String arg : args) {
207-
String[] parts = arg.split("=");
208-
Preconditions.checkArgument(parts.length == 2, "Failed parsing argument: %s", arg);
209-
argMap.put(parts[0].toLowerCase().trim(), parts[1].trim());
169+
private void run() {
170+
System.out.println("Running test " + testCase);
171+
try {
172+
runTest(testCase);
173+
} catch (RuntimeException ex) {
174+
throw ex;
175+
} catch (Exception ex) {
176+
throw new RuntimeException(ex);
210177
}
211-
212-
return argMap;
178+
System.out.println("Test completed.");
213179
}
214180

215-
private static void runTest(Tester tester, String testCase) throws Exception {
181+
private void runTest(String testCase) throws Exception {
216182
if ("empty_unary".equals(testCase)) {
217183
tester.emptyUnary();
218184
} else if ("large_unary".equals(testCase)) {
@@ -234,20 +200,43 @@ private static void runTest(Tester tester, String testCase) throws Exception {
234200
}
235201
}
236202

237-
private static class Tester extends AbstractTransportTest {
238-
private final Transport transport;
239-
private final String host;
240-
private final int port;
241-
242-
public Tester(Transport transport, String host, int port) {
243-
this.transport = transport;
244-
this.host = host;
245-
this.port = port;
246-
}
247-
203+
private class Tester extends AbstractTransportTest {
248204
@Override
249205
protected ChannelImpl createChannel() {
250-
return transport.createChannel(host, port);
206+
if (!useOkHttp) {
207+
InetAddress address;
208+
try {
209+
address = InetAddress.getByName(serverHost);
210+
if (serverHostOverride != null) {
211+
// Force the hostname to match the cert the server uses.
212+
address = InetAddress.getByAddress(serverHostOverride, address.getAddress());
213+
}
214+
} catch (UnknownHostException ex) {
215+
throw new RuntimeException(ex);
216+
}
217+
SslContext sslContext = null;
218+
if (useTestCa) {
219+
try {
220+
String dir = "integration-testing/certs";
221+
sslContext = SslContext.newClientContext(
222+
new File(dir + "/ca.pem"));
223+
} catch (SSLException ex) {
224+
throw new RuntimeException(ex);
225+
}
226+
}
227+
return NettyChannelBuilder.forAddress(new InetSocketAddress(address, serverPort))
228+
.negotiationType(useTls ? NegotiationType.TLS : NegotiationType.PLAINTEXT)
229+
.sslContext(sslContext)
230+
.build();
231+
} else {
232+
if (serverHostOverride != null) {
233+
throw new IllegalStateException("Server host override unsupported with okhttp");
234+
}
235+
if (useTls) {
236+
throw new IllegalStateException("TLS unsupported with okhttp");
237+
}
238+
return OkHttpChannelBuilder.forAddress(serverHost, serverPort).build();
239+
}
251240
}
252241
}
253242
}

0 commit comments

Comments
 (0)