Skip to content

Commit a3393ac

Browse files
committed
Adding new end 2 end test
1 parent 1fbfdab commit a3393ac

File tree

1 file changed

+341
-0
lines changed

1 file changed

+341
-0
lines changed
Lines changed: 341 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
/*
2+
* Copyright (c) 2011-2021 Contributors to the Eclipse Foundation
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License 2.0 which is available at
6+
* http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
7+
* which is available at https://www.apache.org/licenses/LICENSE-2.0.
8+
*
9+
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
10+
*/
11+
12+
package io.vertx.core.net.impl;
13+
14+
import java.io.File;
15+
import java.nio.charset.StandardCharsets;
16+
import java.util.concurrent.CountDownLatch;
17+
18+
import org.junit.Assume;
19+
import org.junit.Rule;
20+
import org.junit.Test;
21+
import org.junit.rules.TemporaryFolder;
22+
23+
import io.netty.buffer.ByteBuf;
24+
import io.netty.buffer.ByteBufAllocator;
25+
import io.netty.buffer.PooledByteBufAllocator;
26+
import io.netty.buffer.Unpooled;
27+
import io.netty.channel.ChannelHandlerContext;
28+
import io.netty.channel.ChannelPipeline;
29+
import io.netty.handler.codec.http.DefaultFullHttpRequest;
30+
import io.netty.handler.codec.http.DefaultFullHttpResponse;
31+
import io.netty.handler.codec.http.HttpClientCodec;
32+
import io.netty.handler.codec.http.HttpHeaderNames;
33+
import io.netty.handler.codec.http.HttpMethod;
34+
import io.netty.handler.codec.http.HttpResponseStatus;
35+
import io.netty.handler.codec.http.HttpServerCodec;
36+
import io.netty.handler.codec.http.HttpVersion;
37+
import io.netty.handler.codec.http.LastHttpContent;
38+
import io.vertx.core.Context;
39+
import io.vertx.core.VertxOptions;
40+
import io.vertx.core.buffer.Buffer;
41+
import io.vertx.core.buffer.impl.PartialPooledByteBufAllocator;
42+
import io.vertx.core.buffer.impl.VertxByteBufAllocator;
43+
import io.vertx.core.http.HttpClient;
44+
import io.vertx.core.http.HttpClientOptions;
45+
import io.vertx.core.http.HttpServer;
46+
import io.vertx.core.http.HttpServerOptions;
47+
import io.vertx.core.net.JdkSSLEngineOptions;
48+
import io.vertx.core.net.NetClient;
49+
import io.vertx.core.net.NetClientOptions;
50+
import io.vertx.core.net.NetServer;
51+
import io.vertx.core.net.NetServerOptions;
52+
import io.vertx.core.net.OpenSSLEngineOptions;
53+
import io.vertx.core.net.SocketAddress;
54+
import io.vertx.test.core.TestUtils;
55+
import io.vertx.test.core.VertxTestBase;
56+
import io.vertx.test.tls.Cert;
57+
import io.vertx.test.tls.Trust;
58+
59+
public class NetAllocatorsTest extends VertxTestBase {
60+
61+
private SocketAddress testAddress;
62+
private NetServer server;
63+
private NetClient client;
64+
private File tmp;
65+
66+
@Rule
67+
public TemporaryFolder testFolder = new TemporaryFolder();
68+
69+
@Override
70+
public void setUp() throws Exception {
71+
super.setUp();
72+
if (USE_DOMAIN_SOCKETS) {
73+
assertTrue("Native transport not enabled", USE_NATIVE_TRANSPORT);
74+
tmp = TestUtils.tmpFile(".sock");
75+
testAddress = SocketAddress.domainSocketAddress(tmp.getAbsolutePath());
76+
} else {
77+
testAddress = SocketAddress.inetSocketAddress(1234, "localhost");
78+
}
79+
client = vertx.createNetClient(new NetClientOptions().setConnectTimeout(1000));
80+
server = vertx.createNetServer();
81+
}
82+
83+
@Override
84+
protected VertxOptions getOptions() {
85+
VertxOptions options = super.getOptions();
86+
options.getAddressResolverOptions().setHostsValue(Buffer.buffer("" +
87+
"127.0.0.1 localhost\n" +
88+
"127.0.0.1 host1\n" +
89+
"127.0.0.1 host2.com\n" +
90+
"127.0.0.1 example.com"));
91+
return options;
92+
}
93+
94+
@Override
95+
protected void tearDown() throws Exception {
96+
if (tmp != null) {
97+
tmp.delete();
98+
}
99+
super.tearDown();
100+
}
101+
102+
@Test
103+
public void testServerAllocatorNoSSL() throws Exception {
104+
server.close();
105+
server = vertx.createNetServer(new NetServerOptions()
106+
.setPort(1234)
107+
.setHost("localhost"));
108+
testServerAllocator(new HttpClientOptions(), false,
109+
PooledByteBufAllocator.DEFAULT, PooledByteBufAllocator.DEFAULT, false);
110+
}
111+
112+
@Test
113+
public void testHeapPoolingServerAllocatorJdkSSL() throws Exception {
114+
server.close();
115+
server = vertx.createNetServer(new NetServerOptions()
116+
.setPort(1234)
117+
.setHost("localhost")
118+
.setSsl(true)
119+
.setSslEngineOptions(new JdkSSLEngineOptions().setPooledHeapBuffers(true))
120+
.setKeyStoreOptions(Cert.SERVER_JKS.get()));
121+
testServerAllocator(new HttpClientOptions()
122+
.setSsl(true)
123+
.setTrustStoreOptions(Trust.SERVER_JKS.get()), true,
124+
// the JDK SSL engine wrapping buffer is heap-based, but the output one not, see:
125+
// see https://github.com/netty/netty/blob/f377e7e23f71fbf1e682bfd5b69b8720338ee8b9/handler/src/main/java/io/netty/handler/ssl/SslHandler.java#L2407
126+
// It uses the allocator's buffer method, which is direct-based on PooledByteBufAllocator.DEFAULT
127+
PooledByteBufAllocator.DEFAULT, PooledByteBufAllocator.DEFAULT, false);
128+
}
129+
130+
@Test
131+
public void testServerAllocatorJdkSSL() throws Exception {
132+
server.close();
133+
server = vertx.createNetServer(new NetServerOptions()
134+
.setPort(1234)
135+
.setHost("localhost")
136+
.setSsl(true)
137+
.setSslEngineOptions(new JdkSSLEngineOptions())
138+
.setKeyStoreOptions(Cert.SERVER_JKS.get()));
139+
testServerAllocator(new HttpClientOptions()
140+
.setSsl(true)
141+
.setTrustStoreOptions(Trust.SERVER_JKS.get()), true,
142+
VertxByteBufAllocator.UNPOOLED_ALLOCATOR, PartialPooledByteBufAllocator.INSTANCE, true);
143+
}
144+
145+
@Test
146+
public void testServerAllocatorOpenSSL() throws Exception {
147+
Assume.assumeTrue(OpenSSLEngineOptions.isAvailable());
148+
server.close();
149+
server = vertx.createNetServer(new NetServerOptions()
150+
.setPort(1234)
151+
.setHost("localhost")
152+
.setSsl(true)
153+
.setSslEngineOptions(new OpenSSLEngineOptions())
154+
.setKeyStoreOptions(Cert.SERVER_JKS.get()));
155+
testServerAllocator(new HttpClientOptions()
156+
.setSsl(true)
157+
.setTrustStoreOptions(Trust.SERVER_JKS.get()), true,
158+
VertxByteBufAllocator.POOLED_ALLOCATOR, PartialPooledByteBufAllocator.INSTANCE, false);
159+
}
160+
161+
private void testServerAllocator(HttpClientOptions clientOptions, boolean expectSSL,
162+
ByteBufAllocator bufferAllocator, ByteBufAllocator channelAllocator,
163+
boolean expectHeapBuffer) throws Exception {
164+
waitFor(2);
165+
server.connectHandler(so -> {
166+
NetSocketInternal internal = (NetSocketInternal) so;
167+
assertEquals(expectSSL, internal.isSsl());
168+
ChannelHandlerContext chctx = internal.channelHandlerContext();
169+
ChannelPipeline pipeline = chctx.pipeline();
170+
pipeline.addBefore("handler", "http", new HttpServerCodec());
171+
// add a new handler which feeds the raw buffer to the http handler: this should receive the buffer
172+
// from the SSL handler, if configured
173+
pipeline.addBefore("http", "raw", new io.netty.channel.ChannelInboundHandlerAdapter() {
174+
@Override
175+
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
176+
assertTrue(msg instanceof ByteBuf);
177+
ByteBuf byteBuf = (ByteBuf) msg;
178+
assertSame(bufferAllocator, byteBuf.alloc());
179+
assertSame(channelAllocator, ctx.channel().config().getAllocator());
180+
assertTrue(expectHeapBuffer == byteBuf.hasArray());
181+
super.channelRead(ctx, msg);
182+
}
183+
});
184+
internal.handler(buff -> fail());
185+
internal.messageHandler(obj -> {
186+
if (obj instanceof LastHttpContent) {
187+
DefaultFullHttpResponse response = new DefaultFullHttpResponse(
188+
HttpVersion.HTTP_1_1,
189+
HttpResponseStatus.OK,
190+
Unpooled.copiedBuffer("Hello World", StandardCharsets.UTF_8));
191+
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, "11");
192+
internal.writeMessage(response, onSuccess(v -> complete()));
193+
}
194+
});
195+
});
196+
startServer(SocketAddress.inetSocketAddress(1234, "localhost"));
197+
HttpClient client = vertx.createHttpClient(clientOptions);
198+
client.request(io.vertx.core.http.HttpMethod.GET, 1234, "localhost", "/somepath", onSuccess(req -> {
199+
req.send(onSuccess(resp -> {
200+
assertEquals(200, resp.statusCode());
201+
resp.body(onSuccess(body -> {
202+
assertEquals("Hello World", body.toString());
203+
complete();
204+
}));
205+
}));
206+
}));
207+
await();
208+
}
209+
210+
@Test
211+
public void testClientAllocatorNoSSL() throws Exception {
212+
testClientAllocator(new HttpServerOptions()
213+
.setHost("localhost")
214+
.setPort(1234), false,
215+
VertxByteBufAllocator.POOLED_ALLOCATOR, PartialPooledByteBufAllocator.INSTANCE, false);
216+
}
217+
218+
@Test
219+
public void testHeapPoolingClientAllocatorJdkSSL() throws Exception {
220+
client.close();
221+
client = vertx.createNetClient(new NetClientOptions()
222+
.setSsl(true)
223+
.setSslEngineOptions(new JdkSSLEngineOptions().setPooledHeapBuffers(true))
224+
.setHostnameVerificationAlgorithm("")
225+
.setTrustStoreOptions(Trust.SERVER_JKS.get()));
226+
testClientAllocator(new HttpServerOptions()
227+
.setHost("localhost")
228+
.setPort(1234)
229+
.setSsl(true)
230+
.setKeyStoreOptions(Cert.SERVER_JKS.get()), true,
231+
// the JDK SSL engine wrapping buffer is heap-based, but the output one not, see:
232+
// see https://github.com/netty/netty/blob/f377e7e23f71fbf1e682bfd5b69b8720338ee8b9/handler/src/main/java/io/netty/handler/ssl/SslHandler.java#L2407
233+
// It uses the allocator's buffer method, which is direct-based on PooledByteBufAllocator.DEFAULT
234+
PooledByteBufAllocator.DEFAULT, PooledByteBufAllocator.DEFAULT, false);
235+
}
236+
237+
@Test
238+
public void testClientAllocatorJdkSSL() throws Exception {
239+
client.close();
240+
client = vertx.createNetClient(new NetClientOptions()
241+
.setSsl(true)
242+
.setSslEngineOptions(new JdkSSLEngineOptions())
243+
.setHostnameVerificationAlgorithm("")
244+
.setTrustStoreOptions(Trust.SERVER_JKS.get()));
245+
testClientAllocator(new HttpServerOptions()
246+
.setHost("localhost")
247+
.setPort(1234)
248+
.setSsl(true)
249+
.setKeyStoreOptions(Cert.SERVER_JKS.get()), true,
250+
VertxByteBufAllocator.UNPOOLED_ALLOCATOR, PartialPooledByteBufAllocator.INSTANCE, true);
251+
}
252+
253+
@Test
254+
public void testClientAllocatorOpenSSL() throws Exception {
255+
Assume.assumeTrue(OpenSSLEngineOptions.isAvailable());
256+
client.close();
257+
client = vertx.createNetClient(new NetClientOptions()
258+
.setSsl(true)
259+
.setSslEngineOptions(new OpenSSLEngineOptions())
260+
.setHostnameVerificationAlgorithm("")
261+
.setTrustStoreOptions(Trust.SERVER_JKS.get()));
262+
testClientAllocator(new HttpServerOptions()
263+
.setHost("localhost")
264+
.setPort(1234)
265+
.setSsl(true)
266+
.setKeyStoreOptions(Cert.SERVER_JKS.get()), true,
267+
VertxByteBufAllocator.POOLED_ALLOCATOR, PartialPooledByteBufAllocator.INSTANCE, false);
268+
}
269+
270+
private void testClientAllocator(HttpServerOptions options,
271+
boolean expectSSL,
272+
ByteBufAllocator expectedBufferAllocator,
273+
ByteBufAllocator expectedChannelAllocator,
274+
boolean expectHeapBuffer) throws Exception {
275+
waitFor(2);
276+
HttpServer server = vertx.createHttpServer(options);
277+
server.requestHandler(req -> {
278+
req.response().end("Hello World"); });
279+
CountDownLatch latch = new CountDownLatch(1);
280+
server.listen(onSuccess(v -> {
281+
latch.countDown();
282+
}));
283+
awaitLatch(latch);
284+
client.connect(1234, "localhost", onSuccess(so -> {
285+
NetSocketInternal soInt = (NetSocketInternal) so;
286+
assertEquals(expectSSL, soInt.isSsl());
287+
ChannelHandlerContext chctx = soInt.channelHandlerContext();
288+
ChannelPipeline pipeline = chctx.pipeline();
289+
pipeline.addBefore("handler", "http", new HttpClientCodec());
290+
// add a new handler which feeds the raw buffer to the http handler: this should receive the buffer
291+
// from the SSL handler, if configured
292+
pipeline.addBefore("http", "raw", new io.netty.channel.ChannelInboundHandlerAdapter() {
293+
@Override
294+
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
295+
assertTrue(msg instanceof ByteBuf);
296+
ByteBuf byteBuf = (ByteBuf) msg;
297+
assertSame(expectedBufferAllocator, byteBuf.alloc());
298+
assertSame(expectedChannelAllocator, ctx.channel().config().getAllocator());
299+
assertTrue(expectHeapBuffer == byteBuf.hasArray());
300+
super.channelRead(ctx, msg);
301+
complete();
302+
}
303+
});
304+
soInt.handler(buff -> fail());
305+
soInt.writeMessage(new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/somepath"), onSuccess(v -> complete()));
306+
}));
307+
await();
308+
}
309+
310+
protected void startServer(SocketAddress remoteAddress) throws Exception {
311+
startServer(remoteAddress, vertx.getOrCreateContext());
312+
}
313+
314+
protected void startServer(SocketAddress remoteAddress, Context context) throws Exception {
315+
startServer(remoteAddress, context, server);
316+
}
317+
318+
protected void startServer(SocketAddress remoteAddress, Context context, NetServer server) throws Exception {
319+
CountDownLatch latch = new CountDownLatch(1);
320+
context.runOnContext(v -> {
321+
server.listen(remoteAddress, onSuccess(s -> latch.countDown()));
322+
});
323+
awaitLatch(latch);
324+
}
325+
326+
protected void startServer() throws Exception {
327+
startServer(testAddress, vertx.getOrCreateContext());
328+
}
329+
330+
protected void startServer(NetServer server) throws Exception {
331+
startServer(testAddress, vertx.getOrCreateContext(), server);
332+
}
333+
334+
protected void startServer(Context context) throws Exception {
335+
startServer(testAddress, context, server);
336+
}
337+
338+
protected void startServer(Context context, NetServer server) throws Exception {
339+
startServer(testAddress, context, server);
340+
}
341+
}

0 commit comments

Comments
 (0)