You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by ec...@apache.org on 2013/07/19 05:47:39 UTC

svn commit: r1504759 [1/6] - in /hive/trunk: ./ testutils/ptest2/ testutils/ptest2/conf/ testutils/ptest2/src/ testutils/ptest2/src/main/ testutils/ptest2/src/main/java/ testutils/ptest2/src/main/java/org/ testutils/ptest2/src/main/java/org/apache/ tes...

Author: ecapriolo
Date: Fri Jul 19 03:47:36 2013
New Revision: 1504759

URL: http://svn.apache.org/r1504759
Log:
HIVE-4675 Create new parallel unit test environment (Brock Noland via egc)

Submitted by: Brock Noland	
Reviewed by: Edward Capriolo	

Added:
    hive/trunk/testutils/ptest2/
    hive/trunk/testutils/ptest2/.gitignore
    hive/trunk/testutils/ptest2/README.md
    hive/trunk/testutils/ptest2/conf/
    hive/trunk/testutils/ptest2/conf/example-apache-trunk.properties
    hive/trunk/testutils/ptest2/pom.xml   (with props)
    hive/trunk/testutils/ptest2/src/
    hive/trunk/testutils/ptest2/src/main/
    hive/trunk/testutils/ptest2/src/main/java/
    hive/trunk/testutils/ptest2/src/main/java/org/
    hive/trunk/testutils/ptest2/src/main/java/org/apache/
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/Status.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/client/
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/client/PTestClient.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestListRequest.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestLogRequest.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestStartRequest.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestStatusRequest.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestStopRequest.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/GenericResponse.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestListResponse.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestLogResponse.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStartResponse.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStatus.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStatusResponse.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStopResponse.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/server/
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/server/ExecutionController.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/server/Test.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/server/TestExecutor.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/server/TestLogger.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/AbortDroneException.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/CleanupPhase.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/Constants.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/Dirs.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/Drone.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/ExecutionPhase.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/HostExecutor.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/JIRAService.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/JUnitReportParser.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/LocalCommand.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/LocalCommandFactory.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/LogDirectoryCleaner.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/PTest.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/Phase.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/PrepPhase.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/ReportingPhase.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/Templates.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/TestsFailedException.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/conf/
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/conf/Context.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/conf/ExecutionContextConfiguration.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/conf/Host.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/conf/QFileTestBatch.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/conf/TestBatch.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/conf/TestConfiguration.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/conf/TestParser.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/conf/UnitTestBatch.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/context/
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/context/CloudComputeService.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/context/CloudExecutionContextProvider.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/context/CreateHostsFailedException.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/context/ExecutionContext.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/context/ExecutionContextProvider.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/context/FixedExecutionContextProvider.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/context/ServiceNotAvailableException.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/ssh/
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/ssh/AbstractSSHCommand.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/ssh/AbstractSSHResult.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/ssh/NonZeroExitCodeException.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/ssh/RSyncCommand.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/ssh/RSyncCommandExecutor.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/ssh/RSyncResult.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/ssh/RemoteCommandResult.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/ssh/SSHCommand.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/ssh/SSHCommandExecutor.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/ssh/SSHExecutionException.java
    hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/execution/ssh/SSHResult.java
    hive/trunk/testutils/ptest2/src/main/resources/
    hive/trunk/testutils/ptest2/src/main/resources/batch-exec.vm
    hive/trunk/testutils/ptest2/src/main/resources/log4j.properties
    hive/trunk/testutils/ptest2/src/main/resources/smart-apply-patch.sh
    hive/trunk/testutils/ptest2/src/main/resources/source-prep.vm
    hive/trunk/testutils/ptest2/src/main/webapp/
    hive/trunk/testutils/ptest2/src/main/webapp/WEB-INF/
    hive/trunk/testutils/ptest2/src/main/webapp/WEB-INF/config/
    hive/trunk/testutils/ptest2/src/main/webapp/WEB-INF/config/web-application-config.xml   (with props)
    hive/trunk/testutils/ptest2/src/main/webapp/WEB-INF/config/webmvc-config.xml   (with props)
    hive/trunk/testutils/ptest2/src/main/webapp/WEB-INF/web.xml   (with props)
    hive/trunk/testutils/ptest2/src/test/
    hive/trunk/testutils/ptest2/src/test/java/
    hive/trunk/testutils/ptest2/src/test/java/org/
    hive/trunk/testutils/ptest2/src/test/java/org/apache/
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/api/
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/api/server/
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/api/server/TestTestExecutor.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/api/server/TestTestLogger.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/AbstractTestPhase.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/ExtendedAssert.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/MockLocalCommandFactory.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/MockRSyncCommandExecutor.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/MockSSHCommandExecutor.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestCleanupPhase.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestCleanupPhase.testExecute.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestExecutionPhase.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestExecutionPhase.testFailingQFile.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestExecutionPhase.testFailingUnitTest.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestExecutionPhase.testPassingQFileTest.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestExecutionPhase.testPassingUnitTest.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestHostExecutor.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestHostExecutor.testBasic.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestHostExecutor.testIsolatedFailsOnExec.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestHostExecutor.testIsolatedFailsOnRsyncOne.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestHostExecutor.testIsolatedFailsOnRsyncUnknown.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestHostExecutor.testParallelFailsOnExec.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestHostExecutor.testParallelFailsOnRsync.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestJIRAService.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestLocalCommand.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestLogDirectoryCleaner.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestPhase.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestPhase.testExecHostsWithFailure.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestPhase.testExecInstancesWithFailure.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestPhase.testRsyncFromLocalToRemoteInstancesWithFailureOne.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestPhase.testRsyncFromLocalToRemoteInstancesWithFailureUnknown.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestPrepPhase.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestPrepPhase.testExecute.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestReportParser.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestReportingPhase.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestReportingPhase.testExecute.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestScripts.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestScripts.testBatch.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestScripts.testPrepGit.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestScripts.testPrepNone.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/TestScripts.testPrepSvn.approved.txt
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/conf/
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/conf/TestQFileTestBatch.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/conf/TestTestConfiguration.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/conf/TestTestParser.java
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/context/
    hive/trunk/testutils/ptest2/src/test/java/org/apache/hive/ptest/execution/context/TestCloudExecutionContextProvider.java
    hive/trunk/testutils/ptest2/src/test/resources/
    hive/trunk/testutils/ptest2/src/test/resources/TEST-SomeTest-failure.xml   (with props)
    hive/trunk/testutils/ptest2/src/test/resources/test-configuration.properties
    hive/trunk/testutils/ptest2/src/test/resources/test-outputs/
    hive/trunk/testutils/ptest2/src/test/resources/test-outputs/TEST-SomeTest-truncated.xml   (with props)
    hive/trunk/testutils/ptest2/src/test/resources/test-outputs/TEST-index_auth.q-bucketcontex-ba31fb54-1d7f-4c70-a89d-477b7d155191-TEST-org.apache.hadoop.hive.cli.TestCliDriver.xml   (with props)
    hive/trunk/testutils/ptest2/src/test/resources/test-outputs/TEST-skewjoin.q-ab8536a7-1b5c-45ed-ba29-14450f27db8b-TEST-org.apache.hadoop.hive.cli.TestCliDriver.xml   (with props)
    hive/trunk/testutils/ptest2/src/test/resources/test-outputs/TEST-skewjoin_union_remove_1.q-6fa31776-d2b0-4e13-9761-11f750627ad1-TEST-org.apache.hadoop.hive.cli.TestCliDriver.xml   (with props)
    hive/trunk/testutils/ptest2/src/test/resources/test-outputs/TEST-union_remove_9.q-acb9de8f-1b9c-4874-924c-b2107ca7b07c-TEST-org.apache.hadoop.hive.cli.TestCliDriver.xml   (with props)
    hive/trunk/testutils/ptest2/src/test/resources/test-outputs/index_auth.q-bucketcontex-ba31fb54-1d7f-4c70-a89d-477b7d155191-hive.log
    hive/trunk/testutils/ptest2/src/test/resources/test-outputs/skewjoin.q-ab8536a7-1b5c-45ed-ba29-14450f27db8b-TestCliDriver.txt
    hive/trunk/testutils/ptest2/src/test/resources/test-outputs/skewjoin.q-ab8536a7-1b5c-45ed-ba29-14450f27db8b-hive.log
    hive/trunk/testutils/ptest2/src/test/resources/test-outputs/skewjoin_union_remove_1.q-6fa31776-d2b0-4e13-9761-11f750627ad1-TestCliDriver.txt
    hive/trunk/testutils/ptest2/src/test/resources/test-outputs/skewjoin_union_remove_1.q-6fa31776-d2b0-4e13-9761-11f750627ad1-hive.log
    hive/trunk/testutils/ptest2/src/test/resources/test-outputs/union_remove_9.q-acb9de8f-1b9c-4874-924c-b2107ca7b07c-TestCliDriver.txt
    hive/trunk/testutils/ptest2/src/test/resources/test-outputs/union_remove_9.q-acb9de8f-1b9c-4874-924c-b2107ca7b07c-hive.log
