Repository: incubator-zeppelin Updated Branches: refs/heads/master 690e2f343 -> 78c221924
Zeppelin - 241: Add REST API Setting CRUD tests This PR adds tests for create, Update Delete settings operations using REST API. Author: eranwitkon <[email protected]> Closes #286 from eranwitkon/241 and squashes the following commits: d73e72e [eranwitkon] Add test for REST API CRUD operation using POST,DELETE,PUT methods add305f [eranwitkon] adds test for the create, Update & delete REST API Project: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/commit/78c22192 Tree: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/tree/78c22192 Diff: http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/diff/78c22192 Branch: refs/heads/master Commit: 78c2219243d1741dff95c46926344993fe9a760c Parents: 690e2f3 Author: eranwitkon <[email protected]> Authored: Mon Sep 7 10:52:33 2015 +0300 Committer: Alexander Bezzubov <[email protected]> Committed: Tue Sep 8 12:06:57 2015 +0900 ---------------------------------------------------------------------- .../zeppelin/rest/AbstractTestRestApi.java | 83 ++++++++++++++------ .../zeppelin/rest/ZeppelinRestApiTest.java | 43 ++++++++-- 2 files changed, 96 insertions(+), 30 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/78c22192/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java ---------------------------------------------------------------------- diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java index aab8043..ecf0c72 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/AbstractTestRestApi.java @@ -22,14 +22,15 @@ import java.io.IOException; import java.lang.ref.WeakReference; import java.net.InetAddress; import java.net.UnknownHostException; +import java.util.Properties; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.apache.commons.httpclient.HttpClient; -import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; -import org.apache.commons.httpclient.methods.GetMethod; -import org.apache.commons.httpclient.methods.PostMethod; -import org.apache.commons.httpclient.methods.RequestEntity; +import org.apache.commons.httpclient.HttpMethodBase; +import org.apache.commons.httpclient.methods.*; +import org.apache.zeppelin.interpreter.InterpreterGroup; +import org.apache.zeppelin.interpreter.InterpreterOption; import org.apache.zeppelin.interpreter.InterpreterSetting; import org.apache.zeppelin.server.ZeppelinServer; import org.hamcrest.Description; @@ -93,14 +94,14 @@ public abstract class AbstractTestRestApi { long s = System.currentTimeMillis(); boolean started = false; while (System.currentTimeMillis() - s < 1000 * 60 * 3) { // 3 minutes - Thread.sleep(2000); - started = checkIfServerIsRuning(); - if (started == true) { - break; - } + Thread.sleep(2000); + started = checkIfServerIsRuning(); + if (started == true) { + break; + } } if (started == false) { - throw new RuntimeException("Can not start Zeppelin server"); + throw new RuntimeException("Can not start Zeppelin server"); } LOG.info("Test Zeppelin stared."); @@ -108,6 +109,7 @@ public abstract class AbstractTestRestApi { // ci environment runs spark cluster for testing // so configure zeppelin use spark cluster if ("true".equals(System.getenv("CI"))) { + // assume first one is spark InterpreterSetting sparkIntpSetting = null; for(InterpreterSetting intpSetting : ZeppelinServer.notebook.getInterpreterFactory().get()) { if (intpSetting.getGroup().equals("spark")) { @@ -124,6 +126,7 @@ public abstract class AbstractTestRestApi { ZeppelinServer.notebook.getInterpreterFactory().restart(sparkIntpSetting.id()); } else { + // assume first one is spark InterpreterSetting sparkIntpSetting = null; for(InterpreterSetting intpSetting : ZeppelinServer.notebook.getInterpreterFactory().get()) { if (intpSetting.getGroup().equals("spark")) { @@ -235,17 +238,27 @@ public abstract class AbstractTestRestApi { LOG.info("Connecting to {}", url + path); HttpClient httpClient = new HttpClient(); GetMethod getMethod = new GetMethod(url + path); - getMethod.addRequestHeader("Origin", "http://localhost:8080"); - httpClient.executeMethod(getMethod); + getMethod.addRequestHeader("Origin", url); + httpClient.executeMethod(getMethod); LOG.info("{} - {}", getMethod.getStatusCode(), getMethod.getStatusText()); return getMethod; } + protected static DeleteMethod httpDelete(String path) throws IOException { + LOG.info("Connecting to {}", url + path); + HttpClient httpClient = new HttpClient(); + DeleteMethod deleteMethod = new DeleteMethod(url + path); + deleteMethod.addRequestHeader("Origin", url); + httpClient.executeMethod(deleteMethod); + LOG.info("{} - {}", deleteMethod.getStatusCode(), deleteMethod.getStatusText()); + return deleteMethod; + } + protected static PostMethod httpPost(String path, String body) throws IOException { LOG.info("Connecting to {}", url + path); HttpClient httpClient = new HttpClient(); PostMethod postMethod = new PostMethod(url + path); - postMethod.addRequestHeader("Origin", "http://localhost:8080"); + postMethod.addRequestHeader("Origin", url); RequestEntity entity = new ByteArrayRequestEntity(body.getBytes("UTF-8")); postMethod.setRequestEntity(entity); httpClient.executeMethod(postMethod); @@ -253,14 +266,26 @@ public abstract class AbstractTestRestApi { return postMethod; } - protected Matcher<GetMethod> responsesWith(final int expectedStatusCode) { - return new TypeSafeMatcher<GetMethod>() { - WeakReference<GetMethod> method; + protected static PutMethod httpPut(String path, String body) throws IOException { + LOG.info("Connecting to {}", url + path); + HttpClient httpClient = new HttpClient(); + PutMethod putMethod = new PutMethod(url + path); + putMethod.addRequestHeader("Origin", url); + RequestEntity entity = new ByteArrayRequestEntity(body.getBytes("UTF-8")); + putMethod.setRequestEntity(entity); + httpClient.executeMethod(putMethod); + LOG.info("{} - {}", putMethod.getStatusCode(), putMethod.getStatusText()); + return putMethod; + } + + protected Matcher<HttpMethodBase> responsesWith(final int expectedStatusCode) { + return new TypeSafeMatcher<HttpMethodBase>() { + WeakReference<HttpMethodBase> method; @Override - public boolean matchesSafely(GetMethod getMethod) { - method = (method == null) ? new WeakReference<GetMethod>(getMethod) : method; - return getMethod.getStatusCode() == expectedStatusCode; + public boolean matchesSafely(HttpMethodBase httpMethodBase) { + method = (method == null) ? new WeakReference<HttpMethodBase>(httpMethodBase) : method; + return httpMethodBase.getStatusCode() == expectedStatusCode; } @Override @@ -270,7 +295,7 @@ public abstract class AbstractTestRestApi { } @Override - protected void describeMismatchSafely(GetMethod item, Description description) { + protected void describeMismatchSafely(HttpMethodBase item, Description description) { description.appendText("got ").appendValue(item.getStatusCode()).appendText(" ") .appendText(item.getStatusText()); } @@ -322,6 +347,14 @@ public abstract class AbstractTestRestApi { }; } + //Create new Setting and return Setting ID + protected String createTempSetting(String tempName) throws IOException { + + InterpreterGroup interpreterGroup = ZeppelinServer.notebook.getInterpreterFactory().add(tempName,"newGroup", + new InterpreterOption(false),new Properties()); + return interpreterGroup.getId(); + } + protected TypeSafeMatcher<? super JsonElement> hasRootElementNamed(final String memberName) { return new TypeSafeMatcher<JsonElement>() { @Override @@ -343,15 +376,15 @@ public abstract class AbstractTestRestApi { } /** Status code matcher */ - protected Matcher<? super GetMethod> isForbiden() { - return responsesWith(403); - } + protected Matcher<? super HttpMethodBase> isForbiden() { return responsesWith(403); } - protected Matcher<? super GetMethod> isAllowed() { + protected Matcher<? super HttpMethodBase> isAllowed() { return responsesWith(200); } - protected Matcher<? super GetMethod> isNotAllowed() { + protected Matcher<? super HttpMethodBase> isCreated() { return responsesWith(201); } + + protected Matcher<? super HttpMethodBase> isNotAllowed() { return responsesWith(405); } http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/78c22192/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java ---------------------------------------------------------------------- diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java index 6987362..e93815c 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java @@ -25,7 +25,10 @@ import java.io.IOException; import java.util.List; import java.util.Map; +import org.apache.commons.httpclient.methods.DeleteMethod; import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.PutMethod; import org.apache.zeppelin.conf.ZeppelinConfiguration; import org.apache.zeppelin.interpreter.InterpreterSetting; import org.apache.zeppelin.notebook.Note; @@ -42,7 +45,6 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; /** * BASIC Zeppelin rest api tests - * TODO: Add Post,Put,Delete test and method * * @author anthonycorbacho * @@ -81,9 +83,10 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi { // then assertThat(get, isAllowed()); - Map<String, Object> resp = gson.fromJson(get.getResponseBodyAsString(), new TypeToken<Map<String, Object>>(){}.getType()); + Map<String, Object> resp = gson.fromJson(get.getResponseBodyAsString(), new TypeToken<Map<String, Object>>() { + }.getType()); Map<String, Object> body = (Map<String, Object>) resp.get("body"); - assertEquals(ZeppelinConfiguration.ConfVars.ZEPPELIN_INTERPRETERS.getStringValue().split(",").length, body.size()); + assertEquals(ZeppelinServer.notebook.getInterpreterFactory().getRegisteredInterpreterList().size(), body.size()); get.releaseConnection(); } @@ -93,12 +96,42 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi { GetMethod get = httpGet("/interpreter/setting"); // then - Map<String, Object> resp = gson.fromJson(get.getResponseBodyAsString(), new TypeToken<Map<String, Object>>(){}.getType()); + Map<String, Object> resp = gson.fromJson(get.getResponseBodyAsString(), new TypeToken<Map<String, Object>>() { + }.getType()); assertThat(get, isAllowed()); get.releaseConnection(); } - + @Test + public void testSettingsCRUD() throws IOException { + // Call Create Setting REST API + String jsonRequest = "{\"name\":\"md2\",\"group\":\"md\",\"properties\":{\"propname\":\"propvalue\"},\"" + + "interpreterGroup\":[{\"class\":\"org.apache.zeppelin.markdown.Markdown\",\"name\":\"md\"}]}"; + PostMethod post = httpPost("/interpreter/setting/", jsonRequest); + LOG.info("testSettingCRUD create response\n" + post.getResponseBodyAsString()); + assertThat("test create method:", post, isCreated()); + + Map<String, Object> resp = gson.fromJson(post.getResponseBodyAsString(), new TypeToken<Map<String, Object>>() { + }.getType()); + Map<String, Object> body = (Map<String, Object>) resp.get("body"); + //extract id from body string {id=2AWMQDNX7, name=md2, group=md, + String newSettingId = body.toString().split(",")[0].split("=")[1]; + post.releaseConnection(); + + // Call Update Setting REST API + jsonRequest = "{\"name\":\"md2\",\"group\":\"md\",\"properties\":{\"propname\":\"Otherpropvalue\"},\"" + + "interpreterGroup\":[{\"class\":\"org.apache.zeppelin.markdown.Markdown\",\"name\":\"md\"}]}"; + PutMethod put = httpPut("/interpreter/setting/" + newSettingId, jsonRequest); + LOG.info("testSettingCRUD update response\n" + put.getResponseBodyAsString()); + assertThat("test update method:", put, isAllowed()); + put.releaseConnection(); + + // Call Delete Setting REST API + DeleteMethod delete = httpDelete("/interpreter/setting/" + newSettingId); + LOG.info("testSettingCRUD delete response\n" + delete.getResponseBodyAsString()); + assertThat("Test delete method:", delete, isAllowed()); + delete.releaseConnection(); + } @Test public void testInterpreterAutoBinding() throws IOException { // create note
