Revert "GEODE-715: Move dunit.standalone under com.gemstone.gemfire.test"
This reverts commit c57a88c6f2437a8d74f51abbe2edc3355eb1806b. Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/dfba327e Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/dfba327e Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/dfba327e Branch: refs/heads/feature/GEODE-714 Commit: dfba327e3060d20dee55d2ae97ed0f299e241cd5 Parents: a826281 Author: Kirk Lund <kl...@pivotal.io> Authored: Mon Jan 4 16:28:15 2016 -0800 Committer: Kirk Lund <kl...@pivotal.io> Committed: Mon Jan 4 16:28:15 2016 -0800 ---------------------------------------------------------------------- .../cache/PartitionedRegionDUnitTestCase.java | 2 +- .../CompressionRegionConfigDUnitTest.java | 2 +- .../test/dunit/standalone/BounceResult.java | 36 -- .../gemfire/test/dunit/standalone/ChildVM.java | 81 ---- .../test/dunit/standalone/DUnitLauncher.java | 461 ------------------ .../test/dunit/standalone/ProcessManager.java | 259 ----------- .../test/dunit/standalone/RemoteDUnitVM.java | 142 ------ .../test/dunit/standalone/RemoteDUnitVMIF.java | 36 -- .../dunit/standalone/StandAloneDUnitEnv.java | 75 --- .../test/dunit/tests/BasicDUnitTest.java | 132 ------ .../gemfire/test/dunit/tests/TestFailure.java | 50 -- .../gemfire/test/dunit/tests/VMDUnitTest.java | 237 ---------- .../src/test/java/dunit/BounceResult.java | 36 ++ gemfire-core/src/test/java/dunit/DUnitEnv.java | 2 - gemfire-core/src/test/java/dunit/Host.java | 2 - .../src/test/java/dunit/RemoteDUnitVMIF.java | 36 ++ gemfire-core/src/test/java/dunit/VM.java | 7 +- .../src/test/java/dunit/standalone/ChildVM.java | 82 ++++ .../java/dunit/standalone/DUnitLauncher.java | 463 +++++++++++++++++++ .../java/dunit/standalone/ProcessManager.java | 261 +++++++++++ .../java/dunit/standalone/RemoteDUnitVM.java | 144 ++++++ .../dunit/standalone/StandAloneDUnitEnv.java | 75 +++ .../test/java/dunit/tests/BasicDUnitTest.java | 132 ++++++ .../src/test/java/dunit/tests/TestFailure.java | 50 ++ .../src/test/java/dunit/tests/VMDUnitTest.java | 237 ++++++++++ 25 files changed, 1520 insertions(+), 1520 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/PartitionedRegionDUnitTestCase.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/PartitionedRegionDUnitTestCase.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/PartitionedRegionDUnitTestCase.java index 74f201d..a4d32f2 100644 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/PartitionedRegionDUnitTestCase.java +++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/cache/PartitionedRegionDUnitTestCase.java @@ -30,10 +30,10 @@ import com.gemstone.gemfire.cache30.CacheTestCase; import com.gemstone.gemfire.internal.logging.InternalLogWriter; import com.gemstone.gemfire.internal.logging.LogWriterImpl; import com.gemstone.gemfire.internal.logging.PureLogWriter; -import com.gemstone.gemfire.test.dunit.standalone.DUnitLauncher; import dunit.Host; import dunit.SerializableRunnable; +import dunit.standalone.DUnitLauncher; /** * This class is extended by some PartitionedRegion related DUnit test cases http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/com/gemstone/gemfire/internal/compression/CompressionRegionConfigDUnitTest.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/compression/CompressionRegionConfigDUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/compression/CompressionRegionConfigDUnitTest.java index 1fb22c6..af7d07f 100644 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/internal/compression/CompressionRegionConfigDUnitTest.java +++ b/gemfire-core/src/test/java/com/gemstone/gemfire/internal/compression/CompressionRegionConfigDUnitTest.java @@ -27,13 +27,13 @@ import com.gemstone.gemfire.cache.server.CacheServer; import com.gemstone.gemfire.cache30.CacheTestCase; import com.gemstone.gemfire.compression.Compressor; import com.gemstone.gemfire.compression.SnappyCompressor; -import com.gemstone.gemfire.test.dunit.standalone.DUnitLauncher; import dunit.DistributedTestCase; import dunit.Host; import dunit.SerializableCallable; import dunit.SerializableRunnable; import dunit.VM; +import dunit.standalone.DUnitLauncher; /** * Sanity checks on a number of basic cluster configurations with compression turned on. http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/BounceResult.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/BounceResult.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/BounceResult.java deleted file mode 100644 index e117004..0000000 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/BounceResult.java +++ /dev/null @@ -1,36 +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 com.gemstone.gemfire.test.dunit.standalone; - -public class BounceResult { - private final int newPid; - private final RemoteDUnitVMIF newClient; - - public BounceResult(int newPid, RemoteDUnitVMIF newClient) { - this.newPid = newPid; - this.newClient = newClient; - } - - public int getNewPid() { - return newPid; - } - - public RemoteDUnitVMIF getNewClient() { - return newClient; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/ChildVM.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/ChildVM.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/ChildVM.java deleted file mode 100644 index 49b53e8..0000000 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/ChildVM.java +++ /dev/null @@ -1,81 +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 com.gemstone.gemfire.test.dunit.standalone; - -import hydra.HydraRuntimeException; -import hydra.Log; - -import java.rmi.Naming; - -import org.apache.logging.log4j.Logger; - -import com.gemstone.gemfire.internal.OSProcess; -import com.gemstone.gemfire.internal.logging.LogService; -import com.gemstone.gemfire.test.dunit.standalone.DUnitLauncher.MasterRemote; - -/** - * @author dsmith - * - */ -public class ChildVM { - - private static boolean stopMainLoop = false; - - /** - * tells the main() loop to exit - */ - public static void stopVM() { - stopMainLoop = true; - } - - static { - createHydraLogWriter(); - } - - private final static Logger logger = LogService.getLogger(); - private static RemoteDUnitVM dunitVM; - - public static void main(String[] args) throws Throwable { - try { - int namingPort = Integer.getInteger(DUnitLauncher.RMI_PORT_PARAM).intValue(); - int vmNum = Integer.getInteger(DUnitLauncher.VM_NUM_PARAM).intValue(); - int pid = OSProcess.getId(); - logger.info("VM" + vmNum + " is launching" + (pid > 0? " with PID " + pid : "")); - MasterRemote holder = (MasterRemote) Naming.lookup("//localhost:" + namingPort + "/" + DUnitLauncher.MASTER_PARAM); - DUnitLauncher.init(holder); - DUnitLauncher.locatorPort = holder.getLocatorPort(); - dunitVM = new RemoteDUnitVM(); - Naming.rebind("//localhost:" + namingPort + "/vm" + vmNum, dunitVM); - holder.signalVMReady(); - //This loop is here so this VM will die even if the master is mean killed. - while (!stopMainLoop) { - holder.ping(); - Thread.sleep(1000); - } - } catch (Throwable t) { - t.printStackTrace(); - System.exit(1); - } - } - - private static void createHydraLogWriter() { - try { - Log.createLogWriter("dunit-childvm", "fine"); - } catch (HydraRuntimeException ignore) { - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/DUnitLauncher.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/DUnitLauncher.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/DUnitLauncher.java deleted file mode 100644 index 1358722..0000000 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/DUnitLauncher.java +++ /dev/null @@ -1,461 +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 com.gemstone.gemfire.test.dunit.standalone; - -import hydra.Log; -import hydra.MethExecutorResult; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.IOException; -import java.lang.reflect.Method; -import java.net.InetAddress; -import java.net.URISyntaxException; -import java.nio.channels.FileChannel; -import java.nio.charset.Charset; -import java.rmi.AccessException; -import java.rmi.AlreadyBoundException; -import java.rmi.NotBoundException; -import java.rmi.Remote; -import java.rmi.RemoteException; -import java.rmi.registry.LocateRegistry; -import java.rmi.registry.Registry; -import java.rmi.server.UnicastRemoteObject; -import java.util.List; -import java.util.Properties; - -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.core.LoggerContext; -import org.apache.logging.log4j.core.appender.FileAppender; -import org.apache.logging.log4j.core.config.LoggerConfig; -import org.apache.logging.log4j.core.layout.PatternLayout; -import org.junit.Assert; - -import batterytest.greplogs.ExpectedStrings; -import batterytest.greplogs.LogConsumer; - -import com.gemstone.gemfire.distributed.Locator; -import com.gemstone.gemfire.distributed.internal.membership.gms.membership.GMSJoinLeave; -import com.gemstone.gemfire.internal.AvailablePortHelper; -import com.gemstone.gemfire.internal.logging.LogService; - -import dunit.DUnitEnv; -import dunit.Host; -import dunit.SerializableCallable; -import dunit.VM; - -/** - * A class to build a fake test configuration and launch some DUnit VMS. - * - * For use within eclipse. This class completely skips hydra and just starts - * some vms directly, creating a fake test configuration - * - * Also, it's a good idea to set your working directory, because the test code - * a lot of files that it leaves around. - * - * @author dsmith - * - */ -public class DUnitLauncher { - - /** change this to use a different log level in unit tests */ - public static final String LOG_LEVEL = System.getProperty("logLevel", "info"); - - static int locatorPort; - - private static final int NUM_VMS = 4; - private static final int DEBUGGING_VM_NUM = -1; - private static final int LOCATOR_VM_NUM = -2; - - static final long STARTUP_TIMEOUT = 30 * 1000; - private static final String SUSPECT_FILENAME = "dunit_suspect.log"; - private static File DUNIT_SUSPECT_FILE; - - public static final String DUNIT_DIR = "dunit"; - public static final String WORKSPACE_DIR_PARAM = "WORKSPACE_DIR"; - public static final boolean LOCATOR_LOG_TO_DISK = Boolean.getBoolean("locatorLogToDisk"); - - static final String MASTER_PARAM = "DUNIT_MASTER"; - static final String RMI_PORT_PARAM = "gemfire.DUnitLauncher.RMI_PORT"; - static final String VM_NUM_PARAM = "gemfire.DUnitLauncher.VM_NUM"; - - private static final String LAUNCHED_PROPERTY = "gemfire.DUnitLauncher.LAUNCHED"; - - private static Master master; - - private DUnitLauncher() { - } - - private static boolean isHydra() { - try { - //TODO - this is hacky way to test for a hydra environment - see - //if there is registered test configuration object. - Class<?> clazz = Class.forName("hydra.TestConfig"); - Method getInstance = clazz.getMethod("getInstance", new Class[0]); - getInstance.invoke(null); - return true; - } catch (Exception e) { - return false; - } - } - /** - * Launch DUnit. If the unit test was launched through - * the hydra framework, leave the test alone. - */ - public static void launchIfNeeded() { - if(System.getProperties().contains(VM_NUM_PARAM)) { - //we're a dunit child vm, do nothing. - return; - } - - if(!isHydra() &&!isLaunched()) { - try { - launch(); - } catch (Exception e) { - throw new RuntimeException("Unable to launch dunit VMS", e); - } - } - } - - /** - * Test it see if the eclise dunit environment is launched. - */ - public static boolean isLaunched() { - return Boolean.getBoolean(LAUNCHED_PROPERTY); - } - - public static String getLocatorString() { - return "localhost[" + locatorPort + "]"; - } - - - private static void launch() throws URISyntaxException, AlreadyBoundException, IOException, InterruptedException, NotBoundException { -// initialize the log writer that hydra uses - Log.createLogWriter( "dunit-master", LOG_LEVEL ); - - DUNIT_SUSPECT_FILE = new File(SUSPECT_FILENAME); - DUNIT_SUSPECT_FILE.delete(); - DUNIT_SUSPECT_FILE.deleteOnExit(); - - locatorPort = AvailablePortHelper.getRandomAvailableTCPPort(); - - //create an RMI registry and add an object to share our tests config - int namingPort = AvailablePortHelper.getRandomAvailableTCPPort(); - Registry registry = LocateRegistry.createRegistry(namingPort); - - final ProcessManager processManager = new ProcessManager(namingPort, registry); - master = new Master(registry, processManager); - registry.bind(MASTER_PARAM, master); - - Runtime.getRuntime().addShutdownHook(new Thread() { - public void run() { -// System.out.println("shutting down DUnit JVMs"); -// for (int i=0; i<NUM_VMS; i++) { -// try { -// processManager.getStub(i).shutDownVM(); -// } catch (Exception e) { -// System.out.println("exception shutting down vm_"+i+": " + e); -// } -// } -// // TODO - hasLiveVMs always returns true -// System.out.print("waiting for JVMs to exit"); -// long giveUp = System.currentTimeMillis() + 5000; -// while (giveUp > System.currentTimeMillis()) { -// if (!processManager.hasLiveVMs()) { -// return; -// } -// System.out.print("."); -// System.out.flush(); -// try { -// Thread.sleep(1000); -// } catch (InterruptedException e) { -// break; -// } -// } -// System.out.println("\nkilling any remaining JVMs"); - processManager.killVMs(); - } - }); - - //Create a VM for the locator - processManager.launchVM(LOCATOR_VM_NUM); - - //Launch an initial set of VMs - for(int i=0; i < NUM_VMS; i++) { - processManager.launchVM(i); - } - - //wait for the VMS to start up - if(!processManager.waitForVMs(STARTUP_TIMEOUT)) { - throw new RuntimeException("VMs did not start up with 30 seconds"); - } - - //populate the Host class with our stubs. The tests use this host class - DUnitHost host = new DUnitHost(InetAddress.getLocalHost().getCanonicalHostName(), processManager); - host.init(registry, NUM_VMS); - - init(master); - - startLocator(registry); - } - - public static Properties getDistributedSystemProperties() { - Properties p = new Properties(); - p.setProperty("locators", getLocatorString()); - p.setProperty("mcast-port", "0"); - p.setProperty("enable-cluster-configuration", "false"); - p.setProperty("use-cluster-configuration", "false"); - p.setProperty("log-level", LOG_LEVEL); - return p; - } - - /** - * Add an appender to Log4j which sends all INFO+ messages to a separate file - * which will be used later to scan for suspect strings. The pattern of the - * messages conforms to the original log format so that hydra will be able - * to parse them. - */ - private static void addSuspectFileAppender(final String workspaceDir) { - final String suspectFilename = new File(workspaceDir, SUSPECT_FILENAME).getAbsolutePath(); - - final LoggerContext appenderContext = ((org.apache.logging.log4j.core.Logger) - LogManager.getLogger(LogService.BASE_LOGGER_NAME)).getContext(); - - final PatternLayout layout = PatternLayout.createLayout( - "[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} <%thread> tid=%tid] %message%n%throwable%n", null, null, - Charset.defaultCharset(), true, false, "", ""); - - final FileAppender fileAppender = FileAppender.createAppender(suspectFilename, "true", "false", - DUnitLauncher.class.getName(), "true", "false", "false", "0", layout, null, null, null, appenderContext.getConfiguration()); - fileAppender.start(); - - LoggerConfig loggerConfig = appenderContext.getConfiguration().getLoggerConfig(LogService.BASE_LOGGER_NAME); - loggerConfig.addAppender(fileAppender, Level.INFO, null); - } - - private static void startLocator(Registry registry) throws IOException, NotBoundException { - RemoteDUnitVMIF remote = (RemoteDUnitVMIF) registry.lookup("vm" + LOCATOR_VM_NUM); - final File locatorLogFile = - LOCATOR_LOG_TO_DISK ? new File("locator-" + locatorPort + ".log") : new File(""); - MethExecutorResult result = remote.executeMethodOnObject(new SerializableCallable() { - public Object call() throws IOException { - Properties p = getDistributedSystemProperties(); - // I never want this locator to end up starting a jmx manager - // since it is part of the unit test framework - p.setProperty("jmx-manager", "false"); - //Disable the shared configuration on this locator. - //Shared configuration tests create their own locator - p.setProperty("enable-cluster-configuration", "false"); - //Tell the locator it's the first in the system for - //faster boot-up - - System.setProperty(GMSJoinLeave.BYPASS_DISCOVERY_PROPERTY, "true"); - try { - Locator.startLocatorAndDS(locatorPort, locatorLogFile, p); - } finally { - System.getProperties().remove(GMSJoinLeave.BYPASS_DISCOVERY_PROPERTY); - } - - return null; - } - }, "call"); - if(result.getException() != null) { - RuntimeException ex = new RuntimeException("Failed to start locator", result.getException()); - ex.printStackTrace(); - throw ex; - } - } - - public static void init(MasterRemote master) { - DUnitEnv.set(new StandAloneDUnitEnv(master)); - //fake out tests that are using a bunch of hydra stuff - String workspaceDir = System.getProperty(DUnitLauncher.WORKSPACE_DIR_PARAM) ; - workspaceDir = workspaceDir == null ? new File(".").getAbsolutePath() : workspaceDir; - - addSuspectFileAppender(workspaceDir); - - //Free off heap memory when disconnecting from the distributed system - System.setProperty("gemfire.free-off-heap-memory", "true"); - - //indicate that this CM is controlled by the eclipse dunit. - System.setProperty(LAUNCHED_PROPERTY, "true"); - } - - public static void closeAndCheckForSuspects() { - if (isLaunched()) { - final boolean skipLogMsgs = ExpectedStrings.skipLogMsgs("dunit"); - final List<?> expectedStrings = ExpectedStrings.create("dunit"); - final LogConsumer logConsumer = new LogConsumer(skipLogMsgs, expectedStrings, "log4j", 5); - - final StringBuilder suspectStringBuilder = new StringBuilder(); - - BufferedReader buffReader = null; - FileChannel fileChannel = null; - try { - fileChannel = new FileOutputStream(DUNIT_SUSPECT_FILE, true).getChannel(); - buffReader = new BufferedReader(new FileReader(DUNIT_SUSPECT_FILE)); - } catch (FileNotFoundException e) { - System.err.println("Could not find the suspect string output file: " + e); - return; - } - try { - String line; - try { - while ((line = buffReader.readLine()) != null) { - final StringBuilder builder = logConsumer.consume(line); - if (builder != null) { - suspectStringBuilder.append(builder); - } - } - } catch (IOException e) { - System.err.println("Could not read the suspect string output file: " + e); - } - - try { - fileChannel.truncate(0); - } catch (IOException e) { - System.err.println("Could not truncate the suspect string output file: " + e); - } - - } finally { - try { - buffReader.close(); - fileChannel.close(); - } catch (IOException e) { - System.err.println("Could not close the suspect string output file: " + e); - } - } - - if (suspectStringBuilder.length() != 0) { - System.err.println("Suspicious strings were written to the log during this run.\n" - + "Fix the strings or use DistributedTestCase.addExpectedException to ignore.\n" - + suspectStringBuilder); - - Assert.fail("Suspicious strings were written to the log during this run.\n" - + "Fix the strings or use DistributedTestCase.addExpectedException to ignore.\n" - + suspectStringBuilder); - } - } - } - - public interface MasterRemote extends Remote { - public int getLocatorPort() throws RemoteException; - public void signalVMReady() throws RemoteException; - public void ping() throws RemoteException; - public BounceResult bounce(int pid) throws RemoteException; - } - - public static class Master extends UnicastRemoteObject implements MasterRemote { - private static final long serialVersionUID = 1178600200232603119L; - - private final Registry registry; - private final ProcessManager processManager; - - - public Master(Registry registry, ProcessManager processManager) throws RemoteException { - this.processManager = processManager; - this.registry = registry; - } - - public int getLocatorPort() throws RemoteException{ - return locatorPort; - } - - public synchronized void signalVMReady() { - processManager.signalVMReady(); - } - - public void ping() { - //do nothing - } - - @Override - public BounceResult bounce(int pid) { - processManager.bounce(pid); - - try { - if(!processManager.waitForVMs(STARTUP_TIMEOUT)) { - throw new RuntimeException("VMs did not start up with 30 seconds"); - } - RemoteDUnitVMIF remote = (RemoteDUnitVMIF) registry.lookup("vm" + pid); - return new BounceResult(pid, remote); - } catch (RemoteException | NotBoundException e) { - throw new RuntimeException("could not lookup name", e); - } catch (InterruptedException e) { - throw new RuntimeException("Failed waiting for VM", e); - } - } - } - - private static class DUnitHost extends Host { - private static final long serialVersionUID = -8034165624503666383L; - - private transient final VM debuggingVM; - - private transient ProcessManager processManager; - - public DUnitHost(String hostName, ProcessManager processManager) throws RemoteException { - super(hostName); - this.debuggingVM = new VM(this, -1, new RemoteDUnitVM()); - this.processManager = processManager; - } - - public void init(Registry registry, int numVMs) throws AccessException, RemoteException, NotBoundException, InterruptedException { - for(int i = 0; i < numVMs; i++) { - RemoteDUnitVMIF remote = processManager.getStub(i); - addVM(i, remote); - } - - addLocator(LOCATOR_VM_NUM, processManager.getStub(LOCATOR_VM_NUM)); - - addHost(this); - } - - @Override - public VM getVM(int n) { - - if(n == DEBUGGING_VM_NUM) { - //for ease of debugging, pass -1 to get the local VM - return debuggingVM; - } - - int oldVMCount = getVMCount(); - if(n >= oldVMCount) { - //If we don't have a VM with that number, dynamically create it. - try { - for(int i = oldVMCount; i <= n; i++) { - processManager.launchVM(i); - } - processManager.waitForVMs(STARTUP_TIMEOUT); - - for(int i = oldVMCount; i <= n; i++) { - addVM(i, processManager.getStub(i)); - } - - } catch (IOException | InterruptedException | NotBoundException e) { - throw new RuntimeException("Could not dynamically launch vm + " + n, e); - } - } - - return super.getVM(n); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/ProcessManager.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/ProcessManager.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/ProcessManager.java deleted file mode 100644 index 7b053b6..0000000 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/ProcessManager.java +++ /dev/null @@ -1,259 +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 com.gemstone.gemfire.test.dunit.standalone; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintStream; -import java.lang.management.ManagementFactory; -import java.lang.management.RuntimeMXBean; -import java.rmi.AccessException; -import java.rmi.NotBoundException; -import java.rmi.RemoteException; -import java.rmi.registry.Registry; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.io.FileUtils; - -import com.gemstone.gemfire.internal.FileUtil; -import com.gemstone.gemfire.internal.logging.LogService; - -/** - * @author dsmith - * - */ -public class ProcessManager { - private int namingPort; - private Map<Integer, ProcessHolder> processes = new HashMap<Integer, ProcessHolder>(); - private File log4jConfig; - private int pendingVMs; - private Registry registry; - private int debugPort = Integer.getInteger("dunit.debug.basePort", 0); - private int suspendVM = Integer.getInteger("dunit.debug.suspendVM", -100); - - public ProcessManager(int namingPort, Registry registry) { - this.namingPort = namingPort; - this.registry = registry; - } - - public void launchVMs() throws IOException, NotBoundException { - log4jConfig = LogService.findLog4jConfigInCurrentDir(); - } - - public synchronized void launchVM(int vmNum) throws IOException { - if(processes.containsKey(vmNum)) { - throw new IllegalStateException("VM " + vmNum + " is already running."); - } - - String[] cmd = buildJavaCommand(vmNum, namingPort); - System.out.println("Executing " + Arrays.asList(cmd)); - File workingDir = getVMDir(vmNum); - try { - FileUtil.delete(workingDir); - } catch(IOException e) { - //This delete is occasionally failing on some platforms, maybe due to a lingering - //process. Allow the process to be launched anyway. - System.err.println("Unable to delete " + workingDir + ". Currently contains " - + Arrays.asList(workingDir.list())); - } - workingDir.mkdirs(); - if (log4jConfig != null) { - FileUtils.copyFileToDirectory(log4jConfig, workingDir); - } - - //TODO - delete directory contents, preferably with commons io FileUtils - Process process = Runtime.getRuntime().exec(cmd, null, workingDir); - pendingVMs++; - ProcessHolder holder = new ProcessHolder(process); - processes.put(vmNum, holder); - linkStreams(vmNum, holder, process.getErrorStream(), System.err); - linkStreams(vmNum, holder, process.getInputStream(), System.out); - } - - public static File getVMDir(int vmNum) { - return new File(DUnitLauncher.DUNIT_DIR, "vm" + vmNum); - } - - public synchronized void killVMs() { - for(ProcessHolder process : processes.values()) { - if(process != null) { - process.kill(); - } - } - } - - public synchronized boolean hasLiveVMs() { - for(ProcessHolder process : processes.values()) { - if(process != null && process.isAlive()) { - return true; - } - } - return false; - } - - public synchronized void bounce(int vmNum) { - if(!processes.containsKey(vmNum)) { - throw new IllegalStateException("No such process " + vmNum); - } - try { - ProcessHolder holder = processes.remove(vmNum); - holder.kill(); - holder.getProcess().waitFor(); - launchVM(vmNum); - } catch (InterruptedException | IOException e) { - throw new RuntimeException("Unable to restart VM " + vmNum, e); - } - } - - private void linkStreams(final int vmNum, final ProcessHolder holder, final InputStream in, final PrintStream out) { - Thread ioTransport = new Thread() { - public void run() { - BufferedReader reader = new BufferedReader(new InputStreamReader(in)); - String vmName = (vmNum==-2)? "[locator]" : "[vm_"+vmNum+"]"; - try { - String line = reader.readLine(); - while(line != null) { - if (line.length() == 0) { - out.println(); - } else { - out.print(vmName); - out.println(line); - } - line = reader.readLine(); - } - } catch(Exception e) { - if(!holder.isKilled()) { - out.println("Error transporting IO from child process"); - e.printStackTrace(out); - } - } - } - }; - - ioTransport.setDaemon(true); - ioTransport.start(); - } - - private String[] buildJavaCommand(int vmNum, int namingPort) { - String cmd = System.getProperty( "java.home" ) + File.separator + "bin" + File.separator + "java"; - String classPath = System.getProperty("java.class.path"); - //String tmpDir = System.getProperty("java.io.tmpdir"); - String agent = getAgentString(); - - String jdkDebug = ""; - if (debugPort > 0) { - jdkDebug += ",address=" + debugPort; - debugPort++; - } - - String jdkSuspend = vmNum == suspendVM ? "y" : "n"; - - return new String[] { - cmd, "-classpath", classPath, - "-D" + DUnitLauncher.RMI_PORT_PARAM + "=" + namingPort, - "-D" + DUnitLauncher.VM_NUM_PARAM + "=" + vmNum, - "-D" + DUnitLauncher.WORKSPACE_DIR_PARAM + "=" + new File(".").getAbsolutePath(), - "-DlogLevel=" + DUnitLauncher.LOG_LEVEL, - "-Djava.library.path=" + System.getProperty("java.library.path"), - "-Xrunjdwp:transport=dt_socket,server=y,suspend=" + jdkSuspend + jdkDebug, - "-XX:+HeapDumpOnOutOfMemoryError", - "-Xmx512m", - "-Dgemfire.DEFAULT_MAX_OPLOG_SIZE=10", - "-Dgemfire.disallowMcastDefaults=true", - "-ea", - agent, - "dunit.standalone.ChildVM" - }; - } - - /** - * Get the java agent passed to this process and pass it to the child VMs. - * This was added to support jacoco code coverage reports - */ - private String getAgentString() { - RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean(); - if (runtimeBean != null) { - for(String arg: runtimeBean.getInputArguments()) { - if(arg.contains("-javaagent:")) { - //HACK for gradle bug GRADLE-2859. Jacoco is passing a relative path - //That won't work when we pass this to dunit VMs in a different - //directory - arg = arg.replace("-javaagent:..", "-javaagent:" + System.getProperty("user.dir") + File.separator + ".."); - arg = arg.replace("destfile=..", "destfile=" + System.getProperty("user.dir") + File.separator + ".."); - return arg; - } - } - } - - return "-DdummyArg=true"; - } - - synchronized void signalVMReady() { - pendingVMs--; - this.notifyAll(); - } - - public synchronized boolean waitForVMs(long timeout) throws InterruptedException { - long end = System.currentTimeMillis() + timeout; - while(pendingVMs > 0) { - long remaining = end - System.currentTimeMillis(); - if(remaining <= 0) { - return false; - } - this.wait(remaining); - } - - return true; - } - - private static class ProcessHolder { - private final Process process; - private volatile boolean killed = false; - - public ProcessHolder(Process process) { - this.process = process; - } - - public void kill() { - this.killed = true; - process.destroy(); - - } - - public Process getProcess() { - return process; - } - - public boolean isKilled() { - return killed; - } - - public boolean isAlive() { - return !killed && process.isAlive(); - } - } - - public RemoteDUnitVMIF getStub(int i) throws AccessException, RemoteException, NotBoundException, InterruptedException { - waitForVMs(DUnitLauncher.STARTUP_TIMEOUT); - return (RemoteDUnitVMIF) registry.lookup("vm" + i); - } -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/RemoteDUnitVM.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/RemoteDUnitVM.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/RemoteDUnitVM.java deleted file mode 100644 index 51c6177..0000000 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/RemoteDUnitVM.java +++ /dev/null @@ -1,142 +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 com.gemstone.gemfire.test.dunit.standalone; - -import java.rmi.RemoteException; -import java.rmi.server.UnicastRemoteObject; - -import org.apache.logging.log4j.Logger; - -import com.gemstone.gemfire.internal.logging.LogService; - -import hydra.MethExecutor; -import hydra.MethExecutorResult; - -/** - * @author dsmith - * - */ -public class RemoteDUnitVM extends UnicastRemoteObject implements RemoteDUnitVMIF { - - private static final Logger logger = LogService.getLogger(); - - public RemoteDUnitVM() throws RemoteException { - super(); - } - - /** - * Called remotely by the master controller to cause the client to execute - * the instance method on the object. Does this synchronously (does not spawn - * a thread). This method is used by the unit test framework, dunit. - * - * @param obj the object to execute the method on - * @param methodName the name of the method to execute - * @return the result of method execution - */ - public MethExecutorResult executeMethodOnObject( Object obj, String methodName ) { - String name = obj.getClass().getName() + "." + methodName + - " on object: " + obj; - logger.info("Received method: " + name); - long start = System.currentTimeMillis(); - MethExecutorResult result = MethExecutor.executeObject( obj, methodName ); - long delta = System.currentTimeMillis() - start; - logger.info( "Got result: " + result.toString().trim() + " from " + - name + " (took " + delta + " ms)"); - return result; - } - - /** - * Executes a given instance method on a given object with the given - * arguments. - */ - public MethExecutorResult executeMethodOnObject(Object obj, - String methodName, - Object[] args) { - String name = obj.getClass().getName() + "." + methodName + - (args != null ? " with " + args.length + " args": "") + - " on object: " + obj; - logger.info("Received method: " + name); - long start = System.currentTimeMillis(); - MethExecutorResult result = - MethExecutor.executeObject(obj, methodName, args); - long delta = System.currentTimeMillis() - start; - logger.info( "Got result: " + result.toString() + " from " + name + - " (took " + delta + " ms)"); - return result; - } - - /** - * Called remotely by the master controller to cause the client to execute - * the method on the class. Does this synchronously (does not spawn a thread). - * This method is used by the unit test framework, dunit. - * - * @param className the name of the class execute - * @param methodName the name of the method to execute - * @return the result of method execution - */ - public MethExecutorResult executeMethodOnClass( String className, String methodName ) { - String name = className + "." + methodName; - logger.info("Received method: " + name); - long start = System.currentTimeMillis(); - MethExecutorResult result = MethExecutor.execute( className, methodName ); - long delta = System.currentTimeMillis() - start; - logger.info( "Got result: " + result.toString() + " from " + name + - " (took " + delta + " ms)"); - - return result; - } - - /** - * Executes a given static method in a given class with the given - * arguments. - */ - public MethExecutorResult executeMethodOnClass(String className, - String methodName, - Object[] args) { - String name = className + "." + methodName + - (args != null ? " with " + args.length + " args": ""); - logger.info("Received method: " + name); - long start = System.currentTimeMillis(); - MethExecutorResult result = - MethExecutor.execute(className, methodName, args); - long delta = System.currentTimeMillis() - start; - logger.info( "Got result: " + result.toString() + " from " + name + - " (took " + delta + " ms)"); - return result; - } - - public void executeTask(int tsid, int type, int index) throws RemoteException { - throw new UnsupportedOperationException(); - - } - - public void runShutdownHook() throws RemoteException { - - } - - public void notifyDynamicActionComplete(int actionId) throws RemoteException { - throw new UnsupportedOperationException(); - - } - - public void shutDownVM() throws RemoteException { - ChildVM.stopVM(); - } - - public void disconnectVM() throws RemoteException { - } -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/RemoteDUnitVMIF.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/RemoteDUnitVMIF.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/RemoteDUnitVMIF.java deleted file mode 100644 index 849e2f2..0000000 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/RemoteDUnitVMIF.java +++ /dev/null @@ -1,36 +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 com.gemstone.gemfire.test.dunit.standalone; - -import hydra.MethExecutorResult; - -import java.rmi.Remote; -import java.rmi.RemoteException; - -public interface RemoteDUnitVMIF extends Remote { - - MethExecutorResult executeMethodOnObject(Object o, String methodName) throws RemoteException; - - MethExecutorResult executeMethodOnObject(Object o, String methodName, - Object[] args) throws RemoteException; - - MethExecutorResult executeMethodOnClass(String name, String methodName, - Object[] args) throws RemoteException; - - void shutDownVM() throws RemoteException; - -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/StandAloneDUnitEnv.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/StandAloneDUnitEnv.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/StandAloneDUnitEnv.java deleted file mode 100644 index eef24fe..0000000 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/StandAloneDUnitEnv.java +++ /dev/null @@ -1,75 +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 com.gemstone.gemfire.test.dunit.standalone; - -import java.io.File; -import java.rmi.RemoteException; -import java.util.Properties; - -import com.gemstone.gemfire.test.dunit.standalone.DUnitLauncher.MasterRemote; - -import dunit.DUnitEnv; - -public class StandAloneDUnitEnv extends DUnitEnv { - - private MasterRemote master; - - public StandAloneDUnitEnv(MasterRemote master) { - this.master = master; - } - - @Override - public String getLocatorString() { - return DUnitLauncher.getLocatorString(); - } - - @Override - public String getLocatorAddress() { - return "localhost"; - } - - @Override - public int getLocatorPort() { - return DUnitLauncher.locatorPort; - } - - @Override - public Properties getDistributedSystemProperties() { - return DUnitLauncher.getDistributedSystemProperties(); - } - - @Override - public int getPid() { - return Integer.getInteger(DUnitLauncher.VM_NUM_PARAM, -1).intValue(); - } - - @Override - public int getVMID() { - return getPid(); - } - - @Override - public BounceResult bounce(int pid) throws RemoteException { - return master.bounce(pid); - } - - @Override - public File getWorkingDirectory(int pid) { - return ProcessManager.getVMDir(pid); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/BasicDUnitTest.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/BasicDUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/BasicDUnitTest.java deleted file mode 100644 index 76faf93..0000000 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/BasicDUnitTest.java +++ /dev/null @@ -1,132 +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 com.gemstone.gemfire.test.dunit.tests; - -import java.util.Properties; - -import dunit.AsyncInvocation; -import dunit.DistributedTestCase; -import dunit.Host; -import dunit.RMIException; -import dunit.VM; - -/** - * This class tests the basic functionality of the distributed unit - * test framework. - */ -public class BasicDUnitTest extends DistributedTestCase { - - public BasicDUnitTest(String name) { - super(name); - } - - //////// Test Methods - - /** - * Tests how the Hydra framework handles an error - */ - public void _testDontCatchRemoteException() { - Host host = Host.getHost(0); - VM vm = host.getVM(0); - vm.invoke(this.getClass(), "remoteThrowException"); - } - - public void testRemoteInvocationWithException() { - Host host = Host.getHost(0); - VM vm = host.getVM(0); - try { - vm.invoke(this.getClass(), "remoteThrowException"); - fail("Should have thrown a BasicTestException"); - - } catch (RMIException ex) { - assertTrue(ex.getCause() instanceof BasicTestException); - } - } - - static class BasicTestException extends RuntimeException { - BasicTestException() { - this("Test exception. Please ignore."); - } - - BasicTestException(String s) { - super(s); - } - } - - /** - * Accessed via reflection. DO NOT REMOVE - * - */ - protected static void remoteThrowException() { - String s = "Test exception. Please ignore."; - throw new BasicTestException(s); - } - - public void _testRemoteInvocationBoolean() { - - } - - public void testRemoteInvokeAsync() throws InterruptedException { - Host host = Host.getHost(0); - VM vm = host.getVM(0); - String name = this.getUniqueName(); - String value = "Hello"; - - AsyncInvocation ai = - vm.invokeAsync(this.getClass(), "remoteBind", - new Object[] { name, value }); - ai.join(); - // TODO shouldn't we call fail() here? - if (ai.exceptionOccurred()) { - fail("remoteBind failed", ai.getException()); - } - - ai = vm.invokeAsync(this.getClass(), "remoteValidateBind", - new Object[] {name, value }); - ai.join(); - if (ai.exceptionOccurred()) { - fail("remoteValidateBind failed", ai.getException()); - } - } - - private static Properties bindings = new Properties(); - private static void remoteBind(String name, String s) { - new BasicDUnitTest("bogus").getSystem(); // forces connection - bindings.setProperty(name, s); - } - - private static void remoteValidateBind(String name, String expected) - { - assertEquals(expected, bindings.getProperty(name)); - } - - public void testRemoteInvokeAsyncWithException() - throws InterruptedException { - - Host host = Host.getHost(0); - VM vm = host.getVM(0); -// String name = this.getUniqueName(); -// String value = "Hello"; - - AsyncInvocation ai = - vm.invokeAsync(this.getClass(), "remoteThrowException"); - ai.join(); - assertTrue(ai.exceptionOccurred()); - Throwable ex = ai.getException(); - assertTrue(ex instanceof BasicTestException); - } -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/TestFailure.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/TestFailure.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/TestFailure.java deleted file mode 100644 index abbe229..0000000 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/TestFailure.java +++ /dev/null @@ -1,50 +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 com.gemstone.gemfire.test.dunit.tests; - -import dunit.*; - -/** - * The tests in this class always fail. It is used when developing - * DUnit to give us an idea of how test failure are logged, etc. - * - * @author David Whitlock - * - * @since 3.0 - */ -public class TestFailure extends DistributedTestCase { - - public TestFailure(String name) { - super(name); - } - - //////// Test Methods - - public void testFailure() { - assertTrue("Test Failure", false); - } - - public void testError() { - String s = "Test Error"; - throw new Error(s); - } - - public void testHang() throws InterruptedException { - Thread.sleep(100000 * 1000); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/VMDUnitTest.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/VMDUnitTest.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/VMDUnitTest.java deleted file mode 100644 index 3562f86..0000000 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/VMDUnitTest.java +++ /dev/null @@ -1,237 +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 com.gemstone.gemfire.test.dunit.tests; - -import dunit.*; - -import java.io.Serializable; - -import java.util.concurrent.atomic.AtomicInteger; - -/** - * This class tests the functionality of the {@link VM} class. - */ -public class VMDUnitTest extends DistributedTestCase { - - private static final boolean BOOLEAN_VALUE = true; - private static final byte BYTE_VALUE = (byte) 40; - private static final long LONG_VALUE = 42L; - private static final String STRING_VALUE = "BLAH BLAH BLAH"; - - public VMDUnitTest(String name) { - super(name); - } - - //////// Test Methods - - public void notestInvokeNonExistentMethod() { - Host host = Host.getHost(0); - VM vm = host.getVM(0); - try { - vm.invoke(VMDUnitTest.class, "nonExistentMethod"); - fail("Should have thrown an RMIException"); - - } catch (RMIException ex) { - String s = "Excepted a NoSuchMethodException, got a " + - ex.getCause();; - assertTrue(s, ex.getCause() instanceof NoSuchMethodException); - } - } - - /** - * Accessed via reflection. DO NOT REMOVE - * @return - */ - protected static byte remoteByteMethod() { - return BYTE_VALUE; - } - - public void notestInvokeStaticBoolean() { - Host host = Host.getHost(0); - VM vm = host.getVM(0); - assertEquals(BOOLEAN_VALUE, - vm.invokeBoolean(VMDUnitTest.class, "remoteBooleanMethod")); - } - - /** - * Accessed via reflection. DO NOT REMOVE - * @return - */ - protected static boolean remoteBooleanMethod() { - return BOOLEAN_VALUE; - } - - public void notestInvokeStaticBooleanNotBoolean() { - Host host = Host.getHost(0); - VM vm = host.getVM(0); - try { - vm.invokeBoolean(VMDUnitTest.class, "remoteByteMethod"); - fail("Should have thrown an IllegalArgumentException"); - - } catch (IllegalArgumentException ex) { - - } - } - - public void notestInvokeStaticLong() { - Host host = Host.getHost(0); - VM vm = host.getVM(0); - assertEquals(LONG_VALUE, - vm.invokeLong(VMDUnitTest.class, "remoteLongMethod")); - } - - /** - * Accessed via reflection. DO NOT REMOVE - * @return - */ - protected static long remoteLongMethod() { - return LONG_VALUE; - } - - public void notestInvokeStaticLongNotLong() { - Host host = Host.getHost(0); - VM vm = host.getVM(0); - try { - vm.invokeLong(VMDUnitTest.class, "remoteByteMethod"); - fail("Should have thrown an IllegalArgumentException"); - - } catch (IllegalArgumentException ex) { - - } - } - - protected static class ClassWithLong implements Serializable { - public long getLong() { - return LONG_VALUE; - } - } - - protected static class ClassWithByte implements Serializable { - public byte getByte() { - return BYTE_VALUE; - } - } - - public void notestInvokeInstanceLong() { - Host host = Host.getHost(0); - VM vm = host.getVM(0); - assertEquals(LONG_VALUE, - vm.invokeLong(new ClassWithLong(), "getLong")); - } - - public void notestInvokeInstanceLongNotLong() { - Host host = Host.getHost(0); - VM vm = host.getVM(0); - try { - vm.invokeLong(new ClassWithByte(), "getByte"); - fail("Should have thrown an IllegalArgumentException"); - - } catch (IllegalArgumentException ex) { - - } - } - - protected static class InvokeRunnable - implements Serializable, Runnable { - - public void run() { - throw new BasicDUnitTest.BasicTestException(); - } - } - - protected static class ClassWithString implements Serializable { - public String getString() { - return STRING_VALUE; - } - } - - public void notestInvokeInstance() { - Host host = Host.getHost(0); - VM vm = host.getVM(0); - assertEquals(STRING_VALUE, - vm.invoke(new ClassWithString(), "getString")); - } - - public void notestInvokeRunnable() { - Host host = Host.getHost(0); - VM vm = host.getVM(0); - try { - vm.invoke(new InvokeRunnable()); - fail("Should have thrown a BasicTestException"); - - } catch (RMIException ex) { - assertTrue(ex.getCause() instanceof BasicDUnitTest.BasicTestException); - } - } - - private static final AtomicInteger COUNTER = new AtomicInteger(); - public static Integer getAndIncStaticCount() { - return new Integer(COUNTER.getAndIncrement()); - } - public static Integer incrementStaticCount(Integer inc) { - return new Integer(COUNTER.addAndGet(inc.intValue())); - } - public static void incStaticCount() { - COUNTER.incrementAndGet(); - } - public static class VMTestObject implements Serializable { - private static final long serialVersionUID = 1L; - private final AtomicInteger val; - public VMTestObject(int init) { - this.val = new AtomicInteger(init); - } - public Integer get() { - return new Integer(this.val.get()); - } - public Integer incrementAndGet() { - return new Integer(this.val.incrementAndGet()); - } - public void set(Integer newVal) { - this.val.set(newVal.intValue()); - } - } - public void testReturnValue() throws Exception { - final Host host = Host.getHost(0); - final VM vm = host.getVM(0); - // Assert class static invocation works - AsyncInvocation a1 = vm.invokeAsync(getClass(), "getAndIncStaticCount"); - a1.join(); - assertEquals(new Integer(0), a1.getReturnValue()); - // Assert class static invocation with args works - a1 = vm.invokeAsync(getClass(), "incrementStaticCount", new Object[] {new Integer(2)}); - a1.join(); - assertEquals(new Integer(3), a1.getReturnValue()); - // Assert that previous values are not returned when invoking method w/ no return val - a1 = vm.invokeAsync(getClass(), "incStaticCount"); - a1.join(); - assertNull(a1.getReturnValue()); - // Assert that previous null returns are over-written - a1 = vm.invokeAsync(getClass(), "getAndIncStaticCount"); - a1.join(); - assertEquals(new Integer(4), a1.getReturnValue()); - - // Assert object method invocation works with zero arg method - final VMTestObject o = new VMTestObject(0); - a1 = vm.invokeAsync(o, "incrementAndGet", new Object[] {}); - a1.join(); - assertEquals(new Integer(1), a1.getReturnValue()); - // Assert object method invocation works with no return - a1 = vm.invokeAsync(o, "set", new Object[] {new Integer(3)}); - a1.join(); - assertNull(a1.getReturnValue()); - } -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/dunit/BounceResult.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/dunit/BounceResult.java b/gemfire-core/src/test/java/dunit/BounceResult.java new file mode 100644 index 0000000..d8ac186 --- /dev/null +++ b/gemfire-core/src/test/java/dunit/BounceResult.java @@ -0,0 +1,36 @@ +/* + * 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 dunit; + +public class BounceResult { + private final int newPid; + private final RemoteDUnitVMIF newClient; + + public BounceResult(int newPid, RemoteDUnitVMIF newClient) { + this.newPid = newPid; + this.newClient = newClient; + } + + public int getNewPid() { + return newPid; + } + + public RemoteDUnitVMIF getNewClient() { + return newClient; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/dunit/DUnitEnv.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/dunit/DUnitEnv.java b/gemfire-core/src/test/java/dunit/DUnitEnv.java index 54fe67f..19c3635 100644 --- a/gemfire-core/src/test/java/dunit/DUnitEnv.java +++ b/gemfire-core/src/test/java/dunit/DUnitEnv.java @@ -23,8 +23,6 @@ import java.io.File; import java.rmi.RemoteException; import java.util.Properties; -import com.gemstone.gemfire.test.dunit.standalone.BounceResult; - /** * This class provides an abstraction over the environment http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/dunit/Host.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/dunit/Host.java b/gemfire-core/src/test/java/dunit/Host.java index 0c69783..cc41316 100644 --- a/gemfire-core/src/test/java/dunit/Host.java +++ b/gemfire-core/src/test/java/dunit/Host.java @@ -18,8 +18,6 @@ package dunit; import java.util.*; -import com.gemstone.gemfire.test.dunit.standalone.RemoteDUnitVMIF; - /** * <P>This class represents a host on which a remote method may be * invoked. It provides access to the VMs and GemFire systems that http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/dunit/RemoteDUnitVMIF.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/dunit/RemoteDUnitVMIF.java b/gemfire-core/src/test/java/dunit/RemoteDUnitVMIF.java new file mode 100644 index 0000000..5dffa47 --- /dev/null +++ b/gemfire-core/src/test/java/dunit/RemoteDUnitVMIF.java @@ -0,0 +1,36 @@ +/* + * 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 dunit; + +import hydra.MethExecutorResult; + +import java.rmi.Remote; +import java.rmi.RemoteException; + +public interface RemoteDUnitVMIF extends Remote { + + MethExecutorResult executeMethodOnObject(Object o, String methodName) throws RemoteException; + + MethExecutorResult executeMethodOnObject(Object o, String methodName, + Object[] args) throws RemoteException; + + MethExecutorResult executeMethodOnClass(String name, String methodName, + Object[] args) throws RemoteException; + + void shutDownVM() throws RemoteException; + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/dunit/VM.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/dunit/VM.java b/gemfire-core/src/test/java/dunit/VM.java index f4cde93..3c0a7b7 100644 --- a/gemfire-core/src/test/java/dunit/VM.java +++ b/gemfire-core/src/test/java/dunit/VM.java @@ -16,6 +16,8 @@ */ package dunit; +import hydra.MethExecutorResult; + import java.io.File; import java.io.PrintWriter; import java.io.StringWriter; @@ -24,11 +26,6 @@ import java.util.concurrent.Callable; //import java.util.Iterator; //import java.util.Vector; -import hydra.MethExecutorResult; - -import com.gemstone.gemfire.test.dunit.standalone.BounceResult; -import com.gemstone.gemfire.test.dunit.standalone.RemoteDUnitVMIF; - /** * This class represents a Java Virtual Machine that runs on a host. * http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/dunit/standalone/ChildVM.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/dunit/standalone/ChildVM.java b/gemfire-core/src/test/java/dunit/standalone/ChildVM.java new file mode 100644 index 0000000..45a236a --- /dev/null +++ b/gemfire-core/src/test/java/dunit/standalone/ChildVM.java @@ -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 dunit.standalone; + +import hydra.HydraRuntimeException; +import hydra.Log; + +import java.rmi.Naming; + +import org.apache.logging.log4j.Logger; + +import com.gemstone.gemfire.internal.OSProcess; +import com.gemstone.gemfire.internal.logging.LogService; + +import dunit.standalone.DUnitLauncher.MasterRemote; + +/** + * @author dsmith + * + */ +public class ChildVM { + + private static boolean stopMainLoop = false; + + /** + * tells the main() loop to exit + */ + public static void stopVM() { + stopMainLoop = true; + } + + static { + createHydraLogWriter(); + } + + private final static Logger logger = LogService.getLogger(); + private static RemoteDUnitVM dunitVM; + + public static void main(String[] args) throws Throwable { + try { + int namingPort = Integer.getInteger(DUnitLauncher.RMI_PORT_PARAM).intValue(); + int vmNum = Integer.getInteger(DUnitLauncher.VM_NUM_PARAM).intValue(); + int pid = OSProcess.getId(); + logger.info("VM" + vmNum + " is launching" + (pid > 0? " with PID " + pid : "")); + MasterRemote holder = (MasterRemote) Naming.lookup("//localhost:" + namingPort + "/" + DUnitLauncher.MASTER_PARAM); + DUnitLauncher.init(holder); + DUnitLauncher.locatorPort = holder.getLocatorPort(); + dunitVM = new RemoteDUnitVM(); + Naming.rebind("//localhost:" + namingPort + "/vm" + vmNum, dunitVM); + holder.signalVMReady(); + //This loop is here so this VM will die even if the master is mean killed. + while (!stopMainLoop) { + holder.ping(); + Thread.sleep(1000); + } + } catch (Throwable t) { + t.printStackTrace(); + System.exit(1); + } + } + + private static void createHydraLogWriter() { + try { + Log.createLogWriter("dunit-childvm", "fine"); + } catch (HydraRuntimeException ignore) { + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/dfba327e/gemfire-core/src/test/java/dunit/standalone/DUnitLauncher.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/dunit/standalone/DUnitLauncher.java b/gemfire-core/src/test/java/dunit/standalone/DUnitLauncher.java new file mode 100644 index 0000000..72c33d6 --- /dev/null +++ b/gemfire-core/src/test/java/dunit/standalone/DUnitLauncher.java @@ -0,0 +1,463 @@ +/* + * 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 dunit.standalone; + +import hydra.Log; +import hydra.MethExecutorResult; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.lang.reflect.Method; +import java.net.InetAddress; +import java.net.URISyntaxException; +import java.nio.channels.FileChannel; +import java.nio.charset.Charset; +import java.rmi.AccessException; +import java.rmi.AlreadyBoundException; +import java.rmi.NotBoundException; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; +import java.rmi.server.UnicastRemoteObject; +import java.util.List; +import java.util.Properties; + +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.appender.FileAppender; +import org.apache.logging.log4j.core.config.LoggerConfig; +import org.apache.logging.log4j.core.layout.PatternLayout; +import org.junit.Assert; + +import batterytest.greplogs.ExpectedStrings; +import batterytest.greplogs.LogConsumer; + +import com.gemstone.gemfire.distributed.Locator; +import com.gemstone.gemfire.distributed.internal.membership.gms.membership.GMSJoinLeave; +import com.gemstone.gemfire.internal.AvailablePortHelper; +import com.gemstone.gemfire.internal.logging.LogService; + +import dunit.BounceResult; +import dunit.DUnitEnv; +import dunit.Host; +import dunit.RemoteDUnitVMIF; +import dunit.SerializableCallable; +import dunit.VM; + +/** + * A class to build a fake test configuration and launch some DUnit VMS. + * + * For use within eclipse. This class completely skips hydra and just starts + * some vms directly, creating a fake test configuration + * + * Also, it's a good idea to set your working directory, because the test code + * a lot of files that it leaves around. + * + * @author dsmith + * + */ +public class DUnitLauncher { + + /** change this to use a different log level in unit tests */ + public static final String LOG_LEVEL = System.getProperty("logLevel", "info"); + + static int locatorPort; + + private static final int NUM_VMS = 4; + private static final int DEBUGGING_VM_NUM = -1; + private static final int LOCATOR_VM_NUM = -2; + + static final long STARTUP_TIMEOUT = 30 * 1000; + private static final String SUSPECT_FILENAME = "dunit_suspect.log"; + private static File DUNIT_SUSPECT_FILE; + + public static final String DUNIT_DIR = "dunit"; + public static final String WORKSPACE_DIR_PARAM = "WORKSPACE_DIR"; + public static final boolean LOCATOR_LOG_TO_DISK = Boolean.getBoolean("locatorLogToDisk"); + + static final String MASTER_PARAM = "DUNIT_MASTER"; + static final String RMI_PORT_PARAM = "gemfire.DUnitLauncher.RMI_PORT"; + static final String VM_NUM_PARAM = "gemfire.DUnitLauncher.VM_NUM"; + + private static final String LAUNCHED_PROPERTY = "gemfire.DUnitLauncher.LAUNCHED"; + + private static Master master; + + private DUnitLauncher() { + } + + private static boolean isHydra() { + try { + //TODO - this is hacky way to test for a hydra environment - see + //if there is registered test configuration object. + Class<?> clazz = Class.forName("hydra.TestConfig"); + Method getInstance = clazz.getMethod("getInstance", new Class[0]); + getInstance.invoke(null); + return true; + } catch (Exception e) { + return false; + } + } + /** + * Launch DUnit. If the unit test was launched through + * the hydra framework, leave the test alone. + */ + public static void launchIfNeeded() { + if(System.getProperties().contains(VM_NUM_PARAM)) { + //we're a dunit child vm, do nothing. + return; + } + + if(!isHydra() &&!isLaunched()) { + try { + launch(); + } catch (Exception e) { + throw new RuntimeException("Unable to launch dunit VMS", e); + } + } + } + + /** + * Test it see if the eclise dunit environment is launched. + */ + public static boolean isLaunched() { + return Boolean.getBoolean(LAUNCHED_PROPERTY); + } + + public static String getLocatorString() { + return "localhost[" + locatorPort + "]"; + } + + + private static void launch() throws URISyntaxException, AlreadyBoundException, IOException, InterruptedException, NotBoundException { +// initialize the log writer that hydra uses + Log.createLogWriter( "dunit-master", LOG_LEVEL ); + + DUNIT_SUSPECT_FILE = new File(SUSPECT_FILENAME); + DUNIT_SUSPECT_FILE.delete(); + DUNIT_SUSPECT_FILE.deleteOnExit(); + + locatorPort = AvailablePortHelper.getRandomAvailableTCPPort(); + + //create an RMI registry and add an object to share our tests config + int namingPort = AvailablePortHelper.getRandomAvailableTCPPort(); + Registry registry = LocateRegistry.createRegistry(namingPort); + + final ProcessManager processManager = new ProcessManager(namingPort, registry); + master = new Master(registry, processManager); + registry.bind(MASTER_PARAM, master); + + Runtime.getRuntime().addShutdownHook(new Thread() { + public void run() { +// System.out.println("shutting down DUnit JVMs"); +// for (int i=0; i<NUM_VMS; i++) { +// try { +// processManager.getStub(i).shutDownVM(); +// } catch (Exception e) { +// System.out.println("exception shutting down vm_"+i+": " + e); +// } +// } +// // TODO - hasLiveVMs always returns true +// System.out.print("waiting for JVMs to exit"); +// long giveUp = System.currentTimeMillis() + 5000; +// while (giveUp > System.currentTimeMillis()) { +// if (!processManager.hasLiveVMs()) { +// return; +// } +// System.out.print("."); +// System.out.flush(); +// try { +// Thread.sleep(1000); +// } catch (InterruptedException e) { +// break; +// } +// } +// System.out.println("\nkilling any remaining JVMs"); + processManager.killVMs(); + } + }); + + //Create a VM for the locator + processManager.launchVM(LOCATOR_VM_NUM); + + //Launch an initial set of VMs + for(int i=0; i < NUM_VMS; i++) { + processManager.launchVM(i); + } + + //wait for the VMS to start up + if(!processManager.waitForVMs(STARTUP_TIMEOUT)) { + throw new RuntimeException("VMs did not start up with 30 seconds"); + } + + //populate the Host class with our stubs. The tests use this host class + DUnitHost host = new DUnitHost(InetAddress.getLocalHost().getCanonicalHostName(), processManager); + host.init(registry, NUM_VMS); + + init(master); + + startLocator(registry); + } + + public static Properties getDistributedSystemProperties() { + Properties p = new Properties(); + p.setProperty("locators", getLocatorString()); + p.setProperty("mcast-port", "0"); + p.setProperty("enable-cluster-configuration", "false"); + p.setProperty("use-cluster-configuration", "false"); + p.setProperty("log-level", LOG_LEVEL); + return p; + } + + /** + * Add an appender to Log4j which sends all INFO+ messages to a separate file + * which will be used later to scan for suspect strings. The pattern of the + * messages conforms to the original log format so that hydra will be able + * to parse them. + */ + private static void addSuspectFileAppender(final String workspaceDir) { + final String suspectFilename = new File(workspaceDir, SUSPECT_FILENAME).getAbsolutePath(); + + final LoggerContext appenderContext = ((org.apache.logging.log4j.core.Logger) + LogManager.getLogger(LogService.BASE_LOGGER_NAME)).getContext(); + + final PatternLayout layout = PatternLayout.createLayout( + "[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} <%thread> tid=%tid] %message%n%throwable%n", null, null, + Charset.defaultCharset(), true, false, "", ""); + + final FileAppender fileAppender = FileAppender.createAppender(suspectFilename, "true", "false", + DUnitLauncher.class.getName(), "true", "false", "false", "0", layout, null, null, null, appenderContext.getConfiguration()); + fileAppender.start(); + + LoggerConfig loggerConfig = appenderContext.getConfiguration().getLoggerConfig(LogService.BASE_LOGGER_NAME); + loggerConfig.addAppender(fileAppender, Level.INFO, null); + } + + private static void startLocator(Registry registry) throws IOException, NotBoundException { + RemoteDUnitVMIF remote = (RemoteDUnitVMIF) registry.lookup("vm" + LOCATOR_VM_NUM); + final File locatorLogFile = + LOCATOR_LOG_TO_DISK ? new File("locator-" + locatorPort + ".log") : new File(""); + MethExecutorResult result = remote.executeMethodOnObject(new SerializableCallable() { + public Object call() throws IOException { + Properties p = getDistributedSystemProperties(); + // I never want this locator to end up starting a jmx manager + // since it is part of the unit test framework + p.setProperty("jmx-manager", "false"); + //Disable the shared configuration on this locator. + //Shared configuration tests create their own locator + p.setProperty("enable-cluster-configuration", "false"); + //Tell the locator it's the first in the system for + //faster boot-up + + System.setProperty(GMSJoinLeave.BYPASS_DISCOVERY_PROPERTY, "true"); + try { + Locator.startLocatorAndDS(locatorPort, locatorLogFile, p); + } finally { + System.getProperties().remove(GMSJoinLeave.BYPASS_DISCOVERY_PROPERTY); + } + + return null; + } + }, "call"); + if(result.getException() != null) { + RuntimeException ex = new RuntimeException("Failed to start locator", result.getException()); + ex.printStackTrace(); + throw ex; + } + } + + public static void init(MasterRemote master) { + DUnitEnv.set(new StandAloneDUnitEnv(master)); + //fake out tests that are using a bunch of hydra stuff + String workspaceDir = System.getProperty(DUnitLauncher.WORKSPACE_DIR_PARAM) ; + workspaceDir = workspaceDir == null ? new File(".").getAbsolutePath() : workspaceDir; + + addSuspectFileAppender(workspaceDir); + + //Free off heap memory when disconnecting from the distributed system + System.setProperty("gemfire.free-off-heap-memory", "true"); + + //indicate that this CM is controlled by the eclipse dunit. + System.setProperty(LAUNCHED_PROPERTY, "true"); + } + + public static void closeAndCheckForSuspects() { + if (isLaunched()) { + final boolean skipLogMsgs = ExpectedStrings.skipLogMsgs("dunit"); + final List<?> expectedStrings = ExpectedStrings.create("dunit"); + final LogConsumer logConsumer = new LogConsumer(skipLogMsgs, expectedStrings, "log4j", 5); + + final StringBuilder suspectStringBuilder = new StringBuilder(); + + BufferedReader buffReader = null; + FileChannel fileChannel = null; + try { + fileChannel = new FileOutputStream(DUNIT_SUSPECT_FILE, true).getChannel(); + buffReader = new BufferedReader(new FileReader(DUNIT_SUSPECT_FILE)); + } catch (FileNotFoundException e) { + System.err.println("Could not find the suspect string output file: " + e); + return; + } + try { + String line; + try { + while ((line = buffReader.readLine()) != null) { + final StringBuilder builder = logConsumer.consume(line); + if (builder != null) { + suspectStringBuilder.append(builder); + } + } + } catch (IOException e) { + System.err.println("Could not read the suspect string output file: " + e); + } + + try { + fileChannel.truncate(0); + } catch (IOException e) { + System.err.println("Could not truncate the suspect string output file: " + e); + } + + } finally { + try { + buffReader.close(); + fileChannel.close(); + } catch (IOException e) { + System.err.println("Could not close the suspect string output file: " + e); + } + } + + if (suspectStringBuilder.length() != 0) { + System.err.println("Suspicious strings were written to the log during this run.\n" + + "Fix the strings or use DistributedTestCase.addExpectedException to ignore.\n" + + suspectStringBuilder); + + Assert.fail("Suspicious strings were written to the log during this run.\n" + + "Fix the strings or use DistributedTestCase.addExpectedException to ignore.\n" + + suspectStringBuilder); + } + } + } + + public interface MasterRemote extends Remote { + public int getLocatorPort() throws RemoteException; + public void signalVMReady() throws RemoteException; + public void ping() throws RemoteException; + public BounceResult bounce(int pid) throws RemoteException; + } + + public static class Master extends UnicastRemoteObject implements MasterRemote { + private static final long serialVersionUID = 1178600200232603119L; + + private final Registry registry; + private final ProcessManager processManager; + + + public Master(Registry registry, ProcessManager processManager) throws RemoteException { + this.processManager = processManager; + this.registry = registry; + } + + public int getLocatorPort() throws RemoteException{ + return locatorPort; + } + + public synchronized void signalVMReady() { + processManager.signalVMReady(); + } + + public void ping() { + //do nothing + } + + @Override + public BounceResult bounce(int pid) { + processManager.bounce(pid); + + try { + if(!processManager.waitForVMs(STARTUP_TIMEOUT)) { + throw new RuntimeException("VMs did not start up with 30 seconds"); + } + RemoteDUnitVMIF remote = (RemoteDUnitVMIF) registry.lookup("vm" + pid); + return new BounceResult(pid, remote); + } catch (RemoteException | NotBoundException e) { + throw new RuntimeException("could not lookup name", e); + } catch (InterruptedException e) { + throw new RuntimeException("Failed waiting for VM", e); + } + } + } + + private static class DUnitHost extends Host { + private static final long serialVersionUID = -8034165624503666383L; + + private transient final VM debuggingVM; + + private transient ProcessManager processManager; + + public DUnitHost(String hostName, ProcessManager processManager) throws RemoteException { + super(hostName); + this.debuggingVM = new VM(this, -1, new RemoteDUnitVM()); + this.processManager = processManager; + } + + public void init(Registry registry, int numVMs) throws AccessException, RemoteException, NotBoundException, InterruptedException { + for(int i = 0; i < numVMs; i++) { + RemoteDUnitVMIF remote = processManager.getStub(i); + addVM(i, remote); + } + + addLocator(LOCATOR_VM_NUM, processManager.getStub(LOCATOR_VM_NUM)); + + addHost(this); + } + + @Override + public VM getVM(int n) { + + if(n == DEBUGGING_VM_NUM) { + //for ease of debugging, pass -1 to get the local VM + return debuggingVM; + } + + int oldVMCount = getVMCount(); + if(n >= oldVMCount) { + //If we don't have a VM with that number, dynamically create it. + try { + for(int i = oldVMCount; i <= n; i++) { + processManager.launchVM(i); + } + processManager.waitForVMs(STARTUP_TIMEOUT); + + for(int i = oldVMCount; i <= n; i++) { + addVM(i, processManager.getStub(i)); + } + + } catch (IOException | InterruptedException | NotBoundException e) { + throw new RuntimeException("Could not dynamically launch vm + " + n, e); + } + } + + return super.getVM(n); + } + } +}