Modified:
    hive/trunk/.gitignore

Modified: hive/trunk/.gitignore
URL: http://svn.apache.org/viewvc/hive/trunk/.gitignore?rev=1504759&r1=1504758&r2=1504759&view=diff
==============================================================================
--- hive/trunk/.gitignore (original)
+++ hive/trunk/.gitignore Fri Jul 19 03:47:36 2013
@@ -16,4 +16,4 @@ common/src/gen
 ql/derby.log
 derby.log
 .arc
-
+ql/TempStatsStore

Added: hive/trunk/testutils/ptest2/.gitignore
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/.gitignore?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/.gitignore (added)
+++ hive/trunk/testutils/ptest2/.gitignore Fri Jul 19 03:47:36 2013
@@ -0,0 +1,11 @@
+/.project
+/.settings
+/.classpath
+/build
+/.idea/
+/logs
+/target
+*.iml
+*.orig
+*~
+velocity.log*

Added: hive/trunk/testutils/ptest2/README.md
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/README.md?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/README.md (added)
+++ hive/trunk/testutils/ptest2/README.md Fri Jul 19 03:47:36 2013
@@ -0,0 +1,85 @@
+# About
+
+Hive-ptest is a parallel testing framework for executing the Hive unit tests. If you'd like
+to dive into the code, start with org.apache.hive.ptest.RunTests.
+
+# Building
+
+    mvn clean package
+
+# Sizing
+
+We utilize 8 servers for this process and trunk builds complete in 1 hour. Each slave
+has 8 physical cores with hyperthreading enabled and 48GB of ram. Each slave is allowed
+8 test "threads". I had used more than 8 threads but Zookeeper timed out randomly.
+
+# Configuring
+
+* Create a user such as hiveptest on the master and all slaves.
+* Setup passwordless ssh form the master to all slaves.
+* Ensure that SSH connection attempts won't fail.
+
+On all slaves add the following to /etc/ssh/sshd_config:
+
+    MaxAuthTries 100
+    MaxSessions 100
+    MaxStartups 100
+
+# Install git, java, ant, and maven
+
+Recent version os java, ant and maven should be installed. Additionally environment variables
+such as MAVEN_OPTS and ANT_OPTS should be configured with large leap sizes:
+
+    $ for item in java maven ant; do echo $item; cat /etc/profile.d/${item}.sh;done
+    java
+    export JAVA_HOME=$(readlink -f /usr/java/default)
+    export PATH=$JAVA_HOME/bin:$PATH
+    maven
+    export M2_HOME=$(readlink -f /usr/local/apache-maven)
+    export PATH=$M2_HOME/bin:$PATH
+    export MAVEN_OPTS="-Xmx2g -XX:MaxPermSize=256M"
+    ant
+    export ANT_HOME=$(readlink -f /usr/local/apache-ant)
+    export PATH=$ANT_HOME/bin:$PATH
+    export ANT_OPTS="-Xmx1g -XX:MaxPermSize=256m"
+
+# Ensure umask is setup to 0022
+
+    $ cat /etc/profile.d/umask.sh 
+    umask 0022
+
+# On all slaves ensure that nproc and nofile are set to high values
+
+# rm /etc/security/limits.d/90-nproc.conf
+
+# cat /etc/security/limits.d/nproc.conf
+
+* soft nproc 32768
+* hard nproc 65536
+
+root soft nproc 32768
+root hard nproc 65536
+# cat /etc/security/limits.d/nofile.conf 
+
+* soft nofile 32768
+* hard nofile 32768
+
+root soft nofile 32768
+root hard nofile 32768
+
+# If using the Cloud Host Provider:
+
+Ensure the user running the tests has strict host/key checking disabled:
+
+   $ cat ~/.ssh/config
+   StrictHostKeyChecking no
+
+
+# Configure properties file
+
+See conf/example-apache-trunk.properties
+
+# Execute
+
+    mvn dependency:copy-dependencies
+    java -Xms4g -Xmx4g -cp "conf/:/home/hiveptest/hive-ptest/target/hive-test-1.0.jar:target/dependency/*" org.apache.hive.ptest.RunTests --properties apache-trunk.properties

