diff options
author | Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> | 2024-01-25 14:45:09 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2024-01-25 14:45:09 +0000 |
commit | 6504e0dcd738d936ee015728dc407b49c45e3a0e (patch) | |
tree | 184c4a9631d9d541b959adf0a88a2a4b8ef2c551 | |
parent | 6466005e07ca8bad8edaee6bed6864524874c0ee (diff) | |
parent | 64599586d3a5fff1723424825f155b37f9ed630a (diff) | |
download | cronet-6504e0dcd738d936ee015728dc407b49c45e3a0e.tar.gz |
Merge "Cherry-pick crrev/c/5233108" into main am: 64599586d3
Original change: https://android-review.googlesource.com/c/platform/external/cronet/+/2924362
Change-Id: Iaa0afb5857adbc9120cd0a23a59169a53664a3a9
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r-- | components/cronet/android/test/src/org/chromium/net/Http2TestServer.java | 162 |
1 files changed, 81 insertions, 81 deletions
diff --git a/components/cronet/android/test/src/org/chromium/net/Http2TestServer.java b/components/cronet/android/test/src/org/chromium/net/Http2TestServer.java index 3bdfc2066..38a076dfc 100644 --- a/components/cronet/android/test/src/org/chromium/net/Http2TestServer.java +++ b/components/cronet/android/test/src/org/chromium/net/Http2TestServer.java @@ -6,13 +6,15 @@ package org.chromium.net; import android.content.Context; import android.os.Build; -import android.os.ConditionVariable; import org.chromium.base.Log; import org.chromium.net.test.util.CertTestUtil; import java.io.File; +import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; @@ -36,9 +38,7 @@ import io.netty.handler.ssl.OpenSslServerContext; import io.netty.handler.ssl.SslContext; import io.netty.handler.ssl.SupportedCipherSuiteFilter; -/** - * Wrapper class to start a HTTP/2 test server. - */ +/** Wrapper class to start a HTTP/2 test server. */ public final class Http2TestServer { private static Channel sServerChannel; private static final String TAG = Http2TestServer.class.getSimpleName(); @@ -51,6 +51,8 @@ public final class Http2TestServer { public static final String SERVER_CERT_PEM; private static final String SERVER_KEY_PKCS8_PEM; + // Used to start http2 test server. + private static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(1); static { // TODO(crbug/1490552): Fallback to MockCertVerifier when custom CAs are not supported. @@ -113,44 +115,32 @@ public final class Http2TestServer { return getServerUrl() + Http2TestHandler.HANGING_REQUEST_PATH; } - /** - * @return url of the server resource which will echo every received stream data frame. - */ + /** @return url of the server resource which will echo every received stream data frame. */ public static String getEchoStreamUrl() { return getServerUrl() + Http2TestHandler.ECHO_STREAM_PATH; } - /** - * @return url of the server resource which will echo request headers as response trailers. - */ + /** @return url of the server resource which will echo request headers as response trailers. */ public static String getEchoTrailersUrl() { return getServerUrl() + Http2TestHandler.ECHO_TRAILERS_PATH; } - /** - * @return url of a brotli-encoded server resource. - */ + /** @return url of a brotli-encoded server resource. */ public static String getServeSimpleBrotliResponse() { return getServerUrl() + Http2TestHandler.SERVE_SIMPLE_BROTLI_RESPONSE; } - /** - * @return url of the reporting collector - */ + /** @return url of the reporting collector */ public static String getReportingCollectorUrl() { return getServerUrl() + Http2TestHandler.REPORTING_COLLECTOR_PATH; } - /** - * @return url of a resource that includes Reporting and NEL policy headers in its response - */ + /** @return url of a resource that includes Reporting and NEL policy headers in its response */ public static String getSuccessWithNELHeadersUrl() { return getServerUrl() + Http2TestHandler.SUCCESS_WITH_NEL_HEADERS_PATH; } - /** - * @return url of a resource that sends response headers with the same key - */ + /** @return url of a resource that sends response headers with the same key */ public static String getCombinedHeadersUrl() { return getServerUrl() + Http2TestHandler.COMBINED_HEADERS_PATH; } @@ -161,90 +151,96 @@ public final class Http2TestServer { } public static boolean startHttp2TestServer(Context context, CountDownLatch hangingUrlLatch) - throws Exception { + throws Exception { TestFilesInstaller.installIfNeeded(context); return startHttp2TestServer( - context, SERVER_CERT_PEM, SERVER_KEY_PKCS8_PEM, hangingUrlLatch); + context, SERVER_CERT_PEM, SERVER_KEY_PKCS8_PEM, hangingUrlLatch); } - private static boolean startHttp2TestServer(Context context, String certFileName, - String keyFileName, CountDownLatch hangingUrlLatch) throws Exception { + private static boolean startHttp2TestServer( + Context context, + String certFileName, + String keyFileName, + CountDownLatch hangingUrlLatch) + throws Exception { sReportingCollector = new ReportingCollector(); Http2TestServerRunnable http2TestServerRunnable = - new Http2TestServerRunnable(new File(CertTestUtil.CERTS_DIRECTORY + certFileName), - new File(CertTestUtil.CERTS_DIRECTORY + keyFileName), hangingUrlLatch); - new Thread(http2TestServerRunnable).start(); - http2TestServerRunnable.blockUntilStarted(); - return true; + new Http2TestServerRunnable( + new File(CertTestUtil.CERTS_DIRECTORY + certFileName), + new File(CertTestUtil.CERTS_DIRECTORY + keyFileName), + hangingUrlLatch); + // This will run synchronously as we can't run the test before we have + // started the test-server, if the test-server has failed to start then + // the caller should assert on the value returned to make sure that the test + // fails if the server has failed to start up. + return EXECUTOR.submit(http2TestServerRunnable).get(); } private Http2TestServer() {} - private static class Http2TestServerRunnable implements Runnable { - private final ConditionVariable mBlock = new ConditionVariable(); + private static class Http2TestServerRunnable implements Callable<Boolean> { private final SslContext mSslCtx; private final CountDownLatch mHangingUrlLatch; Http2TestServerRunnable(File certFile, File keyFile, CountDownLatch hangingUrlLatch) - throws Exception { - ApplicationProtocolConfig applicationProtocolConfig = new ApplicationProtocolConfig( + throws Exception { + ApplicationProtocolConfig applicationProtocolConfig = + new ApplicationProtocolConfig( Protocol.ALPN, SelectorFailureBehavior.NO_ADVERTISE, - SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2); + SelectedListenerFailureBehavior.ACCEPT, + ApplicationProtocolNames.HTTP_2); // Don't make netty use java.security.KeyStore.getInstance("JKS") as it doesn't // exist. Just avoid a KeyManagerFactory as it's unnecessary for our testing. System.setProperty("io.netty.handler.ssl.openssl.useKeyManagerFactory", "false"); - mSslCtx = new OpenSslServerContext(certFile, keyFile, null, null, - Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE, - applicationProtocolConfig, 0, 0); + mSslCtx = + new OpenSslServerContext( + certFile, + keyFile, + null, + null, + Http2SecurityUtil.CIPHERS, + SupportedCipherSuiteFilter.INSTANCE, + applicationProtocolConfig, + 0, + 0); mHangingUrlLatch = hangingUrlLatch; } - public void blockUntilStarted() { - mBlock.block(); - } - @Override - public void run() { - boolean retry = false; - do { + public Boolean call() throws Exception { + for(int retries = 0; retries < 10; retries++) { try { // Configure the server. EventLoopGroup group = new NioEventLoopGroup(); - try { - ServerBootstrap b = new ServerBootstrap(); - b.option(ChannelOption.SO_BACKLOG, 1024); - b.group(group) - .channel(NioServerSocketChannel.class) - .handler(new LoggingHandler(LogLevel.INFO)) - .childHandler( - new Http2ServerInitializer(mSslCtx, mHangingUrlLatch)); - - sServerChannel = b.bind(PORT).sync().channel(); - Log.i(TAG, "Netty HTTP/2 server started on " + getServerUrl()); - mBlock.open(); - sServerChannel.closeFuture().sync(); - } finally { - group.shutdownGracefully(); - } - Log.i(TAG, "Stopped Http2TestServerRunnable!"); - retry = false; + ServerBootstrap b = new ServerBootstrap(); + b.option(ChannelOption.SO_BACKLOG, 1024); + b.group(group) + .channel(NioServerSocketChannel.class) + .handler(new LoggingHandler(LogLevel.INFO)) + .childHandler(new Http2ServerInitializer(mSslCtx, mHangingUrlLatch)); + + sServerChannel = b.bind(PORT).sync().channel(); + Log.i(TAG, "Netty HTTP/2 server started on " + getServerUrl()); + return true; } catch (Exception e) { - Log.e(TAG, "Netty server failed to start", e); - // Retry once if we hit https://github.com/netty/netty/issues/2616 before the - // server starts. - retry = !retry && sServerChannel == null - && e.toString().contains("java.nio.channels.ClosedChannelException"); + // Netty test server fails to startup and this is a common issue + // https://github.com/netty/netty/issues/2616. It is not well understood + // why this is happening or how to fix it, we can workaround this by + // trying to restart the server several times before giving up. + // See crbug/1519471 for more information. + Log.w(TAG, "Netty server failed to start", e); + // Sleep for half a second before trying again. + Thread.sleep(/* milliseconds = */ 500); } - } while (retry); + } + return false; } } - /** - * Sets up the Netty pipeline for the test server. - */ + /** Sets up the Netty pipeline for the test server. */ private static class Http2ServerInitializer extends ChannelInitializer<SocketChannel> { private final SslContext mSslCtx; private final CountDownLatch mHangingUrlLatch; @@ -256,8 +252,10 @@ public final class Http2TestServer { @Override public void initChannel(SocketChannel ch) { - ch.pipeline().addLast( - mSslCtx.newHandler(ch.alloc()), new Http2NegotiationHandler(mHangingUrlLatch)); + ch.pipeline() + .addLast( + mSslCtx.newHandler(ch.alloc()), + new Http2NegotiationHandler(mHangingUrlLatch)); } } @@ -271,13 +269,15 @@ public final class Http2TestServer { @Override protected void configurePipeline(ChannelHandlerContext ctx, String protocol) - throws Exception { + throws Exception { if (ApplicationProtocolNames.HTTP_2.equals(protocol)) { - ctx.pipeline().addLast(new Http2TestHandler.Builder() - .setReportingCollector(sReportingCollector) - .setServerUrl(getServerUrl()) - .setHangingUrlLatch(mHangingUrlLatch) - .build()); + ctx.pipeline() + .addLast( + new Http2TestHandler.Builder() + .setReportingCollector(sReportingCollector) + .setServerUrl(getServerUrl()) + .setHangingUrlLatch(mHangingUrlLatch) + .build()); return; } |