asterixdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mb...@apache.org
Subject [1/2] asterixdb git commit: [ASTERIXDB-2261][TEST] Logging Misc Fixes
Date Tue, 06 Feb 2018 18:04:52 GMT
Repository: asterixdb
Updated Branches:
  refs/heads/master 1a936956d -> 2530e39d7


http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/RecoveryIT.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/RecoveryIT.java b/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/RecoveryIT.java
new file mode 100644
index 0000000..ba367a7
--- /dev/null
+++ b/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/RecoveryIT.java
@@ -0,0 +1,136 @@
+/*
+ * 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.asterix.test.server;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.asterix.test.base.RetainLogsRule;
+import org.apache.asterix.test.common.TestExecutor;
+import org.apache.asterix.test.runtime.HDFSCluster;
+import org.apache.asterix.testframework.context.TestCaseContext;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class RecoveryIT {
+
+    private static final Logger LOGGER = LogManager.getLogger();
+    private static final String PATH_ACTUAL = "target" + File.separator + "rttest" + File.separator;
+    private static final String PATH_BASE = "src/test/resources/transactionts/";
+    private static final String HDFS_BASE = "../asterix-app/";
+    private TestCaseContext tcCtx;
+    private static File asterixInstallerPath;
+    private static File installerTargetPath;
+    private static String ncServiceHomeDirName;
+    private static String ncServiceHomePath;
+    private static String scriptHomePath;
+    private static String reportPath;
+    private static ProcessBuilder pb;
+    private static Map<String, String> env;
+    private final TestExecutor testExecutor = new TestExecutor();
+
+    @Rule
+    public TestRule retainLogs = new RetainLogsRule(ncServiceHomePath, reportPath, this);
+
+    @BeforeClass
+    public static void setUp() throws Exception {
+        File outdir = new File(PATH_ACTUAL);
+        outdir.mkdirs();
+
+        File externalTestsJar =
+                new File(StringUtils.join(new String[] { "..", "asterix-external-data", "target" }, File.separator))
+                        .listFiles((dir, name) -> name.matches("asterix-external-data-.*-tests.jar"))[0];
+
+        asterixInstallerPath = new File(System.getProperty("user.dir"));
+        installerTargetPath = new File(new File(asterixInstallerPath.getParentFile(), "asterix-server"), "target");
+        reportPath = new File(installerTargetPath, "failsafe-reports").getAbsolutePath();
+        ncServiceHomeDirName = installerTargetPath.list(new FilenameFilter() {
+            @Override
+            public boolean accept(File dir, String name) {
+                return new File(dir, name).isDirectory() && name.startsWith("asterix-server")
+                        && name.endsWith("binary-assembly");
+            }
+        })[0];
+        ncServiceHomePath = new File(installerTargetPath, ncServiceHomeDirName).getAbsolutePath();
+
+        LOGGER.info("NCSERVICE_HOME=" + ncServiceHomePath);
+
+        FileUtils.copyFile(externalTestsJar, new File(ncServiceHomePath + "/repo", externalTestsJar.getName()));
+
+        pb = new ProcessBuilder();
+        env = pb.environment();
+        env.put("NCSERVICE_HOME", ncServiceHomePath);
+        env.put("JAVA_HOME", System.getProperty("java.home"));
+        scriptHomePath = asterixInstallerPath + File.separator + "src" + File.separator + "test" + File.separator
+                + "resources" + File.separator + "transactionts" + File.separator + "scripts";
+        env.put("SCRIPT_HOME", scriptHomePath);
+
+        TestExecutor.executeScript(pb,
+                scriptHomePath + File.separator + "setup_teardown" + File.separator + "configure_and_validate.sh");
+        TestExecutor.executeScript(pb,
+                scriptHomePath + File.separator + "setup_teardown" + File.separator + "stop_and_delete.sh");
+        HDFSCluster.getInstance().setup(HDFS_BASE);
+    }
+
+    @AfterClass
+    public static void tearDown() throws Exception {
+        File outdir = new File(PATH_ACTUAL);
+        FileUtils.deleteDirectory(outdir);
+        File dataCopyDir =
+                new File(ncServiceHomePath + File.separator + ".." + File.separator + ".." + File.separator + "data");
+        FileUtils.deleteDirectory(dataCopyDir);
+        TestExecutor.executeScript(pb,
+                scriptHomePath + File.separator + "setup_teardown" + File.separator + "stop_and_delete.sh");
+        HDFSCluster.getInstance().cleanup();
+    }
+
+    @Parameters(name = "RecoveryIT {index}: {0}")
+    public static Collection<Object[]> tests() throws Exception {
+        Collection<Object[]> testArgs = new ArrayList<Object[]>();
+        TestCaseContext.Builder b = new TestCaseContext.Builder();
+        for (TestCaseContext ctx : b.build(new File(PATH_BASE))) {
+            testArgs.add(new Object[] { ctx });
+        }
+        return testArgs;
+    }
+
+    public RecoveryIT(TestCaseContext tcCtx) {
+        this.tcCtx = tcCtx;
+    }
+
+    @Test
+    public void test() throws Exception {
+        testExecutor.executeTest(PATH_ACTUAL, tcCtx, pb, false);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/ReplicationIT.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/ReplicationIT.java b/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/ReplicationIT.java
new file mode 100644
index 0000000..0f058bc
--- /dev/null
+++ b/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/ReplicationIT.java
@@ -0,0 +1,135 @@
+/*
+ * 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.asterix.test.server;
+
+import static org.apache.asterix.test.server.NCServiceExecutionIT.APP_HOME;
+import static org.apache.asterix.test.server.NCServiceExecutionIT.ASTERIX_APP_DIR;
+import static org.apache.asterix.test.server.NCServiceExecutionIT.INSTANCE_DIR;
+import static org.apache.asterix.test.server.NCServiceExecutionIT.LOG_DIR;
+import static org.apache.asterix.test.server.NCServiceExecutionIT.TARGET_DIR;
+
+import java.io.File;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.asterix.test.base.RetainLogsRule;
+import org.apache.asterix.test.common.TestExecutor;
+import org.apache.asterix.testframework.context.TestCaseContext;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hyracks.test.server.process.HyracksVirtualCluster;
+import org.apache.hyracks.util.file.FileUtil;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class ReplicationIT {
+
+    private static final String PATH_BASE =
+            FileUtil.joinPath("src", "test", "resources", "integrationts", "replication");
+    private static final String CONF_DIR =
+            StringUtils.join(new String[] { TARGET_DIR, "test-classes", "ReplicationIT" }, File.separator);
+    private static final String PATH_ACTUAL = FileUtil.joinPath("target", "ittest");
+    private static final Logger LOGGER = LogManager.getLogger();
+    private static String reportPath = new File(FileUtil.joinPath("target", "failsafe-reports")).getAbsolutePath();
+    private static final TestExecutor testExecutor = new TestExecutor();
+    private static HyracksVirtualCluster cluster;
+
+    static {
+        final Map<String, InetSocketAddress> ncEndPoints = new HashMap<>();
+        final Map<String, InetSocketAddress> replicationAddress = new HashMap<>();
+        final String ip = InetAddress.getLoopbackAddress().getHostAddress();
+        ncEndPoints.put("asterix_nc1", InetSocketAddress.createUnresolved(ip, 19004));
+        ncEndPoints.put("asterix_nc2", InetSocketAddress.createUnresolved(ip, 19005));
+        replicationAddress.put("asterix_nc1", InetSocketAddress.createUnresolved(ip, 2001));
+        replicationAddress.put("asterix_nc2", InetSocketAddress.createUnresolved(ip, 2002));
+        testExecutor.setNcEndPoints(ncEndPoints);
+        testExecutor.setNcReplicationAddress(replicationAddress);
+    }
+
+    private TestCaseContext tcCtx;
+
+    public ReplicationIT(TestCaseContext tcCtx) {
+        this.tcCtx = tcCtx;
+    }
+
+    @Rule
+    public TestRule retainLogs = new RetainLogsRule(NCServiceExecutionIT.ASTERIX_APP_DIR, reportPath, this);
+
+    @Before
+    public void before() throws Exception {
+        LOGGER.info("Creating new instance...");
+        File instanceDir = new File(INSTANCE_DIR);
+        if (instanceDir.isDirectory()) {
+            FileUtils.deleteDirectory(instanceDir);
+        }
+
+        cluster = new HyracksVirtualCluster(new File(APP_HOME), new File(ASTERIX_APP_DIR));
+        cluster.addNCService(new File(CONF_DIR, "ncservice1.conf"), new File(LOG_DIR, "ncservice1.log"));
+        cluster.addNCService(new File(CONF_DIR, "ncservice2.conf"), new File(LOG_DIR, "ncservice2.log"));
+
+        // Start CC
+        cluster.start(new File(CONF_DIR, "cc.conf"), new File(LOG_DIR, "cc.log"));
+        LOGGER.info("Instance created.");
+        testExecutor.waitForClusterActive(30, TimeUnit.SECONDS);
+        LOGGER.info("Instance is in ACTIVE state.");
+    }
+
+    @After
+    public void after() {
+        LOGGER.info("Destroying instance...");
+        cluster.stop();
+        LOGGER.info("Instance destroyed.");
+    }
+
+    @Test
+    public void test() throws Exception {
+        testExecutor.executeTest(PATH_ACTUAL, tcCtx, null, false);
+    }
+
+    @Parameterized.Parameters(name = "ReplicationIT {index}: {0}")
+    public static Collection<Object[]> tests() throws Exception {
+        Collection<Object[]> testArgs = buildTestsInXml(TestCaseContext.DEFAULT_TESTSUITE_XML_NAME);
+        if (testArgs.size() == 0) {
+            testArgs = buildTestsInXml(TestCaseContext.DEFAULT_TESTSUITE_XML_NAME);
+        }
+        return testArgs;
+    }
+
+    private static Collection<Object[]> buildTestsInXml(String xmlfile) throws Exception {
+        Collection<Object[]> testArgs = new ArrayList<>();
+        TestCaseContext.Builder b = new TestCaseContext.Builder();
+        for (TestCaseContext ctx : b.build(new File(PATH_BASE), xmlfile)) {
+            testArgs.add(new Object[] { ctx });
+        }
+        return testArgs;
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/SampleLocalClusterIT.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/SampleLocalClusterIT.java b/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/SampleLocalClusterIT.java
new file mode 100644
index 0000000..766402c
--- /dev/null
+++ b/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/SampleLocalClusterIT.java
@@ -0,0 +1,140 @@
+/*
+ * 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.asterix.test.server;
+
+import static org.apache.hyracks.util.file.FileUtil.joinPath;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.asterix.common.utils.Servlets;
+import org.apache.asterix.test.base.TestMethodTracer;
+import org.apache.asterix.test.common.TestExecutor;
+import org.apache.asterix.test.common.TestHelper;
+import org.apache.asterix.testframework.context.TestCaseContext.OutputFormat;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestRule;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class SampleLocalClusterIT {
+
+    // Important paths and files for this test.
+
+    // The "target" subdirectory of asterix-server. All outputs go here.
+    private static final String TARGET_DIR = joinPath("target");
+
+    // Directory where the NCs create and store all data, as configured by
+    // src/test/resources/NCServiceExecutionIT/cc.conf.
+    private static final String OUTPUT_DIR = joinPath(TARGET_DIR, "sample local cluster");
+
+    private static final String LOCAL_SAMPLES_DIR = joinPath(OUTPUT_DIR, "opt", "local");
+
+    @Rule
+    public TestRule watcher = new TestMethodTracer();
+
+    @BeforeClass
+    public static void setUp() throws Exception {
+        // Create actual-results output directory.
+        File outDir = new File(OUTPUT_DIR);
+
+        // Remove any instance data from previous runs.
+        if (outDir.isDirectory()) {
+            FileUtils.deleteDirectory(outDir);
+        }
+        outDir.mkdirs();
+
+        String[] pathElements = new String[] { TARGET_DIR,
+                new File(TARGET_DIR).list((dir, name) -> name.matches("asterix-server.*-binary-assembly.zip"))[0] };
+        String installerZip = joinPath(pathElements);
+
+        TestHelper.unzip(installerZip, OUTPUT_DIR);
+
+    }
+
+    private static List<File> findLogFiles(File directory, List<File> fileList) {
+        File[] match = directory.listFiles(pathname -> pathname.isDirectory() || pathname.toString().endsWith(".log"));
+        if (match != null) {
+            for (File file : match) {
+                if (file.isDirectory()) {
+                    findLogFiles(file, fileList);
+                } else {
+                    fileList.add(file);
+                }
+            }
+        }
+        return fileList;
+    }
+
+    @AfterClass
+    public static void teardown() throws Exception {
+
+        File destDir = new File(TARGET_DIR, joinPath("failsafe-reports", SampleLocalClusterIT.class.getSimpleName()));
+
+        for (File f : findLogFiles(new File(OUTPUT_DIR), new ArrayList<>())) {
+            FileUtils.copyFileToDirectory(f, destDir);
+        }
+    }
+
+    @Test
+    public void test0_startCluster() throws Exception {
+        Process process =
+                new ProcessBuilder(joinPath(LOCAL_SAMPLES_DIR, "bin/stop-sample-cluster.sh"), "-f").inheritIO().start();
+        Assert.assertEquals(0, process.waitFor());
+        process = new ProcessBuilder(joinPath(LOCAL_SAMPLES_DIR, "bin/start-sample-cluster.sh")).inheritIO().start();
+        Assert.assertEquals(0, process.waitFor());
+    }
+
+    @Test
+    public void test1_sanityQuery() throws Exception {
+        TestExecutor testExecutor = new TestExecutor();
+        InputStream resultStream = testExecutor.executeQuery("1+1", OutputFormat.ADM,
+                new URI("http", null, "127.0.0.1", 19002, Servlets.AQL_QUERY, null, null), Collections.emptyList());
+        StringWriter sw = new StringWriter();
+        IOUtils.copy(resultStream, sw);
+        Assert.assertEquals("2", sw.toString().trim());
+    }
+
+    @Test
+    public void test2_stopCluster() throws Exception {
+        Process process =
+                new ProcessBuilder(joinPath(LOCAL_SAMPLES_DIR, "bin/stop-sample-cluster.sh")).inheritIO().start();
+        Assert.assertEquals(0, process.waitFor());
+        try {
+            new URL("http://127.0.0.1:19002").openConnection().connect();
+            Assert.assertTrue("Expected connection to be refused.", false);
+        } catch (IOException e) {
+            // expected
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/SqlppExecutionIT.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/SqlppExecutionIT.java b/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/SqlppExecutionIT.java
new file mode 100644
index 0000000..f1738fe
--- /dev/null
+++ b/asterixdb/asterix-server/src/test/java/org/apache/asterix/test/server/SqlppExecutionIT.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2009-2013 by The Regents of the University of California
+ * Licensed 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 from
+ *
+ *     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.asterix.test.server;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.asterix.testframework.context.TestCaseContext;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Runs the runtime test cases under 'asterix-app/src/test/resources/runtimets'.
+ */
+@RunWith(Parameterized.class)
+public class SqlppExecutionIT extends AbstractExecutionIT {
+
+    @Parameters(name = "SqlppExecutionIT {index}: {0}")
+    public static Collection<Object[]> tests() throws Exception {
+        Collection<Object[]> testArgs = buildTestsInXml("only_sqlpp.xml");
+        if (testArgs.size() == 0) {
+            testArgs = buildTestsInXml("testsuite_sqlpp.xml");
+        }
+        return testArgs;
+    }
+
+    protected static Collection<Object[]> buildTestsInXml(String xmlfile) throws Exception {
+        Collection<Object[]> testArgs = new ArrayList<Object[]>();
+        TestCaseContext.Builder b = new TestCaseContext.Builder();
+        for (TestCaseContext ctx : b.build(new File(PATH_BASE), xmlfile)) {
+            testArgs.add(new Object[] { ctx });
+        }
+        return testArgs;
+
+    }
+
+    public SqlppExecutionIT(TestCaseContext tcCtx) {
+        super(tcCtx);
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/asterixdb/pom.xml
----------------------------------------------------------------------
diff --git a/asterixdb/pom.xml b/asterixdb/pom.xml
index 08781d3..241fa56 100644
--- a/asterixdb/pom.xml
+++ b/asterixdb/pom.xml
@@ -58,7 +58,7 @@
     <maven.test.skip>false</maven.test.skip>
     <skip.surefire.tests>${skipTests}</skip.surefire.tests>
     <skip.testResources>${maven.test.skip}</skip.testResources>
-    <testLog4jConfigFile>${root.dir}/asterix-app/src/test/resources/log4j2-test.xml</testLog4jConfigFile>
+    <testLog4jConfigFile>${root.dir}/asterix-app/src/test/resources/log4j2-asterixdb-test.xml</testLog4jConfigFile>
 
     <!-- Definition of tests in various categories which may be excluded -->
     <repeated.tests>**/RepeatedTest.java</repeated.tests>
@@ -1001,6 +1001,12 @@
       </dependency>
       <dependency>
         <groupId>org.apache.hyracks</groupId>
+        <artifactId>hyracks-server</artifactId>
+        <version>${hyracks.version}</version>
+        <type>test-jar</type>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.hyracks</groupId>
         <artifactId>hyracks-dataflow-common</artifactId>
         <version>${hyracks.version}</version>
       </dependency>

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/hyracks-fullstack/hyracks/hyracks-server/pom.xml
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-server/pom.xml b/hyracks-fullstack/hyracks/hyracks-server/pom.xml
index fcc2d2d..ca04f54 100644
--- a/hyracks-fullstack/hyracks/hyracks-server/pom.xml
+++ b/hyracks-fullstack/hyracks/hyracks-server/pom.xml
@@ -44,6 +44,17 @@
     <plugins>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <executions>
+          <execution>
+            <goals>
+              <goal>test-jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-dependency-plugin</artifactId>
         <configuration>
           <usedDependencies combine.children="append">

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/hyracks-fullstack/hyracks/hyracks-server/src/main/java/org/apache/hyracks/server/process/HyracksCCProcess.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-server/src/main/java/org/apache/hyracks/server/process/HyracksCCProcess.java b/hyracks-fullstack/hyracks/hyracks-server/src/main/java/org/apache/hyracks/server/process/HyracksCCProcess.java
deleted file mode 100644
index 354dc32..0000000
--- a/hyracks-fullstack/hyracks/hyracks-server/src/main/java/org/apache/hyracks/server/process/HyracksCCProcess.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.hyracks.server.process;
-
-import java.io.File;
-import java.util.List;
-
-import org.apache.hyracks.control.cc.CCDriver;
-
-@SuppressWarnings("squid:CommentedOutCodeLine")
-public class HyracksCCProcess extends HyracksServerProcess {
-
-    public HyracksCCProcess(File configFile, File logFile, File appHome, File workingDir) {
-        this.configFile = configFile;
-        this.logFile = logFile;
-        this.appHome = appHome;
-        this.workingDir = workingDir;
-    }
-
-    @Override
-    protected String getMainClassName() {
-        return CCDriver.class.getName();
-    }
-
-    @Override
-    protected void addJvmArgs(List<String> cList) {
-        // CC needs more than default memory
-        cList.add("-Xmx1024m");
-        //cList.add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"); //NOSONAR
-    }
-}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/hyracks-fullstack/hyracks/hyracks-server/src/main/java/org/apache/hyracks/server/process/HyracksNCServiceProcess.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-server/src/main/java/org/apache/hyracks/server/process/HyracksNCServiceProcess.java b/hyracks-fullstack/hyracks/hyracks-server/src/main/java/org/apache/hyracks/server/process/HyracksNCServiceProcess.java
deleted file mode 100644
index 39971ad..0000000
--- a/hyracks-fullstack/hyracks/hyracks-server/src/main/java/org/apache/hyracks/server/process/HyracksNCServiceProcess.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.hyracks.server.process;
-
-import org.apache.hyracks.control.nc.service.NCService;
-
-import java.io.File;
-import java.util.List;
-
-public class HyracksNCServiceProcess extends HyracksServerProcess {
-
-    public HyracksNCServiceProcess(File configFile, File logFile, File appHome, File workingDir) {
-        this.configFile = configFile;
-        this.logFile = logFile;
-        this.appHome = appHome;
-        this.workingDir = workingDir;
-    }
-
-    @Override
-    protected String getMainClassName() {
-        return NCService.class.getName();
-    }
-
-    @Override
-    protected void addJvmArgs(List<String> cList) {
-        // NCService needs little memory
-        cList.add("-Xmx128m");
-    }
-}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/hyracks-fullstack/hyracks/hyracks-server/src/main/java/org/apache/hyracks/server/process/HyracksServerProcess.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-server/src/main/java/org/apache/hyracks/server/process/HyracksServerProcess.java b/hyracks-fullstack/hyracks/hyracks-server/src/main/java/org/apache/hyracks/server/process/HyracksServerProcess.java
deleted file mode 100644
index 0c7be89..0000000
--- a/hyracks-fullstack/hyracks/hyracks-server/src/main/java/org/apache/hyracks/server/process/HyracksServerProcess.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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.hyracks.server.process;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-abstract class HyracksServerProcess {
-    private static final Logger LOGGER = LogManager.getLogger();
-
-    protected Process process;
-    protected File configFile = null;
-    protected File logFile = null;
-    protected File appHome = null;
-    protected File workingDir = null;
-
-    public void start() throws IOException {
-        String[] cmd = buildCommand();
-        if (LOGGER.isInfoEnabled()) {
-            LOGGER.info("Starting command: " + Arrays.toString(cmd));
-        }
-
-        ProcessBuilder pb = new ProcessBuilder(cmd);
-        pb.redirectErrorStream(true);
-        if (logFile != null) {
-            if (LOGGER.isInfoEnabled()) {
-                LOGGER.info("Logging to: " + logFile.getCanonicalPath());
-            }
-            logFile.getParentFile().mkdirs();
-            try (FileWriter writer = new FileWriter(logFile, true)) {
-                writer.write("---------------------\n");
-            }
-            pb.redirectOutput(ProcessBuilder.Redirect.appendTo(logFile));
-        } else {
-            if (LOGGER.isInfoEnabled()) {
-                LOGGER.info("Logfile not set, subprocess will output to stdout");
-            }
-        }
-        pb.directory(workingDir);
-        process = pb.start();
-    }
-
-    public void stop() {
-        process.destroy();
-        try {
-            boolean success = process.waitFor(30, TimeUnit.SECONDS);
-            if (LOGGER.isWarnEnabled()) {
-                LOGGER.warn("Killing unresponsive NC Process");
-            }
-            if (!success) {
-                process.destroyForcibly();
-            }
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-        }
-    }
-
-    public void stop(boolean forcibly) {
-        if (forcibly) {
-            process.destroyForcibly();
-        } else {
-            process.destroy();
-        }
-        try {
-            process.waitFor();
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-        }
-    }
-
-    private String[] buildCommand() {
-        List<String> cList = new ArrayList<String>();
-        cList.add(getJavaCommand());
-        addJvmArgs(cList);
-        cList.add("-Dapp.home=" + appHome.getAbsolutePath());
-        cList.add("-classpath");
-        cList.add(getClasspath());
-        cList.add(getMainClassName());
-        if (configFile != null) {
-            cList.add("-config-file");
-            cList.add(configFile.getAbsolutePath());
-        }
-        addCmdLineArgs(cList);
-        return cList.toArray(new String[cList.size()]);
-    }
-
-    protected void addJvmArgs(List<String> cList) {
-    }
-
-    protected void addCmdLineArgs(List<String> cList) {
-    }
-
-    protected abstract String getMainClassName();
-
-    private final String getClasspath() {
-        return System.getProperty("java.class.path");
-    }
-
-    private final String getJavaCommand() {
-        return System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
-    }
-}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/hyracks-fullstack/hyracks/hyracks-server/src/main/java/org/apache/hyracks/server/process/HyracksVirtualCluster.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-server/src/main/java/org/apache/hyracks/server/process/HyracksVirtualCluster.java b/hyracks-fullstack/hyracks/hyracks-server/src/main/java/org/apache/hyracks/server/process/HyracksVirtualCluster.java
deleted file mode 100644
index 8aa5eab..0000000
--- a/hyracks-fullstack/hyracks/hyracks-server/src/main/java/org/apache/hyracks/server/process/HyracksVirtualCluster.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * 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.hyracks.server.process;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Starts a local hyracks-based cluster (NC and CC child processes).
- */
-public class HyracksVirtualCluster {
-    private final File appHome;
-    private final File workingDir;
-    private List<HyracksNCServiceProcess> ncProcs = new ArrayList<>(3);
-    private HyracksCCProcess ccProc = null;
-
-    /**
-     * Construct a Hyracks-based cluster.
-     * @param appHome - path to the installation root of the Hyracks application.
-     *                At least bin/hyracksnc (or the equivalent NC script for
-     *                the application) must exist in this directory.
-     * @param workingDir - directory to use as CWD for all child processes. May
-     *                be null, in which case the CWD of the invoking process is used.
-     */
-    public HyracksVirtualCluster(File appHome, File workingDir) {
-        this.appHome = appHome;
-        this.workingDir = workingDir;
-    }
-
-    /**
-     * Creates and starts an NCService.
-     * @param configFile - full path to an ncservice.conf. May be null to accept all defaults.
-     * @throws IOException - if there are errors starting the process.
-     */
-    public HyracksNCServiceProcess addNCService(File configFile, File logFile) throws IOException {
-        HyracksNCServiceProcess proc = new HyracksNCServiceProcess(configFile, logFile, appHome, workingDir);
-        proc.start();
-        ncProcs.add(proc);
-        return proc;
-    }
-
-    /**
-     * Starts the CC, initializing the cluster. Expects that any NCs referenced
-     * in the cluster configuration have already been started with addNCService().
-     * @param ccConfigFile - full path to a cluster conf file. May be null to accept all
-     *                     defaults, although this is seldom useful since there are no NCs.
-     * @throws IOException - if there are errors starting the process.
-     */
-    public HyracksCCProcess start(File ccConfigFile, File logFile) throws IOException {
-        ccProc = new HyracksCCProcess(ccConfigFile, logFile, appHome, workingDir);
-        ccProc.start();
-        return ccProc;
-    }
-
-    /**
-     * Stops all processes in the cluster.
-     * QQQ Someday this should probably do a graceful stop of NCs rather than
-     * killing the NCService.
-     */
-    public void stop() {
-        ccProc.stop();
-        for (HyracksNCServiceProcess proc : ncProcs) {
-            proc.stop();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/server/test/NCServiceIT.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/server/test/NCServiceIT.java b/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/server/test/NCServiceIT.java
deleted file mode 100644
index d12c05b..0000000
--- a/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/server/test/NCServiceIT.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * 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.hyracks.server.test;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.util.Iterator;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import junit.framework.Assert;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.util.EntityUtils;
-import org.apache.hyracks.server.process.HyracksVirtualCluster;
-import org.apache.hyracks.util.file.FileUtil;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-public class NCServiceIT {
-
-    private static final String TARGET_DIR = FileUtil.joinPath(".", "target");
-    private static final String LOG_DIR = FileUtil.joinPath(TARGET_DIR, "failsafe-reports");
-    private static final String RESOURCE_DIR = FileUtil.joinPath(TARGET_DIR, "test-classes", "NCServiceIT");
-    private static final String APP_HOME = FileUtil.joinPath(TARGET_DIR, "appassembler");
-    private static final Logger LOGGER = LogManager.getLogger();
-
-    private static HyracksVirtualCluster cluster = null;
-
-    @BeforeClass
-    public static void setUp() throws Exception {
-        cluster = new HyracksVirtualCluster(new File(APP_HOME), null);
-        cluster.addNCService(new File(RESOURCE_DIR, "nc-red.conf"), new File(LOG_DIR, "nc-red.log"));
-        cluster.addNCService(new File(RESOURCE_DIR, "nc-blue.conf"), new File(LOG_DIR, "nc-blue.log"));
-
-        try {
-            Thread.sleep(2000);
-        } catch (InterruptedException ignored) {
-        }
-
-        // Start CC
-        cluster.start(new File(RESOURCE_DIR, "cc.conf"), new File(LOG_DIR, "cc.log"));
-
-        try {
-            Thread.sleep(10000);
-        } catch (InterruptedException ignored) {
-        }
-    }
-
-    @AfterClass
-    public static void tearDown() throws IOException {
-        cluster.stop();
-    }
-
-    private static String getHttp(String url) throws Exception {
-        HttpClient client = HttpClients.createDefault();
-        HttpGet get = new HttpGet(url);
-        int statusCode;
-        final HttpResponse httpResponse;
-        try {
-            httpResponse = client.execute(get);
-            statusCode = httpResponse.getStatusLine().getStatusCode();
-        } catch (Exception e) {
-            e.printStackTrace();
-            throw e;
-        }
-        String response = EntityUtils.toString(httpResponse.getEntity());
-        if (statusCode == HttpStatus.SC_OK) {
-            return response;
-        } else {
-            throw new Exception("HTTP error " + statusCode + ":\n" + response);
-        }
-    }
-
-    private JsonNode getEndpoint(String endpoint) throws Exception {
-        ObjectMapper om = new ObjectMapper();
-        String localhost = InetAddress.getLoopbackAddress().getHostAddress();
-        String response = getHttp("http://" + localhost + ":12345" + endpoint);
-        JsonNode result = om.readTree(response);
-        JsonNode nodes = result.get("result");
-        return nodes;
-    }
-
-    @Test
-    public void IsNodelistCorrect() throws Exception {
-        // Ping the nodelist HTTP API
-
-        JsonNode nodes = getEndpoint("/rest/nodes");
-        int numNodes = nodes.size();
-        Assert.assertEquals("Wrong number of nodes!", 2, numNodes);
-        for (int i = 0; i < nodes.size(); i++) {
-            JsonNode node = nodes.get(i);
-            String id = node.get("node-id").asText();
-            if (id.equals("red") || id.equals("blue")) {
-                continue;
-            }
-            Assert.fail("Unexpected node ID '" + id + "'!");
-        }
-    }
-
-    @Test
-    public void isXmxOverrideCorrect() throws Exception {
-        ArrayNode inputArgs = (ArrayNode) getEndpoint("/rest/nodes/red").get("input-arguments");
-        for (Iterator<JsonNode> it = inputArgs.elements(); it.hasNext();) {
-            String s = it.next().asText();
-            if (s.startsWith("-Xmx") && s.endsWith("m")) {
-                String digits = s.substring(4, 8);
-                Assert.assertEquals("1234", digits);
-            }
-        }
-    }
-
-    public static void main(String[] args) throws Exception {
-        try {
-            setUp();
-        } catch (Exception e) {
-            e.printStackTrace();
-            LOGGER.error("TEST CASE(S) FAILED");
-        } finally {
-            tearDown();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/NCServiceIT.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/NCServiceIT.java b/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/NCServiceIT.java
new file mode 100644
index 0000000..de32991
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/NCServiceIT.java
@@ -0,0 +1,148 @@
+/*
+ * 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.hyracks.test.server;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.Iterator;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+import org.apache.hyracks.test.server.process.HyracksVirtualCluster;
+import org.apache.hyracks.util.file.FileUtil;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import junit.framework.Assert;
+
+public class NCServiceIT {
+
+    private static final String TARGET_DIR = FileUtil.joinPath(".", "target");
+    private static final String LOG_DIR = FileUtil.joinPath(TARGET_DIR, "failsafe-reports");
+    private static final String RESOURCE_DIR = FileUtil.joinPath(TARGET_DIR, "test-classes", "NCServiceIT");
+    private static final String APP_HOME = FileUtil.joinPath(TARGET_DIR, "appassembler");
+    private static final Logger LOGGER = LogManager.getLogger();
+
+    private static HyracksVirtualCluster cluster = null;
+
+    @BeforeClass
+    public static void setUp() throws Exception {
+        cluster = new HyracksVirtualCluster(new File(APP_HOME), null);
+        cluster.addNCService(new File(RESOURCE_DIR, "nc-red.conf"), new File(LOG_DIR, "nc-red.log"));
+        cluster.addNCService(new File(RESOURCE_DIR, "nc-blue.conf"), new File(LOG_DIR, "nc-blue.log"));
+
+        try {
+            Thread.sleep(2000);
+        } catch (InterruptedException ignored) {
+        }
+
+        // Start CC
+        cluster.start(new File(RESOURCE_DIR, "cc.conf"), new File(LOG_DIR, "cc.log"));
+
+        try {
+            Thread.sleep(10000);
+        } catch (InterruptedException ignored) {
+        }
+    }
+
+    @AfterClass
+    public static void tearDown() throws IOException {
+        cluster.stop();
+    }
+
+    private static String getHttp(String url) throws Exception {
+        HttpClient client = HttpClients.createDefault();
+        HttpGet get = new HttpGet(url);
+        int statusCode;
+        final HttpResponse httpResponse;
+        try {
+            httpResponse = client.execute(get);
+            statusCode = httpResponse.getStatusLine().getStatusCode();
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw e;
+        }
+        String response = EntityUtils.toString(httpResponse.getEntity());
+        if (statusCode == HttpStatus.SC_OK) {
+            return response;
+        } else {
+            throw new Exception("HTTP error " + statusCode + ":\n" + response);
+        }
+    }
+
+    private JsonNode getEndpoint(String endpoint) throws Exception {
+        ObjectMapper om = new ObjectMapper();
+        String localhost = InetAddress.getLoopbackAddress().getHostAddress();
+        String response = getHttp("http://" + localhost + ":12345" + endpoint);
+        JsonNode result = om.readTree(response);
+        JsonNode nodes = result.get("result");
+        return nodes;
+    }
+
+    @Test
+    public void IsNodelistCorrect() throws Exception {
+        // Ping the nodelist HTTP API
+
+        JsonNode nodes = getEndpoint("/rest/nodes");
+        int numNodes = nodes.size();
+        Assert.assertEquals("Wrong number of nodes!", 2, numNodes);
+        for (int i = 0; i < nodes.size(); i++) {
+            JsonNode node = nodes.get(i);
+            String id = node.get("node-id").asText();
+            if (id.equals("red") || id.equals("blue")) {
+                continue;
+            }
+            Assert.fail("Unexpected node ID '" + id + "'!");
+        }
+    }
+
+    @Test
+    public void isXmxOverrideCorrect() throws Exception {
+        ArrayNode inputArgs = (ArrayNode) getEndpoint("/rest/nodes/red").get("input-arguments");
+        for (Iterator<JsonNode> it = inputArgs.elements(); it.hasNext();) {
+            String s = it.next().asText();
+            if (s.startsWith("-Xmx") && s.endsWith("m")) {
+                String digits = s.substring(4, 8);
+                Assert.assertEquals("1234", digits);
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        try {
+            setUp();
+        } catch (Exception e) {
+            e.printStackTrace();
+            LOGGER.error("TEST CASE(S) FAILED");
+        } finally {
+            tearDown();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/process/HyracksCCProcess.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/process/HyracksCCProcess.java b/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/process/HyracksCCProcess.java
new file mode 100644
index 0000000..b39def5
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/process/HyracksCCProcess.java
@@ -0,0 +1,47 @@
+/*
+ * 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.hyracks.test.server.process;
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.hyracks.control.cc.CCDriver;
+
+public class HyracksCCProcess extends HyracksServerProcess {
+
+    public HyracksCCProcess(File configFile, File logFile, File appHome, File workingDir) {
+        this.configFile = configFile;
+        this.logFile = logFile;
+        this.appHome = appHome;
+        this.workingDir = workingDir;
+    }
+
+    @Override
+    protected String getMainClassName() {
+        return CCDriver.class.getName();
+    }
+
+    @Override
+    @SuppressWarnings("squid:CommentedOutCodeLine")
+    protected void addJvmArgs(List<String> cList) {
+        // CC needs more than default memory
+        cList.add("-Xmx1024m");
+        // cList.add("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005");
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/process/HyracksNCServiceProcess.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/process/HyracksNCServiceProcess.java b/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/process/HyracksNCServiceProcess.java
new file mode 100644
index 0000000..67fea0f
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/process/HyracksNCServiceProcess.java
@@ -0,0 +1,45 @@
+/*
+ * 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.hyracks.test.server.process;
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.hyracks.control.nc.service.NCService;
+
+public class HyracksNCServiceProcess extends HyracksServerProcess {
+
+    public HyracksNCServiceProcess(File configFile, File logFile, File appHome, File workingDir) {
+        this.configFile = configFile;
+        this.logFile = logFile;
+        this.appHome = appHome;
+        this.workingDir = workingDir;
+    }
+
+    @Override
+    protected String getMainClassName() {
+        return NCService.class.getName();
+    }
+
+    @Override
+    protected void addJvmArgs(List<String> cList) {
+        // NCService needs little memory
+        cList.add("-Xmx128m");
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/process/HyracksServerProcess.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/process/HyracksServerProcess.java b/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/process/HyracksServerProcess.java
new file mode 100644
index 0000000..d157c6f
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/process/HyracksServerProcess.java
@@ -0,0 +1,126 @@
+/*
+ * 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.hyracks.test.server.process;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+abstract class HyracksServerProcess {
+    private static final Logger LOGGER = LogManager.getLogger();
+
+    protected Process process;
+    protected File configFile = null;
+    protected File logFile = null;
+    protected File appHome = null;
+    protected File workingDir = null;
+
+    public void start() throws IOException {
+        String[] cmd = buildCommand();
+        if (LOGGER.isInfoEnabled()) {
+            LOGGER.info("Starting command: " + Arrays.toString(cmd));
+        }
+
+        ProcessBuilder pb = new ProcessBuilder(cmd);
+        pb.redirectErrorStream(true);
+        if (logFile != null) {
+            if (LOGGER.isInfoEnabled()) {
+                LOGGER.info("Logging to: " + logFile.getCanonicalPath());
+            }
+            logFile.getParentFile().mkdirs();
+            try (FileWriter writer = new FileWriter(logFile, true)) {
+                writer.write("---------------------\n");
+            }
+            pb.redirectOutput(ProcessBuilder.Redirect.appendTo(logFile));
+        } else {
+            if (LOGGER.isInfoEnabled()) {
+                LOGGER.info("Logfile not set, subprocess will output to stdout");
+            }
+        }
+        pb.directory(workingDir);
+        process = pb.start();
+    }
+
+    public void stop() {
+        process.destroy();
+        try {
+            boolean success = process.waitFor(30, TimeUnit.SECONDS);
+            if (LOGGER.isWarnEnabled()) {
+                LOGGER.warn("Killing unresponsive NC Process");
+            }
+            if (!success) {
+                process.destroyForcibly();
+            }
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+    }
+
+    public void stop(boolean forcibly) {
+        if (forcibly) {
+            process.destroyForcibly();
+        } else {
+            process.destroy();
+        }
+        try {
+            process.waitFor();
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+    }
+
+    private String[] buildCommand() {
+        List<String> cList = new ArrayList<String>();
+        cList.add(getJavaCommand());
+        addJvmArgs(cList);
+        cList.add("-Dapp.home=" + appHome.getAbsolutePath());
+        cList.add("-classpath");
+        cList.add(getClasspath());
+        cList.add(getMainClassName());
+        if (configFile != null) {
+            cList.add("-config-file");
+            cList.add(configFile.getAbsolutePath());
+        }
+        addCmdLineArgs(cList);
+        return cList.toArray(new String[cList.size()]);
+    }
+
+    protected void addJvmArgs(List<String> cList) {
+    }
+
+    protected void addCmdLineArgs(List<String> cList) {
+    }
+
+    protected abstract String getMainClassName();
+
+    private final String getClasspath() {
+        return System.getProperty("java.class.path");
+    }
+
+    private final String getJavaCommand() {
+        return System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/process/HyracksVirtualCluster.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/process/HyracksVirtualCluster.java b/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/process/HyracksVirtualCluster.java
new file mode 100644
index 0000000..fc7bf73
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-server/src/test/java/org/apache/hyracks/test/server/process/HyracksVirtualCluster.java
@@ -0,0 +1,85 @@
+/*
+ * 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.hyracks.test.server.process;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Starts a local hyracks-based cluster (NC and CC child processes).
+ */
+public class HyracksVirtualCluster {
+    private final File appHome;
+    private final File workingDir;
+    private List<HyracksNCServiceProcess> ncProcs = new ArrayList<>(3);
+    private HyracksCCProcess ccProc = null;
+
+    /**
+     * Construct a Hyracks-based cluster.
+     * @param appHome - path to the installation root of the Hyracks application.
+     *                At least bin/hyracksnc (or the equivalent NC script for
+     *                the application) must exist in this directory.
+     * @param workingDir - directory to use as CWD for all child processes. May
+     *                be null, in which case the CWD of the invoking process is used.
+     */
+    public HyracksVirtualCluster(File appHome, File workingDir) {
+        this.appHome = appHome;
+        this.workingDir = workingDir;
+    }
+
+    /**
+     * Creates and starts an NCService.
+     * @param configFile - full path to an ncservice.conf. May be null to accept all defaults.
+     * @throws IOException - if there are errors starting the process.
+     */
+    public HyracksNCServiceProcess addNCService(File configFile, File logFile) throws IOException {
+        HyracksNCServiceProcess proc = new HyracksNCServiceProcess(configFile, logFile, appHome, workingDir);
+        proc.start();
+        ncProcs.add(proc);
+        return proc;
+    }
+
+    /**
+     * Starts the CC, initializing the cluster. Expects that any NCs referenced
+     * in the cluster configuration have already been started with addNCService().
+     * @param ccConfigFile - full path to a cluster conf file. May be null to accept all
+     *                     defaults, although this is seldom useful since there are no NCs.
+     * @throws IOException - if there are errors starting the process.
+     */
+    public HyracksCCProcess start(File ccConfigFile, File logFile) throws IOException {
+        ccProc = new HyracksCCProcess(ccConfigFile, logFile, appHome, workingDir);
+        ccProc.start();
+        return ccProc;
+    }
+
+    /**
+     * Stops all processes in the cluster.
+     * QQQ Someday this should probably do a graceful stop of NCs rather than
+     * killing the NCService.
+     */
+    public void stop() {
+        ccProc.stop();
+        for (HyracksNCServiceProcess proc : ncProcs) {
+            proc.stop();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/hyracks-fullstack/pom.xml
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/pom.xml b/hyracks-fullstack/pom.xml
index 4538869..437f21a 100644
--- a/hyracks-fullstack/pom.xml
+++ b/hyracks-fullstack/pom.xml
@@ -61,7 +61,7 @@
     <skipTests>false</skipTests>
     <skip.surefire.tests>${skipTests}</skip.surefire.tests>
     <skip.testResources>${maven.test.skip}</skip.testResources>
-    <testLog4jConfigFile>${root.dir}/src/test/resources/log4j2-test.xml</testLog4jConfigFile>
+    <testLog4jConfigFile>${root.dir}/src/test/resources/log4j2-hyracks-test.xml</testLog4jConfigFile>
     <!-- Definition of tests in various categories which may be excluded -->
     <hanging.pregelix.tests>**/pregelix/**/FailureRecovery*.java</hanging.pregelix.tests>
     <hivesterix.perf.tests>**/hivesterix/perf/PerfTestSuite.java</hivesterix.perf.tests>

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/hyracks-fullstack/src/test/resources/log4j2-hyracks-test.xml
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/src/test/resources/log4j2-hyracks-test.xml b/hyracks-fullstack/src/test/resources/log4j2-hyracks-test.xml
new file mode 100644
index 0000000..a8141ee
--- /dev/null
+++ b/hyracks-fullstack/src/test/resources/log4j2-hyracks-test.xml
@@ -0,0 +1,41 @@
+<!--
+ ! 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 complianceo
+ ! 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.
+ !-->
+<Configuration status="WARN">
+  <Appenders>
+    <Console name="Console" target="SYSTEM_OUT">
+      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
+    </Console>
+    <File name="InfoLog" fileName="target/info.log">
+      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
+    </File>
+    <Console name="ConsoleTest" target="SYSTEM_OUT">
+      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %c{1} - %msg%n"/>
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Root level="WARN">
+      <AppenderRef ref="InfoLog"/>
+    </Root>
+    <Logger name="org.apache.hyracks.control.nc.service" level="INFO"/>
+    <Logger name="org.apache.hyracks" level="INFO"/>
+    <Logger name="org.apache.hyracks.test" level="INFO">
+      <AppenderRef ref="ConsoleTest"/>
+    </Logger>
+  </Loggers>
+</Configuration>

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/2530e39d/hyracks-fullstack/src/test/resources/log4j2-test.xml
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/src/test/resources/log4j2-test.xml b/hyracks-fullstack/src/test/resources/log4j2-test.xml
deleted file mode 100644
index a8141ee..0000000
--- a/hyracks-fullstack/src/test/resources/log4j2-test.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<!--
- ! 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 complianceo
- ! 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.
- !-->
-<Configuration status="WARN">
-  <Appenders>
-    <Console name="Console" target="SYSTEM_OUT">
-      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
-    </Console>
-    <File name="InfoLog" fileName="target/info.log">
-      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
-    </File>
-    <Console name="ConsoleTest" target="SYSTEM_OUT">
-      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %c{1} - %msg%n"/>
-    </Console>
-  </Appenders>
-  <Loggers>
-    <Root level="WARN">
-      <AppenderRef ref="InfoLog"/>
-    </Root>
-    <Logger name="org.apache.hyracks.control.nc.service" level="INFO"/>
-    <Logger name="org.apache.hyracks" level="INFO"/>
-    <Logger name="org.apache.hyracks.test" level="INFO">
-      <AppenderRef ref="ConsoleTest"/>
-    </Logger>
-  </Loggers>
-</Configuration>


Mime
View raw message