parameters) {
+ server.addGlobalFilter(name, classname, parameters);
+ }
+
+ /**
+ * 지정한 hostname 과 port 를 기반으로 서버를 구동한다.
+ * @throws IOException
+ */
+ protected void runServer() throws IOException {
+ if (running == false && server == null) {
+ initServer();
+ }
+ if (running == false) {
+ server.start();
+ running = true;
+ }
+ }
+
+ /**
+ * 구동된 서버를 중지시킨다.
+ * @throws Exception
+ */
+ protected void stopServer() throws Exception {
+ if (server == null) {
+ throw new Exception("server is not running");
+ }
+ server.stop();
+ }
+
+ @SuppressWarnings("unchecked")
+ protected P requestToServer(String method, String path) throws Exception {
+ if (isRunning() == false) {
+ runServer();
+ }
+
+ DefaultHttpClient client = new DefaultHttpClient();
+ HttpUriRequest request = invokeMethod(method, getPageURI(path));
+ Page page = new Page(new WebResponse(client.execute(request)));
+ return (P) page;
+ /*
+ // HTMLUnit 으로 작성했다가 필요한 Library 가 워낙 많아서 주석 처리하고 httpcomponent 4.x 으로 변경하고 하위에 inner class 만들었습니다.
+ // maven 을 사용하면 test 용 library 는 제외시키기 편한데 ant 는 건드려야 할 것이 많아서 급 수정
+ WebClient client = new WebClient();
+ WebRequest request = new WebRequest(new URL(getPageURI(path)), HttpMethod.valueOf(method.toUpperCase()));
+ try {
+ return (P) client.getPage(request);
+ } catch (FailingHttpStatusCodeException e) {
+ Page page = new HtmlPage(request.getUrl(), e.getResponse(), client.getCurrentWindow());
+ return (P) page;
+ } catch (MalformedURLException e) {
+ throw e;
+ } catch (IOException e) {
+ throw e;
+ } finally {
+ client.closeAllWindows();
+ }
+ */
+ }
+
+ private HttpUriRequest invokeMethod(String method, String page) {
+ Map> methods = new HashMap>();
+ methods.put("GET", HttpGet.class);
+ methods.put("PUT", HttpPut.class);
+ methods.put("POST", HttpPost.class);
+ methods.put("OPTIONS", HttpOptions.class);
+ methods.put("HEAD", HttpHead.class);
+ methods.put("TRACE", HttpTrace.class);
+ methods.put("DELETE", HttpDelete.class);
+ try {
+ return methods.get(method.toUpperCase()).getConstructor(String.class).newInstance(page);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private boolean isRunning() {
+ return running;
+ }
+
+ /**
+ * 테스트에 사용할 URL 문자열을 만든다.
+ * @param path
+ * @return
+ */
+ protected String getPageURI(String path) {
+ return new StringBuilder("http://").append(getAuthority()).append(path).toString();
+ }
+
+ protected String getAuthority() {
+ return getPort() == 80 ? getHostname() : getHostname() + ":" + getPort();
+ }
+
+ protected String getWebContextPath() {
+ return webContextPath;
+ }
+
+ protected String getHostname() {
+ return hostname;
+ }
+
+ protected int getPort() {
+ return port;
+ }
+
+
+ /**
+ * HtmlUnit 의 Page class 를 코드변경없이 사용하고자 동일한 이름의 클래스로 필요한 것만 작성
+ */
+ protected static class Page {
+ WebResponse response;
+
+ Page(WebResponse response) {
+ this.response = response;
+ }
+
+ public WebResponse getWebResponse() {
+ return response;
+ }
+ }
+
+ /**
+ * HtmlUnit 의 WebResponse class 를 코드변경없이 사용하고자 동일한 이름의 클래스로 필요한 것만 작성
+ */
+ protected static class WebResponse {
+ HttpResponse response;
+
+ WebResponse(HttpResponse response) {
+ this.response = response;
+ }
+
+ public String getResponseHeaderValue(String name) {
+ return response.getFirstHeader(name).getValue();
+ }
+
+ public int getStatusCode() {
+ return response.getStatusLine().getStatusCode();
+ }
+ }
+}
diff --git a/src/test/com/gruter/common/http/TestCommonHttpServer.java b/src/test/com/gruter/common/http/TestCommonHttpServer.java
new file mode 100644
index 0000000..785f343
--- /dev/null
+++ b/src/test/com/gruter/common/http/TestCommonHttpServer.java
@@ -0,0 +1,118 @@
+package com.gruter.common.http;
+
+import static org.hamcrest.CoreMatchers.is;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.zookeeper.server.ServerConfig;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.gruter.common.zk.ZooKeeperLocalServer;
+
+/**
+ * @author Daegeun Kim
+ */
+public class TestCommonHttpServer extends CommonHttpServerTestCase {
+ public TestCommonHttpServer() {
+ super("common_webapps");
+ }
+
+ @Before
+ public void before() throws Exception {
+ initServer();
+ }
+
+ @After
+ public void after() throws Exception {
+ stopServer();
+ }
+
+ @Test
+ public void test200() throws Exception {
+ Page page = requestToServer("GET", "/zktree.html");
+
+ Assert.assertThat(200, is(page.getWebResponse().getStatusCode()));
+ }
+
+ @Test
+ public void test404() throws Exception {
+ Page page = requestToServer("GET", "/12312310293i81093jfpawejfiwoejfowaiej.html");
+
+ Assert.assertThat(404, is(page.getWebResponse().getStatusCode()));
+ }
+
+ @Test
+ public void testServlet() throws Exception {
+ addServlet("test-servlet", "/test", TestServlet.class);
+ Page page = requestToServer("GET", "/test");
+
+ Assert.assertThat(200, is(page.getWebResponse().getStatusCode()));
+ }
+
+ @Test
+ public void testFilter() throws Exception {
+ addFilter("test-filter", TestFilter.class.getName(), null);
+ Page page = requestToServer("GET", "/zktree.html");
+
+ Assert.assertThat(200, is(page.getWebResponse().getStatusCode()));
+ Assert.assertThat(TestFilter.class.getName(), is(getHeader(page, "X-Filter")));
+ }
+
+ @Test
+ public void testGlobalFilter() throws Exception {
+ addServlet("test-servlet", "/test", TestServlet.class);
+ addGlobalFilter("test-filter", TestFilter.class.getName(), null);
+ Page page = requestToServer("GET", "/test");
+
+ Assert.assertThat(200, is(page.getWebResponse().getStatusCode()));
+ Assert.assertThat(TestFilter.class.getName(), is(getHeader(page, "X-Filter")));
+ }
+
+ private String getHeader(Page page, String headerName) {
+ return page.getWebResponse().getResponseHeaderValue(headerName);
+ }
+
+ /**
+ * 테스트용으로 사용할 Filter
+ */
+ public static class TestFilter implements Filter {
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+ ((HttpServletResponse) response).addHeader("X-Filter", TestFilter.class.getName());
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+ @Override
+ public void init(FilterConfig arg0) throws ServletException {
+ }
+ }
+
+ /**
+ * 테스트용으로 사용할 Servlet
+ */
+ public static class TestServlet extends HttpServlet {
+ private static final long serialVersionUID = -1990697247757359833L;
+
+ @Override
+ protected void service(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+ response.setContentType("text/html; charset=UTF-8");
+ }
+ }
+}
diff --git a/src/test/com/gruter/common/zk/TestZKManagerWebServer.java b/src/test/com/gruter/common/zk/TestZKManagerWebServer.java
new file mode 100644
index 0000000..2362194
--- /dev/null
+++ b/src/test/com/gruter/common/zk/TestZKManagerWebServer.java
@@ -0,0 +1,43 @@
+package com.gruter.common.zk;
+
+import static org.hamcrest.CoreMatchers.is;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.gruter.common.http.CommonHttpServerTestCase;
+import com.gruter.common.http.ZKControllerServlet;
+
+/**
+ * @author Daegeun Kim
+ */
+public class TestZKManagerWebServer extends CommonHttpServerTestCase {
+ public TestZKManagerWebServer() {
+ super("common_webapps");
+ }
+
+ @Before
+ public void before() throws Exception {
+ initServer();
+ }
+
+ @After
+ public void after() throws Exception {
+ stopServer();
+ }
+
+ @Test
+ public void testZookeeperServlet() throws Exception {
+ ZooKeeperLocalServer zkserver = new ZooKeeperLocalServer();
+ zkserver.run(21333);
+
+ addServlet("zk-servlet", "/zookeeper", ZKControllerServlet.class);
+ Page page = requestToServer("GET", "/zookeeper?action=GetZKNodeDetail&zkservers=127.0.0.1%3A21333&dir=%2F");
+
+ zkserver.shutdown();
+ Assert.assertThat(200, is(page.getWebResponse().getStatusCode()));
+ //TODO: 임의의 znode 와 data 를 추가하고 넘겨받은 json 결과와 data 비교 검증 필요.
+ }
+}
diff --git a/src/test/com/gruter/common/zk/ZooKeeperLocalServer.java b/src/test/com/gruter/common/zk/ZooKeeperLocalServer.java
new file mode 100644
index 0000000..0177128
--- /dev/null
+++ b/src/test/com/gruter/common/zk/ZooKeeperLocalServer.java
@@ -0,0 +1,38 @@
+package com.gruter.common.zk;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.UUID;
+
+import org.apache.zookeeper.server.ServerConfig;
+import org.apache.zookeeper.server.ZooKeeperServerMain;
+
+/**
+ * zookeeper 는 잘 몰라서 제대로 짠 걸까요. :-)
+ * @author Daegeun Kim
+ */
+public class ZooKeeperLocalServer extends ZooKeeperServerMain {
+ private File tempDir = null;
+
+ public void run(int clientPort) throws IOException {
+ String tempdir = System.getProperty("java.io.tmpdir");
+ tempDir = new File(tempdir, UUID.randomUUID().toString());
+ tempDir.mkdirs();
+ final ServerConfig config = new ServerConfig();
+ config.parse(new String[] { "" + clientPort, tempDir.getAbsolutePath() });
+ new Thread(new Runnable() {
+ public void run() {
+ try {
+ runFromConfig(config);
+ } catch (IOException e) {
+ }
+ }
+ }).start();
+ }
+
+ @Override
+ public void shutdown() {
+ super.shutdown();
+ tempDir.delete();
+ }
+}