summaryrefslogtreecommitdiffstats
path: root/container-search
diff options
context:
space:
mode:
authorHenrik <henrik.hoiness@online.no>2018-06-21 15:32:58 +0200
committerHenrik <henrik.hoiness@online.no>2018-06-22 09:21:06 +0200
commitd8cb472c08ef2bae48aa534030aa9ad97a1e73c2 (patch)
treeba0469ea7c5ef7cf91bb5ca1ad92e562371271e9 /container-search
parentd42507a3cffe99007b61f72d4c53bd43f9298c6e (diff)
Added a few unit-tests for JSON-queries
Diffstat (limited to 'container-search')
-rw-r--r--container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java470
1 files changed, 470 insertions, 0 deletions
diff --git a/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java b/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java
new file mode 100644
index 00000000000..00354af5d30
--- /dev/null
+++ b/container-search/src/test/java/com/yahoo/search/handler/test/JSONSearchHandlerTestCase.java
@@ -0,0 +1,470 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.search.handler.test;
+
+import com.yahoo.container.Container;
+import com.yahoo.container.core.config.testutil.HandlersConfigurerTestWrapper;
+import com.yahoo.container.jdisc.AsyncHttpResponse;
+import com.yahoo.container.jdisc.HttpRequest;
+
+import com.yahoo.container.jdisc.HttpResponse;
+import com.yahoo.container.jdisc.RequestHandlerTestDriver;
+import com.yahoo.container.jdisc.ThreadedHttpRequestHandler;
+import com.yahoo.io.IOUtils;
+import com.yahoo.jdisc.handler.RequestHandler;
+import com.yahoo.net.HostName;
+import com.yahoo.processing.handler.ResponseStatus;
+import com.yahoo.search.Query;
+import com.yahoo.search.Result;
+import com.yahoo.search.Searcher;
+import com.yahoo.search.handler.HttpSearchResponse;
+import com.yahoo.search.handler.SearchHandler;
+import com.yahoo.search.rendering.DefaultRenderer;
+import com.yahoo.search.result.ErrorMessage;
+import com.yahoo.search.result.Hit;
+import com.yahoo.search.searchchain.Execution;
+import com.yahoo.search.searchchain.config.test.SearchChainConfigurerTestCase;
+import com.yahoo.text.JSON;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.*;
+import java.net.URI;
+import java.util.*;
+import java.util.concurrent.Executors;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.*;
+
+
+public class JSONSearchHandlerTestCase {
+
+ private static final String testDir = "src/test/java/com/yahoo/search/handler/test/config";
+ private static final String myHostnameHeader = "my-hostname-header";
+ private static final String selfHostname = HostName.getLocalhost();
+
+ private static String tempDir = "";
+ private static String configId = null;
+ private static final String uri = "http://localhost?";
+
+ @Rule
+ public TemporaryFolder tempfolder = new TemporaryFolder();
+
+ private RequestHandlerTestDriver driver = null;
+ private HandlersConfigurerTestWrapper configurer = null;
+ private SearchHandler searchHandler;
+
+ @Before
+ public void startUp() throws IOException {
+ File cfgDir = tempfolder.newFolder("SearchHandlerTestCase");
+ tempDir = cfgDir.getAbsolutePath();
+ configId = "dir:" + tempDir;
+
+ IOUtils.copyDirectory(new File(testDir), cfgDir, 1); // make configs active
+ generateComponentsConfigForActive();
+
+ configurer = new HandlersConfigurerTestWrapper(new Container(), configId);
+ searchHandler = (SearchHandler)configurer.getRequestHandlerRegistry().getComponent(SearchHandler.class.getName());
+ driver = new RequestHandlerTestDriver(searchHandler);
+ }
+
+ @After
+ public void shutDown() {
+ if (configurer != null) configurer.shutdown();
+ if (driver != null) driver.close();
+ }
+
+ private void generateComponentsConfigForActive() throws IOException {
+ File activeConfig = new File(tempDir);
+ SearchChainConfigurerTestCase.
+ createComponentsConfig(new File(activeConfig, "chains.cfg").getPath(),
+ new File(activeConfig, "handlers.cfg").getPath(),
+ new File(activeConfig, "components.cfg").getPath());
+ }
+
+ private SearchHandler fetchSearchHandler(HandlersConfigurerTestWrapper configurer) {
+ return (SearchHandler) configurer.getRequestHandlerRegistry().getComponent(SearchHandler.class.getName());
+ }
+
+
+ @Test
+ public void testFailing() throws Exception {
+ JSONObject json = new JSONObject();
+ json.put("query", "test");
+ json.put("searchChain", "classLoadingError");
+ assertTrue(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString()).readAll().contains("NoClassDefFoundError"));
+ }
+
+
+ @Test
+ public synchronized void testPluginError() throws Exception {
+ JSONObject json = new JSONObject();
+ json.put("query", "test");
+ json.put("searchChain", "exceptionInPlugin");
+ assertTrue(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString()).readAll().contains("NullPointerException"));
+ }
+
+ @Test
+ public synchronized void testWorkingReconfiguration() throws Exception {
+ JSONObject json = new JSONObject();
+ json.put("query", "abc");
+ assertJsonResult(json, driver);
+
+ // reconfiguration
+ IOUtils.copyDirectory(new File(testDir, "handlers2"), new File(tempDir), 1);
+ generateComponentsConfigForActive();
+ configurer.reloadConfig();
+
+ // ...and check the resulting config
+ SearchHandler newSearchHandler = fetchSearchHandler(configurer);
+ assertNotSame("Have a new instance of the search handler", searchHandler, newSearchHandler);
+ assertNotNull("Have the new search chain", fetchSearchHandler(configurer).getSearchChainRegistry().getChain("hello"));
+ assertNull("Don't have the new search chain", fetchSearchHandler(configurer).getSearchChainRegistry().getChain("classLoadingError"));
+ try (RequestHandlerTestDriver newDriver = new RequestHandlerTestDriver(searchHandler)) {
+ assertJsonResult(json, newDriver);
+ }
+ }
+
+ @Test
+ public void testInvalidYqlQuery() throws Exception {
+ IOUtils.copyDirectory(new File(testDir, "config_yql"), new File(tempDir), 1);
+ generateComponentsConfigForActive();
+ configurer.reloadConfig();
+
+ SearchHandler newSearchHandler = fetchSearchHandler(configurer);
+ assertTrue("Do I have a new instance of the search handler?", searchHandler != newSearchHandler);
+ try (RequestHandlerTestDriver newDriver = new RequestHandlerTestDriver(newSearchHandler)) {
+ JSONObject json = new JSONObject();
+ json.put("yql", "select * from foo where bar > 1453501295");
+ RequestHandlerTestDriver.MockResponseHandler responseHandler = newDriver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString());
+ responseHandler.readAll();
+ assertThat(responseHandler.getStatus(), is(400));
+ }
+ }
+
+ // Query handling takes a different code path when a query profile is active, so we test both paths.
+ @Test
+ public void testInvalidQueryParamWithQueryProfile() throws Exception {
+ try (RequestHandlerTestDriver newDriver = driverWithConfig("config_invalid_param")) {
+ testInvalidQueryParam(newDriver);
+ }
+ }
+
+ private void testInvalidQueryParam(final RequestHandlerTestDriver testDriver) throws Exception{
+ JSONObject json = new JSONObject();
+ json.put("query", "status_code:0");
+ json.put("hits", 20);
+ json.put("offset", -20);
+ RequestHandlerTestDriver.MockResponseHandler responseHandler =
+ testDriver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString());
+ String response = responseHandler.readAll();
+ System.out.println(response);
+ assertThat(responseHandler.getStatus(), is(400));
+ assertThat(response, containsString("offset"));
+ assertThat(response, containsString("\"code\":" + com.yahoo.container.protect.Error.INVALID_QUERY_PARAMETER.code));
+ }
+
+
+
+
+ @Test
+ public void testNormalResultJsonAliasRendering() throws Exception {
+ JSONObject json = new JSONObject();
+ json.put("format", "json");
+ json.put("query", "abc");
+ assertJsonResult(json, driver);
+ }
+
+
+
+ @Test
+ public void testNullQuery() throws Exception {
+ JSONObject json = new JSONObject();
+ json.put("format", "xml");
+
+ assertEquals("<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
+ "<result total-hit-count=\"0\">\n" +
+ " <hit relevancy=\"1.0\">\n" +
+ " <field name=\"relevancy\">1.0</field>\n" +
+ " <field name=\"uri\">testHit</field>\n" +
+ " </hit>\n" +
+ "</result>\n", driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString()).readAll());
+ }
+
+
+
+ @Test
+ public void testWebServiceStatus() throws Exception {
+ JSONObject json = new JSONObject();
+ json.put("query", "web_service_status_code");
+ RequestHandlerTestDriver.MockResponseHandler responseHandler =
+ driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString());
+ String response = responseHandler.readAll();
+ assertThat(responseHandler.getStatus(), is(406));
+ assertThat(response, containsString("\"code\":" + 406));
+ }
+
+ @Test
+ public void testNormalResultImplicitDefaultRendering() throws Exception {
+ JSONObject json = new JSONObject();
+ json.put("query", "abc");
+ assertJsonResult(json, driver);
+ }
+
+ @Test
+ public void testNormalResultExplicitDefaultRendering() throws Exception {
+ JSONObject json = new JSONObject();
+ json.put("query", "abc");
+ json.put("format", "default");
+ assertJsonResult(json, driver);
+ }
+
+ @Test
+ public void testNormalResultXmlAliasRendering() throws Exception {
+ JSONObject json = new JSONObject();
+ json.put("query", "abc");
+ json.put("format", "xml");
+ assertXmlResult(json, driver);
+ }
+
+
+ @Test
+ public void testNormalResultExplicitDefaultRenderingFullRendererName1() throws Exception {
+ JSONObject json = new JSONObject();
+ json.put("query", "abc");
+ json.put("format", "DefaultRenderer");
+ assertXmlResult(json, driver);
+ }
+
+ @Test
+ public void testNormalResultExplicitDefaultRenderingFullRendererName2() throws Exception {
+ JSONObject json = new JSONObject();
+ json.put("query", "abc");
+ json.put("format", "JsonRenderer");
+ assertJsonResult(json, driver);
+ }
+
+ @Test
+ public void testResultLegacyTiledFormat() throws Exception {
+ JSONObject json = new JSONObject();
+ json.put("query", "abc");
+ json.put("format", "tiled");
+ assertTiledResult(json, driver);
+ }
+
+ @Test
+ public void testResultLegacyPageFormat() throws Exception {
+ JSONObject json = new JSONObject();
+ json.put("query", "abc");
+ json.put("format", "page");
+ assertPageResult(json, driver);
+ }
+
+
+ private static final String xmlResult =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
+ "<result total-hit-count=\"0\">\n" +
+ " <hit relevancy=\"1.0\">\n" +
+ " <field name=\"relevancy\">1.0</field>\n" +
+ " <field name=\"uri\">testHit</field>\n" +
+ " </hit>\n" +
+ "</result>\n";
+
+ private void assertXmlResult(JSONObject json, RequestHandlerTestDriver driver) throws Exception {
+ assertOkResult(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString()), xmlResult);
+ }
+
+
+ private static final String jsonResult = "{\"root\":{"
+ + "\"id\":\"toplevel\",\"relevance\":1.0,\"fields\":{\"totalCount\":0},"
+ + "\"children\":["
+ + "{\"id\":\"testHit\",\"relevance\":1.0,\"fields\":{\"uri\":\"testHit\"}}"
+ + "]}}";
+
+ private void assertJsonResult(JSONObject json, RequestHandlerTestDriver driver) throws Exception {
+ assertOkResult(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString()), jsonResult);
+
+ }
+
+ private static final String tiledResult =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
+ "<result version=\"1.0\">\n" +
+ "\n" +
+ " <hit relevance=\"1.0\">\n" +
+ " <id>testHit</id>\n" +
+ " <uri>testHit</uri>\n" +
+ " </hit>\n" +
+ "\n" +
+ "</result>\n";
+
+ private void assertTiledResult(JSONObject json, RequestHandlerTestDriver driver) throws Exception {
+ assertOkResult(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString()), tiledResult);
+ }
+
+ private static final String pageResult =
+ "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" +
+ "<page version=\"1.0\">\n" +
+ "\n" +
+ " <content>\n" +
+ " <hit relevance=\"1.0\">\n" +
+ " <id>testHit</id>\n" +
+ " <uri>testHit</uri>\n" +
+ " </hit>\n" +
+ " </content>\n" +
+ "\n" +
+ "</page>\n";
+
+ private void assertPageResult(JSONObject json, RequestHandlerTestDriver driver) throws Exception {
+ assertOkResult(driver.sendRequest(uri, com.yahoo.jdisc.http.HttpRequest.Method.POST, json.toString()), pageResult);
+ }
+
+ private void assertOkResult(RequestHandlerTestDriver.MockResponseHandler response, String expected) {
+ assertEquals(expected, response.readAll());
+ assertEquals(200, response.getStatus());
+ assertEquals(selfHostname, response.getResponse().headers().get(myHostnameHeader).get(0));
+ }
+
+
+ private RequestHandlerTestDriver driverWithConfig(String configDirectory) throws Exception {
+ IOUtils.copyDirectory(new File(testDir, configDirectory), new File(tempDir), 1);
+ generateComponentsConfigForActive();
+ configurer.reloadConfig();
+
+ SearchHandler newSearchHandler = fetchSearchHandler(configurer);
+ assertTrue("Do I have a new instance of the search handler?", searchHandler != newSearchHandler);
+ return new RequestHandlerTestDriver(newSearchHandler);
+ }
+
+
+
+ /*
+ private Map<String, String> createRequestMapping(JSONObject json) {
+ // Create mapping
+ Map<String, String> requestMap = new HashMap<String, String>();
+ Iterator<?> keys = json.keys();
+
+ while( keys.hasNext() ){
+ String key = (String)keys.next();
+ String value = null;
+ try {
+ value = json.getString(key);
+ requestMap.put(key, value);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ return requestMap;
+ }
+
+ @Test
+ public void testRequestMapping() throws Exception {
+ JSONObject json = new JSONObject();
+ json.put("yql","select * from sources * where sddocname contains \"blog_post\" limit 0 | all(group(date) max(3) order(-count())each(output(count())));");
+ json.put("hits","10");
+ json.put("offset","5");
+ json.put("queryProfile","foo");
+ json.put("nocache","false");
+ json.put("groupingSessionCache","false");
+ json.put("searchChain","exceptionInPlugin");
+ json.put("timeout","0");
+ json.put("tracelevel","1");
+ json.put("trace.timestamps","false");
+
+ JSONObject model = new JSONObject();
+ model.put("defaultIndex","1");
+ model.put("encoding","json");
+ model.put("filter", "default");
+ model.put("language","en");
+ model.put("queryString", "abc");
+ model.put("restrict", "_doc,json,xml");
+ model.put("searchPath", "node1");
+ model.put("sources", "source1,source2");
+ model.put("type", "yql");
+ json.put("model", model);
+
+ JSONObject ranking = new JSONObject();
+ ranking.put("location","123789.89123N;128123W");
+ ranking.put("features","none");
+ ranking.put("listFeatures", "boolean");
+ ranking.put("profile","1");
+ ranking.put("properties", "default");
+ ranking.put("sorting", "desc");
+ ranking.put("freshness", "0.05");
+ ranking.put("queryCache", "false");
+
+ JSONObject matchPhase = new JSONObject();
+ matchPhase.put("maxHits","100");
+ matchPhase.put("attribute","title");
+ matchPhase.put("ascending", "true");
+
+ JSONObject diversity = new JSONObject();
+ diversity.put("attribute","title");
+ diversity.put("minGroups","1");
+ matchPhase.put("diversity", diversity);
+ ranking.put("matchPhase", matchPhase);
+ json.put("ranking", ranking);
+
+ JSONObject presentation = new JSONObject();
+ presentation.put("bolding","true");
+ presentation.put("format","json");
+ presentation.put("summary", "none");
+ presentation.put("template","json");
+ presentation.put("timing", "false");
+ json.put("presentation", presentation);
+
+ JSONObject grouping = new JSONObject();
+ grouping.put("select","_all");
+ grouping.put("collapsefield","none");
+ grouping.put("collapsesize", "2");
+ grouping.put("collapse.summary","default");
+ json.put("grouping", grouping);
+
+ JSONObject pos = new JSONObject();
+ pos.put("ll","1263123N;1231.9W");
+ pos.put("radius","71234m");
+ pos.put("bb", "1237123W;123218N");
+ pos.put("attribute","default");
+ json.put("pos", pos);
+
+ JSONObject streaming = new JSONObject();
+ streaming.put("userid",";123");
+ streaming.put("groupname","abc");
+ streaming.put("selection", "none");
+ streaming.put("priority","10");
+ streaming.put("maxbucketspervisitor","5");
+ json.put("streaming", streaming);
+
+ JSONObject rules = new JSONObject();
+ rules.put("off",";false");
+ rules.put("rulebase","default");
+ json.put("rules", rules);
+
+ json.put("recall","none");
+ json.put("user", "123");
+ json.put("nocachewrite", "false");
+ json.put("hitcountestimate", "true");
+ json.put("metrics.ignore", "false");
+
+ //Create reqMap from JSON.
+ //Create URI-Request with same query
+ //Compare maps
+
+ System.out.println(json.toString());
+ assertTrue(false);
+
+
+
+
+
+
+
+ }*/
+
+
+}