You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tajo.apache.org by hy...@apache.org on 2015/08/14 16:30:07 UTC

[28/51] [partial] tajo git commit: TAJO-1761: Separate an integration unit test kit into an independent module.

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestTaskExecutor.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestTaskExecutor.java b/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestTaskExecutor.java
new file mode 100644
index 0000000..7cb7e71
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestTaskExecutor.java
@@ -0,0 +1,315 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.worker;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.service.CompositeService;
+import org.apache.hadoop.yarn.event.AsyncDispatcher;
+import org.apache.tajo.*;
+import org.apache.tajo.catalog.statistics.TableStats;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.master.cluster.WorkerConnectionInfo;
+import org.apache.tajo.rpc.CallFuture;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.worker.event.NodeResourceAllocateEvent;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.apache.tajo.ResourceProtos.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TestTaskExecutor {
+
+  private NodeResourceManager resourceManager;
+  private NodeStatusUpdater statusUpdater;
+  private TaskManager taskManager;
+  private MyTaskExecutor taskExecutor;
+  private AsyncDispatcher dispatcher;
+  private AsyncDispatcher taskDispatcher;
+  private TajoWorker.WorkerContext workerContext;
+
+  private CompositeService service;
+  private TajoConf conf;
+  private Semaphore barrier;
+  private Semaphore resourceManagerBarrier;
+
+  @Before
+  public void setup() {
+    conf = new TajoConf();
+    conf.set(CommonTestingUtil.TAJO_TEST_KEY, CommonTestingUtil.TAJO_TEST_TRUE);
+    conf.setIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_CPU_CORES, 2);
+    conf.setIntVar(TajoConf.ConfVars.SHUFFLE_FETCHER_PARALLEL_EXECUTION_MAX_NUM, 2);
+    dispatcher = new AsyncDispatcher();
+    taskDispatcher = new AsyncDispatcher();
+
+    workerContext = new MockWorkerContext() {
+      WorkerConnectionInfo workerConnectionInfo;
+
+      @Override
+      public TajoConf getConf() {
+        return conf;
+      }
+
+      @Override
+      public TaskManager getTaskManager() {
+        return taskManager;
+      }
+
+      @Override
+      public org.apache.tajo.worker.TaskExecutor getTaskExecuor() {
+        return taskExecutor;
+      }
+
+      @Override
+      public NodeResourceManager getNodeResourceManager() {
+        return resourceManager;
+      }
+
+      @Override
+      public WorkerConnectionInfo getConnectionInfo() {
+        if (workerConnectionInfo == null) {
+          workerConnectionInfo = new WorkerConnectionInfo("host", 28091, 28092, 21000, 28093, 28080);
+        }
+        return workerConnectionInfo;
+      }
+    };
+
+    barrier = new Semaphore(0);
+    resourceManagerBarrier = new Semaphore(0);
+    taskManager = new MockTaskManager(new Semaphore(0), taskDispatcher, workerContext);
+    taskExecutor = new MyTaskExecutor(barrier, workerContext);
+    resourceManager = new MockNodeResourceManager(resourceManagerBarrier, dispatcher, workerContext);
+    statusUpdater = new MockNodeStatusUpdater(new CountDownLatch(0), workerContext);
+
+    service = new CompositeService("MockService") {
+      @Override
+      protected void serviceInit(Configuration conf) throws Exception {
+        addIfService(dispatcher);
+        addIfService(taskDispatcher);
+        addIfService(taskManager);
+        addIfService(taskExecutor);
+        addIfService(resourceManager);
+        addIfService(statusUpdater);
+        super.serviceInit(conf);
+      }
+
+
+      @Override
+      protected void serviceStop() throws Exception {
+        workerContext.getMetrics().stop();
+        super.serviceStop();
+      }
+    };
+
+    service.init(conf);
+    service.start();
+  }
+
+  @After
+  public void tearDown() {
+    service.stop();
+  }
+
+  @Test
+  public void testTaskRequest() throws Exception {
+    int requestSize = 1;
+
+    QueryId qid = LocalTajoTestingUtility.newQueryId();
+    ExecutionBlockId ebId = QueryIdFactory.newExecutionBlockId(qid, 1);
+
+    CallFuture<BatchAllocationResponse> callFuture  = new CallFuture<BatchAllocationResponse>();
+    BatchAllocationRequest.Builder requestProto = BatchAllocationRequest.newBuilder();
+    requestProto.setExecutionBlockId(ebId.getProto());
+
+    assertEquals(resourceManager.getTotalResource(), resourceManager.getAvailableResource());
+    requestProto.addAllTaskRequest(MockNodeResourceManager.createTaskRequests(ebId, 10, requestSize));
+
+    dispatcher.getEventHandler().handle(new NodeResourceAllocateEvent(requestProto.build(), callFuture));
+
+    //verify running task
+    assertTrue(barrier.tryAcquire(3, TimeUnit.SECONDS));
+    assertEquals(1, taskExecutor.getRunningTasks());
+    assertTrue(barrier.tryAcquire(3, TimeUnit.SECONDS));
+    assertEquals(0, taskExecutor.getRunningTasks());
+    assertEquals(1, taskExecutor.completeTasks);
+
+    //verify the released resources
+    Thread.sleep(100);
+    assertEquals(resourceManager.getTotalResource(), resourceManager.getAvailableResource());
+  }
+
+  @Test
+  public void testTaskException() throws Exception {
+    int requestSize = 1;
+
+    QueryId qid = LocalTajoTestingUtility.newQueryId();
+    ExecutionBlockId ebId = QueryIdFactory.newExecutionBlockId(qid, 1);
+
+    CallFuture<BatchAllocationResponse> callFuture  = new CallFuture<BatchAllocationResponse>();
+    BatchAllocationRequest.Builder requestProto = BatchAllocationRequest.newBuilder();
+    requestProto.setExecutionBlockId(ebId.getProto());
+
+    assertEquals(resourceManager.getTotalResource(), resourceManager.getAvailableResource());
+    requestProto.addAllTaskRequest(MockNodeResourceManager.createTaskRequests(ebId, 10, requestSize));
+
+    taskExecutor.throwException.set(true);
+    dispatcher.getEventHandler().handle(new NodeResourceAllocateEvent(requestProto.build(), callFuture));
+
+    //verify running task
+    assertTrue(barrier.tryAcquire(3, TimeUnit.SECONDS));
+    assertEquals(1, taskExecutor.getRunningTasks());
+    assertTrue(barrier.tryAcquire(3, TimeUnit.SECONDS));
+    assertEquals(0, taskExecutor.getRunningTasks());
+    assertEquals(0, taskExecutor.completeTasks);
+
+    //verify the released resources
+    Thread.sleep(100);
+    assertEquals(resourceManager.getTotalResource(), resourceManager.getAvailableResource());
+  }
+
+  class MyTaskExecutor extends MockTaskExecutor {
+    int completeTasks;
+    AtomicBoolean throwException = new AtomicBoolean();
+
+    public MyTaskExecutor(Semaphore barrier, TajoWorker.WorkerContext workerContext) {
+      super(barrier, workerContext);
+    }
+
+    @Override
+    protected void stopTask(TaskAttemptId taskId) {
+      super.stopTask(taskId);
+      super.barrier.release();
+    }
+
+    @Override
+    protected Task createTask(final ExecutionBlockContext context, TaskRequestProto taskRequest) {
+      final TaskAttemptId taskAttemptId = new TaskAttemptId(taskRequest.getId());
+      final TaskAttemptContext taskAttemptContext = new TaskAttemptContext(null, context, taskAttemptId, null, null);
+
+      return new Task() {
+        @Override
+        public void init() throws IOException {
+
+          try {
+            Thread.sleep(50);
+          } catch (InterruptedException e) {
+            e.printStackTrace();
+          }
+        }
+
+        @Override
+        public void fetch(ExecutorService fetchExecutor) {
+          try {
+            Thread.sleep(50);
+          } catch (InterruptedException e) {
+            e.printStackTrace();
+          }
+        }
+
+        @Override
+        public void run() throws Exception {
+          Thread.sleep(50);
+
+          if(throwException.get()) throw new RuntimeException();
+
+          taskAttemptContext.stop();
+          taskAttemptContext.setProgress(1.0f);
+          taskAttemptContext.setState(TajoProtos.TaskAttemptState.TA_SUCCEEDED);
+          completeTasks++;
+        }
+
+        @Override
+        public void kill() {
+
+        }
+
+        @Override
+        public void abort() {
+
+        }
+
+        @Override
+        public void cleanup() {
+        }
+
+        @Override
+        public boolean hasFetchPhase() {
+          return false;
+        }
+
+        @Override
+        public boolean isProgressChanged() {
+          return false;
+        }
+
+        @Override
+        public boolean isStopped() {
+          return taskAttemptContext.isStopped();
+        }
+
+        @Override
+        public void updateProgress() {
+
+        }
+
+        @Override
+        public TaskAttemptContext getTaskContext() {
+          return taskAttemptContext;
+        }
+
+        @Override
+        public ExecutionBlockContext getExecutionBlockContext() {
+          return context;
+        }
+
+        @Override
+        public TaskStatusProto getReport() {
+          TaskStatusProto.Builder builder = TaskStatusProto.newBuilder();
+          builder.setWorkerName("localhost:0");
+          builder.setId(taskAttemptContext.getTaskId().getProto())
+              .setProgress(taskAttemptContext.getProgress())
+              .setState(taskAttemptContext.getState());
+
+          builder.setInputStats(new TableStats().getProto());
+          return builder.build();
+        }
+
+        @Override
+        public TaskHistory createTaskHistory() {
+          return null;
+        }
+
+        @Override
+        public List<Fetcher> getFetchers() {
+          return null;
+        }
+      };
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestTaskManager.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestTaskManager.java b/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestTaskManager.java
new file mode 100644
index 0000000..1d84afe
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/worker/TestTaskManager.java
@@ -0,0 +1,184 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.worker;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.service.CompositeService;
+import org.apache.hadoop.yarn.event.AsyncDispatcher;
+import org.apache.tajo.ExecutionBlockId;
+import org.apache.tajo.LocalTajoTestingUtility;
+import org.apache.tajo.QueryId;
+import org.apache.tajo.QueryIdFactory;
+import org.apache.tajo.conf.TajoConf;
+import org.apache.tajo.master.cluster.WorkerConnectionInfo;
+import org.apache.tajo.resource.NodeResource;
+import org.apache.tajo.rpc.CallFuture;
+import org.apache.tajo.util.CommonTestingUtil;
+import org.apache.tajo.worker.event.ExecutionBlockStopEvent;
+import org.apache.tajo.worker.event.NodeResourceAllocateEvent;
+import org.apache.tajo.worker.event.TaskStartEvent;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import static org.apache.tajo.ResourceProtos.*;
+import static org.junit.Assert.*;
+
+public class TestTaskManager {
+
+  private NodeResourceManager resourceManager;
+  private NodeStatusUpdater statusUpdater;
+  private TaskManager taskManager;
+  private TaskExecutor taskExecutor;
+  private AsyncDispatcher dispatcher;
+  private AsyncDispatcher taskDispatcher;
+  private TajoWorker.WorkerContext workerContext;
+
+  private CompositeService service;
+  private int taskMemory;
+  private TajoConf conf;
+  private Semaphore barrier;
+
+  @Before
+  public void setup() {
+    conf = new TajoConf();
+    conf.set(CommonTestingUtil.TAJO_TEST_KEY, CommonTestingUtil.TAJO_TEST_TRUE);
+
+    taskMemory = 512;
+    conf.setIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_CPU_CORES, 4);
+    conf.setIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_MEMORY_MB,
+        taskMemory * conf.getIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_CPU_CORES));
+    conf.setIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_DISKS, 4);
+    conf.setIntVar(TajoConf.ConfVars.WORKER_RESOURCE_AVAILABLE_DISK_PARALLEL_NUM, 1);
+    conf.setIntVar(TajoConf.ConfVars.SHUFFLE_FETCHER_PARALLEL_EXECUTION_MAX_NUM, 2);
+
+    dispatcher = new AsyncDispatcher();
+    taskDispatcher = new AsyncDispatcher();
+
+    workerContext = new MockWorkerContext() {
+      WorkerConnectionInfo workerConnectionInfo;
+
+      @Override
+      public TajoConf getConf() {
+        return conf;
+      }
+
+      @Override
+      public TaskManager getTaskManager() {
+        return taskManager;
+      }
+
+      @Override
+      public TaskExecutor getTaskExecuor() {
+        return taskExecutor;
+      }
+
+      @Override
+      public NodeResourceManager getNodeResourceManager() {
+        return resourceManager;
+      }
+
+      @Override
+      public WorkerConnectionInfo getConnectionInfo() {
+        if (workerConnectionInfo == null) {
+          workerConnectionInfo = new WorkerConnectionInfo("host", 28091, 28092, 21000, 28093, 28080);
+        }
+        return workerConnectionInfo;
+      }
+    };
+    barrier = new Semaphore(0);
+    taskManager = new MockTaskManager(barrier, taskDispatcher, workerContext);
+    taskExecutor = new MockTaskExecutor(new Semaphore(0), workerContext);
+    resourceManager = new NodeResourceManager(dispatcher, workerContext);
+    statusUpdater = new MockNodeStatusUpdater(new CountDownLatch(0), workerContext);
+
+    service = new CompositeService("MockService") {
+      @Override
+      protected void serviceInit(Configuration conf) throws Exception {
+        addIfService(dispatcher);
+        addIfService(taskDispatcher);
+        addIfService(taskManager);
+        addIfService(taskExecutor);
+        addIfService(resourceManager);
+        addIfService(statusUpdater);
+        super.serviceInit(conf);
+      }
+
+
+      @Override
+      protected void serviceStop() throws Exception {
+        workerContext.getMetrics().stop();
+        super.serviceStop();
+      }
+    };
+
+    service.init(conf);
+    service.start();
+  }
+
+  @After
+  public void tearDown() {
+    service.stop();
+  }
+
+  @Test(timeout = 10000)
+  public void testExecutionBlockStart() throws Exception {
+    int requestSize = 1;
+    QueryId qid = LocalTajoTestingUtility.newQueryId();
+    ExecutionBlockId ebId = QueryIdFactory.newExecutionBlockId(qid, 1);
+
+    CallFuture<BatchAllocationResponse> callFuture  = new CallFuture<BatchAllocationResponse>();
+    BatchAllocationRequest.Builder requestProto = BatchAllocationRequest.newBuilder();
+    requestProto.setExecutionBlockId(ebId.getProto());
+
+    assertEquals(resourceManager.getTotalResource(), resourceManager.getAvailableResource());
+    requestProto.addAllTaskRequest(MockNodeResourceManager.createTaskRequests(ebId, taskMemory, requestSize));
+
+    dispatcher.getEventHandler().handle(new NodeResourceAllocateEvent(requestProto.build(), callFuture));
+
+    assertTrue(barrier.tryAcquire(3, TimeUnit.SECONDS));
+    assertNotNull(taskManager.getExecutionBlockContext(ebId));
+    assertEquals(ebId, taskManager.getExecutionBlockContext(ebId).getExecutionBlockId());
+  }
+
+  @Test(timeout = 10000)
+  public void testExecutionBlockStop() throws Exception {
+
+    QueryId qid = LocalTajoTestingUtility.newQueryId();
+    ExecutionBlockId ebId = QueryIdFactory.newExecutionBlockId(qid, 1);
+    TaskAllocationProto requestProto =
+        MockNodeResourceManager.createTaskRequests(ebId, taskMemory, 1).poll();
+
+    taskDispatcher.getEventHandler().handle(new TaskStartEvent(requestProto.getTaskRequest(),
+        new NodeResource(requestProto.getResource())));
+
+    assertTrue(barrier.tryAcquire(3, TimeUnit.SECONDS));
+    assertNotNull(taskManager.getExecutionBlockContext(ebId));
+    assertEquals(ebId, taskManager.getExecutionBlockContext(ebId).getExecutionBlockId());
+
+    ExecutionBlockListProto.Builder ebList = ExecutionBlockListProto.newBuilder();
+    taskDispatcher.getEventHandler().handle(new ExecutionBlockStopEvent(ebId.getProto(), ebList.build()));
+    assertTrue(barrier.tryAcquire(3, TimeUnit.SECONDS));
+    assertNull(taskManager.getExecutionBlockContext(ebId));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/RestTestUtils.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/RestTestUtils.java b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/RestTestUtils.java
new file mode 100644
index 0000000..e0d9db3
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/RestTestUtils.java
@@ -0,0 +1,64 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.ws.rs.resources;
+
+import java.lang.reflect.Type;
+import java.util.Map;
+import java.util.TimeZone;
+
+import org.apache.hadoop.fs.Path;
+import org.apache.tajo.catalog.TableMeta;
+import org.apache.tajo.catalog.json.FunctionAdapter;
+import org.apache.tajo.catalog.json.TableMetaAdapter;
+import org.apache.tajo.common.TajoDataTypes.DataType;
+import org.apache.tajo.datum.Datum;
+import org.apache.tajo.function.Function;
+import org.apache.tajo.json.ClassNameSerializer;
+import org.apache.tajo.json.DataTypeAdapter;
+import org.apache.tajo.json.DatumAdapter;
+import org.apache.tajo.json.GsonSerDerAdapter;
+import org.apache.tajo.json.PathSerializer;
+import org.apache.tajo.json.TimeZoneGsonSerdeAdapter;
+import org.apache.tajo.plan.expr.EvalNode;
+import org.apache.tajo.plan.function.AggFunction;
+import org.apache.tajo.plan.function.GeneralFunction;
+import org.apache.tajo.plan.logical.LogicalNode;
+import org.apache.tajo.plan.serder.EvalNodeAdapter;
+import org.apache.tajo.plan.serder.LogicalNodeAdapter;
+import org.apache.tajo.util.TUtil;
+
+public class RestTestUtils {
+  
+  public static Map<Type, GsonSerDerAdapter<?>> registerTypeAdapterMap() {
+    Map<Type, GsonSerDerAdapter<?>> adapters = TUtil.newHashMap();
+    adapters.put(Path.class, new PathSerializer());
+    adapters.put(Class.class, new ClassNameSerializer());
+    adapters.put(LogicalNode.class, new LogicalNodeAdapter());
+    adapters.put(EvalNode.class, new EvalNodeAdapter());
+    adapters.put(TableMeta.class, new TableMetaAdapter());
+    adapters.put(Function.class, new FunctionAdapter());
+    adapters.put(GeneralFunction.class, new FunctionAdapter());
+    adapters.put(AggFunction.class, new FunctionAdapter());
+    adapters.put(Datum.class, new DatumAdapter());
+    adapters.put(DataType.class, new DataTypeAdapter());
+    adapters.put(TimeZone.class, new TimeZoneGsonSerdeAdapter());
+
+    return adapters;
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestClusterResource.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestClusterResource.java b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestClusterResource.java
new file mode 100644
index 0000000..7e18c1d
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestClusterResource.java
@@ -0,0 +1,83 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.ws.rs.resources;
+
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.core.GenericType;
+
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.ws.rs.netty.gson.GsonFeature;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.filter.LoggingFilter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class TestClusterResource extends QueryTestCaseBase {
+  
+  private URI restServiceURI;
+  private URI clusterURI;
+  private Client restClient;
+
+  public TestClusterResource() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+  
+  @Before
+  public void setUp() throws Exception {
+    int restPort = testBase.getTestingCluster().getConfiguration().getIntVar(ConfVars.REST_SERVICE_PORT);
+    restServiceURI = new URI("http", null, "127.0.0.1", restPort, "/rest", null, null);
+    clusterURI = new URI(restServiceURI + "/cluster");
+    restClient = ClientBuilder.newBuilder()
+        .register(new GsonFeature(RestTestUtils.registerTypeAdapterMap()))
+        .register(LoggingFilter.class)
+        .property(ClientProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true)
+        .property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, true)
+        .build();
+  }
+  
+  @After
+  public void tearDown() throws Exception {
+    restClient.close();
+  }
+  
+  @Test
+  public void testGetCluster() throws Exception {
+    Map<String, List<Object>> workerMap =
+        restClient.target(clusterURI)
+        .request().get(new GenericType<Map<String, List<Object>>>(Map.class));
+    
+    assertNotNull(workerMap);
+    assertFalse(workerMap.isEmpty());
+    assertNotNull(workerMap.get("workers"));
+    
+    List<Object> workerList = workerMap.get("workers");
+    
+    assertTrue(workerList.size() > 0);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestDatabasesResource.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestDatabasesResource.java b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestDatabasesResource.java
new file mode 100644
index 0000000..59c53f1
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestDatabasesResource.java
@@ -0,0 +1,189 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.ws.rs.resources;
+
+import java.net.URI;
+import java.util.Collection;
+import java.util.Map;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.ws.rs.netty.gson.GsonFeature;
+import org.apache.tajo.ws.rs.requests.NewDatabaseRequest;
+import org.apache.tajo.ws.rs.responses.DatabaseInfoResponse;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.filter.LoggingFilter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class TestDatabasesResource extends QueryTestCaseBase {
+  
+  private URI restServiceURI;
+  private URI databasesURI;
+  private Client restClient;
+  
+  public TestDatabasesResource() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+  
+  @Before
+  public void setUp() throws Exception {
+    int restPort = testBase.getTestingCluster().getConfiguration().getIntVar(ConfVars.REST_SERVICE_PORT);
+    restServiceURI = new URI("http", null, "127.0.0.1", restPort, "/rest", null, null);
+    databasesURI = new URI(restServiceURI + "/databases");
+    restClient = ClientBuilder.newBuilder()
+        .register(new GsonFeature(RestTestUtils.registerTypeAdapterMap()))
+        .register(LoggingFilter.class)
+        .property(ClientProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true)
+        .property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, true)
+        .build();
+  }
+  
+  @After
+  public void tearDown() throws Exception {
+    restClient.close();
+  }
+  
+  @Test
+  public void testGetAllDatabases() throws Exception {
+    Map<String, Collection<String>> databaseNames = restClient.target(databasesURI)
+        .request().get(new GenericType<Map<String, Collection<String>>>(Map.class));
+    
+    assertNotNull(databaseNames);
+    assertFalse(databaseNames.isEmpty());
+    assertNotNull(databaseNames.get("databases"));
+    
+    Collection<String> databaseNamesCollection = databaseNames.get("databases");
+    
+    assertTrue(databaseNamesCollection.contains(TajoConstants.DEFAULT_DATABASE_NAME));
+  }
+  
+  @Test
+  public void testCreateDatabase() throws Exception {
+    String databaseName = "TestDatabasesResource";
+    NewDatabaseRequest request = new NewDatabaseRequest();
+    
+    request.setDatabaseName(databaseName);
+    
+    Response response = restClient.target(databasesURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON));
+    
+    assertNotNull(response);
+    assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
+    
+    Map<String, Collection<String>> databaseNames = restClient.target(databasesURI)
+        .request().get(new GenericType<Map<String, Collection<String>>>(Map.class));
+    
+    assertNotNull(databaseNames);
+    assertFalse(databaseNames.isEmpty());
+    assertNotNull(databaseNames.get("databases"));
+    
+    Collection<String> databaseNamesCollection = databaseNames.get("databases");
+    
+    assertTrue(databaseNamesCollection.contains(databaseName));
+  }
+  
+  @Test
+  public void testCreateDatabaseBadRequest() throws Exception {
+    NewDatabaseRequest request = new NewDatabaseRequest();
+    
+    Response response = restClient.target(databasesURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON));
+    
+    assertNotNull(response);
+    assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+  }
+
+  @Test
+  public void testGetDatabase() throws Exception {
+    DatabaseInfoResponse response =
+        restClient.target(databasesURI).path("/{databaseName}")
+        .resolveTemplate("databaseName", TajoConstants.DEFAULT_DATABASE_NAME)
+        .request().get(new GenericType<DatabaseInfoResponse>(DatabaseInfoResponse.class));
+    
+    assertNotNull(response);
+    assertEquals(TajoConstants.DEFAULT_DATABASE_NAME, response.getName());
+    assertTrue(response.getTablespace() != null && !response.getTablespace().isEmpty());
+  }
+  
+  @Test
+  public void testGetDatabaseNotFound() throws Exception {
+    Response response =
+        restClient.target(databasesURI).path("/{databaseName}")
+        .resolveTemplate("databaseName", "testGetDatabaseNotFound")
+        .request().get();
+    
+    assertNotNull(response);
+    assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+  }
+  
+  @Test
+  public void testDropDatabase() throws Exception {
+    String databaseName = "TestDropDatabase";
+    NewDatabaseRequest request = new NewDatabaseRequest();
+    
+    request.setDatabaseName(databaseName);
+    
+    Response response = restClient.target(databasesURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON));
+    
+    assertNotNull(response);
+    assertEquals(Status.CREATED.getStatusCode(), response.getStatus());
+    
+    Map<String, Collection<String>> databaseNames = restClient.target(databasesURI)
+        .request().get(new GenericType<Map<String, Collection<String>>>(Map.class));
+    
+    assertNotNull(databaseNames);
+    assertFalse(databaseNames.isEmpty());
+    assertNotNull(databaseNames.get("databases"));
+    
+    Collection<String> databaseNamesCollection = databaseNames.get("databases");
+    
+    assertTrue(databaseNamesCollection.contains(databaseName));
+    
+    response = restClient.target(databasesURI)
+        .path("/{databaseName}").resolveTemplate("databaseName", databaseName)
+        .request().delete();
+    
+    assertNotNull(response);
+    assertEquals(Status.OK.getStatusCode(), response.getStatus());
+  }
+  
+  @Test
+  public void testDropDatabaseNotFound() throws Exception {
+    Response response = restClient.target(databasesURI)
+        .path("/{databaseName}").resolveTemplate("databaseName", "TestDropDatabaseNotFound")
+        .request().delete();
+    
+    assertNotNull(response);
+    assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestFunctionsResource.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestFunctionsResource.java b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestFunctionsResource.java
new file mode 100644
index 0000000..7c7aeae
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestFunctionsResource.java
@@ -0,0 +1,78 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.ws.rs.resources;
+
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.function.FunctionSignature;
+import org.apache.tajo.ws.rs.netty.gson.GsonFeature;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.filter.LoggingFilter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.core.GenericType;
+import java.net.URI;
+import java.util.List;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class TestFunctionsResource extends QueryTestCaseBase {
+  
+  private URI restServiceURI;
+  private URI functionsURI;
+  private Client restClient;
+  
+  public TestFunctionsResource() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+  
+  @Before
+  public void setUp() throws Exception {
+    int restPort = testBase.getTestingCluster().getConfiguration().getIntVar(ConfVars.REST_SERVICE_PORT);
+    restServiceURI = new URI("http", null, "127.0.0.1", restPort, "/rest", null, null);
+    functionsURI = new URI(restServiceURI + "/functions");
+    restClient = ClientBuilder.newBuilder()
+        .register(new GsonFeature(RestTestUtils.registerTypeAdapterMap()))
+        .register(LoggingFilter.class)
+        .property(ClientProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true)
+        .property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, true)
+        .build();
+  }
+  
+  @After
+  public void tearDown() throws Exception {
+    restClient.close();
+  }
+  
+  @Test
+  public void testGetAllFunctions() throws Exception {
+    List<FunctionSignature> functionSignatures =
+        restClient.target(functionsURI)
+        .request().get(new GenericType<List<FunctionSignature>>(List.class));
+    
+    assertNotNull(functionSignatures);
+    assertTrue(functionSignatures.size() > 0);
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResource.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResource.java b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResource.java
new file mode 100644
index 0000000..210d38d
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResource.java
@@ -0,0 +1,199 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.ws.rs.resources;
+
+import com.google.gson.internal.StringMap;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.error.Errors.ResultCode;
+import org.apache.tajo.exception.ErrorUtil;
+import org.apache.tajo.master.QueryInfo;
+import org.apache.tajo.ws.rs.netty.gson.GsonFeature;
+import org.apache.tajo.ws.rs.requests.NewSessionRequest;
+import org.apache.tajo.ws.rs.requests.SubmitQueryRequest;
+import org.apache.tajo.ws.rs.responses.GetSubmitQueryResponse;
+import org.apache.tajo.ws.rs.responses.NewSessionResponse;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.filter.LoggingFilter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.MediaType;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+public class TestQueryResource extends QueryTestCaseBase {
+  
+  private URI restServiceURI;
+  private URI sessionsURI;
+  private URI queriesURI;
+  private Client restClient;
+  
+  private static final String tajoSessionIdHeaderName = "X-Tajo-Session";
+  
+  public TestQueryResource() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+  
+  @Before
+  public void setUp() throws Exception {
+    int restPort = testBase.getTestingCluster().getConfiguration().getIntVar(ConfVars.REST_SERVICE_PORT);
+    restServiceURI = new URI("http", null, "127.0.0.1", restPort, "/rest", null, null);
+    sessionsURI = new URI(restServiceURI + "/sessions");
+    queriesURI = new URI(restServiceURI + "/queries");
+    restClient = ClientBuilder.newBuilder()
+        .register(new GsonFeature(RestTestUtils.registerTypeAdapterMap()))
+        .register(LoggingFilter.class)
+        .property(ClientProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true)
+        .property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, true)
+        .build();
+  }
+  
+  @After
+  public void tearDown() throws Exception {
+    restClient.close();
+  }
+  
+  private SubmitQueryRequest createNewQueryRequest(String query) throws Exception {
+    SubmitQueryRequest request = new SubmitQueryRequest();
+    request.setQuery(query);
+    return request;
+  }
+  
+  private String generateNewSessionAndGetId() throws Exception {
+    NewSessionRequest request = new NewSessionRequest();
+    request.setUserName("tajo-user");
+    request.setDatabaseName(TajoConstants.DEFAULT_DATABASE_NAME);
+    
+    NewSessionResponse response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+    
+    assertNotNull(response);
+    assertTrue(ErrorUtil.isOk(response.getResultCode()));
+    assertTrue(response.getId() != null && !response.getId().isEmpty());
+    
+    return response.getId();
+  }
+  
+  @Test
+  public void testGetAllQueries() throws Exception {
+    String sessionId = generateNewSessionAndGetId();
+    SubmitQueryRequest queryRequest = createNewQueryRequest("select * from lineitem");
+
+    GetSubmitQueryResponse response = restClient.target(queriesURI)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .post(Entity.entity(queryRequest, MediaType.APPLICATION_JSON),
+            new GenericType<GetSubmitQueryResponse>(GetSubmitQueryResponse.class));
+
+    assertNotNull(response);
+    assertEquals(ResultCode.OK, response.getResultCode());
+    String location = response.getUri().toString();
+    assertTrue(location != null && !location.isEmpty());
+    
+    String queryId = location.lastIndexOf('/') >= 0?
+			location.substring(location.lastIndexOf('/')+1):null;
+        
+    assertTrue(queryId != null && !queryId.isEmpty());
+    
+    Map<String, List<StringMap>> queriesMap = restClient.target(queriesURI)
+        .request().get(new GenericType<Map<String, List<StringMap>>>(Map.class));
+    
+    assertNotNull(queriesMap);
+    
+    List<StringMap> queryInfoList = queriesMap.get("queries");
+    assertNotNull(queryInfoList);
+    
+    boolean assertQueryIdFound = false;
+    for (StringMap queryInfo: queryInfoList) {
+      if (queryId.equals(queryInfo.get("queryIdStr"))) {
+        assertQueryIdFound = true;
+      }
+    }
+    
+    assertTrue(assertQueryIdFound);
+  }
+  
+  @Test
+  public void testSubmitQuery() throws Exception {
+    String sessionId = generateNewSessionAndGetId();
+    SubmitQueryRequest queryRequest = createNewQueryRequest("select * from lineitem");
+
+    GetSubmitQueryResponse response = restClient.target(queriesURI)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .post(Entity.entity(queryRequest, MediaType.APPLICATION_JSON),
+            new GenericType<GetSubmitQueryResponse>(GetSubmitQueryResponse.class));
+
+    assertNotNull(response);
+    assertEquals(ResultCode.OK, response.getResultCode());
+    String location = response.getUri().toString();
+    assertTrue(location != null && !location.isEmpty());
+    
+    String queryId = location.lastIndexOf('/') >= 0?
+			location.substring(location.lastIndexOf('/')+1):null;
+        
+    assertTrue(queryId != null && !queryId.isEmpty());
+    
+    QueryInfo queryInfo = restClient.target(queriesURI)
+        .path("/{queryId}")
+        .resolveTemplate("queryId", queryId)
+        .queryParam("print", "BRIEF")
+        .request().get(new GenericType<QueryInfo>(QueryInfo.class));
+    
+    assertNotNull(queryInfo);
+    assertEquals(queryId, queryInfo.getQueryIdStr());
+  }
+
+  @Test
+  public void testGetQueryInfoWithDefault() throws Exception {
+    String sessionId = generateNewSessionAndGetId();
+    SubmitQueryRequest queryRequest = createNewQueryRequest("select * from lineitem");
+
+    GetSubmitQueryResponse response = restClient.target(queriesURI)
+      .request().header(tajoSessionIdHeaderName, sessionId)
+      .post(Entity.entity(queryRequest, MediaType.APPLICATION_JSON),
+          new GenericType<GetSubmitQueryResponse>(GetSubmitQueryResponse.class));
+
+    assertNotNull(response);
+    assertEquals(ResultCode.OK, response.getResultCode());
+    String location = response.getUri().toString();
+    assertTrue(location != null && !location.isEmpty());
+
+    String queryId = location.lastIndexOf('/') >= 0?
+			location.substring(location.lastIndexOf('/')+1):null;
+
+    assertTrue(queryId != null && !queryId.isEmpty());
+
+    QueryInfo queryInfo = restClient.target(queriesURI)
+      .path("/{queryId}")
+      .resolveTemplate("queryId", queryId)
+      .request().get(new GenericType<QueryInfo>(QueryInfo.class));
+
+    assertNotNull(queryInfo);
+    assertEquals(queryId, queryInfo.getQueryIdStr());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResultResource.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResultResource.java b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResultResource.java
new file mode 100644
index 0000000..7762b05
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestQueryResultResource.java
@@ -0,0 +1,296 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.ws.rs.resources;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.error.Errors.ResultCode;
+import org.apache.tajo.exception.ErrorUtil;
+import org.apache.tajo.storage.RowStoreUtil;
+import org.apache.tajo.storage.Tuple;
+import org.apache.tajo.util.TUtil;
+import org.apache.tajo.ws.rs.netty.gson.GsonFeature;
+import org.apache.tajo.ws.rs.requests.NewSessionRequest;
+import org.apache.tajo.ws.rs.requests.SubmitQueryRequest;
+import org.apache.tajo.ws.rs.responses.GetQueryResultDataResponse;
+import org.apache.tajo.ws.rs.responses.GetSubmitQueryResponse;
+import org.apache.tajo.ws.rs.responses.NewSessionResponse;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.filter.LoggingFilter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.InputStream;
+import java.net.URI;
+import java.security.MessageDigest;
+import java.util.List;
+
+import static org.apache.tajo.exception.ErrorUtil.isOk;
+import static org.junit.Assert.*;
+
+public class TestQueryResultResource extends QueryTestCaseBase {
+
+  private URI restServiceURI;
+  private URI sessionsURI;
+  private URI queriesURI;
+  private Client restClient;
+
+  private static final String tajoSessionIdHeaderName = "X-Tajo-Session";
+  private static final String tajoDigestHeaderName = "X-Tajo-Digest";
+	private static final String tajoOffsetHeaderName = "X-Tajo-Offset";
+	private static final String tajoCountHeaderName = "X-Tajo-Count";
+	private static final String tajoEOSHeaderName = "X-Tajo-EOS";
+
+  public TestQueryResultResource() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    int restPort = testBase.getTestingCluster().getConfiguration().getIntVar(ConfVars.REST_SERVICE_PORT);
+    restServiceURI = new URI("http", null, "127.0.0.1", restPort, "/rest", null, null);
+    sessionsURI = new URI(restServiceURI + "/sessions");
+    queriesURI = new URI(restServiceURI + "/queries");
+    restClient = ClientBuilder.newBuilder()
+        .register(new GsonFeature(RestTestUtils.registerTypeAdapterMap()))
+        .register(LoggingFilter.class)
+        .property(ClientProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true)
+        .property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, true)
+        .build();
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    restClient.close();
+  }
+
+  private String generateNewSessionAndGetId() throws Exception {
+    NewSessionRequest request = new NewSessionRequest();
+    request.setUserName("tajo-user");
+    request.setDatabaseName(TajoConstants.DEFAULT_DATABASE_NAME);
+
+    NewSessionResponse response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+
+    assertNotNull(response);
+    assertTrue(isOk(response.getResultCode()));
+    assertTrue(response.getId() != null && !response.getId().isEmpty());
+
+    return response.getId();
+  }
+
+  private URI sendNewQueryResquest(String sessionId, String query) throws Exception {
+
+    SubmitQueryRequest request = new SubmitQueryRequest();
+    request.setQuery(query);
+
+    GetSubmitQueryResponse response = restClient.target(queriesURI)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .post(Entity.entity(request, MediaType.APPLICATION_JSON),
+					new GenericType<GetSubmitQueryResponse>(GetSubmitQueryResponse.class));
+
+    assertNotNull(response);
+    assertEquals(ResultCode.OK, response.getResultCode());
+    String location = response.getUri().toString();
+    assertTrue(location != null && !location.isEmpty());
+
+    URI queryIdURI = new URI(location);
+
+    assertNotNull(queryIdURI);
+
+    return queryIdURI;
+  }
+
+  @Test
+  public void testGetQueryResult() throws Exception {
+    String sessionId = generateNewSessionAndGetId();
+    URI queryIdURI = sendNewQueryResquest(sessionId, "select * from lineitem");
+    URI queryResultURI = new URI(queryIdURI + "/result");
+
+    GetQueryResultDataResponse response = restClient.target(queryResultURI)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .get(new GenericType<GetQueryResultDataResponse>(GetQueryResultDataResponse.class));
+
+    assertNotNull(response);
+    assertNotNull(response.getResultCode());
+    assertTrue(isOk(response.getResultCode()));
+    assertNotNull(response.getSchema());
+    assertEquals(16, response.getSchema().getRootColumns().size());
+    assertNotNull(response.getResultset());
+    assertTrue(response.getResultset().getId() != 0);
+    assertNotNull(response.getResultset().getLink());
+  }
+
+  @Test
+  public void testGetQueryResultNotFound() throws Exception {
+    String sessionId = generateNewSessionAndGetId();
+    URI queryIdURI = new URI(queriesURI + "/q_11111_0001");
+    URI queryResultURI = new URI(queryIdURI + "/result");
+
+    Response response = restClient.target(queryResultURI)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .get();
+
+    assertNotNull(response);
+    assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+  }
+
+  @Test
+  public void testGetQueryResultSet() throws Exception {
+    String sessionId = generateNewSessionAndGetId();
+    URI queryIdURI = sendNewQueryResquest(sessionId, "select * from lineitem");
+    URI queryResultURI = new URI(queryIdURI + "/result");
+
+    GetQueryResultDataResponse response = restClient.target(queryResultURI)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .get(new GenericType<GetQueryResultDataResponse>(GetQueryResultDataResponse.class));
+
+    assertNotNull(response);
+    assertNotNull(response.getResultCode());
+    assertTrue(ErrorUtil.isOk(response.getResultCode()));
+    assertNotNull(response.getSchema());
+    assertEquals(16, response.getSchema().getRootColumns().size());
+    assertNotNull(response.getResultset());
+    assertTrue(response.getResultset().getId() != 0);
+    assertNotNull(response.getResultset().getLink());
+
+    URI queryResultSetURI = response.getResultset().getLink();
+
+    Response queryResultSetResponse = restClient.target(queryResultSetURI)
+        .queryParam("count", 100)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .get();
+
+    assertNotNull(queryResultSetResponse);
+    String tajoDigest = queryResultSetResponse.getHeaderString(tajoDigestHeaderName);
+    assertTrue(tajoDigest != null && !tajoDigest.isEmpty());
+
+    DataInputStream queryResultSetInputStream =
+        new DataInputStream(new BufferedInputStream(queryResultSetResponse.readEntity(InputStream.class)));
+
+    assertNotNull(queryResultSetInputStream);
+
+    boolean isFinished = false;
+    List<Tuple> tupleList = TUtil.newList();
+    RowStoreUtil.RowStoreDecoder decoder = RowStoreUtil.createDecoder(response.getSchema());
+    MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
+    while (!isFinished) {
+      try {
+        int length = queryResultSetInputStream.readInt();
+        byte[] dataByteArray = new byte[length];
+        int readBytes = queryResultSetInputStream.read(dataByteArray);
+
+        assertEquals(length, readBytes);
+
+        tupleList.add(decoder.toTuple(dataByteArray));
+        messageDigest.update(dataByteArray);
+      } catch (EOFException eof) {
+        isFinished = true;
+      }
+    }
+
+    assertEquals(5, tupleList.size());
+    assertEquals(tajoDigest, Base64.encodeBase64String(messageDigest.digest()));
+
+    for (Tuple aTuple: tupleList) {
+      assertTrue(aTuple.getInt4(response.getSchema().getColumnId("l_orderkey")) > 0);
+    }
+  }
+
+  @Test
+  public void testGetQueryResultSetWithDefaultCount() throws Exception {
+    String sessionId = generateNewSessionAndGetId();
+    URI queryIdURI = sendNewQueryResquest(sessionId, "select * from lineitem");
+    URI queryResultURI = new URI(queryIdURI + "/result");
+
+    GetQueryResultDataResponse response = restClient.target(queryResultURI)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .get(new GenericType<GetQueryResultDataResponse>(GetQueryResultDataResponse.class));
+
+    assertNotNull(response);
+    assertNotNull(response.getResultCode());
+    assertTrue(isOk(response.getResultCode()));
+    assertNotNull(response.getSchema());
+    assertEquals(16, response.getSchema().getRootColumns().size());
+    assertNotNull(response.getResultset());
+    assertTrue(response.getResultset().getId() != 0);
+    assertNotNull(response.getResultset().getLink());
+
+    URI queryResultSetURI = response.getResultset().getLink();
+
+    Response queryResultSetResponse = restClient.target(queryResultSetURI)
+        .request().header(tajoSessionIdHeaderName, sessionId)
+        .get();
+
+    assertNotNull(queryResultSetResponse);
+    String tajoDigest = queryResultSetResponse.getHeaderString(tajoDigestHeaderName);
+    int offset = Integer.valueOf(queryResultSetResponse.getHeaderString(tajoOffsetHeaderName));
+    int count = Integer.valueOf(queryResultSetResponse.getHeaderString(tajoCountHeaderName));
+    boolean eos = Boolean.valueOf(queryResultSetResponse.getHeaderString(tajoEOSHeaderName));
+
+    assertTrue(tajoDigest != null && !tajoDigest.isEmpty());
+    assertTrue(eos);
+    assertEquals(0, offset);
+    assertEquals(5, count);
+
+    DataInputStream queryResultSetInputStream =
+        new DataInputStream(new BufferedInputStream(queryResultSetResponse.readEntity(InputStream.class)));
+
+    assertNotNull(queryResultSetInputStream);
+
+    boolean isFinished = false;
+    List<Tuple> tupleList = TUtil.newList();
+    RowStoreUtil.RowStoreDecoder decoder = RowStoreUtil.createDecoder(response.getSchema());
+    MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
+    while (!isFinished) {
+      try {
+        int length = queryResultSetInputStream.readInt();
+        byte[] dataByteArray = new byte[length];
+        int readBytes = queryResultSetInputStream.read(dataByteArray);
+
+        assertEquals(length, readBytes);
+
+        tupleList.add(decoder.toTuple(dataByteArray));
+        messageDigest.update(dataByteArray);
+      } catch (EOFException eof) {
+        isFinished = true;
+      }
+    }
+
+    assertEquals(5, tupleList.size());
+    assertEquals(tajoDigest, Base64.encodeBase64String(messageDigest.digest()));
+
+    for (Tuple aTuple: tupleList) {
+      assertTrue(aTuple.getInt4(response.getSchema().getColumnId("l_orderkey")) > 0);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestSessionsResource.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestSessionsResource.java b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestSessionsResource.java
new file mode 100644
index 0000000..7b293d8
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestSessionsResource.java
@@ -0,0 +1,263 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.tajo.ws.rs.resources;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.TajoConstants;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.ws.rs.netty.gson.GsonFeature;
+import org.apache.tajo.ws.rs.requests.NewSessionRequest;
+import org.apache.tajo.ws.rs.responses.NewSessionResponse;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.filter.LoggingFilter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class TestSessionsResource extends QueryTestCaseBase {
+  
+  private URI restServiceURI;
+  private URI sessionsURI;
+  private Client restClient;
+
+  public TestSessionsResource() {
+    super(TajoConstants.DEFAULT_DATABASE_NAME);
+  }
+  
+  @Before
+  public void setUp() throws Exception {
+    int restPort = testBase.getTestingCluster().getConfiguration().getIntVar(ConfVars.REST_SERVICE_PORT);
+    restServiceURI = new URI("http", null, "127.0.0.1", restPort, "/rest", null, null);
+    sessionsURI = new URI(restServiceURI + "/sessions");
+    restClient = ClientBuilder.newBuilder()
+        .register(new GsonFeature(RestTestUtils.registerTypeAdapterMap()))
+        .register(LoggingFilter.class)
+        .property(ClientProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true)
+        .property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, true)
+        .build();
+  }
+  
+  @After
+  public void tearDown() throws Exception {
+    restClient.close();
+  }
+  
+  private NewSessionRequest createNewSessionRequest() {
+    NewSessionRequest request = new NewSessionRequest();
+    
+    request.setUserName("tajo-user1");
+    request.setDatabaseName("default");
+    
+    return request;
+  }
+  
+  @Test
+  public void testNewSession() throws Exception {    
+    NewSessionRequest request = createNewSessionRequest();
+    
+    assertNotNull(request);
+    
+    NewSessionResponse response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+    
+    assertNotNull(response);
+    assertNotNull(response.getId());
+    assertTrue(response.getMessage() == null || response.getMessage().isEmpty());
+    assertFalse(response.getId().isEmpty());
+  }
+  
+  @Test
+  public void testNewSessionWithoutDBName() throws Exception {
+    NewSessionRequest request = new NewSessionRequest();
+    request.setUserName("tajo-user");
+    
+    NewSessionResponse response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+    
+    assertNotNull(response);
+    assertNotNull(response.getId());
+    assertTrue(response.getMessage() == null || response.getMessage().isEmpty());
+    assertFalse(response.getId().isEmpty());
+  }
+  
+  @Test
+  public void testNewSessionWithBadRequest() throws Exception {
+    NewSessionRequest request = new NewSessionRequest();
+    request.setDatabaseName("default");
+    
+    Response response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON));
+    
+    assertNotNull(response);
+    assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+  }
+
+  @Test
+  public void testRemoveSession() throws Exception {
+    NewSessionRequest request = new NewSessionRequest();
+    request.setUserName("tajo-user");
+
+    NewSessionResponse response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+
+    assertNotNull(response);
+    assertTrue(response.getId() != null && !response.getId().isEmpty());
+
+    Response restResponse = restClient.target(sessionsURI)
+        .path("/{session-id}").resolveTemplate("session-id", response.getId())
+        .request().delete();
+
+    assertNotNull(restResponse);
+    assertEquals(Status.OK.getStatusCode(), restResponse.getStatus());
+  }
+
+  @Test
+  public void testRemoveSessionNotFound() throws Exception {
+    String invalidSessionId = "invalid";
+
+    Response response = restClient.target(sessionsURI)
+        .path("/{session-id}").resolveTemplate("session-id", invalidSessionId)
+        .request().delete();
+
+    assertNotNull(response);
+    assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+  }
+
+  @Test
+  public void testGetAllSessionVariables() throws Exception {
+    NewSessionRequest request = new NewSessionRequest();
+    request.setUserName("tajo-user");
+
+    NewSessionResponse response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+
+    assertNotNull(response);
+    assertTrue(response.getId() != null && !response.getId().isEmpty());
+
+    Map<String, Map<String, String>> variablesMap = restClient.target(sessionsURI)
+        .path("/{session-id}/variables").resolveTemplate("session-id", response.getId())
+        .request().get(new GenericType<Map<String, Map<String, String>>>(Map.class));
+
+    assertNotNull(variablesMap);
+    assertTrue(variablesMap.containsKey("variables"));
+  }
+
+  @Test
+  public void testGetAllSessionVariablesNotFound() throws Exception {
+    String invalidSessionId = "invalid";
+
+    Response response = restClient.target(sessionsURI)
+        .path("/{session-id}/variables").resolveTemplate("session-id", invalidSessionId)
+        .request().get();
+
+    assertNotNull(response);
+    assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+  }
+
+  @Test
+  public void testUpdateSessionVariables() throws Exception {
+    NewSessionRequest request = new NewSessionRequest();
+    request.setUserName("tajo-user");
+
+    NewSessionResponse response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+
+    assertNotNull(response);
+    assertTrue(response.getId() != null && !response.getId().isEmpty());
+
+    Map<String, String> variablesMap = new HashMap<String, String>();
+    variablesMap.put("variableA", "valueA");
+    variablesMap.put("variableB", "valueB");
+    Map<String, Map<String, String>> variables = new HashMap<String, Map<String, String>>();
+    variables.put("variables", variablesMap);
+    Response restResponse = restClient.target(sessionsURI)
+        .path("/{session-id}/variables").resolveTemplate("session-id", response.getId())
+        .request().put(Entity.entity(variables, MediaType.APPLICATION_JSON));
+
+    assertNotNull(restResponse);
+    assertEquals(Status.OK.getStatusCode(), restResponse.getStatus());
+    
+    Map<String, Map<String, String>> retrievedVariables = restClient.target(sessionsURI)
+        .path("/{session-id}/variables").resolveTemplate("session-id", response.getId())
+        .request().get(new GenericType<Map<String, Map<String, String>>>(Map.class));
+    
+    assertNotNull(retrievedVariables);
+    assertFalse(retrievedVariables.isEmpty());
+    
+    Map<String, String> retrievedVariablesMap = retrievedVariables.get("variables");
+    
+    assertNotNull(retrievedVariablesMap);
+    assertFalse(retrievedVariablesMap.isEmpty());
+    
+    assertTrue(retrievedVariablesMap.containsKey("variableA"));
+    assertTrue(retrievedVariablesMap.containsKey("variableB"));
+    assertTrue("valueA".equals(retrievedVariablesMap.get("variableA")));
+    assertTrue("valueB".equals(retrievedVariablesMap.get("variableB")));
+  }
+  
+  @Test
+  public void testUpdateSessionVariable() throws Exception {
+    NewSessionRequest request = new NewSessionRequest();
+    request.setUserName("tajo-user");
+
+    NewSessionResponse response = restClient.target(sessionsURI)
+        .request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+
+    assertNotNull(response);
+    assertTrue(response.getId() != null && !response.getId().isEmpty());
+
+    Map<String, String> variablesMap = new HashMap<String, String>();
+    variablesMap.put("variableA", "valueA");
+    Response restResponse = restClient.target(sessionsURI)
+        .path("/{session-id}/variables").resolveTemplate("session-id", response.getId())
+        .request().put(Entity.entity(variablesMap, MediaType.APPLICATION_JSON));
+
+    assertNotNull(restResponse);
+    assertEquals(Status.OK.getStatusCode(), restResponse.getStatus());
+    
+    Map<String, Map<String, String>> retrievedVariables = restClient.target(sessionsURI)
+        .path("/{session-id}/variables").resolveTemplate("session-id", response.getId())
+        .request().get(new GenericType<Map<String, Map<String, String>>>(Map.class));
+    
+    assertNotNull(retrievedVariables);
+    assertFalse(retrievedVariables.isEmpty());
+    
+    Map<String, String> retrievedVariablesMap = retrievedVariables.get("variables");
+    
+    assertNotNull(retrievedVariablesMap);
+    assertFalse(retrievedVariablesMap.isEmpty());
+    
+    assertTrue(retrievedVariablesMap.containsKey("variableA"));
+    assertTrue("valueA".equals(retrievedVariablesMap.get("variableA")));
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestTablesResource.java
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestTablesResource.java b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestTablesResource.java
new file mode 100644
index 0000000..aa8a696
--- /dev/null
+++ b/tajo-core-tests/src/test/java/org/apache/tajo/ws/rs/resources/TestTablesResource.java
@@ -0,0 +1,202 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.tajo.ws.rs.resources;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.tajo.QueryTestCaseBase;
+import org.apache.tajo.catalog.CatalogUtil;
+import org.apache.tajo.catalog.TableDesc;
+import org.apache.tajo.conf.TajoConf.ConfVars;
+import org.apache.tajo.error.Errors.ResultCode;
+import org.apache.tajo.ws.rs.netty.gson.GsonFeature;
+import org.apache.tajo.ws.rs.requests.NewSessionRequest;
+import org.apache.tajo.ws.rs.requests.SubmitQueryRequest;
+import org.apache.tajo.ws.rs.responses.GetSubmitQueryResponse;
+import org.apache.tajo.ws.rs.responses.NewSessionResponse;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.filter.LoggingFilter;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+import java.net.URI;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.*;
+
+public class TestTablesResource extends QueryTestCaseBase {
+  
+  private URI restServiceURI;
+  private URI tablesURI;
+	private URI queriesURI;
+	private URI sessionsURI;
+
+	private Client restClient;
+  
+  private static final String defaultDatabaseName = "testtablesdb";
+	private static final String tajoSessionIdHeaderName = "X-Tajo-Session";
+
+	public TestTablesResource() {
+    super(defaultDatabaseName);
+  }
+
+  @Before
+  public void setUp() throws Exception {
+    int restPort = testBase.getTestingCluster().getConfiguration().getIntVar(ConfVars.REST_SERVICE_PORT);
+    restServiceURI = new URI("http", null, "127.0.0.1", restPort, "/rest", null, null);
+    tablesURI = new URI(restServiceURI + "/databases/" + defaultDatabaseName + "/tables");
+		queriesURI = new URI(restServiceURI + "/queries");
+		sessionsURI = new URI(restServiceURI + "/sessions");
+		restClient = ClientBuilder.newBuilder()
+        .register(new GsonFeature(RestTestUtils.registerTypeAdapterMap()))
+        .register(LoggingFilter.class)
+        .property(ClientProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true)
+        .property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, true)
+        .build();
+  }
+  
+  @After
+  public void tearDown() throws Exception {
+    restClient.close();
+  }
+
+	private SubmitQueryRequest createNewQueryRequest(String query) throws Exception {
+		SubmitQueryRequest request = new SubmitQueryRequest();
+		request.setQuery(query);
+		return request;
+	}
+
+	private String generateNewSessionAndGetId() throws Exception {
+		NewSessionRequest request = new NewSessionRequest();
+		request.setUserName("tajo-user");
+		request.setDatabaseName(defaultDatabaseName);
+
+		NewSessionResponse response = restClient.target(sessionsURI)
+			.request().post(Entity.entity(request, MediaType.APPLICATION_JSON), NewSessionResponse.class);
+
+		assertNotNull(response);
+		assertTrue(ResultCode.OK.equals(response.getResultCode()));
+		assertTrue(response.getId() != null && !response.getId().isEmpty());
+
+		return response.getId();
+	}
+
+	private void createNewTableForTestCreateTable(String tableName, String sessionId) throws Exception {
+		String query = "create table " + tableName + " (column1 text)";
+		SubmitQueryRequest queryRequest = createNewQueryRequest(query);
+
+		GetSubmitQueryResponse response = restClient.target(queriesURI)
+			.request().header(tajoSessionIdHeaderName, sessionId)
+			.post(Entity.entity(queryRequest, MediaType.APPLICATION_JSON),
+				new GenericType<GetSubmitQueryResponse>(GetSubmitQueryResponse.class));
+
+		assertNotNull(response);
+		assertEquals(ResultCode.OK, response.getResultCode());
+	}
+
+  @Test
+  public void testGetAllTable() throws Exception {
+    String tableName = "testgetalltable";
+		String sessionId = generateNewSessionAndGetId();
+
+		createNewTableForTestCreateTable(tableName, sessionId);
+
+    Map<String, Collection<String>> tables = restClient.target(tablesURI)
+        .request().get(new GenericType<Map<String, Collection<String>>>(Map.class));
+
+    List<String> tableNames = (List<String>)tables.get("tables");
+    assertNotNull(tableNames);
+    assertTrue(!tableNames.isEmpty());
+
+    boolean tableFound = false;
+    for (String table: tableNames) {
+      if (StringUtils.equalsIgnoreCase(tableName, CatalogUtil.extractSimpleName(table))) {
+        tableFound = true;
+        break;
+      }
+    }
+    
+    assertTrue(tableFound);
+  }
+  
+  @Test
+  public void testGetTable() throws Exception {
+    String tableName = "testgettable";
+		String sessionId = generateNewSessionAndGetId();
+
+		createNewTableForTestCreateTable(tableName, sessionId);
+    
+    TableDesc selectedTable = restClient.target(tablesURI)
+        .path("/{tableName}").resolveTemplate("tableName", tableName)
+        .request().get(new GenericType<TableDesc>(TableDesc.class));
+    
+    assertNotNull(selectedTable);
+    assertTrue(StringUtils.equalsIgnoreCase(tableName, CatalogUtil.extractSimpleName(selectedTable.getName())));
+  }
+  
+  @Test
+  public void testGetTableNotFound() throws Exception {
+    Response response = restClient.target(tablesURI)
+        .path("/{tableName}").resolveTemplate("tableName", "TestGetTableNotFound")
+        .request().get();
+    
+    assertNotNull(response);
+    assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+  }
+  
+  @Test
+  public void testDropTable() throws Exception {
+    String tableName = "testdroptable";
+		String sessionId = generateNewSessionAndGetId();
+
+		createNewTableForTestCreateTable(tableName, sessionId);
+    
+    TableDesc selectedTable = restClient.target(tablesURI)
+        .path("/{tableName}").resolveTemplate("tableName", tableName)
+        .request().get(new GenericType<TableDesc>(TableDesc.class));
+    
+    assertNotNull(selectedTable);
+    assertTrue(StringUtils.equalsIgnoreCase(tableName, CatalogUtil.extractSimpleName(selectedTable.getName())));
+    
+    Response response = restClient.target(tablesURI)
+        .path("/{tableName}").resolveTemplate("tableName", tableName)
+        .request().delete();
+    
+    assertNotNull(response);
+    assertEquals(Status.OK.getStatusCode(), response.getStatus());
+  }
+  
+  @Test
+  public void testDropTableNotFound() throws Exception {
+    Response response = restClient.target(tablesURI)
+        .path("/{tableName}").resolveTemplate("tableName", "TestDropTableNotFound")
+        .request().delete();
+    
+    assertNotNull(response);
+    assertEquals(Status.NOT_FOUND.getStatusCode(), response.getStatus());
+  }
+}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestAlterTable/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestAlterTable/table1.tbl b/tajo-core-tests/src/test/resources/dataset/TestAlterTable/table1.tbl
new file mode 100644
index 0000000..340fe85
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestAlterTable/table1.tbl
@@ -0,0 +1,3 @@
+1|abc|2
+2|def|5
+3|ghi|8

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestAlterTable/table2.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestAlterTable/table2.tbl b/tajo-core-tests/src/test/resources/dataset/TestAlterTable/table2.tbl
new file mode 100644
index 0000000..59f652e
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestAlterTable/table2.tbl
@@ -0,0 +1 @@
+aaa+AAA|bbb+BBB|ccc

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestCreateTable/table1/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestCreateTable/table1/table1.tbl b/tajo-core-tests/src/test/resources/dataset/TestCreateTable/table1/table1.tbl
new file mode 100644
index 0000000..8095c0b
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestCreateTable/table1/table1.tbl
@@ -0,0 +1,3 @@
+1|abc|2
+2|def|5
+3|ghi|8
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestCreateTable/table2/table2.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestCreateTable/table2/table2.tbl b/tajo-core-tests/src/test/resources/dataset/TestCreateTable/table2/table2.tbl
new file mode 100644
index 0000000..953ee3d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestCreateTable/table2/table2.tbl
@@ -0,0 +1,3 @@
+4|jkl|7
+5|opq|8
+6|stu|9
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestDropTable/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestDropTable/table1.tbl b/tajo-core-tests/src/test/resources/dataset/TestDropTable/table1.tbl
new file mode 100644
index 0000000..340fe85
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestDropTable/table1.tbl
@@ -0,0 +1,3 @@
+1|abc|2
+2|def|5
+3|ghi|8

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestHBaseTable/splits.data
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestHBaseTable/splits.data b/tajo-core-tests/src/test/resources/dataset/TestHBaseTable/splits.data
new file mode 100644
index 0000000..417d480
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestHBaseTable/splits.data
@@ -0,0 +1,4 @@
+010
+040
+060
+080
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestJoinQuery/table1/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestJoinQuery/table1/table1.tbl b/tajo-core-tests/src/test/resources/dataset/TestJoinQuery/table1/table1.tbl
new file mode 100644
index 0000000..6405b31
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestJoinQuery/table1/table1.tbl
@@ -0,0 +1,5 @@
+1|ooo|1.1|a
+2|ppp|2.3|b
+3|qqq|3.4|c
+4|rrr|4.5|d
+5|xxx|5.6|e
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestJoinQuery/table2/table2.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestJoinQuery/table2/table2.tbl b/tajo-core-tests/src/test/resources/dataset/TestJoinQuery/table2/table2.tbl
new file mode 100644
index 0000000..68340bf
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestJoinQuery/table2/table2.tbl
@@ -0,0 +1,4 @@
+1|NULL|NULL|a
+2|NULL|NULL|b
+NULL|NULL|10.0|c
+NULL|NULL|20.0|d
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestNetTypes/table1/table1.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestNetTypes/table1/table1.tbl b/tajo-core-tests/src/test/resources/dataset/TestNetTypes/table1/table1.tbl
new file mode 100644
index 0000000..63db89d
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestNetTypes/table1/table1.tbl
@@ -0,0 +1,5 @@
+1|ooo|1.1|a|127.0.0.1
+2|ppp|2.3|b|127.0.1.1
+3|qqq|3.4|c|127.0.0.8
+4|rrr|4.5|d|127.0.0.1
+5|xxx|5.6|e|127.0.1.1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestNetTypes/table2/table2.tbl
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestNetTypes/table2/table2.tbl b/tajo-core-tests/src/test/resources/dataset/TestNetTypes/table2/table2.tbl
new file mode 100644
index 0000000..9d46bc0
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestNetTypes/table2/table2.tbl
@@ -0,0 +1,5 @@
+1|NULL|NULL|a|127.0.0.8
+2|NULL|NULL|b|127.0.0.8
+NULL|NULL|10.0|c|NULL
+NULL|NULL|20.0|d|127.0.0.1
+NULL|NULL|20.0|d|255.255.255.255
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/sample1/table.json
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/sample1/table.json b/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/sample1/table.json
new file mode 100644
index 0000000..db3ad6c
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/sample1/table.json
@@ -0,0 +1,3 @@
+{ "title" : "Hand of the King", "name" : { "first_name": "Eddard", "last_name": "Stark"}}
+{ "title" : "Assassin", "name" : { "first_name": "Arya", "last_name": "Stark"}}
+{ "title" : "Dancing Master", "name" : { "first_name": "Syrio", "last_name": "Forel"}}

http://git-wip-us.apache.org/repos/asf/tajo/blob/a4106883/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/sample2/sample2.json
----------------------------------------------------------------------
diff --git a/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/sample2/sample2.json b/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/sample2/sample2.json
new file mode 100644
index 0000000..20bab62
--- /dev/null
+++ b/tajo-core-tests/src/test/resources/dataset/TestSelectNestedRecord/sample2/sample2.json
@@ -0,0 +1 @@
+{ "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": { "GlossEntry": { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": { "para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": ["GML", "XML"] }, "GlossSee": "markup" } } } } }
\ No newline at end of file