Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

7097 flaky HTTP/2 bookstore test #7137

Merged
merged 1 commit into from
Jun 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 21 additions & 13 deletions tests/apps/bookstore/bookstore-se/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@
<artifactId>helidon-tests-apps-bookstore-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.helidon.nima.testing.junit5
</groupId>
<artifactId>helidon-nima-testing-junit5-webserver</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
Expand All @@ -101,12 +107,6 @@
<artifactId>hamcrest-all</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.14.1</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand All @@ -128,13 +128,21 @@
<compilerArg>--enable-preview</compilerArg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>--enable-preview</argLine>
</configuration>
<executions>
<execution>
<id>default-testCompile</id>
<configuration>
<!--
We use HTTP client from tests, and we do not want it as a module dependency
-->
<compilerArgs>
<compilerArg>--enable-preview</compilerArg>
<compilerArg>--add-modules</compilerArg>
<compilerArg>java.net.http</compilerArg>
</compilerArgs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,29 +73,31 @@ static WebServer startServer() {
* @return the created {@link WebServer} instance
*/
static WebServer startServer(boolean ssl, boolean http2, boolean compression) {
WebServerConfig.Builder serverBuilder = WebServerConfig.builder();
setupServer(serverBuilder, ssl);

WebServer server = serverBuilder.build();
server.start();
String url = (ssl ? "https" : "http") + "://localhost:" + server.port() + SERVICE_PATH;
System.out.println("WEB server is up! " + url + " [ssl=" + ssl + ", http2=" + http2
+ ", compression=" + compression + "]");

return server;
}

static void setupServer(WebServerConfig.Builder serverBuilder, boolean ssl) {
// load logging configuration
LogConfig.configureRuntime();

// By default this will pick up application.yaml from the classpath
Config config = Config.create();

// Build server config based on params
var serverBuilder = WebServer.builder()
serverBuilder
.addRouting(createRouting(config))
.config(config.get("server"))
.update(it -> configureJsonSupport(it, config))
.update(it -> configureSsl(it, ssl));
// .enableCompression(compression);

configureJsonSupport(serverBuilder, config);

WebServer server = serverBuilder.build();
server.start();
String url = (ssl ? "https" : "http") + "://localhost:" + server.port() + SERVICE_PATH;
System.out.println("WEB server is up! " + url + " [ssl=" + ssl + ", http2=" + http2
+ ", compression=" + compression + "]");

return server;
}

static JsonLibrary getJsonLibrary(Config config) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ app:
json-library: jsonp

server:
port: 8080
# Random port
port: -1
host: 0.0.0.0

# ssl:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ java.util.logging.SimpleFormatter.format=%1$tY.%1$tm.%1$td %1$tH:%1$tM:%1$tS %4$
#io.helidon.config.level=INFO
#io.helidon.security.level=INFO
#io.helidon.common.level=INFO
#io.netty.level=INFO
#io.helidon.nima.level=ALL
Original file line number Diff line number Diff line change
Expand Up @@ -16,48 +16,51 @@

package io.helidon.tests.apps.bookstore.se;

import io.helidon.common.configurable.ThreadPoolSupplier;
import io.helidon.nima.testing.junit5.webserver.ServerTest;
import io.helidon.nima.testing.junit5.webserver.SetUpServer;
import io.helidon.nima.webserver.WebServer;
import io.helidon.nima.webserver.WebServerConfig;
import org.junit.jupiter.api.Test;

import javax.net.ssl.SSLContext;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

import io.helidon.common.configurable.ThreadPoolSupplier;

import io.helidon.nima.webserver.WebServer;
import okhttp3.OkHttpClient;
import okhttp3.Protocol;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

import static io.helidon.tests.apps.bookstore.se.TestServer.APPLICATION_JSON;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.fail;

/**
* Tests SSL/TLS with HTTP 2 upgrades and compression.
*/
@Disabled("https://github.com/helidon-io/helidon/issues/7097")
@ServerTest
public class Http2SslTest {

private static WebServer webServer;
private static OkHttpClient client;

@BeforeAll
public static void startServer() throws Exception {
webServer = TestServer.start(true, true, true);
client = TestServer.newOkHttpClient(true, true);
private static HttpClient client;
private final URI baseSslUri;

public Http2SslTest(WebServer server) throws Exception {
SSLContext sslContext = TestServer.setupSSLTrust();
baseSslUri = URI.create("https://localhost:" + server.port());
client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.sslContext(sslContext)
.connectTimeout(Duration.ofSeconds(5))
.build();
}

@AfterAll
public static void stopServer() throws Exception {
TestServer.stop(webServer);
@SetUpServer
static void server(WebServerConfig.Builder server) {
Main.setupServer(server, true);
}

@Test
Expand All @@ -72,74 +75,110 @@ public void testHelloWorldHttp2SslCompression() throws Exception {

@Test
public void testHelloWorldHttp2SslPostFirst() throws Exception {
Request.Builder builder = TestServer.newRequestBuilder(webServer, "/books", true);
Request postBook = builder.post(
RequestBody.create(APPLICATION_JSON, TestServer.getBookAsJson())).build();
try (Response postBookRes = client.newCall(postBook).execute()) {
assertThat(postBookRes.code(), is(200));
assertThat(postBookRes.protocol(), is(Protocol.HTTP_2));
}

builder = TestServer.newRequestBuilder(webServer, "/books/123456", true);
Request deleteBook = builder.delete().build();
try (Response deleteBookRes = client.newCall(deleteBook).execute()) {
assertThat(deleteBookRes.code(), is(200));
assertThat(deleteBookRes.protocol(), is(Protocol.HTTP_2));
}
HttpRequest postBookReq = HttpRequest.newBuilder()
.uri(baseSslUri.resolve("/books"))
.version(HttpClient.Version.HTTP_2)
.setHeader("Accept-Encoding", "gzip")
.POST(HttpRequest.BodyPublishers.ofString(TestServer.getBookAsJson()))
.build();

var postBookRes = client.send(postBookReq, HttpResponse.BodyHandlers.ofString());
assertThat(postBookRes.statusCode(), is(200));
assertThat(postBookRes.version(), is(HttpClient.Version.HTTP_2));

HttpRequest deleteBookReq = HttpRequest.newBuilder()
.uri(baseSslUri.resolve("/books/123456"))
.version(HttpClient.Version.HTTP_2)
.setHeader("Accept-Encoding", "gzip")
.DELETE()
.build();

var deleteBookRes = client.send(deleteBookReq, HttpResponse.BodyHandlers.ofString());
assertThat(deleteBookRes.statusCode(), is(200));
assertThat(deleteBookRes.version(), is(HttpClient.Version.HTTP_2));

}

@Test
public void testHelloWorldHttp2SslConcurrent() throws Exception {
ExecutorService executor = ThreadPoolSupplier.create("test-thread-pool").get();
Request.Builder builder = TestServer.newRequestBuilder(webServer, "/books", true);
Request getBooks = builder.build();

List<Callable<Response>> tasks = Collections.nCopies(10, () -> client.newCall(getBooks).execute());
HttpRequest getBookReq = HttpRequest.newBuilder()
.uri(baseSslUri.resolve("/books"))
.version(HttpClient.Version.HTTP_2)
.setHeader("Accept-Encoding", "gzip")
.GET()
.build();

List<Callable<HttpResponse<String>>> tasks =
Collections.nCopies(10, () -> client.send(getBookReq, HttpResponse.BodyHandlers.ofString()));
executor.invokeAll(tasks).forEach(f -> {
try {
Response r = f.get(1, TimeUnit.SECONDS);
assertThat(r.code(), is(200));
assertThat(r.protocol(), is(Protocol.HTTP_2));
HttpResponse<String> r = f.get(1, TimeUnit.SECONDS);
assertThat(r.statusCode(), is(200));
assertThat(r.version(), is(HttpClient.Version.HTTP_2));
} catch (Exception e) {
fail(e);
}
});
}

private void testHelloWorld(boolean compression) throws Exception {
Request.Builder builder = TestServer.newRequestBuilder(webServer, "/books", true, compression);

Request getBooks = builder.build();
try (Response getBooksRes = client.newCall(getBooks).execute()) {
assertThat(getBooksRes.code(), is(200));
assertThat(getBooksRes.protocol(), is(Protocol.HTTP_2));
}

Request postBook = builder.post(
RequestBody.create(APPLICATION_JSON, TestServer.getBookAsJson())).build();
try (Response postBookRes = client.newCall(postBook).execute()) {
assertThat(postBookRes.code(), is(200));
assertThat(postBookRes.protocol(), is(Protocol.HTTP_2));
}

builder = TestServer.newRequestBuilder(webServer, "/books/123456", true, compression);
Request getBook = builder.build();
try (Response getBookRes = client.newCall(getBook).execute()) {
assertThat(getBookRes.code(), is(200));
assertThat(getBookRes.protocol(), is(Protocol.HTTP_2));
}

Request deleteBook = builder.delete().build();
try (Response deleteBookRes = client.newCall(deleteBook).execute()) {
assertThat(deleteBookRes.code(), is(200));
assertThat(deleteBookRes.protocol(), is(Protocol.HTTP_2));

}

Request getNoBook = builder.build();
try (Response getNoBookRes = client.newCall(getNoBook).execute()) {
assertThat(getNoBookRes.code(), is(404));
assertThat(getNoBookRes.protocol(), is(Protocol.HTTP_2));
}
HttpRequest getBooksReq = HttpRequest.newBuilder()
.uri(baseSslUri.resolve("/books"))
.version(HttpClient.Version.HTTP_2)
.setHeader("Accept-Encoding", compression ? "gzip" : "none")
.GET()
.build();

var getBooksRes = client.send(getBooksReq, HttpResponse.BodyHandlers.ofString());
assertThat(getBooksRes.statusCode(), is(200));
assertThat(getBooksRes.version(), is(HttpClient.Version.HTTP_2));

HttpRequest postBookReq = HttpRequest.newBuilder()
.uri(baseSslUri.resolve("/books"))
.version(HttpClient.Version.HTTP_2)
.setHeader("Accept-Encoding", compression ? "gzip" : "none")
.POST(HttpRequest.BodyPublishers.ofString(TestServer.getBookAsJson()))
.build();

var postBookRes = client.send(postBookReq, HttpResponse.BodyHandlers.ofString());
assertThat(postBookRes.statusCode(), is(200));
assertThat(postBookRes.version(), is(HttpClient.Version.HTTP_2));

HttpRequest getBookReq = HttpRequest.newBuilder()
.uri(baseSslUri.resolve("/books/123456"))
.version(HttpClient.Version.HTTP_2)
.setHeader("Accept-Encoding", compression ? "gzip" : "none")
.GET()
.build();

var getBookRes = client.send(getBookReq, HttpResponse.BodyHandlers.ofString());

assertThat(getBookRes.statusCode(), is(200));
assertThat(getBookRes.version(), is(HttpClient.Version.HTTP_2));

HttpRequest deleteBookReq = HttpRequest.newBuilder()
.uri(baseSslUri.resolve("/books/123456"))
.version(HttpClient.Version.HTTP_2)
.setHeader("Accept-Encoding", compression ? "gzip" : "none")
.DELETE()
.build();

var deleteBookRes = client.send(deleteBookReq, HttpResponse.BodyHandlers.ofString());
assertThat(deleteBookRes.statusCode(), is(200));
assertThat(deleteBookRes.version(), is(HttpClient.Version.HTTP_2));

HttpRequest getNoBookReq = HttpRequest.newBuilder()
.uri(baseSslUri.resolve("/books/123456"))
.version(HttpClient.Version.HTTP_2)
.setHeader("Accept-Encoding", compression ? "gzip" : "none")
.GET()
.build();

var getNoBookRes = client.send(getNoBookReq, HttpResponse.BodyHandlers.ofString());

assertThat(getNoBookRes.statusCode(), is(404));
assertThat(getNoBookRes.version(), is(HttpClient.Version.HTTP_2));
}
}
Loading