Added: hive/trunk/testutils/ptest2/conf/example-apache-trunk.properties
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/conf/example-apache-trunk.properties?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/conf/example-apache-trunk.properties (added)
+++ hive/trunk/testutils/ptest2/conf/example-apache-trunk.properties Fri Jul 19 03:47:36 2013
@@ -0,0 +1,87 @@
+# 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.
+
+# This configuration has two hosts
+hosts = hiveptest-2 hiveptest-3
+host.hiveptest-2.user = hiveptest
+host.hiveptest-2.host = hiveptest-2.some.domain.com
+host.hiveptest-2.threads = 2
+# Each host has two disks
+host.hiveptest-2.localDirs = /media/ephemeral0/hiveptest/,/media/ephemeral1/hiveptest/
+host.hiveptest-3.user = hiveptest
+host.hiveptest-3.host = hiveptest-3.some.domain.com
+host.hiveptest-3.threads = 2
+host.hiveptest-3.localDirs = /media/ephemeral0/hiveptest/,/media/ephemeral1/hiveptest/
+
+privateKey = /home/hiveptest/.ssh/id_rsa
+repository = git://github.com/apache/hive.git
+repositoryName = apache-github
+branch = trunk
+workingDirectory = /media/ephemeral0/hiveptest/
+antArgs = -Dtest.continue.on.failure=true
+# antEnvOpts can be used to set ANT_OPTS properties
+
+unitTests.directories = build/anttasks/test/classes build/beeline/test/classes build/cli/test/classes \
+   build/common/test/classes build/contrib/test/classes build/hbase-handler/test/classes \
+   build/hwi/test/classes build/jdbc/test/classes build/metastore/test/classes build/odbc/test/classes \
+   build/ql/test/classes build/serde/test/classes build/service/test/classes build/shims/test/classes \
+   build/testutils/test/classes \
+   hcatalog/core/build/test/classes hcatalog/hcatalog-pig-adapter/build/test/classes \
+   hcatalog/server-extensions/build/test/classes hcatalog/webhcat/svr/build/test/classes \
+   hcatalog/webhcat/java-client/build/test/classes hcatalog/storage-handlers/hbase/build/test/classes
+
+unitTests.isolate = TestRemoteHiveMetaStore TestEmbeddedHiveMetaStore TestSetUGIOnBothClientServer TestSetUGIOnOnlyClient TestSetUGIOnOnlyServer TestHiveRemote TestAuthorizationPreEventListener TestRemoteHiveMetaStoreIpAddress TestMetaStoreEventListener TestRemoteUGIHiveMetaStoreIpAddress TestDefaultHiveMetastoreAuthorizationProvider TestExecDriver TestMetaStoreAuthorization TestHiveMetaStoreWithEnvironmentContext TestHBaseMinimrCliDriver TestHadoop20SAuthBridge TestHCatPartitionPublish TestMultiOutputFormat TestHCatMultiOutputFormat TestHBaseInputFormat TestIDGenerator TestRevisionManager TestZNodeSetUp TestHBaseBulkOutputFormat TestHBaseDirectOutputFormat TestHBaseInputFormat TestSnapshots TestHCatStorerWrapper
+unitTests.exclude = TestHiveMetaStore TestSerDe TestBeeLineDriver TestHiveServer2Concurrency TestJdbcDriver2 TestHiveServer2Concurrency TestBeeLineDriver
+
+qFileTests = clientPositive miniMr clientNegative miniMrNegative
+
+qFileTest.clientPositive.driver = TestCliDriver
+qFileTest.clientPositive.directory = ql/src/test/queries/clientpositive
+qFileTest.clientPositive.batchSize = 15
+qFileTest.clientPositive.queryFilesProperty = qfile
+qFileTest.clientPositive.exclude = minimr
+qFileTest.clientPositive.groups.minimr = input16_cc.q scriptfile1.q bucket4.q bucketmapjoin6.q disable_merge_for_bucketing.q reduce_deduplicate.q smb_mapjoin_8.q join1.q groupby2.q bucketizedhiveinputformat.q bucketmapjoin7.q optrstat_groupby.q bucket_num_reducers.q 
+
+qFileTest.miniMr.driver = TestMinimrCliDriver
+qFileTest.miniMr.directory = ql/src/test/queries/clientpositive
+qFileTest.miniMr.batchSize = 1000
+qFileTest.miniMr.queryFilesProperty = minimr.query.files
+qFileTest.miniMr.include = normal
+qFileTest.miniMr.isolate = flaky
+# normal are tests that run in minimr mode via build-common.xml
+qFileTest.miniMr.groups.normal = input16_cc.q scriptfile1.q bucket4.q bucketmapjoin6.q disable_merge_for_bucketing.q reduce_deduplicate.q smb_mapjoin_8.q join1.q groupby2.q bucketizedhiveinputformat.q bucketmapjoin7.q optrstat_groupby.q bucket_num_reducers.q
+qFileTest.miniMr.groups.flaky = bucketizedhiveinputformat.q
+
+qFileTest.miniMrNegative.driver = TestNegativeMinimrCliDriver
+qFileTest.miniMrNegative.directory = ql/src/test/queries/clientnegative
+qFileTest.miniMrNegative.batchSize = 1000
+qFileTest.miniMrNegative.queryFilesProperty = minimr.query.negative.files
+qFileTest.miniMrNegative.include = normal
+qFileTest.miniMrNegative.isolate = flaky
+# normal are tests that run in minimr mode via build-common.xml
+qFileTest.miniMrNegative.groups.normal = cluster_tasklog_retrieval.q minimr_broken_pipe.q mapreduce_stack_trace.q mapreduce_stack_trace_turnoff.q mapreduce_stack_trace_hadoop20.q mapreduce_stack_trace_turnoff_hadoop20.q
+qFileTest.miniMrNegative.groups.flaky = mapreduce_stack_trace_hadoop20.q
+
+qFileTest.clientNegative.driver = TestNegativeCliDriver
+qFileTest.clientNegative.directory = ql/src/test/queries/clientnegative
+qFileTest.clientNegative.batchSize = 1000
+qFileTest.clientNegative.queryFilesProperty = qfile
+qFileTest.clientNegative.exclude = miniMrNormal failing
+# stats_aggregator_error_1.q fails in both negative client and minimr mode
+qFileTest.clientNegative.groups.failing = stats_aggregator_error_1.q 
+# normal are run via minimr
+qFileTest.clientNegative.groups.miniMrNormal = cluster_tasklog_retrieval.q minimr_broken_pipe.q mapreduce_stack_trace.q mapreduce_stack_trace_turnoff.q mapreduce_stack_trace_hadoop20.q mapreduce_stack_trace_turnoff_hadoop20.q

Added: hive/trunk/testutils/ptest2/pom.xml
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/pom.xml?rev=1504759&view=auto
==============================================================================
Binary file - no diff available.

Propchange: hive/trunk/testutils/ptest2/pom.xml
------------------------------------------------------------------------------
    svn:mime-type = application/xml

Added: hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/Status.java
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/Status.java?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/Status.java (added)
+++ hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/Status.java Fri Jul 19 03:47:36 2013
@@ -0,0 +1,111 @@
+/*
+ * 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.hive.ptest.api;
+
+/**
+ * Represents a generic status for a GenericResponse
+ * in addition to the Status of a job.
+ */
+public class Status {
+  private Name name;
+  private String message;
+  public Status() {
+
+  }
+  public Status(Name name, String message) {
+    this.name = name;
+    this.message = message;
+  }
+  public Name getName() {
+    return name;
+  }
+  public void setName(Name name) {
+    this.name = name;
+  }
+  public String getMessage() {
+    return message;
+  }
+  public void setMessage(String message) {
+    this.message = message;
+  }
+
+  @Override
+  public String toString() {
+    return "Status [name=" + name + ", message=" + message + "]";
+  }
+
+  public static enum Name {
+    ILLEGAL_ARGUMENT(),
+    QUEUE_FULL(),
+    INTERNAL_ERROR(),
+    PENDING(),
+    IN_PROGRESS(),
+    FAILED(),
+    OK();
+  }
+  public static void assertOK(Status status) {
+    if(!isOK(status)) {
+      throw new RuntimeException(status == null ? "Status is null" : status.toString());
+    }
+  }
+  public static void assertOKOrFailed(Status status) {
+    if(!(isOK(status) || isFailed(status))) {
+      throw new RuntimeException(status == null ? "Status is null" : status.toString());
+    }
+  }
+  public static boolean isInProgress(Status status) {
+    return status != null && Name.IN_PROGRESS.equals(status.getName());
+  }
+  public static boolean isPending(Status status) {
+    return status != null && Name.PENDING.equals(status.getName());
+  }
+  public static boolean isOK(Status status) {
+    return status != null && Name.OK.equals(status.getName());
+  }
+  public static boolean isIllegalArgument(Status status) {
+    return status != null && Name.ILLEGAL_ARGUMENT.equals(status.getName());
+  }
+  public static boolean isFailed(Status status) {
+    return status != null && Name.FAILED.equals(status.getName());
+  }
+  public static Status illegalArgument() {
+    return illegalArgument(null);
+  }
+  public static Status illegalArgument(String message) {
+    return new Status(Name.ILLEGAL_ARGUMENT, message);
+  }
+  public static Status queueFull() {
+    return new Status(Name.QUEUE_FULL, null);
+  }
+  public static Status internalError(String message) {
+    return new Status(Name.INTERNAL_ERROR, message);
+  }
+  public static Status pending() {
+    return new Status(Name.PENDING, null);
+  }
+  public static Status inProgress() {
+    return new Status(Name.IN_PROGRESS, null);
+  }
+  public static Status failed(String message) {
+    return new Status(Name.FAILED, message);
+  }
+  public static Status ok() {
+    return new Status(Name.OK, null);
+  }
+}

