Skip to content

Commit

Permalink
Verify that all graceful closure use-cases also work with HTTP/2 (#1180)
Browse files Browse the repository at this point in the history
Motivation:

`GracefulConnectionClosureHandlingTest` provides a comprehensive testing
for graceful closure with HTTP/1. We need to make sure, the same cases
work correctly when users switch to HTTP/2.

Modifications:

- Add `HttpProtocol` parameter for `GracefulConnectionClosureHandlingTest`;

Result:

All use-cases of `GracefulConnectionClosureHandlingTest` are tested with
HTTP/1.x and HTTP/2.
  • Loading branch information
idelpivnitskiy authored Oct 15, 2020
1 parent ca407b0 commit 5b0e4ec
Showing 1 changed file with 34 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
import java.io.IOException;
import java.net.SocketAddress;
import java.nio.channels.ClosedChannelException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
Expand All @@ -71,6 +72,7 @@
import static io.servicetalk.http.api.HttpResponseStatus.OK;
import static io.servicetalk.http.api.HttpSerializationProviders.textSerializer;
import static io.servicetalk.http.api.Matchers.contentEqualTo;
import static io.servicetalk.http.netty.HttpProtocol.HTTP_2;
import static io.servicetalk.http.netty.HttpsProxyTest.safeClose;
import static io.servicetalk.transport.netty.internal.AddressUtils.localAddress;
import static io.servicetalk.transport.netty.internal.AddressUtils.newSocketAddress;
Expand All @@ -95,6 +97,8 @@
@RunWith(Parameterized.class)
public class GracefulConnectionClosureHandlingTest {

private static final Collection<Boolean> TRUE_FALSE = asList(true, false);

@ClassRule
public static final ExecutionContextRule SERVER_CTX = cached("server-io", "server-executor");
@ClassRule
Expand All @@ -106,6 +110,7 @@ public class GracefulConnectionClosureHandlingTest {
@Rule
public final ServiceTalkTestTimeout timeout = new ServiceTalkTestTimeout();

private final HttpProtocol protocol;
private final boolean initiateClosureFromClient;
private final AsyncCloseable toClose;
private final CountDownLatch onClosing = new CountDownLatch(1);
Expand All @@ -125,8 +130,9 @@ public class GracefulConnectionClosureHandlingTest {
private final CountDownLatch serverSendResponse = new CountDownLatch(1);
private final CountDownLatch serverSendResponsePayload = new CountDownLatch(1);

public GracefulConnectionClosureHandlingTest(boolean initiateClosureFromClient, boolean useUds,
boolean viaProxy) throws Exception {
public GracefulConnectionClosureHandlingTest(HttpProtocol protocol, boolean initiateClosureFromClient,
boolean useUds, boolean viaProxy) throws Exception {
this.protocol = protocol;
this.initiateClosureFromClient = initiateClosureFromClient;

if (useUds) {
Expand All @@ -136,18 +142,20 @@ public GracefulConnectionClosureHandlingTest(boolean initiateClosureFromClient,
CLIENT_CTX.ioExecutor().isUnixDomainSocketSupported());
assumeFalse("UDS cannot be used via proxy", viaProxy);
}
assumeFalse("Proxy is not supported with HTTP/2", protocol == HTTP_2 && viaProxy);

HttpServerBuilder serverBuilder = (useUds ?
HttpServers.forAddress(newSocketAddress()) :
HttpServers.forAddress(localAddress(0)))
.protocols(protocol.config)
.ioExecutor(SERVER_CTX.ioExecutor())
.executionStrategy(defaultStrategy(SERVER_CTX.executor()))
.enableWireLogging("servicetalk-tests-wire-logger")
.appendConnectionAcceptorFilter(original -> new DelegatingConnectionAcceptor(original) {
@Override
public Completable accept(final ConnectionContext context) {
if (!initiateClosureFromClient) {
((NettyHttpServer.NettyHttpServerConnection) context).onClosing()
((NettyConnectionContext) context).onClosing()
.whenFinally(onClosing::countDown).subscribe();
}
context.onClose().whenFinally(serverConnectionClosed::countDown).subscribe();
Expand Down Expand Up @@ -194,6 +202,7 @@ public Completable accept(final ConnectionContext context) {
.trustManager(DefaultTestCerts::loadServerCAPem)
.commit() :
HttpClients.forResolvedAddress(serverContext.listenAddress()))
.protocols(protocol.config)
.ioExecutor(CLIENT_CTX.ioExecutor())
.executionStrategy(defaultStrategy(CLIENT_CTX.executor()))
.enableWireLogging("servicetalk-tests-wire-logger")
Expand All @@ -206,15 +215,24 @@ public Completable accept(final ConnectionContext context) {
toClose = initiateClosureFromClient ? connection : serverContext;
}

@Parameters(name = "initiateClosureFromClient={0} useUds={1} viaProxy={2}")
public static Collection<Boolean[]> data() {
return asList(
new Boolean[] {false, false, false},
new Boolean[] {false, false, true},
new Boolean[] {false, true, false},
new Boolean[] {true, false, false},
new Boolean[] {true, false, true},
new Boolean[] {true, true, false});
@Parameters(name = "{index}: protocol={0} initiateClosureFromClient={1} useUds={2} viaProxy={3}")
public static Collection<Object[]> data() {
Collection<Object[]> data = new ArrayList<>();
for (HttpProtocol protocol : HttpProtocol.values()) {
for (boolean initiateClosureFromClient : TRUE_FALSE) {
for (boolean useUds : TRUE_FALSE) {
for (boolean viaProxy : TRUE_FALSE) {
if (viaProxy && (useUds || protocol == HTTP_2)) {
// UDS cannot be used via proxy
// Proxy is not supported with HTTP/2
continue;
}
data.add(new Object[] {protocol, initiateClosureFromClient, useUds, viaProxy});
}
}
}
}
return data;
}

@After
Expand Down Expand Up @@ -476,6 +494,10 @@ private void assertClosedChannelException(ThrowingRunnable runnable, CloseEvent
Exception e = assertThrows(ExecutionException.class, runnable);
Throwable cause = e.getCause();
assertThat(cause, instanceOf(ClosedChannelException.class));
if (protocol == HTTP_2) {
// HTTP/2 does not enhance ClosedChannelException with CloseEvent
return;
}
while (cause != null && !(cause instanceof CloseEventObservedException)) {
cause = cause.getCause();
}
Expand Down

0 comments on commit 5b0e4ec

Please sign in to comment.