summaryrefslogtreecommitdiffstats
path: root/application/src/test/java
diff options
context:
space:
mode:
Diffstat (limited to 'application/src/test/java')
-rw-r--r--application/src/test/java/com/yahoo/application/ApplicationBuilderTest.java78
-rw-r--r--application/src/test/java/com/yahoo/application/container/JDiscContainerSearchTest.java60
-rw-r--r--application/src/test/java/com/yahoo/application/container/JDiscTest.java179
-rw-r--r--application/src/test/java/com/yahoo/application/container/handlers/TestHandler.java25
-rw-r--r--application/src/test/java/com/yahoo/application/container/jersey/JerseyTest.java193
-rw-r--r--application/src/test/java/com/yahoo/application/container/jersey/resources/TestResource.java14
-rw-r--r--application/src/test/java/com/yahoo/application/container/jersey/resources/nestedpackage1/NestedTestResource1.java14
-rw-r--r--application/src/test/java/com/yahoo/application/container/jersey/resources/nestedpackage2/NestedTestResource2.java14
-rw-r--r--application/src/test/java/com/yahoo/application/container/searchers/AddHitSearcher.java24
9 files changed, 601 insertions, 0 deletions
diff --git a/application/src/test/java/com/yahoo/application/ApplicationBuilderTest.java b/application/src/test/java/com/yahoo/application/ApplicationBuilderTest.java
new file mode 100644
index 00000000000..62b5fc9e1a8
--- /dev/null
+++ b/application/src/test/java/com/yahoo/application/ApplicationBuilderTest.java
@@ -0,0 +1,78 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.application;
+
+import com.yahoo.io.IOUtils;
+import org.junit.Test;
+
+import java.nio.file.Files;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * @author Tony Vaagenes
+ * @author ovirtanen
+ */
+public class ApplicationBuilderTest {
+ @Test
+ public void query_profile_types_can_be_added() throws Exception {
+ withApplicationBuilder(builder -> {
+ builder.queryProfileType("MyProfileType", "<query-profile-type id=\"MyProfileType\">" + //
+ "<field name=\"age\" type=\"integer\" />" + //
+ "<field name=\"profession\" type=\"string\" />" + //
+ "<field name=\"user\" type=\"query-profile:MyUserProfile\" />" + //
+ "</query-profile-type>");
+
+ assertTrue(Files.exists(builder.getPath().resolve("search/query-profiles/types/MyProfileType.xml")));
+ });
+ }
+
+ @Test
+ public void query_profile_can_be_added() throws Exception {
+ withApplicationBuilder(builder -> {
+ builder.queryProfile("MyProfile", "<query-profile id=\"MyProfile\">" + //
+ "<field name=\"message\">Hello world!</field>" + //
+ "</query-profile>");
+
+ assertTrue(Files.exists(builder.getPath().resolve("search/query-profiles/MyProfile.xml")));
+ });
+ }
+
+ @Test
+ public void rank_expression_can_be_added() throws Exception {
+ withApplicationBuilder(builder -> {
+ builder.rankExpression("myExpression", "content");
+ assertTrue(Files.exists(builder.getPath().resolve("searchdefinitions/myExpression.expression")));
+ });
+ }
+
+ @Test
+ public void builder_cannot_be_reused() throws Exception {
+ try {
+ ApplicationBuilder builder = new ApplicationBuilder();
+ builder.servicesXml("<jdisc version=\"1.0\" />");
+ builder.build();
+
+ builder.servicesXml("");
+ fail("Expected exception.");
+ } catch (RuntimeException e) {
+ assertThat(e.getMessage(), containsString("build method"));
+ }
+
+ }
+
+ private interface TestCase {
+ public void accept(ApplicationBuilder ab) throws Exception;
+ }
+
+ public void withApplicationBuilder(TestCase f) throws Exception {
+ ApplicationBuilder builder = new ApplicationBuilder();
+ try {
+ f.accept(builder);
+ } finally {
+ IOUtils.recursiveDeleteDir(builder.getPath().toFile());
+ }
+ }
+}
diff --git a/application/src/test/java/com/yahoo/application/container/JDiscContainerSearchTest.java b/application/src/test/java/com/yahoo/application/container/JDiscContainerSearchTest.java
new file mode 100644
index 00000000000..b94b4a67c67
--- /dev/null
+++ b/application/src/test/java/com/yahoo/application/container/JDiscContainerSearchTest.java
@@ -0,0 +1,60 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.application.container;
+
+import com.yahoo.application.Networking;
+import com.yahoo.application.container.searchers.AddHitSearcher;
+import com.yahoo.component.ComponentSpecification;
+import com.yahoo.search.Query;
+import com.yahoo.search.Result;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * @author gjoranv
+ * @author ovirtanen
+ */
+public class JDiscContainerSearchTest {
+ @Test
+ public void processing_and_rendering_works() throws Exception {
+ final String searcherId = AddHitSearcher.class.getName();
+
+ try (JDisc container = containerWithSearch(searcherId)) {
+ byte[] rendered = container.search().processAndRender(ComponentSpecification.fromString("mychain"),
+ ComponentSpecification.fromString("DefaultRenderer"), new Query(""));
+ String renderedAsString = new String(rendered, "utf-8");
+ assertThat(renderedAsString, containsString(searcherId));
+ }
+ }
+
+ @Test
+ public void searching_works() throws Exception {
+ final String searcherId = AddHitSearcher.class.getName();
+
+ try (JDisc container = containerWithSearch(searcherId)) {
+ Search searching = container.search();
+ Result result = searching.process(ComponentSpecification.fromString("mychain"), new Query(""));
+ String hitTitle = result.hits().get(0).getField("title").toString();
+ assertThat(hitTitle, is(searcherId));
+ }
+ }
+
+ public JDisc containerWithSearch(String searcherId) {
+ return JDisc.fromServicesXml("<container version=\"1.0\">" + //
+ "<search>" + //
+ "<chain id=\"mychain\">" + //
+ "<searcher id=\"" + searcherId + "\"/>" + //
+ "</chain>" + //
+ "</search>" + //
+ "</container>", Networking.disable);
+ }
+
+ @Test(expected = UnsupportedOperationException.class)
+ public void retrieving_search_from_container_without_search_is_illegal() throws Exception {
+ try (JDisc container = JDisc.fromServicesXml("<container version=\"1.0\" />", Networking.disable)) {
+ container.search(); // throws
+ }
+ }
+}
diff --git a/application/src/test/java/com/yahoo/application/container/JDiscTest.java b/application/src/test/java/com/yahoo/application/container/JDiscTest.java
new file mode 100644
index 00000000000..3526708c84a
--- /dev/null
+++ b/application/src/test/java/com/yahoo/application/container/JDiscTest.java
@@ -0,0 +1,179 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.application.container;
+
+import com.yahoo.application.Application;
+import com.yahoo.application.ApplicationBuilder;
+import com.yahoo.application.Networking;
+import com.yahoo.application.container.handler.Request;
+import com.yahoo.application.container.handler.Response;
+import com.yahoo.application.container.handlers.TestHandler;
+import com.yahoo.component.ComponentSpecification;
+import com.yahoo.container.Container;
+import com.yahoo.jdisc.http.server.jetty.JettyHttpServer;
+import com.yahoo.jdisc.service.ServerProvider;
+import com.yahoo.search.Query;
+import com.yahoo.search.Result;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.nio.charset.CharacterCodingException;
+import java.nio.file.FileSystems;
+
+import static com.yahoo.application.container.JDisc.fromServicesXml;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+/**
+ * @author Tony Vaagenes
+ * @author gjoranv
+ * @author ovirtanen
+ */
+public class JDiscTest {
+ @Test
+ public void jdisc_can_be_used_as_top_level_element() throws Exception {
+ try (JDisc container = fromServicesXml("<jdisc version=\"1.0\">" + //
+ "<search />" + //
+ "</jdisc>", Networking.disable)) {
+ assertNotNull(container.search());
+ }
+ }
+
+ @Test
+ public void jdisc_id_can_be_set() throws Exception {
+ try (JDisc container = fromServicesXml("<jdisc version=\"1.0\" id=\"my-service-id\">" + //
+ "<search />" + //
+ "</jdisc>", Networking.disable)) {
+ assertNotNull(container.search());
+ }
+ }
+
+ @Test
+ public void jdisc_can_be_embedded_in_services_tag() throws Exception {
+ try (JDisc container = fromServicesXml("<services>" + //
+ "<jdisc version=\"1.0\" id=\"my-service-id\">" + //
+ "<search />" + //
+ "</jdisc>" + //
+ "</services>", Networking.disable)) {
+ assertNotNull(container.search());
+ }
+ }
+
+ @Test
+ @SuppressWarnings("try") // container is unused inside the try block
+ public void multiple_jdisc_elements_gives_exception() {
+ try (JDisc container = fromServicesXml("<services>" + //
+ "<jdisc version=\"1.0\" id=\"id1\" />" + //
+ "<jdisc version=\"1.0\" />" + //
+ "<container version=\"1.0\"/>" + //
+ "</services>", Networking.disable)) {
+ fail("expected exception");
+ } catch (Exception e) {
+ assertThat(e.getMessage(), containsString("container id='', jdisc id='id1', jdisc id=''"));
+ }
+ }
+
+ @Test
+ public void handleRequest_yields_response_from_correct_request_handler() throws Exception {
+ final String handlerClass = TestHandler.class.getName();
+ try (JDisc container = fromServicesXml("<container version=\"1.0\">" + //
+ "<handler id=\"test-handler\" class=\"" + handlerClass + "\">" + //
+ "<binding>http://*/TestHandler</binding>" + //
+ "</handler>" + //
+ "</container>", Networking.disable)) {
+ Response response = container.handleRequest(new Request("http://foo/TestHandler"));
+ try {
+ assertThat(response.getBodyAsString(), is(TestHandler.RESPONSE));
+ } catch (CharacterCodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Test
+ public void load_searcher_from_bundle() throws Exception {
+ try (JDisc container = JDisc.fromPath(FileSystems.getDefault().getPath("src/test/app-packages/searcher-app"),
+ Networking.disable)) {
+ Result result = container.search().process(ComponentSpecification.fromString("default"),
+ new Query("?query=ignored"));
+ assertThat(result.hits().get(0).getField("title").toString(), is("Heal the World!"));
+ }
+ }
+
+ @Test
+ public void document_types_can_be_accessed() throws Exception {
+ try (Application application = new ApplicationBuilder().documentType("example", EXAMPLE_DOCUMENT)
+ .servicesXml(CONTAINER_WITH_DOCUMENT_PROCESSING).build()) {
+ JDisc container = application.getJDisc("jdisc");
+ DocumentProcessing processing = container.documentProcessing();
+ assertThat(processing.getDocumentTypes().keySet(), hasItem("example"));
+ }
+ }
+
+ @Test
+ public void annotation_types_can_be_accessed() throws Exception {
+ try (Application application = new ApplicationBuilder().documentType("example", "search example {\n" + //
+ " " + EXAMPLE_DOCUMENT + "\n" + //
+ " annotation exampleAnnotation {}\n" + //
+ "}\n").//
+ servicesXml(CONTAINER_WITH_DOCUMENT_PROCESSING).build()) {
+ JDisc container = application.getJDisc("jdisc");
+ DocumentProcessing processing = container.documentProcessing();
+ assertThat(processing.getAnnotationTypes().keySet(), hasItem("exampleAnnotation"));
+ }
+ }
+
+ @Ignore // Enable this when static state has been removed.
+ @Test
+ public void multiple_containers_can_be_run_in_parallel() throws Exception {
+ try (JDisc jdisc1 = jdiscWithHttp(); JDisc jdisc2 = jdiscWithHttp()) {
+ sendRequest(jdisc1);
+ sendRequest(jdisc2);
+ }
+ }
+
+ private void sendRequest(JDisc jdisc) throws CharacterCodingException {
+ Response response = jdisc.handleRequest(new Request("http://foo/TestHandler"));
+ assertThat(response.getBodyAsString(), is(TestHandler.RESPONSE));
+ }
+
+ public static final String CONTAINER_WITH_DOCUMENT_PROCESSING = //
+ "<jdisc version=\"1.0\">" + //
+ "<http />" + //
+ "<document-processing />" + //
+ "</jdisc>";
+
+ public static final String EXAMPLE_DOCUMENT = //
+ "document example {\n" + //
+ "\n" + //
+ " field title type string {\n" + //
+ " indexing: summary | index # How this field should be indexed\n" + //
+ " weight: 75 # Ranking importancy of this field, used by the built in nativeRank feature\n" + //
+ " header\n" + //
+ " }\n" + //
+ "}\n";
+
+ protected JDisc jdiscWithHttp() {
+ final String handlerId = TestHandler.class.getName();
+ final String xml = //
+ "<jdisc version=\"1.0\">" + //
+ "<handler id=" + handlerId + " />" + //
+ "<http>\n" + //
+ "<server id=\"main\" port=\"9999\" />\n" + //
+ "</http>\n" + //
+ "</jdisc>";
+ return JDisc.fromServicesXml(xml, Networking.disable);
+ }
+
+ public static int getListenPort() {
+ for (ServerProvider server : Container.get().getServerProviderRegistry().allComponents()) {
+ if (null != server && server instanceof JettyHttpServer) {
+ return ((JettyHttpServer) server).getListenPort();
+ }
+ }
+ throw new RuntimeException("No http server found");
+ }
+}
diff --git a/application/src/test/java/com/yahoo/application/container/handlers/TestHandler.java b/application/src/test/java/com/yahoo/application/container/handlers/TestHandler.java
new file mode 100644
index 00000000000..6da8783cf86
--- /dev/null
+++ b/application/src/test/java/com/yahoo/application/container/handlers/TestHandler.java
@@ -0,0 +1,25 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.application.container.handlers;
+
+import com.yahoo.jdisc.handler.AbstractRequestHandler;
+import com.yahoo.jdisc.handler.ContentChannel;
+import com.yahoo.jdisc.handler.FastContentWriter;
+import com.yahoo.jdisc.handler.ResponseDispatch;
+import com.yahoo.jdisc.handler.ResponseHandler;
+
+/**
+ * @author gjoranv
+ * @author ovirtanen
+ */
+public class TestHandler extends AbstractRequestHandler {
+ public static final String RESPONSE = "Hello, World!";
+
+ public ContentChannel handleRequest(com.yahoo.jdisc.Request request, ResponseHandler handler) {
+ FastContentWriter writer = ResponseDispatch.newInstance(com.yahoo.jdisc.Response.Status.OK)
+ .connectFastWriter(handler);
+ writer.write(RESPONSE);
+ writer.close();
+ return null;
+ }
+
+}
diff --git a/application/src/test/java/com/yahoo/application/container/jersey/JerseyTest.java b/application/src/test/java/com/yahoo/application/container/jersey/JerseyTest.java
new file mode 100644
index 00000000000..e85bd6ba4d9
--- /dev/null
+++ b/application/src/test/java/com/yahoo/application/container/jersey/JerseyTest.java
@@ -0,0 +1,193 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.application.container.jersey;
+
+import com.yahoo.application.Networking;
+import com.yahoo.application.container.JDisc;
+import com.yahoo.application.container.JDiscTest;
+import com.yahoo.application.container.jersey.resources.TestResource;
+import com.yahoo.application.container.jersey.resources.nestedpackage1.NestedTestResource1;
+import com.yahoo.application.container.jersey.resources.nestedpackage2.NestedTestResource2;
+import com.yahoo.container.test.jars.jersey.resources.TestResourceBase;
+import com.yahoo.osgi.maven.ProjectBundleClassPaths;
+import com.yahoo.osgi.maven.ProjectBundleClassPaths.BundleClasspathMapping;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.util.EntityUtils;
+import org.junit.Test;
+
+import javax.ws.rs.core.UriBuilder;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static java.util.Collections.emptyList;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Tony Vaagenes
+ * @author ovirtanen
+ */
+public class JerseyTest {
+ private final Path testJar = Paths.get("target/test-jars/jersey-resources.jar");
+ private final String testClassesDirectory = "target/test-classes";
+ private final String bundleSymbolicName = "myBundle";
+
+ private static final Set<Class<? extends TestResourceBase>> classPathResources;
+ private static final Set<Class<? extends TestResourceBase>> jarFileResources;
+
+ static {
+ classPathResources = new HashSet<>();
+ classPathResources.add(TestResource.class);
+ classPathResources.add(NestedTestResource1.class);
+ classPathResources.add(NestedTestResource2.class);
+
+ jarFileResources = new HashSet<>();
+ jarFileResources.add(com.yahoo.container.test.jars.jersey.resources.TestResource.class);
+ jarFileResources.add(com.yahoo.container.test.jars.jersey.resources.nestedpackage1.NestedTestResource1.class);
+ jarFileResources.add(com.yahoo.container.test.jars.jersey.resources.nestedpackage2.NestedTestResource2.class);
+ }
+
+ @Test
+ public void jersey_resources_on_classpath_can_be_invoked_from_application() throws Exception {
+ saveMainBundleClassPathMappings(testClassesDirectory);
+
+ with_jersey_resources(emptyList(), httpGetter -> assertResourcesResponds(classPathResources, httpGetter));
+ }
+
+ @Test
+ public void jersey_resources_in_provided_dependencies_can_be_invoked_from_application() throws Exception {
+ BundleClasspathMapping providedDependency = new BundleClasspathMapping(bundleSymbolicName,
+ Arrays.asList(testClassesDirectory));
+
+ save(new ProjectBundleClassPaths(new BundleClasspathMapping("main", emptyList()),
+ Arrays.asList(providedDependency)));
+ with_jersey_resources(emptyList(), httpGetter -> assertResourcesResponds(classPathResources, httpGetter));
+ }
+
+ @Test
+ public void jersey_resource_on_classpath_can_be_filtered_using_packages() throws Exception {
+ saveMainBundleClassPathMappings(testClassesDirectory);
+
+ with_jersey_resources(Arrays.asList("com.yahoo.application.container.jersey.resources",
+ "com.yahoo.application.container.jersey.resources.nestedpackage1"), httpGetter -> {
+ Class<NestedTestResource2> nestedResource2 = NestedTestResource2.class;
+ assertDoesNotRespond(nestedResource2, httpGetter);
+ assertResourcesResponds(copySetExcept(classPathResources, nestedResource2), httpGetter);
+ });
+ }
+
+ @Test
+ public void jersey_resource_in_jar_can_be_invoked_from_application() throws Exception {
+ saveMainBundleJarClassPathMappings(testJar);
+
+ with_jersey_resources(emptyList(), httpGetter -> assertResourcesResponds(jarFileResources, httpGetter));
+ }
+
+ @Test
+ public void jersey_resource_in_jar_can_be_filtered_using_packages() throws Exception {
+ saveMainBundleJarClassPathMappings(testJar);
+
+ with_jersey_resources(Arrays.asList("com.yahoo.container.test.jars.jersey.resources",
+ "com.yahoo.container.test.jars.jersey.resources.nestedpackage1"), httpGetter -> {
+ Class<com.yahoo.container.test.jars.jersey.resources.nestedpackage2.NestedTestResource2> nestedResource2 = com.yahoo.container.test.jars.jersey.resources.nestedpackage2.NestedTestResource2.class;
+
+ assertDoesNotRespond(nestedResource2, httpGetter);
+ assertResourcesResponds(copySetExcept(jarFileResources, nestedResource2), httpGetter);
+ });
+ }
+
+ private static <T> Set<T> copySetExcept(Set<T> in, T except) {
+ Set<T> ret = new HashSet<>(in);
+ ret.remove(except);
+ return ret;
+ }
+
+ private interface ThrowingConsumer<T> {
+ public void accept(T arg) throws Exception;
+ }
+
+ private interface HttpGetter {
+ public HttpResponse get(String path) throws Exception;
+ }
+
+ @SuppressWarnings("try") // jdisc unused inside try-with-resources
+ private void with_jersey_resources(List<String> packagesToScan, ThrowingConsumer<HttpGetter> f) throws Exception {
+ StringBuffer packageElements = new StringBuffer();
+ for (String p : packagesToScan) {
+ packageElements.append("<package>");
+ packageElements.append(p);
+ packageElements.append("</package>");
+ }
+
+ try (JDisc jdisc = JDisc.fromServicesXml(
+ "<services>" + //
+ "<jdisc version=\"1.0\" id=\"default\" jetty=\"true\">" + //
+ "<rest-api path=\"rest-api\" jersey2=\"true\">" + //
+ "<components bundle=\"" + bundleSymbolicName + "\">" + //
+ packageElements + //
+ "</components>" + //
+ "</rest-api>" + //
+ "<http>" + //
+ "<server id=\"mainServer\" port=\"0\" />" + //
+ "</http>" + //
+ "</jdisc>" + //
+ "</services>", //
+ Networking.enable)) {
+ final int port = JDiscTest.getListenPort();
+ f.accept(path -> {
+ String p = path.startsWith("/") ? path.substring(1) : path;
+ CloseableHttpClient client = HttpClientBuilder.create().build();
+ return client.execute(new HttpGet("http://localhost:" + port + "/rest-api/" + p));
+ });
+ }
+ }
+
+ public void assertResourcesResponds(Collection<Class<? extends TestResourceBase>> resourceClasses,
+ HttpGetter httpGetter) throws Exception {
+ for (Class<? extends TestResourceBase> resource : resourceClasses) {
+ HttpResponse response = httpGetter.get(path(resource));
+ assertThat("Failed sending response to " + resource, response.getStatusLine().getStatusCode(), is(200));
+
+ String content = IOUtils.toString(response.getEntity().getContent());
+ assertThat(content, is(TestResourceBase.content(resource)));
+ }
+ }
+
+ public void assertDoesNotRespond(Class<? extends TestResourceBase> resourceClass, HttpGetter httpGetter)
+ throws Exception {
+ HttpResponse response = httpGetter.get(path(resourceClass));
+ assertThat(response.getStatusLine().getStatusCode(), is(404));
+ EntityUtils.consume(response.getEntity());
+ }
+
+ public void saveMainBundleJarClassPathMappings(Path jarFile) throws Exception {
+ assertTrue("Couldn't find file " + jarFile + ", please remember to run mvn process-test-resources first.",
+ Files.isRegularFile(jarFile));
+ saveMainBundleClassPathMappings(jarFile.toAbsolutePath().toString());
+ }
+
+ public void saveMainBundleClassPathMappings(String classPathElement) throws Exception {
+ BundleClasspathMapping mainBundleClassPathMappings = new BundleClasspathMapping(bundleSymbolicName,
+ Arrays.asList(classPathElement));
+ save(new ProjectBundleClassPaths(mainBundleClassPathMappings, emptyList()));
+ }
+
+ public void save(ProjectBundleClassPaths projectBundleClassPaths) throws Exception {
+ Path path = Paths.get(testClassesDirectory).resolve(ProjectBundleClassPaths.CLASSPATH_MAPPINGS_FILENAME);
+ ProjectBundleClassPaths.save(path, projectBundleClassPaths);
+ }
+
+ public String path(Class<?> resourceClass) {
+ return UriBuilder.fromResource(resourceClass).build().toString();
+ }
+}
diff --git a/application/src/test/java/com/yahoo/application/container/jersey/resources/TestResource.java b/application/src/test/java/com/yahoo/application/container/jersey/resources/TestResource.java
new file mode 100644
index 00000000000..b3c21ae4f99
--- /dev/null
+++ b/application/src/test/java/com/yahoo/application/container/jersey/resources/TestResource.java
@@ -0,0 +1,14 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.application.container.jersey.resources;
+
+import com.yahoo.container.test.jars.jersey.resources.TestResourceBase;
+
+import javax.ws.rs.Path;
+
+/**
+ * @author Tony Vaagenes
+ * @author ovirtanen
+ */
+@Path("/test-resource")
+public class TestResource extends TestResourceBase {
+}
diff --git a/application/src/test/java/com/yahoo/application/container/jersey/resources/nestedpackage1/NestedTestResource1.java b/application/src/test/java/com/yahoo/application/container/jersey/resources/nestedpackage1/NestedTestResource1.java
new file mode 100644
index 00000000000..6fc03c034c0
--- /dev/null
+++ b/application/src/test/java/com/yahoo/application/container/jersey/resources/nestedpackage1/NestedTestResource1.java
@@ -0,0 +1,14 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.application.container.jersey.resources.nestedpackage1;
+
+import com.yahoo.container.test.jars.jersey.resources.TestResourceBase;
+
+import javax.ws.rs.Path;
+
+/**
+ * @author Tony Vaagenes
+ * @author ovirtanen
+ */
+@Path("/nested-test-resource1")
+public class NestedTestResource1 extends TestResourceBase {
+}
diff --git a/application/src/test/java/com/yahoo/application/container/jersey/resources/nestedpackage2/NestedTestResource2.java b/application/src/test/java/com/yahoo/application/container/jersey/resources/nestedpackage2/NestedTestResource2.java
new file mode 100644
index 00000000000..a592b072f6e
--- /dev/null
+++ b/application/src/test/java/com/yahoo/application/container/jersey/resources/nestedpackage2/NestedTestResource2.java
@@ -0,0 +1,14 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.application.container.jersey.resources.nestedpackage2;
+
+import com.yahoo.container.test.jars.jersey.resources.TestResourceBase;
+
+import javax.ws.rs.Path;
+
+/**
+ * @author Tony Vaagenes
+ * @author ovirtanen
+ */
+@Path("/nested-test-resource2")
+public class NestedTestResource2 extends TestResourceBase {
+}
diff --git a/application/src/test/java/com/yahoo/application/container/searchers/AddHitSearcher.java b/application/src/test/java/com/yahoo/application/container/searchers/AddHitSearcher.java
new file mode 100644
index 00000000000..274c37bcfc1
--- /dev/null
+++ b/application/src/test/java/com/yahoo/application/container/searchers/AddHitSearcher.java
@@ -0,0 +1,24 @@
+// Copyright 2018 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.application.container.searchers;
+
+import com.yahoo.search.Query;
+import com.yahoo.search.Result;
+import com.yahoo.search.Searcher;
+import com.yahoo.search.result.Hit;
+import com.yahoo.search.searchchain.Execution;
+
+public class AddHitSearcher extends Searcher {
+ @Override
+ public Result search(Query query, Execution execution) {
+ Result result = execution.search(query);
+ result.hits().add(getDummyHit());
+
+ return result;
+ }
+
+ private Hit getDummyHit() {
+ Hit hit = new Hit("dummy");
+ hit.setField("title", getId().getName());
+ return hit;
+ }
+}