Added: hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/client/PTestClient.java
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/client/PTestClient.java?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/client/PTestClient.java (added)
+++ hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/client/PTestClient.java Fri Jul 19 03:47:36 2013
@@ -0,0 +1,295 @@
+/*
+ * 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.hive.ptest.api.client;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.GnuParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Options;
+import org.apache.commons.io.IOUtils;
+import org.apache.hive.ptest.api.Status;
+import org.apache.hive.ptest.api.request.TestListRequest;
+import org.apache.hive.ptest.api.request.TestLogRequest;
+import org.apache.hive.ptest.api.request.TestStartRequest;
+import org.apache.hive.ptest.api.request.TestStatusRequest;
+import org.apache.hive.ptest.api.response.GenericResponse;
+import org.apache.hive.ptest.api.response.TestListResponse;
+import org.apache.hive.ptest.api.response.TestLogResponse;
+import org.apache.hive.ptest.api.response.TestStartResponse;
+import org.apache.hive.ptest.api.response.TestStatus;
+import org.apache.hive.ptest.api.response.TestStatusResponse;
+import org.apache.http.HttpResponse;
+import org.apache.http.StatusLine;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.util.EntityUtils;
+import org.codehaus.jackson.map.ObjectMapper;
+
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.io.Resources;
+
+/**
+ * Quick and dirty REST client for the PTest server. It's not expected the scope
+ * of this project will expand significantly therefore a simple REST client should suffice.
+ */
+public class PTestClient {
+  private static final ImmutableMap<Class<?>, EndPointResponsePair> REQUEST_TO_ENDPOINT =
+      ImmutableMap.<Class<?>, EndPointResponsePair>builder()
+      .put(TestStartRequest.class, new EndPointResponsePair("/testStart", TestStartResponse.class))
+      .put(TestStatusRequest.class, new EndPointResponsePair("/testStatus", TestStatusResponse.class))
+      .put(TestLogRequest.class, new EndPointResponsePair("/testLog", TestLogResponse.class))
+      .put(TestListRequest.class, new EndPointResponsePair("/testList", TestListResponse.class))
+      .build();
+
+  private static final String HELP_LONG = "help";
+  private static final String HELP_SHORT = "h";
+  private static final String ENDPOINT = "endpoint";
+  private static final String COMMAND = "command";
+  private static final String PASSWORD = "password";
+  private static final String PROFILE = "profile";
+  private static final String PATCH = "patch";
+  private static final String JIRA = "jira";
+  private static final String OUTPUT_DIR = "outputDir";
+  private static final String TEST_HANDLE = "testHandle";
+  private final String mApiEndPoint;
+  private final String mLogsEndpoint;
+  private final ObjectMapper mMapper;
+  private final DefaultHttpClient mHttpClient;
+
+  public PTestClient(String endPoint, String password)
+      throws MalformedURLException {
+    if(endPoint.endsWith("/")) {
+      mApiEndPoint = endPoint + "api/v1";
+      mLogsEndpoint = endPoint + "logs/";
+    } else {
+      mApiEndPoint = endPoint + "/api/v1";
+      mLogsEndpoint = endPoint + "/logs/";
+    }
+    URL apiURL = new URL(mApiEndPoint);
+    mMapper = new ObjectMapper();
+    mHttpClient = new DefaultHttpClient();
+    mHttpClient.getCredentialsProvider().setCredentials(
+        new AuthScope(apiURL.getHost(), apiURL.getPort(), AuthScope.ANY_REALM),
+        new UsernamePasswordCredentials("hive", password));
+  }
+  public boolean testStart(String profile, String testHandle,
+      String jira, String patch, String testOutputDir)
+  throws Exception {
+    patch = Strings.nullToEmpty(patch).trim();
+    if(!patch.isEmpty()) {
+      byte[] bytes = Resources.toByteArray(new URL(patch));
+      if(bytes.length == 0) {
+        throw new IllegalArgumentException("Patch " + patch + " was zero bytes");
+      }
+    }
+    TestStartRequest startRequest = new TestStartRequest(profile, testHandle, jira, patch);
+    post(startRequest);
+    boolean result = false;
+    try {
+      result = testTailLog(testHandle);
+      if(testOutputDir != null) {
+        downloadTestResults(testHandle, testOutputDir);
+      }
+    } finally {
+      System.out.println("\n\nLogs are located: " + mLogsEndpoint + testHandle + "\n\n");
+    }
+    return result;
+  }
+  public boolean testList()
+  throws Exception {
+    TestListRequest testListRequest = new TestListRequest();
+    TestListResponse testListResponse = post(testListRequest);
+    for(TestStatus testStatus : testListResponse.getEntries()) {
+      System.out.println(testStatus);
+    }
+    return true;
+  }
+  public boolean testTailLog(String testHandle)
+  throws Exception {
+    testHandle = Strings.nullToEmpty(testHandle).trim();
+    if(testHandle.isEmpty()) {
+      throw new IllegalArgumentException("TestHandle is required");
+    }
+    TestStatusRequest statusRequest = new TestStatusRequest(testHandle);
+    TestStatusResponse statusResponse;
+    do {
+      TimeUnit.SECONDS.sleep(5);
+      statusResponse = post(statusRequest);
+    } while(Status.isPending(statusResponse.getTestStatus().getStatus()));
+    long offset = 0;
+    do {
+      long length = statusResponse.getTestStatus().getLogFileLength();
+      if(length > offset) {
+        offset = printLogs(testHandle, offset);
+      } else {
+        TimeUnit.SECONDS.sleep(5);
+      }
+      statusResponse = post(statusRequest);
+    } while(Status.isInProgress(statusResponse.getTestStatus().getStatus()));
+    while(offset < statusResponse.getTestStatus().getLogFileLength()) {
+      offset = printLogs(testHandle, offset);
+    }
+    Status.assertOKOrFailed(statusResponse.getTestStatus().getStatus());
+    return Status.isOK(statusResponse.getTestStatus().getStatus());
+  }
+  private void downloadTestResults(String testHandle, String testOutputDir)
+  throws Exception {
+    HttpGet request = new HttpGet(mLogsEndpoint + testHandle + "/test-results.tar.gz");
+    FileOutputStream output = null;
+    try {
+      HttpResponse httpResponse = mHttpClient.execute(request);
+      StatusLine statusLine = httpResponse.getStatusLine();
+      if(statusLine.getStatusCode() != 200) {
+        throw new RuntimeException(statusLine.getStatusCode() + " " + statusLine.getReasonPhrase());
+      }
+      output = new FileOutputStream(new File(testOutputDir, "test-results.tar.gz"));
+      IOUtils.copyLarge(httpResponse.getEntity().getContent(), output);
+      output.flush();
+    } finally {
+      request.abort();
+      if(output != null) {
+        output.close();
+      }
+    }
+  }
+  private long printLogs(String testHandle, long offset)
+  throws Exception {
+    TestLogRequest logsRequest = new TestLogRequest(testHandle, offset, 64 * 1024);
+    TestLogResponse logsResponse = post(logsRequest);
+    System.out.print(logsResponse.getBody());
+    return logsResponse.getOffset();
+  }
+  private <S extends GenericResponse> S post(Object payload)
+  throws Exception {
+    EndPointResponsePair endPointResponse = Preconditions.
+        checkNotNull(REQUEST_TO_ENDPOINT.get(payload.getClass()), payload.getClass().getName());
+    HttpPost request = new HttpPost(mApiEndPoint + endPointResponse.getEndpoint());
+    try {
+      String payloadString = mMapper.writeValueAsString(payload);
+      StringEntity params = new StringEntity(payloadString);
+      request.addHeader("content-type", "application/json");
+      request.setEntity(params);
+      HttpResponse httpResponse = mHttpClient.execute(request);
+      StatusLine statusLine = httpResponse.getStatusLine();
+      if(statusLine.getStatusCode() != 200) {
+        throw new RuntimeException(statusLine.getStatusCode() + " " + statusLine.getReasonPhrase());
+      }
+      String response = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
+      @SuppressWarnings("unchecked")
+      S result =  (S)endPointResponse.
+          getResponseClass().cast(mMapper.readValue(response, endPointResponse.getResponseClass()));
+      Status.assertOK(result.getStatus());
+      if(System.getProperty("DEBUG_PTEST_CLIENT") != null) {
+        System.err.println("payload " + payloadString);
+        if(result instanceof TestLogResponse) {
+          System.err.println("response " + ((TestLogResponse)result).getOffset() + " " + ((TestLogResponse)result).getStatus());
+        } else {
+          System.err.println("response " + response);
+        }
+      }
+      Thread.sleep(1000);
+      return result;
+    } finally {
+      request.abort();
+    }
+  }
+  private static class EndPointResponsePair {
+    final String endpoint;
+    final Class<? extends GenericResponse> responseClass;
+    public EndPointResponsePair(String endpoint,
+        Class<? extends GenericResponse> responseClass) {
+      this.endpoint = endpoint;
+      this.responseClass = responseClass;
+    }
+    public String getEndpoint() {
+      return endpoint;
+    }
+    public Class<? extends GenericResponse> getResponseClass() {
+      return responseClass;
+    }
+  }
+  private static void assertRequired(CommandLine commandLine, String[] requiredOptions) {
+    for(String requiredOption : requiredOptions) {
+      if(!commandLine.hasOption(requiredOption)) {
+        throw new IllegalArgumentException(requiredOption + " is required");
+      } 
+    }
+  }
+  public static void main(String[] args) throws Exception {
+    CommandLineParser parser = new GnuParser();
+    Options options = new Options();
+    options.addOption(HELP_SHORT, HELP_LONG, false, "Display help text and exit");
+    options.addOption(null, ENDPOINT, true, "Service to use. E.g. http://localhost/ (Required)");
+    options.addOption(null, COMMAND, true, "Command: [testStart, testStop, testTailLog, testList] (Required)");
+    options.addOption(null, PASSWORD, true, "Password for service. Any committer should know this otherwise as private@. (Required)");
+    options.addOption(null, PROFILE, true, "Test profile such as trunk-mr1 or trunk-mr2 (Required for testStart)");
+    options.addOption(null, PATCH, true, "URI to patch, must start with http(s):// (Optional for testStart)");
+    options.addOption(null, JIRA, true, "JIRA to post the results to e.g.: HIVE-XXXX");
+    options.addOption(null, TEST_HANDLE, true, "Server supplied test handle. (Required for testStop and testTailLog)");
+    options.addOption(null, OUTPUT_DIR, true, "Directory to download and save test-results.tar.gz to. (Optional for testStart)");
+
+    CommandLine commandLine = parser.parse(options, args);
+
+    if(commandLine.hasOption(HELP_SHORT)) {
+      new HelpFormatter().printHelp(PTestClient.class.getName(), options, true);
+      System.exit(0);
+    }
+    assertRequired(commandLine, new String[] {
+      COMMAND,
+      PASSWORD,
+      ENDPOINT
+    });
+    PTestClient client = new PTestClient(commandLine.getOptionValue(ENDPOINT),
+        commandLine.getOptionValue(PASSWORD));
+    String command = commandLine.getOptionValue(COMMAND);
+    boolean result;
+    if("testStart".equalsIgnoreCase(command)) {
+      assertRequired(commandLine, new String[] {
+          PROFILE,
+          TEST_HANDLE
+        });
+      result = client.testStart(commandLine.getOptionValue(PROFILE), commandLine.getOptionValue(TEST_HANDLE),
+          commandLine.getOptionValue(JIRA), commandLine.getOptionValue(PATCH), commandLine.getOptionValue(OUTPUT_DIR));
+    } else if("testTailLog".equalsIgnoreCase(command)) {
+      result = client.testTailLog(commandLine.getOptionValue(TEST_HANDLE));
+    } else if("testList".equalsIgnoreCase(command)) {
+      result = client.testList();
+    } else {
+      throw new IllegalArgumentException("Unknown " + COMMAND + ": " + command);
+    }
+    if(result) {
+      System.exit(0);
+    } else {
+      System.exit(1);
+    }
+  }
+}

