You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by kl...@apache.org on 2015/12/29 00:47:22 UTC
[1/2] incubator-geode git commit: GEODE-715: Move dunit.standalone
under com.gemstone.gemfire.test
Repository: incubator-geode
Updated Branches:
refs/heads/feature/GEODE-715 [created] 3c80c599f
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3c80c599/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
deleted file mode 100644
index 45a236a..0000000
--- a/gemfire-core/src/test/java/dunit/standalone/ChildVM.java
+++ /dev/null
@@ -1,82 +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 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/3c80c599/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
deleted file mode 100644
index 72c33d6..0000000
--- a/gemfire-core/src/test/java/dunit/standalone/DUnitLauncher.java
+++ /dev/null
@@ -1,463 +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 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);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3c80c599/gemfire-core/src/test/java/dunit/standalone/ProcessManager.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/dunit/standalone/ProcessManager.java b/gemfire-core/src/test/java/dunit/standalone/ProcessManager.java
deleted file mode 100644
index 7fc762f..0000000
--- a/gemfire-core/src/test/java/dunit/standalone/ProcessManager.java
+++ /dev/null
@@ -1,261 +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 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;
-
-import dunit.RemoteDUnitVMIF;
-
-/**
- * @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/3c80c599/gemfire-core/src/test/java/dunit/standalone/RemoteDUnitVM.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/dunit/standalone/RemoteDUnitVM.java b/gemfire-core/src/test/java/dunit/standalone/RemoteDUnitVM.java
deleted file mode 100644
index 742dc55..0000000
--- a/gemfire-core/src/test/java/dunit/standalone/RemoteDUnitVM.java
+++ /dev/null
@@ -1,144 +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 dunit.standalone;
-
-import hydra.MethExecutor;
-import hydra.MethExecutorResult;
-
-import java.rmi.RemoteException;
-import java.rmi.server.UnicastRemoteObject;
-
-import org.apache.logging.log4j.Logger;
-
-import com.gemstone.gemfire.internal.logging.LogService;
-
-import dunit.RemoteDUnitVMIF;
-
-/**
- * @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/3c80c599/gemfire-core/src/test/java/dunit/standalone/StandAloneDUnitEnv.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/dunit/standalone/StandAloneDUnitEnv.java b/gemfire-core/src/test/java/dunit/standalone/StandAloneDUnitEnv.java
deleted file mode 100644
index 085035d..0000000
--- a/gemfire-core/src/test/java/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 dunit.standalone;
-
-import java.io.File;
-import java.rmi.RemoteException;
-import java.util.Properties;
-
-import dunit.BounceResult;
-import dunit.DUnitEnv;
-import dunit.standalone.DUnitLauncher.MasterRemote;
-
-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/3c80c599/gemfire-core/src/test/java/dunit/tests/BasicDUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/dunit/tests/BasicDUnitTest.java b/gemfire-core/src/test/java/dunit/tests/BasicDUnitTest.java
deleted file mode 100644
index c284b3a..0000000
--- a/gemfire-core/src/test/java/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 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/3c80c599/gemfire-core/src/test/java/dunit/tests/TestFailure.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/dunit/tests/TestFailure.java b/gemfire-core/src/test/java/dunit/tests/TestFailure.java
deleted file mode 100644
index 17a39fa..0000000
--- a/gemfire-core/src/test/java/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 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/3c80c599/gemfire-core/src/test/java/dunit/tests/VMDUnitTest.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/dunit/tests/VMDUnitTest.java b/gemfire-core/src/test/java/dunit/tests/VMDUnitTest.java
deleted file mode 100644
index 27736dc..0000000
--- a/gemfire-core/src/test/java/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 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());
- }
-}
[2/2] incubator-geode git commit: GEODE-715: Move dunit.standalone
under com.gemstone.gemfire.test
Posted by kl...@apache.org.
GEODE-715: Move dunit.standalone under com.gemstone.gemfire.test
* Move dunit.BounceResult and dunit.RemoteDUnitVMIF to dunit.standalone
* Move dunit.standalone to com.gemstone.gemfire.test.dunit.standalone
* Copy hydra.MethExecutor and hydra.MethExecutorResult to dunit.standalone
* Remove hydra dependencies from com.gemstone.gemfire.test.dunit.standalone
Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/3c80c599
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/3c80c599
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/3c80c599
Branch: refs/heads/feature/GEODE-715
Commit: 3c80c599fa66dff3c37eb1cf0e6f5040ca104504
Parents: 093ac12
Author: Kirk Lund <kl...@pivotal.io>
Authored: Mon Dec 28 15:10:27 2015 -0800
Committer: Kirk Lund <kl...@pivotal.io>
Committed: Mon Dec 28 15:10:27 2015 -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/MethExecutor.java | 392 ++++++++++++++++
.../dunit/standalone/MethExecutorResult.java | 179 +++++++
.../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 +
.../test/java/dunit/DistributedTestCase.java | 3 +-
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 ----------
28 files changed, 2092 insertions(+), 1522 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3c80c599/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 a4d32f2..74f201d 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/3c80c599/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 af7d07f..1fb22c6 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/3c80c599/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
new file mode 100644
index 0000000..e117004
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/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 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/3c80c599/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
new file mode 100644
index 0000000..49b53e8
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/ChildVM.java
@@ -0,0 +1,81 @@
+/*
+ * 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/3c80c599/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
new file mode 100644
index 0000000..1358722
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/DUnitLauncher.java
@@ -0,0 +1,461 @@
+/*
+ * 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/3c80c599/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/MethExecutor.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/MethExecutor.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/MethExecutor.java
new file mode 100755
index 0000000..e78e70d
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/MethExecutor.java
@@ -0,0 +1,392 @@
+/*
+ * 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.*;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+
+import com.gemstone.gemfire.SystemFailure;
+
+/**
+*
+* A class specialized for executing (via reflection) the receiver/selector
+* pairs found in TestTasks.
+*
+*/
+public class MethExecutor {
+
+ // @todo lises add static args method
+
+ /**
+ * Helper method that searches a class (and its superclasses) for a
+ * method with the given name and parameter types.
+ *
+ * @throws NoSuchMethodException
+ * If the method cannot be found
+ */
+ public static Method getMethod(Class c, String methodName, Class[] paramTypes)
+ throws NoSuchMethodException {
+
+ ArrayList matchingMethods = new ArrayList();
+ for (Class q = c; q != null; q = q.getSuperclass()) {
+ Method[] methods = q.getDeclaredMethods();
+ NEXT_METHOD:
+ for (int i = 0; i < methods.length; i++) {
+ Method m = methods[i];
+ if (!m.getName().equals(methodName)) {
+ continue;
+ }
+
+ Class[] argTypes = m.getParameterTypes();
+ if (argTypes.length != paramTypes.length) {
+ continue;
+ }
+
+ for (int j = 0; j < argTypes.length; j++) {
+ if(paramTypes[j] == null) {
+ if(argTypes[j].isPrimitive()) {
+ //this parameter is not ok, the parameter is a primative and the value is null
+ continue NEXT_METHOD;
+ } else {
+ //this parameter is ok, the argument is an object and the value is null
+ continue;
+ }
+ }
+ if (!argTypes[j].isAssignableFrom(paramTypes[j])) {
+ Class argType = argTypes[j];
+ Class paramType = paramTypes[j];
+
+ if (argType.isPrimitive()) {
+ if ((argType.equals(boolean.class) &&
+ paramType.equals(Boolean.class)) ||
+ (argType.equals(short.class) &&
+ paramType.equals(Short.class)) ||
+ (argType.equals(int.class) &&
+ paramType.equals(Integer.class)) ||
+ (argType.equals(long.class) &&
+ paramType.equals(Long.class)) ||
+ (argType.equals(float.class) &&
+ paramType.equals(Float.class)) ||
+ (argType.equals(double.class) &&
+ paramType.equals(Double.class)) ||
+ (argType.equals(char.class) &&
+ paramType.equals(Character.class)) ||
+ (argType.equals(byte.class) &&
+ paramType.equals(Byte.class)) ||
+ false) {
+
+ // This parameter is okay, try the next arg
+ continue;
+ }
+ }
+ continue NEXT_METHOD;
+ }
+ }
+
+ matchingMethods.add(m);
+ }
+
+ //We want to check to make sure there aren't two
+ //ambiguous methods on the same class. But a subclass
+ //can still override a method on a super class, so we'll stop
+ //if we found a method on the subclass.
+ if(matchingMethods.size() > 0) {
+ break;
+ }
+ }
+
+ if(matchingMethods.isEmpty()) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("Could not find method ");
+ sb.append(methodName);
+ sb.append(" with ");
+ sb.append(paramTypes.length);
+ sb.append(" parameters [");
+ for (int i = 0; i < paramTypes.length; i++) {
+ String name = paramTypes[i] == null ? null : paramTypes[i].getName();
+ sb.append(name);
+ if (i < paramTypes.length - 1) {
+ sb.append(", ");
+ }
+ }
+ sb.append("] in class ");
+ sb.append(c.getName());
+ throw new NoSuchMethodException(sb.toString());
+ }
+ if(matchingMethods.size() > 1) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("Method is ambiguous ");
+ sb.append(methodName);
+ sb.append(" with ");
+ sb.append(paramTypes.length);
+ sb.append(" parameters [");
+ for (int i = 0; i < paramTypes.length; i++) {
+ String name = paramTypes[i] == null ? null : paramTypes[i].getName();
+ sb.append(name);
+ if (i < paramTypes.length - 1) {
+ sb.append(", ");
+ }
+ }
+ sb.append("] in class ");
+ sb.append(c.getName());
+ throw new NoSuchMethodException(sb.toString());
+ }
+ else return (Method) matchingMethods.get(0);
+ }
+
+ /**
+ *
+ * Send the message "selector" to the class named "receiver".
+ * Return the result, including stack trace (if any).
+ *
+ */
+ public static MethExecutorResult execute(String receiver, String selector) {
+ return execute(receiver, selector, null);
+ }
+
+ /**
+ * Executes the given static method on the given class with the
+ * given arguments.
+ */
+ public static MethExecutorResult execute(String receiver,
+ String selector,
+ Object[] args) {
+ try {
+ // get the class
+ Class receiverClass = Class.forName(receiver);
+
+ // invoke the method
+ Object res = null;
+ try {
+ Class[] paramTypes;
+ if (args == null) {
+ paramTypes = new Class[0];
+
+ } else {
+ paramTypes = new Class[args.length];
+ for (int i = 0; i < args.length; i++) {
+ if (args[i] == null) {
+ paramTypes[i] = null;
+
+ } else {
+ paramTypes[i] = args[i].getClass();
+ }
+ }
+ }
+
+ Method theMethod =
+ getMethod(receiverClass, selector, paramTypes);
+ theMethod.setAccessible(true);
+ res = theMethod.invoke(receiverClass, args);
+ return new MethExecutorResult( res );
+
+ } catch (InvocationTargetException invTargEx) {
+ Throwable targEx = invTargEx.getTargetException();
+ if ( targEx == null ) {
+ return new MethExecutorResult( res );
+
+ } else {
+ return new MethExecutorResult(targEx);
+ }
+ }
+
+ }
+ catch (VirtualMachineError e) {
+ SystemFailure.initiateFailure(e);
+ throw e;
+ }
+ catch (Throwable t) {
+// String s = "While trying to invoke " + receiver + "." +
+// selector;
+// t = new HydraConfigException(s, t);
+ return new MethExecutorResult(t);
+ }
+ }
+
+ /**
+ *
+ * Send the message "selector" to the object "target".
+ * Return the result, including stack trace (if any).
+ *
+ */
+ public static MethExecutorResult executeObject(Object target, String selector) {
+ return executeObject(target, selector, null);
+ }
+
+ /**
+ * Executes the given instance method on the given object with the
+ * given arguments.
+ */
+ public static MethExecutorResult executeObject(Object target,
+ String selector,
+ Object[] args) {
+ try {
+ // get the class
+ Class receiverClass = Class.forName(target.getClass().getName());
+
+ // invoke the method
+ Object res = null;
+ try {
+ Class[] paramTypes;
+ if (args == null) {
+ paramTypes = new Class[0];
+
+ } else {
+ paramTypes = new Class[args.length];
+ for (int i = 0; i < args.length; i++) {
+ if (args[i] == null) {
+ paramTypes[i] = Object.class;
+
+ } else {
+ paramTypes[i] = args[i].getClass();
+ }
+ }
+ }
+
+ Method theMethod =
+ getMethod(receiverClass, selector, paramTypes);
+ theMethod.setAccessible(true);
+ res = theMethod.invoke(target, args);
+ return new MethExecutorResult( res );
+
+ } catch (InvocationTargetException invTargEx) {
+ Throwable targEx = invTargEx.getTargetException();
+ if ( targEx == null ) {
+ return new MethExecutorResult( res );
+
+ } else {
+ return new MethExecutorResult(targEx);
+ }
+ }
+
+ }
+ catch (VirtualMachineError e) {
+ SystemFailure.initiateFailure(e);
+ throw e;
+ }
+ catch (Throwable t) {
+ return new MethExecutorResult(t);
+ }
+ }
+
+ /**
+ *
+ * Send the message "selector" to an instance of the class named "receiver".
+ * Return the result, including stack trace (if any).
+ *
+ */
+ public static MethExecutorResult executeInstance( String receiver, String selector ) {
+
+ try {
+ // get the class
+ Class receiverClass = Class.forName(receiver);
+ Object target = receiverClass.newInstance();
+
+ // invoke the method
+ Object res = null;
+ try {
+ Method theMethod =
+ getMethod(receiverClass, selector, new Class[0]);
+ res = theMethod.invoke(target, new Object[0] );
+ return new MethExecutorResult( res );
+
+ } catch (InvocationTargetException invTargEx) {
+ Throwable targEx = invTargEx.getTargetException();
+ if ( targEx == null ) {
+ return new MethExecutorResult( res );
+ } else {
+ return new MethExecutorResult(targEx);
+ }
+ }
+
+ }
+ catch (VirtualMachineError e) {
+ SystemFailure.initiateFailure(e);
+ throw e;
+ }
+ catch (Throwable t) {
+ return new MethExecutorResult(t);
+ }
+ }
+
+ /**
+ *
+ * Send the message "selector" to an instance of the class named "receiver".
+ * Return the result, including stack trace (if any).
+ *
+ */
+ public static MethExecutorResult executeInstance( String receiver, String selector,
+ Class[] types, Object[] args ) {
+
+ try {
+ // get the class
+ Class receiverClass = Class.forName(receiver);
+ Constructor init =
+ receiverClass.getDeclaredConstructor(new Class[0]);
+ init.setAccessible(true);
+ Object target = init.newInstance(new Object[0]);
+
+ // invoke the method
+ Object res = null;
+ try {
+ Method theMethod = getMethod(receiverClass, selector, types);
+ res = theMethod.invoke(target, args );
+ return new MethExecutorResult( res );
+
+ } catch (InvocationTargetException invTargEx) {
+ Throwable targEx = invTargEx.getTargetException();
+ if ( targEx == null ) {
+ return new MethExecutorResult( res );
+
+ } else {
+ return new MethExecutorResult(targEx);
+ }
+ }
+
+ }
+ catch (VirtualMachineError e) {
+ SystemFailure.initiateFailure(e);
+ throw e;
+ }
+ catch (Throwable t) {
+ return new MethExecutorResult(t);
+ }
+ }
+
+ /**
+ *
+ * A small program for testing this class.
+ *
+ */
+ public static String testMethod1() {
+ return "The result is: " + System.currentTimeMillis();
+ }
+ public static String testMethod2() {
+ throw new ArrayIndexOutOfBoundsException("frip");
+ }
+ public static void main(String[] args) {
+ MethExecutorResult result = null;
+ result = MethExecutor.execute( "hydra.MethExecutor", "testMethod1" );
+ System.out.println(result.toString());
+ result = MethExecutor.execute( "hydra.MethExecutor", "testMethod2" );
+ System.out.println(result.toString());
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3c80c599/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/MethExecutorResult.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/MethExecutorResult.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/MethExecutorResult.java
new file mode 100755
index 0000000..4f5d109
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/MethExecutorResult.java
@@ -0,0 +1,179 @@
+/*
+ * 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.*;
+
+/**
+*
+* The result of a MethExecutor execute method.
+*
+*/
+public class MethExecutorResult implements Serializable {
+
+ /** A "result" object that indicates that an exception occurred
+ * while invoking the method */
+ public static final Serializable EXCEPTION_OCCURRED = new
+ Serializable() {
+ public boolean equals(Object o) {
+ // Allows instances to be compared across VMs
+ return o != null && this.getClass().equals(o.getClass());
+ }
+
+ public String toString() {
+ return "EXCEPTION_OCCURRED";
+ }
+ };
+
+ /** A "exception" object that indicates that an exception could not
+ * be serialized. */
+ public static final Throwable NONSERIALIZABLE_EXCEPTION = new
+ Throwable() {
+ public boolean equals(Object o) {
+ // Allows instances to be compared across VMs
+ return o != null && this.getClass().equals(o.getClass());
+ }
+
+ public String toString() {
+ return "NONSERIALIZABLE_EXCEPTION";
+ }
+ };
+
+
+ //////////////////// Instance Methods ///////////////////////////
+
+ /** The result of execution (may be an exception or error type) */
+ private Object result;
+
+ /** The exception that resulted from invoking the method */
+ private Throwable exception;
+
+ /** Type of the exception (if applicable) */
+ private String exceptionClassName;
+
+ /** Message of the exception (if applicable) */
+ private String exceptionMessage;
+
+ /** Stack trace information (if applicable) */
+ private String stackTrace;
+
+ public MethExecutorResult() {
+ this.result = null;
+ }
+
+ public MethExecutorResult( Object result ) {
+ this.result = result;
+ }
+
+ /**
+ * This constructor is invoked when invoking a method resulted in an
+ * exception being thrown. The "result" is set to {@link
+ * #EXCEPTION_OCCURRED}. If the exception could not be serialized,
+ * {@link #getException()} will return IOException with the exception
+ * stack as the message.
+ */
+ public MethExecutorResult(Throwable thr) {
+ this.result = EXCEPTION_OCCURRED;
+ this.exceptionClassName = thr.getClass().getName();
+ this.exceptionMessage = thr.getMessage();
+
+ StringWriter sw = new StringWriter();
+
+ thr.printStackTrace(new PrintWriter(sw, true));
+ this.stackTrace = sw.toString();
+
+ try {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(baos);
+ oos.writeObject(thr);
+ this.exception = thr;
+
+ } catch (IOException ex) {
+ sw = new StringWriter();
+ ex.printStackTrace(new PrintWriter(sw, true));
+ this.exception = new IOException(sw.toString());
+ }
+ }
+
+ public String toString() {
+ StringBuffer s = new StringBuffer();
+ s.append( this.getResult() );
+ s.append( "\n" );
+ if ( this.getStackTrace() != null ) {
+ s.append( this.getStackTrace() );
+ }
+ return s.toString();
+ }
+
+ /**
+ * Returns the result of the method call. If an exception was
+ * thrown during the method call, {@link #EXCEPTION_OCCURRED} is
+ * returned.
+ *
+ * @see #exceptionOccurred()
+ */
+ public Object getResult() {
+ return this.result;
+ }
+
+ /**
+ * Returns the name of the exception class of the exception that
+ * was thrown while invoking a method. If no exception was thrown,
+ * <code>null</code> is returned.
+ */
+ public String getExceptionClassName() {
+ return this.exceptionClassName;
+ }
+
+ /**
+ * Returns the message of the exception that was thrown while
+ * invoking a method. If no exception was thrown, <code>null</code>
+ * is returned.
+ */
+ public String getExceptionMessage() {
+ return this.exceptionMessage;
+ }
+
+ /**
+ * Returns the stack trace of the exception that was thrown while
+ * invoking a method. If no exception was thrown, <code>null</code>
+ * is returned.
+ */
+ public String getStackTrace() {
+ return this.stackTrace;
+ }
+
+ /**
+ * Returns the exception that was thrown while invoking a method.
+ * If the exception could not be serialized, then {@link
+ * #NONSERIALIZABLE_EXCEPTION} is returned. If no exception was
+ * thrown, <code>null</code> is returned.
+ */
+ public Throwable getException() {
+ return this.exception;
+ }
+
+ /**
+ * Returns whether or not an exception occurred while invoking the
+ * method
+ */
+ public boolean exceptionOccurred() {
+ return EXCEPTION_OCCURRED.equals(this.result);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3c80c599/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
new file mode 100644
index 0000000..7b053b6
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/ProcessManager.java
@@ -0,0 +1,259 @@
+/*
+ * 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/3c80c599/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
new file mode 100644
index 0000000..51c6177
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/RemoteDUnitVM.java
@@ -0,0 +1,142 @@
+/*
+ * 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/3c80c599/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
new file mode 100644
index 0000000..57bbee2
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/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 com.gemstone.gemfire.test.dunit.standalone;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+import hydra.MethExecutorResult;
+
+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/3c80c599/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
new file mode 100644
index 0000000..eef24fe
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/StandAloneDUnitEnv.java
@@ -0,0 +1,75 @@
+/*
+ * 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/3c80c599/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
new file mode 100644
index 0000000..76faf93
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/BasicDUnitTest.java
@@ -0,0 +1,132 @@
+/*
+ * 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/3c80c599/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
new file mode 100644
index 0000000..abbe229
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/TestFailure.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package 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/3c80c599/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
new file mode 100644
index 0000000..3562f86
--- /dev/null
+++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/tests/VMDUnitTest.java
@@ -0,0 +1,237 @@
+/*
+ * 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/3c80c599/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
deleted file mode 100644
index d8ac186..0000000
--- a/gemfire-core/src/test/java/dunit/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 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/3c80c599/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 19c3635..54fe67f 100644
--- a/gemfire-core/src/test/java/dunit/DUnitEnv.java
+++ b/gemfire-core/src/test/java/dunit/DUnitEnv.java
@@ -23,6 +23,8 @@ 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/3c80c599/gemfire-core/src/test/java/dunit/DistributedTestCase.java
----------------------------------------------------------------------
diff --git a/gemfire-core/src/test/java/dunit/DistributedTestCase.java b/gemfire-core/src/test/java/dunit/DistributedTestCase.java
index a3d4785..7aa8e6f 100755
--- a/gemfire-core/src/test/java/dunit/DistributedTestCase.java
+++ b/gemfire-core/src/test/java/dunit/DistributedTestCase.java
@@ -86,8 +86,7 @@ import com.gemstone.gemfire.internal.logging.LogWriterImpl;
import com.gemstone.gemfire.internal.logging.ManagerLogWriter;
import com.gemstone.gemfire.internal.logging.log4j.LogWriterLogger;
import com.gemstone.gemfire.management.internal.cli.LogWrapper;
-
-import dunit.standalone.DUnitLauncher;
+import com.gemstone.gemfire.test.dunit.standalone.DUnitLauncher;
/**
* This class is the superclass of all distributed unit tests.
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/3c80c599/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 cc41316..0c69783 100644
--- a/gemfire-core/src/test/java/dunit/Host.java
+++ b/gemfire-core/src/test/java/dunit/Host.java
@@ -18,6 +18,8 @@ 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/3c80c599/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
deleted file mode 100644
index 5dffa47..0000000
--- a/gemfire-core/src/test/java/dunit/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 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/3c80c599/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 3c0a7b7..816794d 100644
--- a/gemfire-core/src/test/java/dunit/VM.java
+++ b/gemfire-core/src/test/java/dunit/VM.java
@@ -16,8 +16,6 @@
*/
package dunit;
-import hydra.MethExecutorResult;
-
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -26,6 +24,11 @@ import java.util.concurrent.Callable;
//import java.util.Iterator;
//import java.util.Vector;
+import com.gemstone.gemfire.test.dunit.standalone.BounceResult;
+import com.gemstone.gemfire.test.dunit.standalone.RemoteDUnitVMIF;
+
+import hydra.MethExecutorResult;
+
/**
* This class represents a Java Virtual Machine that runs on a host.
*