summaryrefslogtreecommitdiffstats
path: root/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/RestApiTest.java
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/RestApiTest.java
Publish
Diffstat (limited to 'vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/RestApiTest.java')
-rw-r--r--vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/RestApiTest.java298
1 files changed, 298 insertions, 0 deletions
diff --git a/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/RestApiTest.java b/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/RestApiTest.java
new file mode 100644
index 00000000000..036dc63ad34
--- /dev/null
+++ b/vespaclient-container-plugin/src/test/java/com/yahoo/document/restapi/resource/RestApiTest.java
@@ -0,0 +1,298 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.document.restapi.resource;
+
+import com.yahoo.application.Application;
+import com.yahoo.application.Networking;
+import com.yahoo.application.container.handler.Request;
+import com.yahoo.container.Container;
+import com.yahoo.jdisc.http.server.jetty.JettyHttpServer;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.entity.ContentType;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.util.EntityUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.nio.file.Paths;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsNot.not;
+import static org.hamcrest.core.StringContains.containsString;
+import static org.hamcrest.core.StringStartsWith.startsWith;
+import static org.junit.Assert.assertThat;
+
+public class RestApiTest {
+ Application application;
+
+ @Before
+ public void setup() throws Exception {
+ application = Application.fromApplicationPackage(Paths.get("src/test/application"), Networking.enable);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ application.close();
+ }
+
+ String post_test_uri = "/document/v1/namespace/testdocument/docid/c";
+ String post_test_doc = "{\n" +
+ "\"foo\" : \"bar\"," +
+ "\"fields\": {\n" +
+ "\"title\": \"This is the title\",\n" +
+ "\"body\": \"This is the body\"" +
+ "}" +
+ "}";
+ String post_test_response = "{\"id\":\"id:namespace:testdocument::c\"," +
+ "\"pathId\":\"/document/v1/namespace/testdocument/docid/c\"}";
+
+ // Run this test to manually do request against the REST-API with backend mock.
+ @Ignore
+ @Test
+ public void blockingTest() throws Exception {
+ System.out.println("Running on port " + getFirstListenPort());
+ Thread.sleep(Integer.MAX_VALUE);
+ }
+
+ @Test
+ public void testbasicPost() throws Exception {
+ Request request = new Request("http://localhost:" + getFirstListenPort() + post_test_uri);
+ HttpPost httpPost = new HttpPost(request.getUri());
+ StringEntity entity = new StringEntity(post_test_doc, ContentType.create("application/json"));
+ httpPost.setEntity(entity);
+ String x = doRest(httpPost);
+ assertThat(x, is(post_test_response));
+ }
+
+ String post_test_uri_cond = "/document/v1/namespace/testdocument/docid/c?condition=foo";
+ String post_test_doc_cond = "{\n" +
+ "\"foo\" : \"bar\"," +
+ "\"fields\": {\n" +
+ "\"title\": \"This is the title\",\n" +
+ "\"body\": \"This is the body\"" +
+ "}" +
+ "}";
+ String post_test_response_cond = "{\"id\":\"id:namespace:testdocument::c\"," +
+ "\"pathId\":\"/document/v1/namespace/testdocument/docid/c\"}";
+
+ @Test
+ public void testConditionalPost() throws Exception {
+ Request request = new Request("http://localhost:" + getFirstListenPort() + post_test_uri_cond);
+ HttpPost httpPost = new HttpPost(request.getUri());
+ StringEntity entity = new StringEntity(post_test_doc_cond, ContentType.create("application/json"));
+ httpPost.setEntity(entity);
+ String x = doRest(httpPost);
+ assertThat(x, is(post_test_response_cond));
+ }
+
+ String post_test_empty_response = "{\"errors\":[\"Could not read document, no document?\"]";
+ @Test
+ public void testEmptyPost() throws Exception {
+ Request request = new Request("http://localhost:" + getFirstListenPort() + post_test_uri);
+ HttpPost httpPost = new HttpPost(request.getUri());
+ StringEntity entity = new StringEntity("", ContentType.create("application/json"));
+ httpPost.setEntity(entity);
+ String x = doRest(httpPost);
+ assertThat(x, startsWith(post_test_empty_response));
+ }
+
+ String update_test_uri = "/document/v1/namespace/testdocument/docid/c";
+ String update_test_doc = "{\n" +
+ "\t\"fields\": {\n" +
+ "\"title\": {\n" +
+ "\"assign\": \"Oh lala\"\n" +
+ "}\n" +
+ "}\n" +
+ "}\n";
+
+ String update_test_response = "{\"id\":\"id:namespace:testdocument::c\"," +
+ "\"pathId\":\"/document/v1/namespace/testdocument/docid/c\"}";
+
+ @Test
+ public void testbasicUpdate() throws Exception {
+ Request request = new Request("http://localhost:" + getFirstListenPort() + update_test_uri);
+ HttpPut httpPut = new HttpPut(request.getUri());
+ StringEntity entity = new StringEntity(update_test_doc, ContentType.create("application/json"));
+ httpPut.setEntity(entity);
+ assertThat(doRest(httpPut), is(update_test_response));
+ assertThat(getLog(), not(containsString("CREATE IF NON EXISTING IS TRUE")));
+ }
+
+ @Test
+ public void testbasicUpdateCreateTrue() throws Exception {
+ Request request = new Request("http://localhost:" + getFirstListenPort() + update_test_uri + "?create=true");
+ HttpPut httpPut = new HttpPut(request.getUri());
+ StringEntity entity = new StringEntity(update_test_doc, ContentType.create("application/json"));
+ httpPut.setEntity(entity);
+ assertThat(doRest(httpPut), is(update_test_response));
+ assertThat(getLog(), containsString("CREATE IF NON EXISTENT IS TRUE"));
+ }
+
+ String update_test_create_if_non_existient_uri = "/document/v1/namespace/testdocument/docid/c";
+ String update_test_create_if_non_existient_doc = "{\n" +
+ "\"create\":true," +
+ "\t\"fields\": {\n" +
+ "\"title\": {\n" +
+ "\"assign\": \"Oh lala\"\n" +
+ "}\n" +
+ "}\n" +
+ "}\n";
+
+ String update_test_create_if_non_existing_response = "{\"id\":\"id:namespace:testdocument::c\"," +
+ "\"pathId\":\"/document/v1/namespace/testdocument/docid/c\"}";
+
+ @Test
+ public void testCreateIfNonExistingUpdateInDocTrue() throws Exception {
+ Request request = new Request("http://localhost:" + getFirstListenPort() + update_test_create_if_non_existient_uri);
+ HttpPut httpPut = new HttpPut(request.getUri());
+ StringEntity entity = new StringEntity(update_test_create_if_non_existient_doc, ContentType.create("application/json"));
+ httpPut.setEntity(entity);
+ assertThat(doRest(httpPut), is(update_test_create_if_non_existing_response));
+ assertThat(getLog(), containsString("CREATE IF NON EXISTENT IS TRUE"));
+
+ }
+
+ @Test
+ public void testCreateIfNonExistingUpdateInDocTrueButQueryParamsFalse() throws Exception {
+ Request request = new Request("http://localhost:" + getFirstListenPort() + update_test_create_if_non_existient_uri + "?create=false");
+ HttpPut httpPut = new HttpPut(request.getUri());
+ StringEntity entity = new StringEntity(update_test_create_if_non_existient_doc, ContentType.create("application/json"));
+ httpPut.setEntity(entity);
+ assertThat(doRest(httpPut), is(update_test_create_if_non_existing_response));
+ assertThat(getLog(), not(containsString("CREATE IF NON EXISTENT IS TRUE")));
+
+ }
+
+ // Get logs through some hackish fetch method. Logs is something the mocked backend write.
+ String getLog() throws IOException {
+ // The mocked backend will throw a runtime exception wtih a log if delete is called three times..
+ Request request = new Request("http://localhost:" + getFirstListenPort() + remove_test_uri);
+ HttpDelete delete = new HttpDelete(request.getUri());
+ doRest(delete);
+ return doRest(delete);
+ }
+
+
+ String remove_test_uri = "/document/v1/namespace/testdocument/docid/c";
+ String remove_test_response = "{\"id\":\"id:namespace:testdocument::c\"," +
+ "\"pathId\":\"/document/v1/namespace/testdocument/docid/c\"}";
+
+ @Test
+ public void testbasicRemove() throws Exception {
+ Request request = new Request("http://localhost:" + getFirstListenPort() + remove_test_uri);
+ HttpDelete delete = new HttpDelete(request.getUri());
+ assertThat(doRest(delete), is(remove_test_response));
+ }
+
+ String get_test_uri = "/document/v1/namespace/document-type/docid/c";
+ String get_response_part1 = "\"pathId\":\"/document/v1/namespace/document-type/docid/c\"";
+ String get_response_part2 = "\"id\":\"id:namespace:document-type::c\"";
+
+
+ @Test
+ public void testbasicGet() throws Exception {
+ Request request = new Request("http://localhost:" + getFirstListenPort() + get_test_uri);
+ HttpGet get = new HttpGet(request.getUri());
+ final String rest = doRest(get);
+ assertThat(rest, containsString(get_response_part1));
+ assertThat(rest, containsString(get_response_part2));
+ }
+
+ String id_test_uri = "/document/v1/namespace/document-type/docid/f/u/n/n/y/!";
+ String id_response_part1 = "\"pathId\":\"/document/v1/namespace/document-type/docid/f/u/n/n/y/!\"";
+ String id_response_part2 = "\"id\":\"id:namespace:document-type::f/u/n/n/y/!\"";
+
+ @Test
+ public void testSlashesInId() throws Exception {
+ Request request = new Request("http://localhost:" + getFirstListenPort() + id_test_uri);
+ HttpGet get = new HttpGet(request.getUri());
+ final String rest = doRest(get);
+ assertThat(rest, containsString(id_response_part1));
+ assertThat(rest, containsString(id_response_part2));
+ }
+
+
+ String get_enc_id = "!\":æøå@/& Q1+";
+ // Space encoded as %20, not encoding !
+ String get_enc_id_encoded_v1 = "!%22%3A%C3%A6%C3%B8%C3%A5%40%2F%26%20Q1%2B";
+ // Space encoded as +
+ String get_enc_id_encoded_v2 = "%21%22%3A%C3%A6%C3%B8%C3%A5%40%2F%26+Q1%2B";
+ String get_enc_test_uri_v1 = "/document/v1/namespace/document-type/docid/" + get_enc_id_encoded_v1;
+ String get_enc_test_uri_v2 = "/document/v1/namespace/document-type/docid/" + get_enc_id_encoded_v2;
+ String get_enc_response_part1 = "\"pathId\":\"/document/v1/namespace/document-type/docid/" + get_enc_id_encoded_v1 + "\"";
+ String get_enc_response_part1_v2 = "\"pathId\":\"/document/v1/namespace/document-type/docid/" + get_enc_id_encoded_v2 + "\"";
+
+ // JSON encode " as \"
+ String get_enc_response_part2 = "\"id\":\"id:namespace:document-type::" + get_enc_id.replace("\"", "\\\"") + "\"";
+
+
+ @Test
+ public void testbasicEncodingV1() throws Exception {
+ Request request = new Request("http://localhost:" + getFirstListenPort() + get_enc_test_uri_v1);
+ HttpGet get = new HttpGet(request.getUri());
+ final String rest = doRest(get);
+ assertThat(rest, containsString(get_enc_response_part1));
+ assertThat(rest, containsString(get_enc_response_part2));
+ }
+
+ @Test
+ public void testbasicEncodingV2() throws Exception {
+ Request request = new Request("http://localhost:" + getFirstListenPort() + get_enc_test_uri_v2);
+ HttpGet get = new HttpGet(request.getUri());
+ final String rest = doRest(get);
+ assertThat(rest, containsString(get_enc_response_part1_v2));
+ assertThat(rest, containsString(get_enc_response_part2));
+ }
+
+ String visit_test_uri = "/document/v1/namespace/document-type/docid/?continuation=abc";
+ String visit_response_part1 = "\"documents\":[List of json docs, cont token abc, doc selection: '']";
+ String visit_response_part2 = "\"continuation\":\"token\"";
+ String visit_response_part3 = "\"pathId\":\"/document/v1/namespace/document-type/docid/\"";
+
+
+ @Test
+ public void testbasicVisit() throws Exception {
+ Request request = new Request("http://localhost:" + getFirstListenPort() + visit_test_uri);
+ HttpGet get = new HttpGet(request.getUri());
+ final String rest = doRest(get);
+ assertThat(rest, containsString(visit_response_part1));
+ assertThat(rest, containsString(visit_response_part2));
+ assertThat(rest, containsString(visit_response_part3));
+ }
+
+ String visit_test_bad_uri = "/document/v1/namespace/document-type/group/abc?continuation=abc";
+ String visit_test_bad_response = "Visiting does not support setting value for group/value,";
+
+
+ @Test
+ public void testBadVisit() throws Exception {
+ final Request request = new Request("http://localhost:" + getFirstListenPort() + visit_test_bad_uri);
+ HttpGet get = new HttpGet(request.getUri());
+ final String rest = doRest(get);
+ assertThat(rest, containsString(visit_test_bad_response));
+ }
+
+ private String doRest(HttpRequestBase request) throws IOException {
+ HttpClient client = HttpClientBuilder.create().build();
+ HttpResponse response = client.execute(request);
+ HttpEntity entity = response.getEntity();
+ return EntityUtils.toString(entity);
+ }
+
+ private String getFirstListenPort() {
+ JettyHttpServer serverProvider =
+ (JettyHttpServer) Container.get().getServerProviderRegistry().allComponents().get(0);
+ return Integer.toString(serverProvider.getListenPort());
+ }
+
+}