Added: hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestListRequest.java
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestListRequest.java?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestListRequest.java (added)
+++ hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestListRequest.java Fri Jul 19 03:47:36 2013
@@ -0,0 +1,35 @@
+/*
+ * 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.hive.ptest.api.request;
+
+public class TestListRequest {
+  /**
+   * Do not use. Required by Jackson.
+   */
+  private String dummy;
+  public TestListRequest() {
+
+  }
+  public String getDummy() {
+    return dummy;
+  }
+  public void setDummy(String dummy) {
+    this.dummy = dummy;
+  }
+}

Added: hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestLogRequest.java
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestLogRequest.java?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestLogRequest.java (added)
+++ hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestLogRequest.java Fri Jul 19 03:47:36 2013
@@ -0,0 +1,53 @@
+/*
+ * 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.hive.ptest.api.request;
+
+public class TestLogRequest {
+  private String testHandle;
+  private long offset;
+  private long length;
+
+  public TestLogRequest() {
+
+  }
+  public TestLogRequest(String testHandle, long offset, long length) {
+    super();
+    this.testHandle = testHandle;
+    this.offset = offset;
+    this.length = length;
+  }
+  public long getOffset() {
+    return offset;
+  }
+  public void setOffset(long offset) {
+    this.offset = offset;
+  }
+  public long getLength() {
+    return length;
+  }
+  public void setLength(long length) {
+    this.length = length;
+  }
+  public String getTestHandle() {
+    return testHandle;
+  }
+  public void setTestHandle(String testHandle) {
+    this.testHandle = testHandle;
+  }
+}

Added: hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestStartRequest.java
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestStartRequest.java?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestStartRequest.java (added)
+++ hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestStartRequest.java Fri Jul 19 03:47:36 2013
@@ -0,0 +1,69 @@
+/*
+ * 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.hive.ptest.api.request;
+
+public class TestStartRequest {
+  private String profile;
+  private String testHandle;
+  private String patchURL;
+  private String jiraName;
+
+  public TestStartRequest() {
+
+  }
+  public TestStartRequest(String profile, String testHandle, 
+      String jiraName, String patchURL) {
+    this.profile = profile;
+    this.testHandle = testHandle;
+    this.jiraName = jiraName;
+    this.patchURL = patchURL;
+  }
+  public String getProfile() {
+    return profile;
+  }
+  public void setProfile(String profile) {
+    this.profile = profile;
+  }
+  public String getPatchURL() {
+    return patchURL;
+  }
+  public void setPatchURL(String patchURL) {
+    this.patchURL = patchURL;
+  }
+  
+  public String getJiraName() {
+    return jiraName;
+  }
+  public void setJiraName(String jiraName) {
+    this.jiraName = jiraName;
+  }
+  
+  public String getTestHandle() {
+    return testHandle;
+  }
+  public void setTestHandle(String testHandle) {
+    this.testHandle = testHandle;
+  }
+  @Override
+  public String toString() {
+    return "TestStartRequest [profile=" + profile + ", testHandle="
+        + testHandle + ", patchURL=" + patchURL + ", jiraName=" + jiraName
+        + "]";
+  }
+}

Added: hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestStatusRequest.java
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestStatusRequest.java?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestStatusRequest.java (added)
+++ hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestStatusRequest.java Fri Jul 19 03:47:36 2013
@@ -0,0 +1,40 @@
+/*
+ * 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.hive.ptest.api.request;
+
+public class TestStatusRequest {
+  private String testHandle;
+
+  public TestStatusRequest() {
+
+  }
+  public TestStatusRequest(String testHandle) {
+    super();
+    this.testHandle = testHandle;
+  }
+
+  public String getTestHandle() {
+    return testHandle;
+  }
+
+  public void setTestHandle(String testHandle) {
+    this.testHandle = testHandle;
+  }
+
+}

Added: hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestStopRequest.java
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestStopRequest.java?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestStopRequest.java (added)
+++ hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/request/TestStopRequest.java Fri Jul 19 03:47:36 2013
@@ -0,0 +1,40 @@
+/*
+ * 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.hive.ptest.api.request;
+
+public class TestStopRequest {
+  private String testHandle;
+
+  public TestStopRequest() {
+
+  }
+  public TestStopRequest(String testHandle) {
+    super();
+    this.testHandle = testHandle;
+  }
+
+  public String getTestHandle() {
+    return testHandle;
+  }
+
+  public void setTestHandle(String testHandle) {
+    this.testHandle = testHandle;
+  }
+
+}

Added: hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/GenericResponse.java
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/GenericResponse.java?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/GenericResponse.java (added)
+++ hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/GenericResponse.java Fri Jul 19 03:47:36 2013
@@ -0,0 +1,25 @@
+/*
+ * 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.hive.ptest.api.response;
+
+import org.apache.hive.ptest.api.Status;
+
+public interface GenericResponse {
+  public Status getStatus();
+}

Added: hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestListResponse.java
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestListResponse.java?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestListResponse.java (added)
+++ hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestListResponse.java Fri Jul 19 03:47:36 2013
@@ -0,0 +1,53 @@
+/*
+ * 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.hive.ptest.api.response;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.hive.ptest.api.Status;
+
+public class TestListResponse implements GenericResponse {
+  private Status status;
+  private List<TestStatus> entries;
+
+  public TestListResponse() {
+    this(null);
+  }
+  public TestListResponse(Status status) {
+    this(status, Collections.<TestStatus>emptyList());
+  }
+  public TestListResponse(Status status, List<TestStatus> entries) {
+    this.status = status;
+    this.entries = entries;
+  }
+  @Override
+  public Status getStatus() {
+    return status;
+  }
+  public void setStatus(Status status) {
+    this.status = status;
+  }
+  public List<TestStatus> getEntries() {
+    return entries;
+  }
+  public void setEntries(List<TestStatus> entries) {
+    this.entries = entries;
+  }
+}

Added: hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestLogResponse.java
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestLogResponse.java?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestLogResponse.java (added)
+++ hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestLogResponse.java Fri Jul 19 03:47:36 2013
@@ -0,0 +1,59 @@
+/*
+ * 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.hive.ptest.api.response;
+
+import org.apache.hive.ptest.api.Status;
+
+public class TestLogResponse implements GenericResponse {
+  private Status status;
+  private String body;
+  private long offset;
+
+  public TestLogResponse() {
+    this(null);
+  }
+  public TestLogResponse(Status status) {
+    this(status, 0L, null);
+  }
+  public TestLogResponse(Status status, long offset, String body) {
+    super();
+    this.status = status;
+    this.offset = offset;
+    this.body = body;
+  }
+  @Override
+  public Status getStatus() {
+    return status;
+  }
+  public void setStatus(Status status) {
+    this.status = status;
+  }
+  public String getBody() {
+    return body;
+  }
+  public void setBody(String body) {
+    this.body = body;
+  }
+  public long getOffset() {
+    return offset;
+  }
+  public void setOffset(long offset) {
+    this.offset = offset;
+  }
+}

Added: hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStartResponse.java
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStartResponse.java?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStartResponse.java (added)
+++ hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStartResponse.java Fri Jul 19 03:47:36 2013
@@ -0,0 +1,44 @@
+/*
+ * 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.hive.ptest.api.response;
+
+import org.apache.hive.ptest.api.Status;
+
+public class TestStartResponse implements GenericResponse {
+  private Status status;
+
+  public TestStartResponse() {
+    this(null);
+  }
+  public TestStartResponse(Status status) {
+    super();
+    this.status = status;
+  }
+  @Override
+  public Status getStatus() {
+    return status;
+  }
+  public void setStatus(Status status) {
+    this.status = status;
+  }
+  @Override
+  public String toString() {
+    return "StartResponse [status=" + status +  "]";
+  }
+}

Added: hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStatus.java
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStatus.java?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStatus.java (added)
+++ hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStatus.java Fri Jul 19 03:47:36 2013
@@ -0,0 +1,82 @@
+/*
+ * 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.hive.ptest.api.response;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.hive.ptest.api.Status;
+
+public class TestStatus {
+  private String testHandle;
+  private Status status;
+  private long elapsedQueueTime;
+  private long elapsedExecutionTime;
+  private long logFileLength;
+  public TestStatus(String testHandle, Status status, long elapsedQueueTime,
+      long elapsedExecutionTime, long logFileLength) {
+    super();
+    this.testHandle = testHandle;
+    this.status = status;
+    this.elapsedQueueTime = elapsedQueueTime;
+    this.elapsedExecutionTime = elapsedExecutionTime;
+    this.logFileLength = logFileLength;
+  }
+  public TestStatus() {
+
+  }
+  public String getTestHandle() {
+    return testHandle;
+  }
+  public void setTestHandle(String testHandle) {
+    this.testHandle = testHandle;
+  }
+  public Status getStatus() {
+    return status;
+  }
+  public void setStatus(Status status) {
+    this.status = status;
+  }
+  public long getElapsedQueueTime() {
+    return elapsedQueueTime;
+  }
+  public void setElapsedQueueTime(long elapsedQueueTime) {
+    this.elapsedQueueTime = elapsedQueueTime;
+  }
+  public long getElapsedExecutionTime() {
+    return elapsedExecutionTime;
+  }
+  public void setElapsedExecutionTime(long elapsedExecutionTime) {
+    this.elapsedExecutionTime = elapsedExecutionTime;
+  }
+  public long getLogFileLength() {
+    return logFileLength;
+  }
+  public void setLogFileLength(long logFileLength) {
+    this.logFileLength = logFileLength;
+  }
+  @Override
+  public String toString() {
+    return "TestStatus [testHandle=" + testHandle + ", status=" + status
+        + ", elapsedQueueTime=" + toMinutes(elapsedQueueTime) + " minute(s), elapsedExecutionTime="
+        + toMinutes(elapsedExecutionTime) + " minute(s), logFileLength=" + logFileLength + "]";
+  }
+  private long toMinutes(long value) {
+    return TimeUnit.MINUTES.convert(value, TimeUnit.MILLISECONDS);
+  }
+}

Added: hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStatusResponse.java
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStatusResponse.java?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStatusResponse.java (added)
+++ hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStatusResponse.java Fri Jul 19 03:47:36 2013
@@ -0,0 +1,50 @@
+/*
+ * 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.hive.ptest.api.response;
+
+import org.apache.hive.ptest.api.Status;
+
+public class TestStatusResponse implements GenericResponse {
+  private Status status;
+  private TestStatus testStatus;
+
+  public TestStatusResponse() {
+    this(null);
+  }
+  public TestStatusResponse(Status status) {
+    this(status, null);
+  }
+  public TestStatusResponse(Status status, TestStatus testStatus) {
+    this.status = status;
+    this.testStatus = testStatus;
+  }
+  @Override
+  public Status getStatus() {
+    return status;
+  }
+  public void setStatus(Status status) {
+    this.status = status;
+  }
+  public TestStatus getTestStatus() {
+    return testStatus;
+  }
+  public void setTestStatus(TestStatus testStatus) {
+    this.testStatus = testStatus;
+  }
+}

Added: hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStopResponse.java
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStopResponse.java?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStopResponse.java (added)
+++ hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/response/TestStopResponse.java Fri Jul 19 03:47:36 2013
@@ -0,0 +1,39 @@
+/*
+ * 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.hive.ptest.api.response;
+
+import org.apache.hive.ptest.api.Status;
+
+public class TestStopResponse implements GenericResponse {
+  private Status status;
+
+  public TestStopResponse() {
+    this(null);
+  }
+  public TestStopResponse(Status status) {
+    this.status = status;
+  }
+  @Override
+  public Status getStatus() {
+    return status;
+  }
+  public void setStatus(Status status) {
+    this.status = status;
+  }
+}

Added: hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/server/ExecutionController.java
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/server/ExecutionController.java?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/server/ExecutionController.java (added)
+++ hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/server/ExecutionController.java Fri Jul 19 03:47:36 2013
@@ -0,0 +1,233 @@
+/*
+ * 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.hive.ptest.api.server;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+
+import org.apache.hive.ptest.api.Status;
+import org.apache.hive.ptest.api.request.TestListRequest;
+import org.apache.hive.ptest.api.request.TestLogRequest;
+import org.apache.hive.ptest.api.request.TestStartRequest;
+import org.apache.hive.ptest.api.request.TestStopRequest;
+import org.apache.hive.ptest.api.response.TestListResponse;
+import org.apache.hive.ptest.api.response.TestLogResponse;
+import org.apache.hive.ptest.api.response.TestStartResponse;
+import org.apache.hive.ptest.api.response.TestStatus;
+import org.apache.hive.ptest.api.response.TestStatusResponse;
+import org.apache.hive.ptest.api.response.TestStopResponse;
+import org.apache.hive.ptest.execution.PTest;
+import org.apache.hive.ptest.execution.conf.ExecutionContextConfiguration;
+import org.apache.hive.ptest.execution.context.ExecutionContextProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
+import com.google.common.collect.Lists;
+
+
+/**
+ * Server interface of the ptest environment. Each request
+ * is converted from JSON and each response is returned in JSON.
+ */
+@Controller
+@RequestMapping(value = "/api/v1")
+public class ExecutionController {
+  private static final long MAX_READ_SIZE = 1024L * 1024L;
+  private static final String CONF_PROPERTY = "hive.ptest.execution.context.conf";
+
+  private static final Logger LOG = LoggerFactory
+      .getLogger(ExecutionController.class);
+  private final ExecutionContextConfiguration mExecutionContextConfiguration;
+  private final ExecutionContextProvider mExecutionContextProvider;
+  private final Map<String, Test> mTests;
+  private final BlockingQueue<Test> mTestQueue;
+  private final TestExecutor mTestExecutor;
+  private final File mGlobalLogDir;
+  public ExecutionController()
+      throws IOException {
+    String executionContextConfigurationFile = System.getProperty(CONF_PROPERTY, "").trim();
+    Preconditions.checkArgument(!executionContextConfigurationFile.isEmpty(), CONF_PROPERTY + " is required");
+    mExecutionContextConfiguration = ExecutionContextConfiguration.fromFile(executionContextConfigurationFile);
+    mExecutionContextProvider = mExecutionContextConfiguration.getExecutionContextProvider();
+    mTests = Collections.synchronizedMap(new LinkedHashMap<String, Test>() {
+      private static final long serialVersionUID = 1L;
+      @Override
+      public boolean removeEldestEntry(Map.Entry<String, Test> entry) {
+        Test testExecution = entry.getValue();
+        File testOutputFile = testExecution.getOutputFile();
+        return size() > 30 || (testOutputFile != null && !testOutputFile.isFile());
+      }
+    });
+    mTestQueue = new ArrayBlockingQueue<Test>(5);
+    mGlobalLogDir = new File(mExecutionContextConfiguration.getGlobalLogDirectory());
+    mTestExecutor = new TestExecutor(mExecutionContextConfiguration, mExecutionContextProvider,
+        mTestQueue, new PTest.Builder());
+    mTestExecutor.setName("TestExecutor");
+    mTestExecutor.setDaemon(true);
+    mTestExecutor.start();
+    Runtime.getRuntime().addShutdownHook(new Thread() {
+      @Override
+    public void run() {
+        try {
+          mTestExecutor.shutdown();
+        } catch (Exception e) {
+          LOG.error("Error shutting down TestExecutor", e);
+        }
+        try {
+          mExecutionContextProvider.close();
+        } catch (Exception e) {
+          LOG.error("Error shutting down ExecutionContextProvider", e);
+        }
+      }
+    });
+  }
+
+  @RequestMapping(value="/testStart", method = RequestMethod.POST)
+  public @ResponseBody TestStartResponse testStart(@RequestBody TestStartRequest startRequest,
+      BindingResult result) {
+    LOG.info("startRequest " + startRequest.toString());
+    TestStartResponse startResponse = doStartTest(startRequest, result);
+    LOG.info("startResponse " + startResponse.toString());
+    return startResponse;
+  }
+
+  private TestStartResponse doStartTest(TestStartRequest startRequest, BindingResult result) {
+    if(result.hasErrors() ||
+        Strings.nullToEmpty(startRequest.getProfile()).trim().isEmpty() ||
+        Strings.nullToEmpty(startRequest.getTestHandle()).trim().isEmpty() ||
+        startRequest.getProfile().contains("/")) {
+      return new TestStartResponse(Status.illegalArgument());
+    }
+    if(!assertTestHandleIsAvailable(startRequest.getTestHandle())) {
+      return new TestStartResponse(Status.illegalArgument("Test handle " + startRequest.getTestHandle() + " already used")); 
+    }
+    Test test = new Test(startRequest,
+        Status.pending(), System.currentTimeMillis());
+    if(mTestQueue.offer(test)) {
+      mTests.put(startRequest.getTestHandle(), test);
+      return new TestStartResponse(Status.ok());
+    } else {
+      return new TestStartResponse(Status.queueFull());
+    }
+  }
+
+  @RequestMapping(value="/testStop", method = RequestMethod.POST)
+  public @ResponseBody TestStopResponse testStop(@RequestBody TestStopRequest stopRequest,
+      BindingResult result) {
+    String testHandle = stopRequest.getTestHandle();
+    Test test = mTests.get(testHandle);
+    if(result.hasErrors() ||
+        Strings.emptyToNull(stopRequest.getTestHandle()).trim().isEmpty() ||
+        test == null) {
+      return new TestStopResponse(Status.illegalArgument());
+    }
+    test.setStopRequested(true);
+    return new TestStopResponse(Status.ok());
+  }
+
+  @RequestMapping(value="/testStatus", method = RequestMethod.POST)
+  public @ResponseBody TestStatusResponse testStatus(@RequestBody TestStopRequest stopRequest,
+      BindingResult result) {
+    String testHandle = stopRequest.getTestHandle();
+    Test test = mTests.get(testHandle);
+    if(result.hasErrors() ||
+        Strings.emptyToNull(stopRequest.getTestHandle()).trim().isEmpty() ||
+        test == null) {
+      return new TestStatusResponse(Status.illegalArgument());
+    }
+    return new TestStatusResponse(Status.ok(), test.toTestStatus());
+  }
+
+  @RequestMapping(value="/testLog", method = RequestMethod.POST)
+  public @ResponseBody TestLogResponse testLog(@RequestBody TestLogRequest logsRequest,
+      BindingResult result) {
+    String testHandle = logsRequest.getTestHandle();
+    Test testExecution = mTests.get(testHandle);
+    if(result.hasErrors() ||
+        Strings.emptyToNull(logsRequest.getTestHandle()).trim().isEmpty() ||
+        testExecution == null ||
+        logsRequest.getLength() > MAX_READ_SIZE) {
+      return new TestLogResponse(Status.illegalArgument());
+    }
+    File outputFile = testExecution.getOutputFile();
+    if(outputFile == null ||
+        logsRequest.getOffset() > outputFile.length()) {
+      return new TestLogResponse(Status.illegalArgument());
+    }
+    RandomAccessFile fileHandle = null;
+    try {
+      fileHandle = new RandomAccessFile(outputFile, "r");
+      long offset = logsRequest.getOffset();
+      fileHandle.seek(offset);
+      int readLength = 0;
+      if(offset < fileHandle.length()) {
+        readLength = (int)Math.min(fileHandle.length() - offset, logsRequest.getLength());
+      }
+      byte[] buffer = new byte[readLength];
+      fileHandle.readFully(buffer);
+      offset += readLength;
+      return new TestLogResponse(Status.ok(), offset,
+          new String(buffer, Charsets.UTF_8));
+    } catch (IOException e) {
+      LOG.info("Unexpected IO error reading " + testExecution.getOutputFile() , e);
+      return new TestLogResponse(Status.internalError(e.getMessage()));
+    } finally {
+      if(fileHandle != null) {
+        try {
+          fileHandle.close();
+        } catch (IOException e) {
+          LOG.warn("Error closing " + outputFile, e);
+        }
+      }
+    }
+  }
+
+  @RequestMapping(value="/testList", method = RequestMethod.POST)
+  public @ResponseBody TestListResponse testList(@RequestBody TestListRequest request) {
+    List<TestStatus> entries = Lists.newArrayList();
+    synchronized (mTests) {
+      for(String testHandle : mTests.keySet()) {
+        Test test = mTests.get(testHandle);
+        entries.add(test.toTestStatus());
+      }
+    }
+    return new TestListResponse(Status.ok(), entries);
+  }
+  private synchronized boolean assertTestHandleIsAvailable(final String testHandle) {
+    File testOutputDir = new File(mGlobalLogDir, testHandle);
+    Preconditions.checkState(!testOutputDir.isFile(), "Output directory " + testOutputDir + " is file");
+    return testOutputDir.mkdir();
+  }
+}
\ No newline at end of file

