diff options
author | Bjørn Christian Seime <bjorncs@verizonmedia.com> | 2021-04-23 15:18:00 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-23 15:18:00 +0200 |
commit | 75880a3716c3c34951811f0d8515cda4c6a2bf23 (patch) | |
tree | 31ee02ae8fbd9bd4f8bfcea4d75536744267fc63 | |
parent | 808df548a06fe642e752dd23973044756157b268 (diff) | |
parent | 83efef08ca194f08c2f40f397c6d95adac54ee03 (diff) |
Merge pull request #17563 from vespa-engine/bjorncs/restapi-test-driver
Bjorncs/restapi test driver
21 files changed, 616 insertions, 419 deletions
diff --git a/container-core/abi-spec.json b/container-core/abi-spec.json index 9b139aacf3f..5e4033c22a7 100644 --- a/container-core/abi-spec.json +++ b/container-core/abi-spec.json @@ -654,6 +654,23 @@ ], "fields": [] }, + "com.yahoo.container.jdisc.HttpRequestBuilder": { + "superClass": "java.lang.Object", + "interfaces": [], + "attributes": [ + "public" + ], + "methods": [ + "public static com.yahoo.container.jdisc.HttpRequestBuilder create(com.yahoo.jdisc.http.HttpRequest$Method, java.lang.String)", + "public com.yahoo.container.jdisc.HttpRequestBuilder withQueryParameter(java.lang.String, java.lang.String)", + "public com.yahoo.container.jdisc.HttpRequestBuilder withHeader(java.lang.String, java.lang.String)", + "public com.yahoo.container.jdisc.HttpRequestBuilder withRequestContent(java.io.InputStream)", + "public com.yahoo.container.jdisc.HttpRequestBuilder withScheme(java.lang.String)", + "public com.yahoo.container.jdisc.HttpRequestBuilder withHostname(java.lang.String)", + "public com.yahoo.container.jdisc.HttpRequest build()" + ], + "fields": [] + }, "com.yahoo.container.jdisc.HttpRequestHandler": { "superClass": "java.lang.Object", "interfaces": [ diff --git a/container-core/src/main/java/com/yahoo/container/jdisc/HttpRequestBuilder.java b/container-core/src/main/java/com/yahoo/container/jdisc/HttpRequestBuilder.java new file mode 100644 index 00000000000..3f70f4b75bb --- /dev/null +++ b/container-core/src/main/java/com/yahoo/container/jdisc/HttpRequestBuilder.java @@ -0,0 +1,71 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.container.jdisc; + +import com.yahoo.jdisc.http.HttpRequest.Method; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; + +/** + * Builder for creating a {@link HttpRequest} to be used in test context + * + * @author bjorncs + */ +public class HttpRequestBuilder { + private final Method method; + private final String path; + private final Map<String, List<String>> queryParameters = new TreeMap<>(); + private final Map<String, String> headers = new TreeMap<>(); + private String scheme; + private String hostname; + private InputStream content; + + private HttpRequestBuilder(Method method, String path) { + this.method = method; + this.path = path; + } + + public static HttpRequestBuilder create(Method method, String path) { return new HttpRequestBuilder(method, path); } + + public HttpRequestBuilder withQueryParameter(String name, String value) { + this.queryParameters.computeIfAbsent(name, ignored -> new ArrayList<>()).add(value); + return this; + } + + public HttpRequestBuilder withHeader(String name, String value) { this.headers.put(name, value); return this; } + + public HttpRequestBuilder withRequestContent(InputStream content) { this.content = content; return this; } + + public HttpRequestBuilder withScheme(String scheme) { this.scheme = scheme; return this; } + + public HttpRequestBuilder withHostname(String hostname) { this.hostname = hostname; return this; } + + public HttpRequest build() { + String scheme = this.scheme != null ? this.scheme : "http"; + String hostname = this.hostname != null ? this.hostname : "localhost"; + StringBuilder uriBuilder = new StringBuilder(scheme).append("://").append(hostname).append(path); + if (queryParameters.size() > 0) { + uriBuilder.append('?'); + queryParameters.forEach((name, values) -> { + for (String value : values) { + uriBuilder.append(name).append('=').append(value).append('&'); + } + }); + int lastIndex = uriBuilder.length() - 1; + if (uriBuilder.charAt(lastIndex) == '&') { + uriBuilder.setLength(lastIndex); + } + } + HttpRequest request; + if (content != null) { + request = HttpRequest.createTestRequest(uriBuilder.toString(), method, content); + } else { + request = HttpRequest.createTestRequest(uriBuilder.toString(), method); + } + headers.forEach((name, value) -> request.getJDiscRequest().headers().put(name, value)); + return request; + } +} diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/guiceModules/ConnectorFactoryRegistryModule.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/testutils/ConnectorFactoryRegistryModule.java index cc2a00c08c6..9d475309955 100644 --- a/container-core/src/test/java/com/yahoo/jdisc/http/guiceModules/ConnectorFactoryRegistryModule.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/testutils/ConnectorFactoryRegistryModule.java @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.guiceModules; +package com.yahoo.jdisc.http.server.jetty.testutils; import com.google.inject.Binder; import com.google.inject.Module; @@ -7,7 +7,6 @@ import com.google.inject.Provides; import com.yahoo.component.ComponentId; import com.yahoo.component.provider.ComponentRegistry; import com.yahoo.jdisc.http.ConnectorConfig; -import com.yahoo.jdisc.http.ConnectorConfig.Builder; import com.yahoo.jdisc.http.server.jetty.ConnectorFactory; import com.yahoo.jdisc.http.ssl.impl.ConfiguredSslContextFactoryProvider; @@ -19,29 +18,28 @@ import com.yahoo.jdisc.http.ssl.impl.ConfiguredSslContextFactoryProvider; */ public class ConnectorFactoryRegistryModule implements Module { - private final Builder connectorConfigBuilder; + private final ConnectorConfig config; - public ConnectorFactoryRegistryModule(Builder connectorConfigBuilder) { - this.connectorConfigBuilder = connectorConfigBuilder; + public ConnectorFactoryRegistryModule(ConnectorConfig config) { + this.config = config; } public ConnectorFactoryRegistryModule() { - this(new Builder()); + this(new ConnectorConfig(new ConnectorConfig.Builder())); } + @SuppressWarnings("unused") @Provides public ComponentRegistry<ConnectorFactory> connectorFactoryComponentRegistry() { ComponentRegistry<ConnectorFactory> registry = new ComponentRegistry<>(); registry.register(ComponentId.createAnonymousComponentId("connector-factory"), - new StaticKeyDbConnectorFactory(new ConnectorConfig(connectorConfigBuilder))); + new StaticKeyDbConnectorFactory(config)); registry.freeze(); return registry; } - @Override - public void configure(Binder binder) { - } + @Override public void configure(Binder binder) {} private static class StaticKeyDbConnectorFactory extends ConnectorFactory { diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/guiceModules/ServletModule.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/testutils/ServletModule.java index dd6511d1f88..a507255c9b7 100644 --- a/container-core/src/test/java/com/yahoo/jdisc/http/guiceModules/ServletModule.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/testutils/ServletModule.java @@ -1,5 +1,5 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.guiceModules; +package com.yahoo.jdisc.http.server.jetty.testutils; import com.google.inject.Binder; import com.google.inject.Module; @@ -12,13 +12,12 @@ import org.eclipse.jetty.servlet.ServletHolder; * @author Tony Vaagenes */ public class ServletModule implements Module { - @Override - public void configure(Binder binder) { - } + @SuppressWarnings("unused") @Provides public ComponentRegistry<ServletHolder> servletHolderComponentRegistry() { return new ComponentRegistry<>(); } + @Override public void configure(Binder binder) { } } diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/testutils/TestDriver.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/testutils/TestDriver.java new file mode 100644 index 00000000000..7f3d54f1d34 --- /dev/null +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/testutils/TestDriver.java @@ -0,0 +1,122 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.jdisc.http.server.jetty.testutils; + +import com.google.inject.AbstractModule; +import com.google.inject.Module; +import com.google.inject.util.Modules; +import com.yahoo.container.logging.ConnectionLog; +import com.yahoo.container.logging.RequestLog; +import com.yahoo.jdisc.application.ContainerBuilder; +import com.yahoo.jdisc.handler.RequestHandler; +import com.yahoo.jdisc.http.ConnectorConfig; +import com.yahoo.jdisc.http.ServerConfig; +import com.yahoo.jdisc.http.ServletPathsConfig; +import com.yahoo.jdisc.http.server.jetty.FilterBindings; +import com.yahoo.jdisc.http.server.jetty.JettyHttpServer; +import com.yahoo.jdisc.http.server.jetty.VoidConnectionLog; +import com.yahoo.jdisc.http.server.jetty.VoidRequestLog; +import com.yahoo.security.SslContextBuilder; + +import javax.net.ssl.SSLContext; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.SortedMap; +import java.util.TreeMap; + +/** + * A {@link com.yahoo.jdisc.test.TestDriver} that is configured with {@link JettyHttpServer}. + * + * @author bjorncs + */ +public class TestDriver implements AutoCloseable { + + private final com.yahoo.jdisc.test.TestDriver jdiscCoreTestDriver; + private final JettyHttpServer server; + private final SSLContext sslContext; + + private TestDriver(Builder builder) { + ServerConfig serverConfig = + builder.serverConfig != null ? builder.serverConfig : new ServerConfig(new ServerConfig.Builder()); + ConnectorConfig connectorConfig = + builder.connectorConfig != null ? builder.connectorConfig : new ConnectorConfig(new ConnectorConfig.Builder()); + Module baseModule = createBaseModule(serverConfig, connectorConfig); + Module combinedModule = + builder.extraGuiceModules.isEmpty() ? baseModule : Modules.override(baseModule).with(builder.extraGuiceModules); + com.yahoo.jdisc.test.TestDriver jdiscCoreTestDriver = + com.yahoo.jdisc.test.TestDriver.newSimpleApplicationInstance(combinedModule); + ContainerBuilder containerBuilder = jdiscCoreTestDriver.newContainerBuilder(); + JettyHttpServer server = containerBuilder.getInstance(JettyHttpServer.class); + containerBuilder.serverProviders().install(server); + builder.handlers.forEach((binding, handler) -> containerBuilder.serverBindings().bind(binding, handler)); + jdiscCoreTestDriver.activateContainer(containerBuilder); + server.start(); + this.jdiscCoreTestDriver = jdiscCoreTestDriver; + this.server = server; + this.sslContext = newSslContext(containerBuilder); + } + + public static Builder newBuilder() { return new Builder(); } + + public SSLContext sslContext() { return sslContext; } + public JettyHttpServer server() { return server; } + + @Override public void close() { shutdown(); } + + public boolean shutdown() { + server.close(); + server.release(); + return jdiscCoreTestDriver.close(); + } + + private static SSLContext newSslContext(ContainerBuilder builder) { + ConnectorConfig.Ssl sslConfig = builder.getInstance(ConnectorConfig.class).ssl(); + if (!sslConfig.enabled()) return null; + + return new SslContextBuilder() + .withKeyStore(Paths.get(sslConfig.privateKeyFile()), Paths.get(sslConfig.certificateFile())) + .withTrustStore(Paths.get(sslConfig.caCertificateFile())) + .build(); + } + + private static Module createBaseModule(ServerConfig serverConfig, ConnectorConfig connectorConfig) { + return Modules.combine( + new AbstractModule() { + @Override + protected void configure() { + bind(ServletPathsConfig.class).toInstance(new ServletPathsConfig(new ServletPathsConfig.Builder())); + bind(ServerConfig.class).toInstance(serverConfig); + bind(ConnectorConfig.class).toInstance(connectorConfig); + bind(FilterBindings.class).toInstance(new FilterBindings.Builder().build()); + bind(ConnectionLog.class).toInstance(new VoidConnectionLog()); + bind(RequestLog.class).toInstance(new VoidRequestLog()); + } + }, + new ConnectorFactoryRegistryModule(connectorConfig), + new ServletModule()); + } + + public static class Builder { + private final SortedMap<String, RequestHandler> handlers = new TreeMap<>(); + private final List<Module> extraGuiceModules = new ArrayList<>(); + private ServerConfig serverConfig; + private ConnectorConfig connectorConfig; + + private Builder() {} + + public Builder withRequestHandler(String binding, RequestHandler handler) { + this.handlers.put(binding, handler); return this; + } + + public Builder withRequestHandler(RequestHandler handler) { return withRequestHandler("http://*/*", handler); } + + public Builder withServerConfig(ServerConfig config) { this.serverConfig = config; return this; } + + public Builder withConnectorConfig(ConnectorConfig config) { this.connectorConfig = config; return this; } + + public Builder withGuiceModule(Module module) { this.extraGuiceModules.add(module); return this; } + + public TestDriver build() { return new TestDriver(this); } + + } +} diff --git a/container-core/src/main/java/com/yahoo/restapi/RestApiRequestHandler.java b/container-core/src/main/java/com/yahoo/restapi/RestApiRequestHandler.java index 5640bbc5445..c501ad8c804 100644 --- a/container-core/src/main/java/com/yahoo/restapi/RestApiRequestHandler.java +++ b/container-core/src/main/java/com/yahoo/restapi/RestApiRequestHandler.java @@ -4,6 +4,9 @@ package com.yahoo.restapi; import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.container.jdisc.HttpResponse; import com.yahoo.container.jdisc.LoggingRequestHandler; +import com.yahoo.jdisc.Metric; + +import java.util.concurrent.Executor; /** * @author bjorncs @@ -25,11 +28,25 @@ public abstract class RestApiRequestHandler<T extends RestApiRequestHandler<T>> this.restApi = provider.createRestApi((T)this); } + /** + * @see #RestApiRequestHandler(Context, RestApiProvider) + */ + @SuppressWarnings("unchecked") + protected RestApiRequestHandler(Executor executor, Metric metric, RestApiProvider<T> provider) { + super(executor, metric); + this.restApi = provider.createRestApi((T)this); + } + protected RestApiRequestHandler(LoggingRequestHandler.Context context, RestApi restApi) { super(context); this.restApi = restApi; } + protected RestApiRequestHandler(Executor executor, Metric metric, RestApi restApi) { + super(executor, metric); + this.restApi = restApi; + } + @Override public final HttpResponse handle(HttpRequest request) { return restApi.handleRequest(request); } public RestApi restApi() { return restApi; } diff --git a/container-core/src/main/java/com/yahoo/restapi/RestApiTestDriver.java b/container-core/src/main/java/com/yahoo/restapi/RestApiTestDriver.java new file mode 100644 index 00000000000..7dc5b710bbe --- /dev/null +++ b/container-core/src/main/java/com/yahoo/restapi/RestApiTestDriver.java @@ -0,0 +1,96 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.restapi; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.yahoo.container.jdisc.HttpRequest; +import com.yahoo.container.jdisc.HttpResponse; +import com.yahoo.container.jdisc.LoggingRequestHandler; +import com.yahoo.jdisc.http.server.jetty.testutils.TestDriver; +import com.yahoo.jdisc.test.MockMetric; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.OptionalInt; +import java.util.concurrent.Executors; + +import static com.yahoo.yolean.Exceptions.uncheck; + +/** + * Test driver for {@link RestApi} + * + * @author bjorncs + */ +public class RestApiTestDriver implements AutoCloseable { + + private final RestApiRequestHandler<?> handler; + private final TestDriver testDriver; + + private RestApiTestDriver(Builder builder) { + this.handler = builder.handler; + this.testDriver = builder.jdiscHttpServer ? TestDriver.newBuilder().withRequestHandler(builder.handler).build() : null; + } + + public static Builder newBuilder(RestApiRequestHandler<?> handler) { return new Builder(handler); } + + @FunctionalInterface public interface RestApiRequestHandlerFactory { RestApiRequestHandler<?> create(LoggingRequestHandler.Context context); } + public static Builder newBuilder(RestApiRequestHandlerFactory factory) { return new Builder(factory); } + + public static LoggingRequestHandler.Context createHandlerTestContext() { + return new LoggingRequestHandler.Context(Executors.newSingleThreadExecutor(), new MockMetric()); + } + + public OptionalInt listenPort() { + return testDriver != null ? OptionalInt.of(testDriver.server().getListenPort()) : OptionalInt.empty(); + } + + public RestApiRequestHandler<?> handler() { return handler; } + public RestApi restApi() { return handler.restApi(); } + public ObjectMapper jacksonJsonMapper() { return handler.restApi().jacksonJsonMapper(); } + + public HttpResponse executeRequest(HttpRequest request) { return handler.handle(request); } + + public InputStream requestContentOf(Object jacksonEntity) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + uncheck(() -> handler.restApi().jacksonJsonMapper().writeValue(out, jacksonEntity)); + return new ByteArrayInputStream(out.toByteArray()); + } + + public <T> T parseJacksonResponseContent(HttpResponse response, TypeReference<T> type) { + return uncheck(() -> handler.restApi().jacksonJsonMapper().readValue(responseData(response), type)); + } + + public <T> T parseJacksonResponseContent(HttpResponse response, Class<T> type) { + return uncheck(() -> handler.restApi().jacksonJsonMapper().readValue(responseData(response), type)); + } + + private static byte[] responseData(HttpResponse response) { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + uncheck(() -> response.render(out)); + return out.toByteArray(); + } + + @Override + public void close() throws Exception { + if (testDriver != null) { + testDriver.close(); + } + } + + public static class Builder { + private final RestApiRequestHandler<?> handler; + private boolean jdiscHttpServer = false; + + private Builder(RestApiRequestHandler<?> handler) { + this.handler = handler; + } + + private Builder(RestApiRequestHandlerFactory factory) { this(factory.create(createHandlerTestContext())); } + + public Builder withJdiscHttpServer() { this.jdiscHttpServer = true; return this; } + + public RestApiTestDriver build() { return new RestApiTestDriver(this); } + } + +} diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java index 01337dcc65d..43f722df3c9 100644 --- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java +++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/FilterTestCase.java @@ -28,9 +28,8 @@ import com.yahoo.jdisc.http.filter.ResponseFilter; import com.yahoo.jdisc.http.filter.ResponseHeaderFilter; import com.yahoo.jdisc.http.filter.chain.RequestFilterChain; import com.yahoo.jdisc.http.filter.chain.ResponseFilterChain; -import com.yahoo.jdisc.http.guiceModules.ConnectorFactoryRegistryModule; +import com.yahoo.jdisc.http.server.jetty.testutils.ConnectorFactoryRegistryModule; import org.assertj.core.api.Assertions; -import org.bouncycastle.cert.ocsp.Req; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -67,7 +66,7 @@ public class FilterTestCase { .addRequestFilterBinding("my-request-filter", "http://*/filtered/*") .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, filterBindings); + final JettyTestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html"); @@ -85,7 +84,7 @@ public class FilterTestCase { .addRequestFilterBinding("my-request-filter", "http://*/filtered/*") .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, filterBindings); + final JettyTestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/filtered/status.html"); @@ -103,7 +102,7 @@ public class FilterTestCase { .addRequestFilterBinding("my-request-filter", "http://*/*") .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, filterBindings); + final JettyTestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html"); @@ -120,7 +119,7 @@ public class FilterTestCase { .addRequestFilterBinding("my-request-filter", "http://*/*") .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, filterBindings); + final JettyTestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html").expectStatusCode(is(Response.Status.FORBIDDEN)); @@ -138,7 +137,7 @@ public class FilterTestCase { .addRequestFilterBinding("my-request-filter", "http://*/*") .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, filterBindings); + final JettyTestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html") .expectStatusCode(is(responseStatus)) @@ -156,7 +155,7 @@ public class FilterTestCase { .addRequestFilterBinding("my-request-filter", "http://*/*") .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, filterBindings); + final JettyTestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html").expectStatusCode(is(Response.Status.INTERNAL_SERVER_ERROR)); @@ -173,7 +172,7 @@ public class FilterTestCase { .addResponseFilterBinding("my-response-filter", "http://*/filtered/*") .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, filterBindings); + final JettyTestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html"); @@ -191,7 +190,7 @@ public class FilterTestCase { .addResponseFilterBinding("my-response-filter", "http://*/filtered/*") .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, filterBindings); + final JettyTestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/filtered/status.html"); @@ -208,7 +207,7 @@ public class FilterTestCase { .addResponseFilterBinding("my-response-filter", "http://*/*") .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, filterBindings); + final JettyTestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html") .expectHeader("foo", is("bar")); @@ -225,7 +224,7 @@ public class FilterTestCase { .addResponseFilterBinding("my-response-filter", "http://*/*") .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, filterBindings); + final JettyTestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html").expectStatusCode(is(Response.Status.INTERNAL_SERVER_ERROR)); @@ -246,7 +245,7 @@ public class FilterTestCase { .addResponseFilterBinding("my-response-filter", uriPattern) .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, filterBindings); + final JettyTestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html"); @@ -266,7 +265,7 @@ public class FilterTestCase { .addResponseFilterBinding("my-response-filter", "http://*/*") .build(); final MyRequestHandler requestHandler = new MyRequestHandler(); - final TestDriver testDriver = newDriver(requestHandler, filterBindings); + final JettyTestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html") .expectStatusCode(is(Response.Status.FORBIDDEN)) @@ -416,7 +415,7 @@ public class FilterTestCase { .setRequestFilterDefaultForPort(defaultFilterId, 0) .build(); MyRequestHandler requestHandler = new MyRequestHandler(); - TestDriver testDriver = newDriver(requestHandler, filterBindings); + JettyTestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html"); @@ -439,7 +438,7 @@ public class FilterTestCase { .setResponseFilterDefaultForPort(defaultFilterId, 0) .build(); MyRequestHandler requestHandler = new MyRequestHandler(); - TestDriver testDriver = newDriver(requestHandler, filterBindings); + JettyTestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/status.html"); @@ -462,7 +461,7 @@ public class FilterTestCase { .setRequestFilterDefaultForPort(defaultFilterId, 0) .build(); MyRequestHandler requestHandler = new MyRequestHandler(); - TestDriver testDriver = newDriver(requestHandler, filterBindings); + JettyTestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/filtered/status.html"); @@ -485,7 +484,7 @@ public class FilterTestCase { .setResponseFilterDefaultForPort(defaultFilterId, 0) .build(); MyRequestHandler requestHandler = new MyRequestHandler(); - TestDriver testDriver = newDriver(requestHandler, filterBindings); + JettyTestDriver testDriver = newDriver(requestHandler, filterBindings); testDriver.client().get("/filtered/status.html"); @@ -504,7 +503,7 @@ public class FilterTestCase { .build(); MetricConsumerMock metricConsumerMock = new MetricConsumerMock(); MyRequestHandler requestHandler = new MyRequestHandler(); - TestDriver testDriver = newDriver(requestHandler, filterBindings, metricConsumerMock, false); + JettyTestDriver testDriver = newDriver(requestHandler, filterBindings, metricConsumerMock, false); testDriver.client().get("/status.html"); assertThat(requestHandler.awaitInvocation(), is(true)); @@ -527,7 +526,7 @@ public class FilterTestCase { .addRequestFilterBinding("my-request-filter", "http://*/filtered/*") .build(); MyRequestHandler requestHandler = new MyRequestHandler(); - TestDriver testDriver = newDriver(requestHandler, filterBindings, new MetricConsumerMock(), true); + JettyTestDriver testDriver = newDriver(requestHandler, filterBindings, new MetricConsumerMock(), true); testDriver.client().get("/unfiltered/") .expectStatusCode(is(Response.Status.FORBIDDEN)) @@ -557,7 +556,7 @@ public class FilterTestCase { .addRequestFilterBinding("my-request-filter", "http://*/filtered/*") .build(); - TestDriver testDriver = newDriver(requestHandler, filterBindings, new MetricConsumerMock(), true); + JettyTestDriver testDriver = newDriver(requestHandler, filterBindings, new MetricConsumerMock(), true); testDriver.client().get("/filtered/") .expectStatusCode(is(Response.Status.OK)); @@ -566,17 +565,16 @@ public class FilterTestCase { Assertions.assertThat(requestArgumentCaptor.getValue().context()).containsKey(RequestHandlerSpec.ATTRIBUTE_NAME); } - private static TestDriver newDriver(MyRequestHandler requestHandler, FilterBindings filterBindings) { + private static JettyTestDriver newDriver(MyRequestHandler requestHandler, FilterBindings filterBindings) { return newDriver(requestHandler, filterBindings, new MetricConsumerMock(), false); } - private static TestDriver newDriver( + private static JettyTestDriver newDriver( MyRequestHandler requestHandler, FilterBindings filterBindings, MetricConsumerMock metricConsumer, boolean strictFiltering) { - return TestDriver.newInstance( - JettyHttpServer.class, + return JettyTestDriver.newInstance( requestHandler, newFilterModule(filterBindings, metricConsumer, strictFiltering)); } diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerConformanceTest.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerConformanceTest.java index 5659dfc2d3c..825e3eba110 100644 --- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerConformanceTest.java +++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerConformanceTest.java @@ -8,7 +8,7 @@ import com.yahoo.container.logging.ConnectionLog; import com.yahoo.container.logging.RequestLog; import com.yahoo.jdisc.http.ServerConfig; import com.yahoo.jdisc.http.ServletPathsConfig; -import com.yahoo.jdisc.http.guiceModules.ConnectorFactoryRegistryModule; +import com.yahoo.jdisc.http.server.jetty.testutils.ConnectorFactoryRegistryModule; import com.yahoo.jdisc.test.ServerProviderConformanceTest; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java index 4dd270306f8..a5804dc9b86 100644 --- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java +++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/HttpServerTest.java @@ -26,7 +26,7 @@ import com.yahoo.jdisc.http.Cookie; import com.yahoo.jdisc.http.HttpRequest; import com.yahoo.jdisc.http.HttpResponse; import com.yahoo.jdisc.http.ServerConfig; -import com.yahoo.jdisc.http.server.jetty.TestDrivers.TlsClientAuth; +import com.yahoo.jdisc.http.server.jetty.JettyTestDriver.TlsClientAuth; import com.yahoo.jdisc.service.BindingSetNotFoundException; import com.yahoo.security.KeyUtils; import com.yahoo.security.Pkcs10Csr; @@ -139,16 +139,16 @@ public class HttpServerTest { @Test public void requireThatServerCanListenToRandomPort() throws Exception { - final TestDriver driver = TestDrivers.newInstance(mockRequestHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(mockRequestHandler()); assertNotEquals(0, driver.server().getListenPort()); assertTrue(driver.close()); } @Test public void requireThatServerCanNotListenToBoundPort() throws Exception { - final TestDriver driver = TestDrivers.newInstance(mockRequestHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(mockRequestHandler()); try { - TestDrivers.newConfiguredInstance( + JettyTestDriver.newConfiguredInstance( mockRequestHandler(), new ServerConfig.Builder(), new ConnectorConfig.Builder() @@ -162,7 +162,7 @@ public class HttpServerTest { @Test public void requireThatBindingSetNotFoundReturns404() throws Exception { - final TestDriver driver = TestDrivers.newConfiguredInstance( + final JettyTestDriver driver = JettyTestDriver.newConfiguredInstance( mockRequestHandler(), new ServerConfig.Builder() .developerMode(true), @@ -179,7 +179,7 @@ public class HttpServerTest { @Test public void requireThatTooLongInitLineReturns414() throws Exception { - final TestDriver driver = TestDrivers.newConfiguredInstance( + final JettyTestDriver driver = JettyTestDriver.newConfiguredInstance( mockRequestHandler(), new ServerConfig.Builder(), new ConnectorConfig.Builder() @@ -192,7 +192,7 @@ public class HttpServerTest { @Test public void requireThatAccessLogIsCalledForRequestRejectedByJetty() throws Exception { BlockingQueueRequestLog requestLogMock = new BlockingQueueRequestLog(); - final TestDriver driver = TestDrivers.newConfiguredInstance( + final JettyTestDriver driver = JettyTestDriver.newConfiguredInstance( mockRequestHandler(), new ServerConfig.Builder(), new ConnectorConfig.Builder().requestHeaderSize(1), @@ -206,7 +206,7 @@ public class HttpServerTest { @Test public void requireThatServerCanEcho() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new EchoRequestHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(new EchoRequestHandler()); driver.client().get("/status.html") .expectStatusCode(is(OK)); assertTrue(driver.close()); @@ -214,7 +214,7 @@ public class HttpServerTest { @Test public void requireThatServerCanEchoCompressed() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new EchoRequestHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(new EchoRequestHandler()); SimpleHttpClient client = driver.newClient(true); client.get("/status.html") .expectStatusCode(is(OK)); @@ -223,7 +223,7 @@ public class HttpServerTest { @Test public void requireThatServerCanHandleMultipleRequests() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new EchoRequestHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(new EchoRequestHandler()); driver.client().get("/status.html") .expectStatusCode(is(OK)); driver.client().get("/status.html") @@ -233,7 +233,7 @@ public class HttpServerTest { @Test public void requireThatFormPostWorks() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new ParameterPrinterRequestHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(new ParameterPrinterRequestHandler()); final String requestContent = generateContent('a', 30); final ResponseValidator response = driver.client().newPost("/status.html") @@ -247,7 +247,7 @@ public class HttpServerTest { @Test public void requireThatFormPostDoesNotRemoveContentByDefault() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new ParameterPrinterRequestHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(new ParameterPrinterRequestHandler()); final ResponseValidator response = driver.client().newPost("/status.html") .addHeader(CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED) @@ -260,7 +260,7 @@ public class HttpServerTest { @Test public void requireThatFormPostKeepsContentWhenConfiguredTo() throws Exception { - final TestDriver driver = newDriverWithFormPostContentRemoved(new ParameterPrinterRequestHandler(), false); + final JettyTestDriver driver = newDriverWithFormPostContentRemoved(new ParameterPrinterRequestHandler(), false); final ResponseValidator response = driver.client().newPost("/status.html") .addHeader(CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED) @@ -273,7 +273,7 @@ public class HttpServerTest { @Test public void requireThatFormPostRemovesContentWhenConfiguredTo() throws Exception { - final TestDriver driver = newDriverWithFormPostContentRemoved(new ParameterPrinterRequestHandler(), true); + final JettyTestDriver driver = newDriverWithFormPostContentRemoved(new ParameterPrinterRequestHandler(), true); final ResponseValidator response = driver.client().newPost("/status.html") .addHeader(CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED) @@ -286,7 +286,7 @@ public class HttpServerTest { @Test public void requireThatFormPostWithCharsetSpecifiedWorks() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new ParameterPrinterRequestHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(new ParameterPrinterRequestHandler()); final String requestContent = generateContent('a', 30); final ResponseValidator response = driver.client().newPost("/status.html") @@ -301,7 +301,7 @@ public class HttpServerTest { @Test public void requireThatEmptyFormPostWorks() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new ParameterPrinterRequestHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(new ParameterPrinterRequestHandler()); final ResponseValidator response = driver.client().newPost("/status.html") .addHeader(CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED) @@ -313,7 +313,7 @@ public class HttpServerTest { @Test public void requireThatFormParametersAreParsed() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new ParameterPrinterRequestHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(new ParameterPrinterRequestHandler()); final ResponseValidator response = driver.client().newPost("/status.html") .addHeader(CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED) @@ -326,7 +326,7 @@ public class HttpServerTest { @Test public void requireThatUriParametersAreParsed() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new ParameterPrinterRequestHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(new ParameterPrinterRequestHandler()); final ResponseValidator response = driver.client().newPost("/status.html?a=b&c=d") .addHeader(CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED) @@ -338,7 +338,7 @@ public class HttpServerTest { @Test public void requireThatFormAndUriParametersAreMerged() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new ParameterPrinterRequestHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(new ParameterPrinterRequestHandler()); final ResponseValidator response = driver.client().newPost("/status.html?a=b&c=d1") .addHeader(CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED) @@ -351,7 +351,7 @@ public class HttpServerTest { @Test public void requireThatFormCharsetIsHonored() throws Exception { - final TestDriver driver = newDriverWithFormPostContentRemoved(new ParameterPrinterRequestHandler(), true); + final JettyTestDriver driver = newDriverWithFormPostContentRemoved(new ParameterPrinterRequestHandler(), true); final ResponseValidator response = driver.client().newPost("/status.html") .addHeader(CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED + ";charset=ISO-8859-1") @@ -364,7 +364,7 @@ public class HttpServerTest { @Test public void requireThatUnknownFormCharsetIsTreatedAsBadRequest() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new ParameterPrinterRequestHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(new ParameterPrinterRequestHandler()); final ResponseValidator response = driver.client().newPost("/status.html") .addHeader(CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED + ";charset=FLARBA-GARBA-7") @@ -376,7 +376,7 @@ public class HttpServerTest { @Test public void requireThatFormPostWithPercentEncodedContentIsDecoded() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new ParameterPrinterRequestHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(new ParameterPrinterRequestHandler()); final ResponseValidator response = driver.client().newPost("/status.html") .addHeader(CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED) @@ -389,7 +389,7 @@ public class HttpServerTest { @Test public void requireThatFormPostWithThrowingHandlerIsExceptionSafe() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new ThrowingHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(new ThrowingHandler()); final ResponseValidator response = driver.client().newPost("/status.html") .addHeader(CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED) @@ -406,7 +406,7 @@ public class HttpServerTest { final String updaterConfContent = "identifier = updater\n" + "server_type = gds\n"; - final TestDriver driver = TestDrivers.newInstance(new EchoRequestHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(new EchoRequestHandler()); final ResponseValidator response = driver.client().newPost("/status.html") .setMultipartContent( @@ -420,7 +420,7 @@ public class HttpServerTest { @Test public void requireThatRequestCookiesAreReceived() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new CookiePrinterRequestHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(new CookiePrinterRequestHandler()); final ResponseValidator response = driver.client().newPost("/status.html") .addHeader(COOKIE, "foo=bar") @@ -432,7 +432,7 @@ public class HttpServerTest { @Test public void requireThatSetCookieHeaderIsCorrect() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new CookieSetterRequestHandler( + final JettyTestDriver driver = JettyTestDriver.newInstance(new CookieSetterRequestHandler( new Cookie("foo", "bar") .setDomain(".localhost") .setHttpOnly(true) @@ -448,7 +448,7 @@ public class HttpServerTest { @Test public void requireThatTimeoutWorks() throws Exception { final UnresponsiveHandler requestHandler = new UnresponsiveHandler(); - final TestDriver driver = TestDrivers.newInstance(requestHandler); + final JettyTestDriver driver = JettyTestDriver.newInstance(requestHandler); driver.client().get("/status.html") .expectStatusCode(is(GATEWAY_TIMEOUT)); ResponseDispatch.newInstance(OK).dispatch(requestHandler.responseHandler); @@ -459,7 +459,7 @@ public class HttpServerTest { // Details in https://github.com/eclipse/jetty.project/issues/1116 @Test public void requireThatHeaderWithNullValueIsOmitted() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new EchoWithHeaderRequestHandler("X-Foo", null)); + final JettyTestDriver driver = JettyTestDriver.newInstance(new EchoWithHeaderRequestHandler("X-Foo", null)); driver.client().get("/status.html") .expectStatusCode(is(OK)) .expectNoHeader("X-Foo"); @@ -470,7 +470,7 @@ public class HttpServerTest { // Details in https://github.com/eclipse/jetty.project/issues/1116 @Test public void requireThatHeaderWithEmptyValueIsAllowed() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new EchoWithHeaderRequestHandler("X-Foo", "")); + final JettyTestDriver driver = JettyTestDriver.newInstance(new EchoWithHeaderRequestHandler("X-Foo", "")); driver.client().get("/status.html") .expectStatusCode(is(OK)) .expectHeader("X-Foo", is("")); @@ -479,7 +479,7 @@ public class HttpServerTest { @Test public void requireThatNoConnectionHeaderMeansKeepAliveInHttp11KeepAliveDisabled() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new EchoWithHeaderRequestHandler(CONNECTION, CLOSE)); + final JettyTestDriver driver = JettyTestDriver.newInstance(new EchoWithHeaderRequestHandler(CONNECTION, CLOSE)); driver.client().get("/status.html") .expectHeader(CONNECTION, is(CLOSE)); assertThat(driver.close(), is(true)); @@ -488,7 +488,7 @@ public class HttpServerTest { @Test public void requireThatConnectionIsClosedAfterXRequests() throws Exception { final int MAX_KEEPALIVE_REQUESTS = 100; - final TestDriver driver = TestDrivers.newConfiguredInstance(new EchoRequestHandler(), + final JettyTestDriver driver = JettyTestDriver.newConfiguredInstance(new EchoRequestHandler(), new ServerConfig.Builder(), new ConnectorConfig.Builder().maxRequestsPerConnection(MAX_KEEPALIVE_REQUESTS)); for (int i = 0; i < MAX_KEEPALIVE_REQUESTS - 1; i++) { @@ -508,7 +508,7 @@ public class HttpServerTest { Path certificateFile = tmpFolder.newFile().toPath(); generatePrivateKeyAndCertificate(privateKeyFile, certificateFile); - final TestDriver driver = TestDrivers.newInstanceWithSsl(new EchoRequestHandler(), certificateFile, privateKeyFile, TlsClientAuth.WANT); + final JettyTestDriver driver = JettyTestDriver.newInstanceWithSsl(new EchoRequestHandler(), certificateFile, privateKeyFile, TlsClientAuth.WANT); driver.client().get("/status.html") .expectStatusCode(is(OK)); assertTrue(driver.close()); @@ -522,7 +522,7 @@ public class HttpServerTest { MetricConsumerMock metricConsumer = new MetricConsumerMock(); InMemoryConnectionLog connectionLog = new InMemoryConnectionLog(); - TestDriver driver = createSslTestDriver(certificateFile, privateKeyFile, metricConsumer, connectionLog); + JettyTestDriver driver = createSslTestDriver(certificateFile, privateKeyFile, metricConsumer, connectionLog); try (CloseableHttpAsyncClient client = createHttp2Client(certificateFile, privateKeyFile)) { String uri = "https://localhost:" + driver.server().getListenPort() + "/status.html"; SimpleHttpResponse response = client.execute(SimpleHttpRequests.get(uri), null).get(); @@ -539,7 +539,7 @@ public class HttpServerTest { Path privateKeyFile = tmpFolder.newFile().toPath(); Path certificateFile = tmpFolder.newFile().toPath(); generatePrivateKeyAndCertificate(privateKeyFile, certificateFile); - TestDriver driver = createSslWithTlsClientAuthenticationEnforcer(certificateFile, privateKeyFile); + JettyTestDriver driver = createSslWithTlsClientAuthenticationEnforcer(certificateFile, privateKeyFile); SSLContext trustStoreOnlyCtx = new SslContextBuilder() .withTrustStore(certificateFile) @@ -557,7 +557,7 @@ public class HttpServerTest { Path privateKeyFile = tmpFolder.newFile().toPath(); Path certificateFile = tmpFolder.newFile().toPath(); generatePrivateKeyAndCertificate(privateKeyFile, certificateFile); - TestDriver driver = TestDrivers.newInstanceWithSsl(new EchoRequestHandler(), certificateFile, privateKeyFile, TlsClientAuth.WANT); + JettyTestDriver driver = JettyTestDriver.newInstanceWithSsl(new EchoRequestHandler(), certificateFile, privateKeyFile, TlsClientAuth.WANT); SSLContext trustStoreOnlyCtx = new SslContextBuilder() .withTrustStore(certificateFile) @@ -572,7 +572,7 @@ public class HttpServerTest { @Test public void requireThatConnectedAtReturnsNonZero() throws Exception { - final TestDriver driver = TestDrivers.newInstance(new ConnectedAtRequestHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(new ConnectedAtRequestHandler()); driver.client().get("/status.html") .expectStatusCode(is(OK)) .expectContent(matchesPattern("\\d{13,}")); @@ -581,7 +581,7 @@ public class HttpServerTest { @Test public void requireThatGzipEncodingRequestsAreAutomaticallyDecompressed() throws Exception { - TestDriver driver = TestDrivers.newInstance(new ParameterPrinterRequestHandler()); + JettyTestDriver driver = JettyTestDriver.newInstance(new ParameterPrinterRequestHandler()); String requestContent = generateContent('a', 30); ResponseValidator response = driver.client().newPost("/status.html") .addHeader(CONTENT_TYPE, APPLICATION_X_WWW_FORM_URLENCODED) @@ -595,7 +595,7 @@ public class HttpServerTest { @Test public void requireThatResponseStatsAreCollected() throws Exception { RequestTypeHandler handler = new RequestTypeHandler(); - TestDriver driver = TestDrivers.newInstance(handler); + JettyTestDriver driver = JettyTestDriver.newInstance(handler); HttpResponseStatisticsCollector statisticsCollector = ((AbstractHandlerContainer) driver.server().server().getHandler()) .getChildHandlerByClass(HttpResponseStatisticsCollector.class); @@ -650,7 +650,7 @@ public class HttpServerTest { @Test public void requireThatConnectionThrottleDoesNotBlockConnectionsBelowThreshold() throws Exception { - TestDriver driver = TestDrivers.newConfiguredInstance( + JettyTestDriver driver = JettyTestDriver.newConfiguredInstance( new EchoRequestHandler(), new ServerConfig.Builder(), new ConnectorConfig.Builder() @@ -671,7 +671,7 @@ public class HttpServerTest { generatePrivateKeyAndCertificate(privateKeyFile, certificateFile); var metricConsumer = new MetricConsumerMock(); InMemoryConnectionLog connectionLog = new InMemoryConnectionLog(); - TestDriver driver = createSslTestDriver(certificateFile, privateKeyFile, metricConsumer, connectionLog); + JettyTestDriver driver = createSslTestDriver(certificateFile, privateKeyFile, metricConsumer, connectionLog); SSLContext clientCtx = new SslContextBuilder() .withTrustStore(certificateFile) @@ -693,7 +693,7 @@ public class HttpServerTest { generatePrivateKeyAndCertificate(privateKeyFile, certificateFile); var metricConsumer = new MetricConsumerMock(); InMemoryConnectionLog connectionLog = new InMemoryConnectionLog(); - TestDriver driver = createSslTestDriver(certificateFile, privateKeyFile, metricConsumer, connectionLog); + JettyTestDriver driver = createSslTestDriver(certificateFile, privateKeyFile, metricConsumer, connectionLog); SSLContext clientCtx = new SslContextBuilder() .withTrustStore(certificateFile) @@ -719,7 +719,7 @@ public class HttpServerTest { generatePrivateKeyAndCertificate(privateKeyFile, certificateFile); var metricConsumer = new MetricConsumerMock(); InMemoryConnectionLog connectionLog = new InMemoryConnectionLog(); - TestDriver driver = createSslTestDriver(certificateFile, privateKeyFile, metricConsumer, connectionLog); + JettyTestDriver driver = createSslTestDriver(certificateFile, privateKeyFile, metricConsumer, connectionLog); SSLContext clientCtx = new SslContextBuilder() .withTrustStore(certificateFile) @@ -743,7 +743,7 @@ public class HttpServerTest { generatePrivateKeyAndCertificate(serverPrivateKeyFile, serverCertificateFile); var metricConsumer = new MetricConsumerMock(); InMemoryConnectionLog connectionLog = new InMemoryConnectionLog(); - TestDriver driver = createSslTestDriver(serverCertificateFile, serverPrivateKeyFile, metricConsumer, connectionLog); + JettyTestDriver driver = createSslTestDriver(serverCertificateFile, serverPrivateKeyFile, metricConsumer, connectionLog); Path clientPrivateKeyFile = tmpFolder.newFile().toPath(); Path clientCertificateFile = tmpFolder.newFile().toPath(); @@ -774,7 +774,7 @@ public class HttpServerTest { generatePrivateKeyAndCertificate(rootPrivateKeyFile, rootCertificateFile, privateKeyFile, certificateFile, notAfter); var metricConsumer = new MetricConsumerMock(); InMemoryConnectionLog connectionLog = new InMemoryConnectionLog(); - TestDriver driver = createSslTestDriver(rootCertificateFile, rootPrivateKeyFile, metricConsumer, connectionLog); + JettyTestDriver driver = createSslTestDriver(rootCertificateFile, rootPrivateKeyFile, metricConsumer, connectionLog); SSLContext clientCtx = new SslContextBuilder() .withTrustStore(rootCertificateFile) @@ -797,7 +797,7 @@ public class HttpServerTest { generatePrivateKeyAndCertificate(privateKeyFile, certificateFile); InMemoryRequestLog requestLogMock = new InMemoryRequestLog(); InMemoryConnectionLog connectionLog = new InMemoryConnectionLog(); - TestDriver driver = createSslWithProxyProtocolTestDriver(certificateFile, privateKeyFile, requestLogMock, /*mixedMode*/connectionLog, false); + JettyTestDriver driver = createSslWithProxyProtocolTestDriver(certificateFile, privateKeyFile, requestLogMock, /*mixedMode*/connectionLog, false); String proxiedRemoteAddress = "192.168.0.100"; int proxiedRemotePort = 12345; @@ -822,7 +822,7 @@ public class HttpServerTest { generatePrivateKeyAndCertificate(privateKeyFile, certificateFile); InMemoryRequestLog requestLogMock = new InMemoryRequestLog(); InMemoryConnectionLog connectionLog = new InMemoryConnectionLog(); - TestDriver driver = createSslWithProxyProtocolTestDriver(certificateFile, privateKeyFile, requestLogMock, /*mixedMode*/connectionLog, true); + JettyTestDriver driver = createSslWithProxyProtocolTestDriver(certificateFile, privateKeyFile, requestLogMock, /*mixedMode*/connectionLog, true); String proxiedRemoteAddress = "192.168.0.100"; sendJettyClientRequest(driver, certificateFile, null); @@ -847,7 +847,7 @@ public class HttpServerTest { generatePrivateKeyAndCertificate(privateKeyFile, certificateFile); InMemoryRequestLog requestLogMock = new InMemoryRequestLog(); InMemoryConnectionLog connectionLog = new InMemoryConnectionLog(); - TestDriver driver = createSslWithProxyProtocolTestDriver(certificateFile, privateKeyFile, requestLogMock, connectionLog, /*mixedMode*/false); + JettyTestDriver driver = createSslWithProxyProtocolTestDriver(certificateFile, privateKeyFile, requestLogMock, connectionLog, /*mixedMode*/false); String proxiedRemoteAddress = "192.168.0.100"; int proxiedRemotePort = 12345; @@ -870,7 +870,7 @@ public class HttpServerTest { generatePrivateKeyAndCertificate(privateKeyFile, certificateFile); InMemoryConnectionLog connectionLog = new InMemoryConnectionLog(); Module overrideModule = binder -> binder.bind(ConnectionLog.class).toInstance(connectionLog); - TestDriver driver = TestDrivers.newInstanceWithSsl(new OkRequestHandler(), certificateFile, privateKeyFile, TlsClientAuth.NEED, overrideModule); + JettyTestDriver driver = JettyTestDriver.newInstanceWithSsl(new OkRequestHandler(), certificateFile, privateKeyFile, TlsClientAuth.NEED, overrideModule); int listenPort = driver.server().getListenPort(); StringBuilder builder = new StringBuilder(); for (int i = 0; i < 1000; i++) { @@ -905,7 +905,7 @@ public class HttpServerTest { @Test public void requireThatRequestIsTrackedInAccessLog() throws IOException, InterruptedException { BlockingQueueRequestLog requestLogMock = new BlockingQueueRequestLog(); - TestDriver driver = TestDrivers.newConfiguredInstance( + JettyTestDriver driver = JettyTestDriver.newConfiguredInstance( new EchoRequestHandler(), new ServerConfig.Builder(), new ConnectorConfig.Builder(), @@ -917,7 +917,7 @@ public class HttpServerTest { assertThat(driver.close(), is(true)); } - private ContentResponse sendJettyClientRequest(TestDriver testDriver, Path certificateFile, Object tag) + private ContentResponse sendJettyClientRequest(JettyTestDriver testDriver, Path certificateFile, Object tag) throws Exception { HttpClient client = createJettyHttpClient(certificateFile); try { @@ -954,9 +954,9 @@ public class HttpServerTest { } private static CloseableHttpAsyncClient createHttp2Client(Path certificateFile, Path privateKeyFile) { - TestDriver driver = TestDrivers.newInstanceWithSsl(new EchoRequestHandler(), certificateFile, privateKeyFile, TlsClientAuth.WANT); + JettyTestDriver driver = JettyTestDriver.newInstanceWithSsl(new EchoRequestHandler(), certificateFile, privateKeyFile, TlsClientAuth.WANT); TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create() - .setSslContext(driver.newSslContext()) + .setSslContext(driver.sslContext()) .build(); var client = HttpAsyncClientBuilder.create() .setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_2) @@ -997,7 +997,7 @@ public class HttpServerTest { assertEquals(expectedException.getName(), exceptionEntry.name()); } - private static TestDriver createSslWithProxyProtocolTestDriver( + private static JettyTestDriver createSslWithProxyProtocolTestDriver( Path certificateFile, Path privateKeyFile, RequestLog requestLog, ConnectionLog connectionLog, boolean mixedMode) { ConnectorConfig.Builder connectorConfig = new ConnectorConfig.Builder() @@ -1010,7 +1010,7 @@ public class HttpServerTest { .privateKeyFile(privateKeyFile.toString()) .certificateFile(certificateFile.toString()) .caCertificateFile(certificateFile.toString())); - return TestDrivers.newConfiguredInstance( + return JettyTestDriver.newConfiguredInstance( new EchoRequestHandler(), new ServerConfig.Builder().connectionLog(new ServerConfig.ConnectionLog.Builder().enabled(true)), connectorConfig, @@ -1020,7 +1020,7 @@ public class HttpServerTest { }); } - private static TestDriver createSslWithTlsClientAuthenticationEnforcer(Path certificateFile, Path privateKeyFile) { + private static JettyTestDriver createSslWithTlsClientAuthenticationEnforcer(Path certificateFile, Path privateKeyFile) { ConnectorConfig.Builder connectorConfig = new ConnectorConfig.Builder() .tlsClientAuthEnforcer( new ConnectorConfig.TlsClientAuthEnforcer.Builder() @@ -1032,25 +1032,25 @@ public class HttpServerTest { .privateKeyFile(privateKeyFile.toString()) .certificateFile(certificateFile.toString()) .caCertificateFile(certificateFile.toString())); - return TestDrivers.newConfiguredInstance( + return JettyTestDriver.newConfiguredInstance( new EchoRequestHandler(), new ServerConfig.Builder().connectionLog(new ServerConfig.ConnectionLog.Builder().enabled(true)), connectorConfig, binder -> {}); } - private static TestDriver createSslTestDriver( + private static JettyTestDriver createSslTestDriver( Path serverCertificateFile, Path serverPrivateKeyFile, MetricConsumerMock metricConsumer, InMemoryConnectionLog connectionLog) throws IOException { Module extraModule = binder -> { binder.bind(MetricConsumer.class).toInstance(metricConsumer.mockitoMock()); binder.bind(ConnectionLog.class).toInstance(connectionLog); }; - return TestDrivers.newInstanceWithSsl( + return JettyTestDriver.newInstanceWithSsl( new EchoRequestHandler(), serverCertificateFile, serverPrivateKeyFile, TlsClientAuth.NEED, extraModule); } private static void assertHttpsRequestTriggersSslHandshakeException( - TestDriver testDriver, + JettyTestDriver testDriver, SSLContext sslContext, String protocolOverride, String cipherOverride, @@ -1110,9 +1110,9 @@ public class HttpServerTest { return ret.toString(); } - private static TestDriver newDriverWithFormPostContentRemoved(RequestHandler requestHandler, - boolean removeFormPostBody) throws Exception { - return TestDrivers.newConfiguredInstance( + private static JettyTestDriver newDriverWithFormPostContentRemoved(RequestHandler requestHandler, + boolean removeFormPostBody) throws Exception { + return JettyTestDriver.newConfiguredInstance( requestHandler, new ServerConfig.Builder() .removeRawPostBodyForWwwUrlEncodedPost(removeFormPostBody), diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/JDiscHttpServletTest.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/JDiscHttpServletTest.java index 23c229e2ec5..d46531ad844 100644 --- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/JDiscHttpServletTest.java +++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/JDiscHttpServletTest.java @@ -33,7 +33,7 @@ public class JDiscHttpServletTest { @Test public void requireThatServerRespondsToAllMethods() throws Exception { - final TestDriver driver = TestDrivers.newInstance(newEchoHandler()); + final JettyTestDriver driver = JettyTestDriver.newInstance(newEchoHandler()); final URI uri = driver.client().newUri("/status.html"); driver.client().execute(new HttpGet(uri)) .expectStatusCode(is(OK)); @@ -56,7 +56,7 @@ public class JDiscHttpServletTest { @Test public void requireThatServerResponds405ToUnknownMethods() throws IOException { - TestDriver driver = TestDrivers.newInstance(newEchoHandler()); + JettyTestDriver driver = JettyTestDriver.newInstance(newEchoHandler()); final URI uri = driver.client().newUri("/status.html"); driver.client().execute(new UnknownMethodHttpRequest(uri)) .expectStatusCode(is(METHOD_NOT_ALLOWED)); diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/JettyTestDriver.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/JettyTestDriver.java new file mode 100644 index 00000000000..57438cbe207 --- /dev/null +++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/JettyTestDriver.java @@ -0,0 +1,90 @@ +// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.jdisc.http.server.jetty; + +import com.google.inject.Module; +import com.yahoo.jdisc.handler.RequestHandler; +import com.yahoo.jdisc.http.ConnectorConfig; +import com.yahoo.jdisc.http.ServerConfig; +import com.yahoo.jdisc.http.server.jetty.testutils.TestDriver; + +import javax.net.ssl.SSLContext; +import java.nio.file.Path; +import java.util.Collection; +import java.util.List; + +import static com.yahoo.yolean.Exceptions.uncheck; + +/** + * Provides functionality for setting up a jdisc container with an HTTP server, handlers and a simple http client. + * + * @author bjorncs + * @author Simon Thoresen Hult + * @author bakksjo + */ +public class JettyTestDriver { + + public enum TlsClientAuth { NEED, WANT } + + private final TestDriver driver; + private final SimpleHttpClient client; + + private JettyTestDriver(RequestHandler requestHandler, + ServerConfig serverConfig, + ConnectorConfig connectorConfig, + Collection<Module> guiceModules) { + var builder = TestDriver.newBuilder() + .withRequestHandler(requestHandler) + .withServerConfig(serverConfig) + .withConnectorConfig(connectorConfig); + guiceModules.forEach(builder::withGuiceModule); + this.driver = builder.build(); + this.client = new SimpleHttpClient(driver.sslContext(), driver.server().getListenPort(), false); + } + + public boolean close() { + uncheck(client::close); + return driver.shutdown(); + } + + public JettyHttpServer server() { return driver.server(); } + public SimpleHttpClient client() { return client; } + public SSLContext sslContext() { return driver.sslContext(); } + + public SimpleHttpClient newClient(boolean useCompression) { + return new SimpleHttpClient(driver.sslContext(), driver.server().getListenPort(), useCompression); + } + + public static JettyTestDriver newConfiguredInstance(RequestHandler requestHandler, + ServerConfig.Builder serverConfig, + ConnectorConfig.Builder connectorConfig, + Module... guiceModules) { + return new JettyTestDriver(requestHandler, serverConfig.build(), connectorConfig.build(), List.of(guiceModules)); + } + + public static JettyTestDriver newInstance(RequestHandler requestHandler, Module... guiceModules) { + return newConfiguredInstance(requestHandler, new ServerConfig.Builder(), new ConnectorConfig.Builder(), guiceModules); + } + + + public static JettyTestDriver newInstanceWithSsl(RequestHandler requestHandler, + Path certificateFile, + Path privateKeyFile, + TlsClientAuth tlsClientAuth, + Module... guiceModules) { + return newConfiguredInstance( + requestHandler, + new ServerConfig.Builder().connectionLog(new ServerConfig.ConnectionLog.Builder().enabled(true)), + new ConnectorConfig.Builder() + .http2Enabled(true) + .ssl(new ConnectorConfig.Ssl.Builder() + .enabled(true) + .clientAuth(tlsClientAuth == TlsClientAuth.NEED + ? ConnectorConfig.Ssl.ClientAuth.Enum.NEED_AUTH + : ConnectorConfig.Ssl.ClientAuth.Enum.WANT_AUTH) + .privateKeyFile(privateKeyFile.toString()) + .certificateFile(certificateFile.toString()) + .caCertificateFile(certificateFile.toString())), + guiceModules); + } + +} diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/TestDriver.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/TestDriver.java deleted file mode 100644 index 49928a5679e..00000000000 --- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/TestDriver.java +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.server.jetty; - -import com.google.inject.Module; -import com.yahoo.jdisc.application.ContainerBuilder; -import com.yahoo.jdisc.handler.RequestHandler; -import com.yahoo.jdisc.http.ConnectorConfig; -import com.yahoo.security.SslContextBuilder; - -import javax.net.ssl.SSLContext; -import java.nio.file.Paths; - -import static com.yahoo.yolean.Exceptions.uncheck; - -/** - * Provides functionality for setting up a jdisc container with an HTTP server and handlers. - * - * @author Simon Thoresen Hult - * @author bakksjo - */ -public class TestDriver { - - private final com.yahoo.jdisc.test.TestDriver driver; - private final JettyHttpServer server; - private final SimpleHttpClient client; - - private TestDriver(com.yahoo.jdisc.test.TestDriver driver, JettyHttpServer server, SimpleHttpClient client) { - this.driver = driver; - this.server = server; - this.client = client; - } - - public static TestDriver newInstance(Class<? extends JettyHttpServer> serverClass, - RequestHandler requestHandler, - Module testConfig) { - com.yahoo.jdisc.test.TestDriver driver = - com.yahoo.jdisc.test.TestDriver.newSimpleApplicationInstance(testConfig); - ContainerBuilder builder = driver.newContainerBuilder(); - JettyHttpServer server = builder.getInstance(serverClass); - builder.serverProviders().install(server); - builder.serverBindings().bind("http://*/*", requestHandler); - driver.activateContainer(builder); - server.start(); - - SimpleHttpClient client = new SimpleHttpClient(newSslContext(builder), server.getListenPort(), false); - return new TestDriver(driver, server, client); - } - - public boolean close() { - server.close(); - server.release(); - uncheck(client::close); - return driver.close(); - } - - public JettyHttpServer server() { return server; } - - public SimpleHttpClient client() { return client; } - - public SimpleHttpClient newClient(final boolean useCompression) { - return new SimpleHttpClient(newSslContext(), server.getListenPort(), useCompression); - } - - public SSLContext newSslContext() { - return newSslContext(driver.newContainerBuilder()); - } - - private static SSLContext newSslContext(ContainerBuilder builder) { - ConnectorConfig.Ssl sslConfig = builder.getInstance(ConnectorConfig.class).ssl(); - if (!sslConfig.enabled()) return null; - - return new SslContextBuilder() - .withKeyStore(Paths.get(sslConfig.privateKeyFile()), Paths.get(sslConfig.certificateFile())) - .withTrustStore(Paths.get(sslConfig.caCertificateFile())) - .build(); - } - -} diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/TestDrivers.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/TestDrivers.java deleted file mode 100644 index 75fc0948da9..00000000000 --- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/TestDrivers.java +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package com.yahoo.jdisc.http.server.jetty; - -import com.google.inject.AbstractModule; -import com.google.inject.Module; -import com.google.inject.util.Modules; -import com.yahoo.container.logging.ConnectionLog; -import com.yahoo.container.logging.RequestLog; -import com.yahoo.jdisc.handler.RequestHandler; -import com.yahoo.jdisc.http.ConnectorConfig; -import com.yahoo.jdisc.http.ServerConfig; -import com.yahoo.jdisc.http.ServletPathsConfig; -import com.yahoo.jdisc.http.guiceModules.ConnectorFactoryRegistryModule; -import com.yahoo.jdisc.http.guiceModules.ServletModule; - -import java.nio.file.Path; - -/** - * @author Simon Thoresen Hult - * @author bjorncs - */ -public class TestDrivers { - - public static TestDriver newConfiguredInstance(RequestHandler requestHandler, - ServerConfig.Builder serverConfig, - ConnectorConfig.Builder connectorConfig, - Module... guiceModules) { - return TestDriver.newInstance( - JettyHttpServer.class, - requestHandler, - newConfigModule(serverConfig, connectorConfig, guiceModules)); - } - - public static TestDriver newInstance(RequestHandler requestHandler, Module... guiceModules) { - return TestDriver.newInstance( - JettyHttpServer.class, - requestHandler, - newConfigModule( - new ServerConfig.Builder(), - new ConnectorConfig.Builder(), - guiceModules - )); - } - - public enum TlsClientAuth { NEED, WANT } - - public static TestDriver newInstanceWithSsl(RequestHandler requestHandler, - Path certificateFile, - Path privateKeyFile, - TlsClientAuth tlsClientAuth, - Module... guiceModules) { - return TestDriver.newInstance( - JettyHttpServer.class, - requestHandler, - newConfigModule( - new ServerConfig.Builder().connectionLog(new ServerConfig.ConnectionLog.Builder().enabled(true)), - new ConnectorConfig.Builder() - .http2Enabled(true) - .ssl(new ConnectorConfig.Ssl.Builder() - .enabled(true) - .clientAuth(tlsClientAuth == TlsClientAuth.NEED - ? ConnectorConfig.Ssl.ClientAuth.Enum.NEED_AUTH - : ConnectorConfig.Ssl.ClientAuth.Enum.WANT_AUTH) - .privateKeyFile(privateKeyFile.toString()) - .certificateFile(certificateFile.toString()) - .caCertificateFile(certificateFile.toString())), - guiceModules)); - } - - private static Module newConfigModule(ServerConfig.Builder serverConfig, - ConnectorConfig.Builder connectorConfigBuilder, - Module... guiceModules) { - return Modules.override( - Modules.combine( - new AbstractModule() { - @Override - protected void configure() { - bind(ServletPathsConfig.class).toInstance(new ServletPathsConfig(new ServletPathsConfig.Builder())); - bind(ServerConfig.class).toInstance(new ServerConfig(serverConfig)); - bind(ConnectorConfig.class).toInstance(new ConnectorConfig(connectorConfigBuilder)); - bind(FilterBindings.class).toInstance(new FilterBindings.Builder().build()); - bind(ConnectionLog.class).toInstance(new VoidConnectionLog()); - bind(RequestLog.class).toInstance(new VoidRequestLog()); - } - }, - new ConnectorFactoryRegistryModule(connectorConfigBuilder), - new ServletModule())) - .with(guiceModules); - } - -} diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/servlet/JDiscFilterForServletTest.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/servlet/JDiscFilterForServletTest.java index 16969a47b84..0479374854c 100644 --- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/servlet/JDiscFilterForServletTest.java +++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/servlet/JDiscFilterForServletTest.java @@ -15,8 +15,7 @@ import com.yahoo.jdisc.http.filter.ResponseFilter; import com.yahoo.jdisc.http.server.jetty.FilterBindings; import com.yahoo.jdisc.http.server.jetty.FilterInvoker; import com.yahoo.jdisc.http.server.jetty.SimpleHttpClient.ResponseValidator; -import com.yahoo.jdisc.http.server.jetty.TestDriver; -import com.yahoo.jdisc.http.server.jetty.TestDrivers; +import com.yahoo.jdisc.http.server.jetty.JettyTestDriver; import org.junit.Test; import javax.servlet.http.HttpServletRequest; @@ -36,7 +35,7 @@ import static org.hamcrest.CoreMatchers.is; public class JDiscFilterForServletTest extends ServletTestBase { @Test public void request_filter_can_return_response() throws IOException, InterruptedException { - TestDriver testDriver = requestFilterTestDriver(); + JettyTestDriver testDriver = requestFilterTestDriver(); ResponseValidator response = httpGet(testDriver, TestServlet.PATH).execute(); response.expectContent(containsString(TestRequestFilter.responseContent)); @@ -44,7 +43,7 @@ public class JDiscFilterForServletTest extends ServletTestBase { @Test public void request_can_be_forwarded_through_request_filter_to_servlet() throws IOException { - TestDriver testDriver = requestFilterTestDriver(); + JettyTestDriver testDriver = requestFilterTestDriver(); ResponseValidator response = httpGet(testDriver, TestServlet.PATH). addHeader(TestRequestFilter.BYPASS_FILTER_HEADER, Boolean.TRUE.toString()). execute(); @@ -54,7 +53,7 @@ public class JDiscFilterForServletTest extends ServletTestBase { @Test public void response_filter_can_modify_response() throws IOException { - TestDriver testDriver = responseFilterTestDriver(); + JettyTestDriver testDriver = responseFilterTestDriver(); ResponseValidator response = httpGet(testDriver, TestServlet.PATH).execute(); response.expectHeader(TestResponseFilter.INVOKED_HEADER, is(Boolean.TRUE.toString())); @@ -62,7 +61,7 @@ public class JDiscFilterForServletTest extends ServletTestBase { @Test public void response_filter_is_run_on_empty_sync_response() throws IOException { - TestDriver testDriver = responseFilterTestDriver(); + JettyTestDriver testDriver = responseFilterTestDriver(); ResponseValidator response = httpGet(testDriver, NoContentTestServlet.PATH).execute(); response.expectHeader(TestResponseFilter.INVOKED_HEADER, is(Boolean.TRUE.toString())); @@ -70,7 +69,7 @@ public class JDiscFilterForServletTest extends ServletTestBase { @Test public void response_filter_is_run_on_empty_async_response() throws IOException { - TestDriver testDriver = responseFilterTestDriver(); + JettyTestDriver testDriver = responseFilterTestDriver(); ResponseValidator response = httpGet(testDriver, NoContentTestServlet.PATH). addHeader(NoContentTestServlet.HEADER_ASYNC, Boolean.TRUE.toString()). execute(); @@ -78,20 +77,20 @@ public class JDiscFilterForServletTest extends ServletTestBase { response.expectHeader(TestResponseFilter.INVOKED_HEADER, is(Boolean.TRUE.toString())); } - private TestDriver requestFilterTestDriver() throws IOException { + private JettyTestDriver requestFilterTestDriver() throws IOException { FilterBindings filterBindings = new FilterBindings.Builder() .addRequestFilter("my-request-filter", new TestRequestFilter()) .addRequestFilterBinding("my-request-filter", "http://*/*") .build(); - return TestDrivers.newInstance(dummyRequestHandler, bindings(filterBindings)); + return JettyTestDriver.newInstance(dummyRequestHandler, bindings(filterBindings)); } - private TestDriver responseFilterTestDriver() throws IOException { + private JettyTestDriver responseFilterTestDriver() throws IOException { FilterBindings filterBindings = new FilterBindings.Builder() .addResponseFilter("my-response-filter", new TestResponseFilter()) .addResponseFilterBinding("my-response-filter", "http://*/*") .build(); - return TestDrivers.newInstance(dummyRequestHandler, bindings(filterBindings)); + return JettyTestDriver.newInstance(dummyRequestHandler, bindings(filterBindings)); } diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/servlet/ServletAccessLoggingTest.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/servlet/ServletAccessLoggingTest.java index a533a447f6a..39d28465b17 100644 --- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/servlet/ServletAccessLoggingTest.java +++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/servlet/ServletAccessLoggingTest.java @@ -7,8 +7,7 @@ import com.google.inject.util.Modules; import com.yahoo.container.logging.AccessLog; import com.yahoo.container.logging.RequestLog; import com.yahoo.container.logging.RequestLogEntry; -import com.yahoo.jdisc.http.server.jetty.TestDriver; -import com.yahoo.jdisc.http.server.jetty.TestDrivers; +import com.yahoo.jdisc.http.server.jetty.JettyTestDriver; import org.junit.Test; import org.mockito.verification.VerificationMode; @@ -30,7 +29,7 @@ public class ServletAccessLoggingTest extends ServletTestBase { @Test public void accessLogIsInvokedForNonJDiscServlet() throws Exception { final AccessLog accessLog = mock(AccessLog.class); - final TestDriver testDriver = newTestDriver(accessLog); + final JettyTestDriver testDriver = newTestDriver(accessLog); httpGet(testDriver, TestServlet.PATH).execute(); verifyCallsLog(accessLog, timeout(MAX_LOG_WAIT_TIME_MILLIS).times(1)); } @@ -38,7 +37,7 @@ public class ServletAccessLoggingTest extends ServletTestBase { @Test public void accessLogIsInvokedForJDiscServlet() throws Exception { final AccessLog accessLog = mock(AccessLog.class); - final TestDriver testDriver = newTestDriver(accessLog); + final JettyTestDriver testDriver = newTestDriver(accessLog); testDriver.client().newGet("/status.html").execute(); verifyCallsLog(accessLog, timeout(MAX_LOG_WAIT_TIME_MILLIS).times(1)); } @@ -47,8 +46,8 @@ public class ServletAccessLoggingTest extends ServletTestBase { verify(requestLog, verificationMode).log(any(RequestLogEntry.class)); } - private TestDriver newTestDriver(RequestLog requestLog) throws IOException { - return TestDrivers.newInstance(dummyRequestHandler, bindings(requestLog)); + private JettyTestDriver newTestDriver(RequestLog requestLog) throws IOException { + return JettyTestDriver.newInstance(dummyRequestHandler, bindings(requestLog)); } private Module bindings(RequestLog requestLog) { diff --git a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/servlet/ServletTestBase.java b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/servlet/ServletTestBase.java index 54bfe8c026d..e1f1a818ab0 100644 --- a/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/servlet/ServletTestBase.java +++ b/container-core/src/test/java/com/yahoo/jdisc/http/server/jetty/servlet/ServletTestBase.java @@ -14,7 +14,7 @@ import com.yahoo.jdisc.handler.ResponseHandler; import com.yahoo.jdisc.http.ServletPathsConfig; import com.yahoo.jdisc.http.ServletPathsConfig.Servlets.Builder; import com.yahoo.jdisc.http.server.jetty.SimpleHttpClient.RequestExecutor; -import com.yahoo.jdisc.http.server.jetty.TestDriver; +import com.yahoo.jdisc.http.server.jetty.JettyTestDriver; import org.eclipse.jetty.servlet.ServletHolder; import javax.servlet.ServletException; @@ -46,7 +46,7 @@ public class ServletTestBase { new ServletInstance(TestServlet.ID, TestServlet.PATH, new TestServlet()), new ServletInstance(NoContentTestServlet.ID, NoContentTestServlet.PATH, new NoContentTestServlet())); - protected RequestExecutor httpGet(TestDriver testDriver, String path) { + protected RequestExecutor httpGet(JettyTestDriver testDriver, String path) { return testDriver.client().newGet("/" + path); } diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/ApplicationSuspensionRequestHandlerTest.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/ApplicationSuspensionRequestHandlerTest.java index 176a95d1c04..864516acbc5 100644 --- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/ApplicationSuspensionRequestHandlerTest.java +++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/ApplicationSuspensionRequestHandlerTest.java @@ -2,10 +2,11 @@ package com.yahoo.vespa.orchestrator.resources;// Copyright Verizon Media. Licen import com.fasterxml.jackson.core.type.TypeReference; import com.yahoo.cloud.config.ConfigserverConfig; +import com.yahoo.container.jdisc.HttpRequestBuilder; import com.yahoo.container.jdisc.HttpResponse; -import com.yahoo.container.jdisc.LoggingRequestHandler; import com.yahoo.jdisc.core.SystemTimer; import com.yahoo.jdisc.test.MockMetric; +import com.yahoo.restapi.RestApiTestDriver; import com.yahoo.vespa.curator.mock.MockCurator; import com.yahoo.vespa.flags.InMemoryFlagSource; import com.yahoo.vespa.orchestrator.DummyServiceMonitor; @@ -18,11 +19,9 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Set; -import java.util.concurrent.Executors; import static com.yahoo.jdisc.http.HttpRequest.Method; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -38,7 +37,7 @@ class ApplicationSuspensionRequestHandlerTest { private static final String RESOURCE_2 = "test-tenant-id:application:instance"; private static final String INVALID_RESOURCE_NAME = "something_without_colons"; - ApplicationSuspensionRequestHandler handler; + private RestApiTestDriver testDriver; @BeforeEach void createHandler() { @@ -50,8 +49,8 @@ class ApplicationSuspensionRequestHandlerTest { serviceMonitor, new ConfigserverConfig(new ConfigserverConfig.Builder()), new InMemoryFlagSource()); - var handlerContext = new LoggingRequestHandler.Context(Executors.newSingleThreadExecutor(), new MockMetric()); - this.handler = new ApplicationSuspensionRequestHandler(handlerContext, orchestrator); + var handler = new ApplicationSuspensionRequestHandler(RestApiTestDriver.createHandlerTestContext(), orchestrator); + testDriver = RestApiTestDriver.newBuilder(handler).build(); } @@ -136,22 +135,17 @@ class ApplicationSuspensionRequestHandlerTest { assertEquals(RESOURCE_2, set.iterator().next()); } - private HttpResponse executeRequest(Method method, String path, String applicationId) throws IOException { - String uri = "http://localhost/orchestrator/v1/suspensions/applications" + path; - com.yahoo.container.jdisc.HttpRequest request; + private HttpResponse executeRequest(Method method, String relativePath, String applicationId) { + String fullPath = "/orchestrator/v1/suspensions/applications" + relativePath; + var builder = HttpRequestBuilder.create(method, fullPath); if (applicationId != null) { - ByteArrayInputStream requestData = new ByteArrayInputStream(applicationId.getBytes(StandardCharsets.UTF_8)); - request = com.yahoo.container.jdisc.HttpRequest.createTestRequest(uri, method, requestData); - } else { - request = com.yahoo.container.jdisc.HttpRequest.createTestRequest(uri, method); + builder.withRequestContent(new ByteArrayInputStream(applicationId.getBytes(StandardCharsets.UTF_8))); } - return handler.handle(request); + return testDriver.executeRequest(builder.build()); } - private <T> T parseResponseContent(HttpResponse response, TypeReference<T> responseEntityType) throws IOException { + private <T> T parseResponseContent(HttpResponse response, TypeReference<T> type) { assertEquals(200, response.getStatus()); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - response.render(out); - return handler.restApi().jacksonJsonMapper().readValue(out.toByteArray(), responseEntityType); + return testDriver.parseJacksonResponseContent(response, type); } }
\ No newline at end of file diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/HostRequestHandlerTest.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/HostRequestHandlerTest.java index c34775c1910..f6dc6d7676c 100644 --- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/HostRequestHandlerTest.java +++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/HostRequestHandlerTest.java @@ -2,13 +2,12 @@ package com.yahoo.vespa.orchestrator.resources; import com.google.common.util.concurrent.UncheckedTimeoutException; -import com.yahoo.container.jdisc.HttpRequest; +import com.yahoo.container.jdisc.HttpRequestBuilder; import com.yahoo.container.jdisc.HttpResponse; -import com.yahoo.container.jdisc.LoggingRequestHandler; import com.yahoo.jdisc.Metric; import com.yahoo.jdisc.http.HttpRequest.Method; -import com.yahoo.jdisc.test.MockMetric; import com.yahoo.jdisc.test.TestTimer; +import com.yahoo.restapi.RestApiTestDriver; import com.yahoo.test.json.JsonTestHelper; import com.yahoo.vespa.applicationmodel.ApplicationInstance; import com.yahoo.vespa.applicationmodel.ApplicationInstanceId; @@ -50,7 +49,6 @@ import com.yahoo.vespa.service.monitor.ServiceMonitor; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.time.Clock; @@ -59,7 +57,6 @@ import java.util.Collections; import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.concurrent.Executors; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; @@ -171,18 +168,18 @@ class HostRequestHandlerTest { @Test void returns_200_on_success() throws IOException { - HostRequestHandler handler = createHandler(alwaysAllowOrchestrator); + RestApiTestDriver testDriver = createTestDriver(alwaysAllowOrchestrator); - HttpResponse response = executeRequest(handler, Method.PUT, "/orchestrator/v1/hosts/hostname/suspended", null); - UpdateHostResponse updateHostResponse = parseResponseContent(handler, response, UpdateHostResponse.class); + HttpResponse response = executeRequest(testDriver, Method.PUT, "/orchestrator/v1/hosts/hostname/suspended", null); + UpdateHostResponse updateHostResponse = parseResponseContent(testDriver, response, UpdateHostResponse.class); assertEquals("hostname", updateHostResponse.hostname()); } @Test void throws_404_when_host_unknown() throws IOException { - HostRequestHandler handler = createHandler(hostNotFoundOrchestrator); + RestApiTestDriver testDriver = createTestDriver(hostNotFoundOrchestrator); - HttpResponse response = executeRequest(handler, Method.PUT, "/orchestrator/v1/hosts/hostname/suspended", null); + HttpResponse response = executeRequest(testDriver, Method.PUT, "/orchestrator/v1/hosts/hostname/suspended", null); assertEquals(404, response.getStatus()); } @@ -220,35 +217,35 @@ class HostRequestHandlerTest { @Test void throws_409_when_request_rejected_by_policies() throws IOException { - HostRequestHandler handler = createHandler(alwaysRejectOrchestrator); + RestApiTestDriver testDriver = createTestDriver(alwaysRejectOrchestrator); - HttpResponse response = executeRequest(handler, Method.PUT, "/orchestrator/v1/hosts/hostname/suspended", null); + HttpResponse response = executeRequest(testDriver, Method.PUT, "/orchestrator/v1/hosts/hostname/suspended", null); assertEquals(409, response.getStatus()); } @Test void patch_state_may_throw_bad_request() throws IOException { Orchestrator orchestrator = mock(Orchestrator.class); - HostRequestHandler handler = createHandler(orchestrator); + RestApiTestDriver testDriver = createTestDriver(orchestrator); PatchHostRequest request = new PatchHostRequest(); request.state = "bad state"; - HttpResponse response = executeRequest(handler, Method.PATCH, "/orchestrator/v1/hosts/hostname", request); + HttpResponse response = executeRequest(testDriver, Method.PATCH, "/orchestrator/v1/hosts/hostname", request); assertEquals(400, response.getStatus()); } @Test void patch_works() throws OrchestrationException, IOException { Orchestrator orchestrator = mock(Orchestrator.class); - HostRequestHandler handler = createHandler(orchestrator); + RestApiTestDriver testDriver = createTestDriver(orchestrator); String hostNameString = "hostname"; PatchHostRequest request = new PatchHostRequest(); request.state = "NO_REMARKS"; - HttpResponse httpResponse = executeRequest(handler, Method.PATCH, "/orchestrator/v1/hosts/hostname", request); - PatchHostResponse response = parseResponseContent(handler, httpResponse, PatchHostResponse.class); + HttpResponse httpResponse = executeRequest(testDriver, Method.PATCH, "/orchestrator/v1/hosts/hostname", request); + PatchHostResponse response = parseResponseContent(testDriver, httpResponse, PatchHostResponse.class); assertEquals(response.description, "ok"); verify(orchestrator, times(1)).setNodeStatus(new HostName(hostNameString), HostStatus.NO_REMARKS); } @@ -256,21 +253,21 @@ class HostRequestHandlerTest { @Test void patch_handles_exception_in_orchestrator() throws OrchestrationException, IOException { Orchestrator orchestrator = mock(Orchestrator.class); - HostRequestHandler handler = createHandler(orchestrator); + RestApiTestDriver testDriver = createTestDriver(orchestrator); String hostNameString = "hostname"; PatchHostRequest request = new PatchHostRequest(); request.state = "NO_REMARKS"; doThrow(new OrchestrationException("error")).when(orchestrator).setNodeStatus(new HostName(hostNameString), HostStatus.NO_REMARKS); - HttpResponse httpResponse = executeRequest(handler, Method.PATCH, "/orchestrator/v1/hosts/hostname", request); + HttpResponse httpResponse = executeRequest(testDriver, Method.PATCH, "/orchestrator/v1/hosts/hostname", request); assertEquals(500, httpResponse.getStatus()); } @Test void getHost_works() throws Exception { Orchestrator orchestrator = mock(Orchestrator.class); - HostRequestHandler handler = createHandler(orchestrator); + RestApiTestDriver testDriver = createTestDriver(orchestrator); HostName hostName = new HostName("hostname"); @@ -293,8 +290,8 @@ class HostRequestHandlerTest { Collections.singletonList(serviceInstance)); when(orchestrator.getHost(hostName)).thenReturn(host); - HttpResponse httpResponse = executeRequest(handler, Method.GET, "/orchestrator/v1/hosts/hostname", null); - GetHostResponse response = parseResponseContent(handler, httpResponse, GetHostResponse.class); + HttpResponse httpResponse = executeRequest(testDriver, Method.GET, "/orchestrator/v1/hosts/hostname", null); + GetHostResponse response = parseResponseContent(testDriver, httpResponse, GetHostResponse.class); assertEquals("http://localhost/orchestrator/v1/instances/tenantId:applicationId", response.applicationUrl()); assertEquals("hostname", response.hostname()); @@ -312,8 +309,8 @@ class HostRequestHandlerTest { Orchestrator orchestrator = mock(Orchestrator.class); doThrow(new UncheckedTimeoutException("Timeout Message")).when(orchestrator).resume(any(HostName.class)); - HostRequestHandler handler = createHandler(orchestrator); - HttpResponse httpResponse = executeRequest(handler, Method.DELETE, "/orchestrator/v1/hosts/hostname/suspended", null); + RestApiTestDriver testDriver = createTestDriver(orchestrator); + HttpResponse httpResponse = executeRequest(testDriver, Method.DELETE, "/orchestrator/v1/hosts/hostname/suspended", null); assertEquals(409, httpResponse.getStatus()); ByteArrayOutputStream out = new ByteArrayOutputStream(); httpResponse.render(out); @@ -327,29 +324,22 @@ class HostRequestHandlerTest { out.toString()); } - private HostRequestHandler createHandler(Orchestrator orchestrator) { - var handlerContext = new LoggingRequestHandler.Context(Executors.newSingleThreadExecutor(), new MockMetric()); - return new HostRequestHandler(handlerContext, orchestrator); + private RestApiTestDriver createTestDriver(Orchestrator orchestrator) { + return RestApiTestDriver.newBuilder(handlerContext -> new HostRequestHandler(handlerContext, orchestrator)) + .build(); } - private HttpResponse executeRequest(HostRequestHandler handler, Method method, String path, Object requestEntity) throws IOException { - String uri = "http://localhost" + path; - HttpRequest request; + private HttpResponse executeRequest(RestApiTestDriver testDriver, Method method, String path, Object requestEntity) { + var builder = HttpRequestBuilder.create(method, path); if (requestEntity != null) { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - handler.restApi().jacksonJsonMapper().writeValue(out, requestEntity); - request = HttpRequest.createTestRequest(uri, method, new ByteArrayInputStream(out.toByteArray())); - } else { - request = HttpRequest.createTestRequest(uri, method); + builder.withRequestContent(testDriver.requestContentOf(requestEntity)); } - return handler.handle(request); + return testDriver.executeRequest(builder.build()); } - private <T> T parseResponseContent(HostRequestHandler handler, HttpResponse response, Class<T> responseEntityType) throws IOException { + private <T> T parseResponseContent(RestApiTestDriver testDriver, HttpResponse response, Class<T> responseEntityType) { assertEquals(200, response.getStatus()); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - response.render(out); - return handler.restApi().jacksonJsonMapper().readValue(out.toByteArray(), responseEntityType); + return testDriver.parseJacksonResponseContent(response, responseEntityType); } } diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/HostSuspensionRequestHandlerTest.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/HostSuspensionRequestHandlerTest.java index 983c28eb2f9..3b12160e708 100644 --- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/HostSuspensionRequestHandlerTest.java +++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/HostSuspensionRequestHandlerTest.java @@ -2,10 +2,9 @@ package com.yahoo.vespa.orchestrator.resources; import com.google.common.util.concurrent.UncheckedTimeoutException; -import com.yahoo.container.jdisc.HttpRequest; +import com.yahoo.container.jdisc.HttpRequestBuilder; import com.yahoo.container.jdisc.HttpResponse; -import com.yahoo.container.jdisc.LoggingRequestHandler; -import com.yahoo.jdisc.test.MockMetric; +import com.yahoo.restapi.RestApiTestDriver; import com.yahoo.test.json.JsonTestHelper; import com.yahoo.vespa.orchestrator.BatchHostNameNotFoundException; import com.yahoo.vespa.orchestrator.BatchInternalErrorException; @@ -20,8 +19,6 @@ import java.io.IOException; import java.time.Clock; import java.time.Instant; import java.util.List; -import java.util.concurrent.Executors; -import java.util.stream.Collectors; import static com.yahoo.jdisc.http.HttpRequest.Method; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -45,15 +42,15 @@ class HostSuspensionRequestHandlerTest { @Test void returns_200_on_success_batch() throws IOException { - HostSuspensionRequestHandler handler = createHandler(HostRequestHandlerTest.createAlwaysAllowOrchestrator(clock)); - HttpResponse response = executeSuspendAllRequest(handler, "parentHostname", List.of("hostname1", "hostname2")); + RestApiTestDriver testDriver = createTestDriver(HostRequestHandlerTest.createAlwaysAllowOrchestrator(clock)); + HttpResponse response = executeSuspendAllRequest(testDriver, "parentHostname", List.of("hostname1", "hostname2")); assertSuccess(response); } @Test void returns_200_empty_batch() throws IOException { - HostSuspensionRequestHandler handler = createHandler(HostRequestHandlerTest.createAlwaysAllowOrchestrator(clock)); - HttpResponse response = executeSuspendAllRequest(handler, "parentHostname", List.of()); + RestApiTestDriver testDriver = createTestDriver(HostRequestHandlerTest.createAlwaysAllowOrchestrator(clock)); + HttpResponse response = executeSuspendAllRequest(testDriver, "parentHostname", List.of()); assertSuccess(response); } @@ -62,16 +59,16 @@ class HostSuspensionRequestHandlerTest { // hostnames are part of the request body for multi-host. @Test void returns_400_when_host_unknown_for_batch() { - HostSuspensionRequestHandler handler = createHandler(HostRequestHandlerTest.createHostNotFoundOrchestrator(clock)); - HttpResponse response = executeSuspendAllRequest(handler, "parentHostname", List.of("hostname1", "hostname2")); + RestApiTestDriver testDriver = createTestDriver(HostRequestHandlerTest.createHostNotFoundOrchestrator(clock)); + HttpResponse response = executeSuspendAllRequest(testDriver, "parentHostname", List.of("hostname1", "hostname2")); assertEquals(400, response.getStatus()); } @Test void returns_409_when_request_rejected_by_policies_for_batch() { OrchestratorImpl alwaysRejectResolver = HostRequestHandlerTest.createAlwaysRejectResolver(clock); - HostSuspensionRequestHandler handler = createHandler(alwaysRejectResolver); - HttpResponse response = executeSuspendAllRequest(handler, "parentHostname", List.of("hostname1", "hostname2")); + RestApiTestDriver testDriver = createTestDriver(alwaysRejectResolver); + HttpResponse response = executeSuspendAllRequest(testDriver, "parentHostname", List.of("hostname1", "hostname2")); assertEquals(409, response.getStatus()); } @@ -80,26 +77,20 @@ class HostSuspensionRequestHandlerTest { void throws_409_on_suspendAll_timeout() throws BatchHostStateChangeDeniedException, BatchHostNameNotFoundException, BatchInternalErrorException { Orchestrator orchestrator = mock(Orchestrator.class); doThrow(new UncheckedTimeoutException("Timeout Message")).when(orchestrator).suspendAll(any(), any()); - HostSuspensionRequestHandler handler = createHandler(orchestrator); - HttpResponse response = executeSuspendAllRequest(handler, "parenthost", List.of("h1", "h2", "h3")); + RestApiTestDriver testDriver = createTestDriver(orchestrator); + HttpResponse response = executeSuspendAllRequest(testDriver, "parenthost", List.of("h1", "h2", "h3")); assertEquals(409, response.getStatus()); } - private static HostSuspensionRequestHandler createHandler(Orchestrator orchestrator) { - return new HostSuspensionRequestHandler( - new LoggingRequestHandler.Context(Executors.newSingleThreadExecutor(), new MockMetric()), - orchestrator); + private static RestApiTestDriver createTestDriver(Orchestrator orchestrator) { + return RestApiTestDriver.newBuilder(ctx -> new HostSuspensionRequestHandler(ctx, orchestrator)) + .build(); } - private static HttpResponse executeSuspendAllRequest(HostSuspensionRequestHandler handler, String parentHostname, List<String> hostnames) { - StringBuilder uriBuilder = new StringBuilder("/orchestrator/v1/suspensions/hosts/").append(parentHostname); - if (!hostnames.isEmpty()) { - uriBuilder.append(hostnames.stream() - .map(hostname -> "hostname=" + hostname) - .collect(Collectors.joining("&", "?", ""))); - } - HttpRequest request = HttpRequest.createTestRequest(uriBuilder.toString(), Method.PUT); - return handler.handle(request); + private static HttpResponse executeSuspendAllRequest(RestApiTestDriver testDriver, String parentHostname, List<String> hostnames) { + var builder = HttpRequestBuilder.create(Method.PUT, "/orchestrator/v1/suspensions/hosts/" + parentHostname); + hostnames.forEach(hostname -> builder.withQueryParameter("hostname", hostname)); + return testDriver.executeRequest(builder.build()); } private static void assertSuccess(HttpResponse response) throws IOException { diff --git a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/InstanceRequestHandlerTest.java b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/InstanceRequestHandlerTest.java index bee19a6d6f5..0a2c73e831f 100644 --- a/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/InstanceRequestHandlerTest.java +++ b/orchestrator/src/test/java/com/yahoo/vespa/orchestrator/resources/InstanceRequestHandlerTest.java @@ -2,15 +2,12 @@ package com.yahoo.vespa.orchestrator.resources; import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.jdk8.Jdk8Module; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.yahoo.config.provision.ApplicationId; import com.yahoo.container.jdisc.HttpRequest; +import com.yahoo.container.jdisc.HttpRequestBuilder; import com.yahoo.container.jdisc.HttpResponse; -import com.yahoo.container.jdisc.LoggingRequestHandler; -import com.yahoo.jdisc.test.MockMetric; import com.yahoo.jrt.slobrok.api.Mirror; +import com.yahoo.restapi.RestApiTestDriver; import com.yahoo.vespa.applicationmodel.ClusterId; import com.yahoo.vespa.applicationmodel.ConfigId; import com.yahoo.vespa.applicationmodel.ServiceStatus; @@ -21,11 +18,9 @@ import com.yahoo.vespa.service.manager.UnionMonitorManager; import com.yahoo.vespa.service.monitor.SlobrokApi; import org.junit.jupiter.api.Test; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.List; -import java.util.concurrent.Executors; import static com.yahoo.jdisc.http.HttpRequest.Method.GET; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -45,19 +40,12 @@ class InstanceRequestHandlerTest { new Mirror.Entry("name1", "tcp/spec:1"), new Mirror.Entry("name2", "tcp/spec:2")); private static final ClusterId CLUSTER_ID = new ClusterId("cluster-id"); - private static final ObjectMapper jsonMapper = new ObjectMapper() - .registerModule(new JavaTimeModule()) - .registerModule(new Jdk8Module()); private final SlobrokApi slobrokApi = mock(SlobrokApi.class); private final UnionMonitorManager rootManager = mock(UnionMonitorManager.class); - private final InstanceRequestHandler handler = new InstanceRequestHandler( - new LoggingRequestHandler.Context(Executors.newSingleThreadExecutor(), new MockMetric()), - null, - null, - slobrokApi, - rootManager); - + private final RestApiTestDriver testDriver = + RestApiTestDriver.newBuilder(ctx -> new InstanceRequestHandler(ctx, null, null, slobrokApi, rootManager)) + .build(); @Test void testGetSlobrokEntries() throws Exception { @@ -78,13 +66,15 @@ class InstanceRequestHandlerTest { .thenReturn(new ServiceStatusInfo(serviceStatus)); - String uriPath = String.format( - "/orchestrator/v1/instances/%s/serviceStatusInfo?clusterId=%s&serviceType=%s&configId=%s", - APPLICATION_INSTANCE_REFERENCE, - CLUSTER_ID.s(), - serviceType.s(), - configId.s()); - ServiceStatusInfo serviceStatusInfo = executeRequest(uriPath, new TypeReference<>(){}); + String uriPath = String.format("/orchestrator/v1/instances/%s/serviceStatusInfo", APPLICATION_INSTANCE_REFERENCE); + HttpRequest request = HttpRequestBuilder.create(GET, uriPath) + .withQueryParameter("clusterId", CLUSTER_ID.s()) + .withQueryParameter("serviceType", serviceType.s()) + .withQueryParameter("configId", configId.s()) + .build(); + HttpResponse response = testDriver.executeRequest(request); + assertEquals(200, response.getStatus()); + ServiceStatusInfo serviceStatusInfo = testDriver.parseJacksonResponseContent(response, ServiceStatusInfo.class); ServiceStatus actualServiceStatus = serviceStatusInfo.serviceStatus(); verify(rootManager).getStatus(APPLICATION_ID, CLUSTER_ID, serviceType, configId); @@ -93,12 +83,11 @@ class InstanceRequestHandlerTest { @Test void testBadRequest() { - String uriPath = String.format( - "/orchestrator/v1/instances/%s/serviceStatusInfo?clusterId=%s", - APPLICATION_INSTANCE_REFERENCE, - CLUSTER_ID.s()); - HttpRequest request = HttpRequest.createTestRequest("http://localhost" + uriPath, GET); - HttpResponse response = handler.handle(request); + String uriPath = String.format("/orchestrator/v1/instances/%s/serviceStatusInfo", APPLICATION_INSTANCE_REFERENCE); + HttpRequest request = HttpRequestBuilder.create(GET, uriPath) + .withQueryParameter("clusterId", CLUSTER_ID.s()) + .build(); + HttpResponse response = testDriver.executeRequest(request); assertEquals(400, response.getStatus()); } @@ -108,25 +97,21 @@ class InstanceRequestHandlerTest { .thenReturn(ENTRIES); String uriPath = String.format("/orchestrator/v1/instances/%s/slobrok", APPLICATION_INSTANCE_REFERENCE); + var builder = HttpRequestBuilder.create(GET, uriPath); if (pattern != null) { - uriPath += "?pattern=" + pattern; + builder.withQueryParameter("pattern", pattern); } - List<SlobrokEntryResponse> response = executeRequest(uriPath, new TypeReference<>() {}); + HttpRequest request = builder.build(); + HttpResponse response = testDriver.executeRequest(request); + assertEquals(200, response.getStatus()); + List<SlobrokEntryResponse> result = testDriver.parseJacksonResponseContent(response, new TypeReference<>() {}); verify(slobrokApi).lookup(APPLICATION_ID, expectedLookupPattern); - String actualJson = jsonMapper.writeValueAsString(response); + String actualJson = testDriver.jacksonJsonMapper().writeValueAsString(result); assertEquals( "[{\"name\":\"name1\",\"spec\":\"tcp/spec:1\"},{\"name\":\"name2\",\"spec\":\"tcp/spec:2\"}]", actualJson); } - private <T> T executeRequest(String path, TypeReference<T> responseEntityType) throws IOException { - HttpRequest request = HttpRequest.createTestRequest("http://localhost" + path, GET); - HttpResponse response = handler.handle(request); - assertEquals(200, response.getStatus()); - ByteArrayOutputStream out = new ByteArrayOutputStream(); - response.render(out); - return jsonMapper.readValue(out.toByteArray(), responseEntityType); - } } |