Added: hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/server/Test.java
URL: http://svn.apache.org/viewvc/hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/server/Test.java?rev=1504759&view=auto
==============================================================================
--- hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/server/Test.java (added)
+++ hive/trunk/testutils/ptest2/src/main/java/org/apache/hive/ptest/api/server/Test.java Fri Jul 19 03:47:36 2013
@@ -0,0 +1,117 @@
+/*
+ * 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.hive.ptest.api.server;
+
+import java.io.File;
+
+import org.apache.hive.ptest.api.Status;
+import org.apache.hive.ptest.api.request.TestStartRequest;
+import org.apache.hive.ptest.api.response.TestStatus;
+
+/**
+ * Represents a test run in memory on the server.
+ */
+class Test {
+  private TestStartRequest startRequest;
+  private Status status;
+  private long enqueueTime;
+  private long dequeueTime;
+  private long executionStartTime;
+  private long executionFinishTime;
+  private File outputFile;
+  private boolean stopRequested;
+
+  Test(TestStartRequest startRequest,
+      Status status, long enqueueTime) {
+    super();
+    this.startRequest = startRequest;
+    this.status = status;
+    this.enqueueTime = enqueueTime;
+  }
+  boolean isStopRequested() {
+    return stopRequested;
+  }
+  void setStopRequested(boolean stopRequested) {
+    this.stopRequested = stopRequested;
+  }
+  TestStartRequest getStartRequest() {
+    return startRequest;
+  }
+  void setStartRequest(TestStartRequest startRequest) {
+    this.startRequest = startRequest;
+  }
+  Status getStatus() {
+    return status;
+  }
+  void setStatus(Status status) {
+    this.status = status;
+  }
+  long getEnqueueTime() {
+    return enqueueTime;
+  }
+  void setEnqueueTime(long enqueueTime) {
+    this.enqueueTime = enqueueTime;
+  }
+  long getExecutionStartTime() {
+    return executionStartTime;
+  }
+  void setExecutionStartTime(long executionStartTime) {
+    this.executionStartTime = executionStartTime;
+  }
+  long getExecutionFinishTime() {
+    return executionFinishTime;
+  }
+  void setExecutionFinishTime(long executionFinishTime) {
+    this.executionFinishTime = executionFinishTime;
+  }
+  File getOutputFile() {
+    return outputFile;
+  }
+  void setOutputFile(File outputFile) {
+    this.outputFile = outputFile;
+  }
+  long getDequeueTime() {
+    return dequeueTime;
+  }
+  void setDequeueTime(long dequeueTime) {
+    this.dequeueTime = dequeueTime;
+  }
+  TestStatus toTestStatus() {
+    long elapsedQueueTime;
+    if(getDequeueTime() > 0) {
+      elapsedQueueTime = getDequeueTime() - getEnqueueTime();
+    } else {
+      elapsedQueueTime = System.currentTimeMillis() - getEnqueueTime();
+    }
+    long elapsedExecutionTime = 0;
+    if(getExecutionStartTime() > 0) {
+      if(getExecutionFinishTime() > 0) {
+        elapsedExecutionTime = getExecutionFinishTime() - getExecutionStartTime();
+      } else {
+        elapsedExecutionTime = System.currentTimeMillis() - getExecutionStartTime();
+      }
+    }
+    long logFileLength = 0;
+    if(getOutputFile() != null) {
+      logFileLength = getOutputFile().length();
+    }
+    return new TestStatus(startRequest.getTestHandle(), getStatus(),
+        elapsedQueueTime, elapsedExecutionTime, logFileLength);
+  }
+}