geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kl...@apache.org
Subject [45/45] incubator-geode git commit: Merge remote-tracking branch 'origin/develop' into feature/GEODE-715
Date Fri, 08 Jan 2016 23:37:46 GMT
Merge remote-tracking branch 'origin/develop' into feature/GEODE-715


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/85db9bbc
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/85db9bbc
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/85db9bbc

Branch: refs/heads/feature/GEODE-715
Commit: 85db9bbcfe5f959f0aaa13980b1fd96c173327cc
Parents: 39a6be3 0c0850c
Author: Kirk Lund <klund@pivotal.io>
Authored: Fri Jan 8 14:48:28 2016 -0800
Committer: Kirk Lund <klund@pivotal.io>
Committed: Fri Jan 8 14:48:28 2016 -0800

----------------------------------------------------------------------
 DISCLAIMER                                      |    6 +
 LICENSE                                         |  279 ++++
 LICENSE.txt                                     |  202 ---
 NOTICE                                          |  334 ----
 README.md                                       |    6 +-
 build.gradle                                    |   12 +
 gemfire-assembly/src/main/dist/DISCLAIMER       |    6 +
 gemfire-assembly/src/main/dist/LICENSE          |  346 +++++
 gemfire-assembly/src/main/dist/NOTICE           |    5 +
 .../cache/query/internal/DefaultQuery.java      |    8 +-
 .../cache/query/internal/QueryMonitor.java      |   26 +-
 .../query/internal/index/CompactRangeIndex.java |   10 +-
 .../query/internal/index/MemoryIndexStore.java  |   33 +-
 .../distributed/internal/DistributionStats.java |   36 +-
 .../distributed/internal/InternalLocator.java   |    7 +-
 .../internal/cache/AbstractRegionMap.java       |    6 +-
 .../internal/cache/GemFireCacheImpl.java        |   12 +-
 .../internal/cache/TombstoneService.java        |   10 +
 .../internal/cache/ha/HARegionQueue.java        |   22 +-
 .../gemfire/internal/logging/LogService.java    |   48 -
 .../internal/logging/log4j/LogWriterLogger.java |    7 -
 .../internal/cli/shell/JmxOperationInvoker.java |   10 +-
 .../config/GemFireFileConfigurationMonitor.java |  145 --
 .../config/xml/GemFireXmlConfiguration.java     |  344 -----
 .../xml/GemFireXmlConfigurationFactory.java     |   59 -
 .../functional/IndexOnEntrySetJUnitTest.java    |  335 ++++
 .../query/functional/PdxGroupByTestImpl.java    |    2 +-
 .../PutAllWithIndexPerfDUnitDisabledTest.java   |  215 ---
 .../index/PutAllWithIndexPerfDUnitTest.java     |  218 +++
 .../gemfire/cache30/Bug40662JUnitTest.java      |    3 -
 .../gemfire/cache30/CacheXml30DUnitTest.java    |   24 +
 .../gemfire/cache30/CacheXml41DUnitTest.java    |    7 +
 .../gemfire/cache30/CacheXml60DUnitTest.java    |   14 +-
 .../gemfire/cache30/CacheXml81DUnitTest.java    |    4 +
 .../cache30/SlowRecDUnitDisabledTest.java       | 1446 -----------------
 .../gemfire/cache30/SlowRecDUnitTest.java       | 1453 ++++++++++++++++++
 .../distributed/DistributedMemberDUnitTest.java |    4 +
 ...cpServerBackwardCompatDUnitDisabledTest.java |  250 ---
 .../TcpServerBackwardCompatDUnitTest.java       |  256 +++
 .../internal/cache/Bug42010StatsDUnitTest.java  |  531 -------
 .../cache/EvictionDUnitDisabledTest.java        |  240 ---
 .../internal/cache/EvictionDUnitTest.java       |  246 +++
 .../cache/OffHeapEvictionDUnitTest.java         |    2 +-
 .../internal/cache/SingleHopStatsDUnitTest.java |  543 +++++++
 .../OnGroupsFunctionExecutionDUnitTest.java     |    7 +-
 .../cache/ha/StatsBugDUnitDisabledTest.java     |  368 -----
 .../internal/cache/ha/StatsBugDUnitTest.java    |  374 +++++
 .../cache/tier/sockets/Bug37210DUnitTest.java   |    2 +
 .../cache/tier/sockets/CacheServerTestUtil.java |    2 +
 .../sockets/HAStartupAndFailoverDUnitTest.java  |   11 +-
 .../InstantiatorPropagationDUnitTest.java       |   37 +-
 .../sockets/UpdatePropagationDUnitTest.java     |    2 +
 .../CompressionCacheConfigDUnitTest.java        |   15 +-
 .../logging/log4j/Log4J2PerformanceTest.java    |    9 -
 .../log4j/LogWriterLoggerPerformanceTest.java   |    9 -
 .../offheap/LifecycleListenerJUnitTest.java     |   23 +-
 .../offheap/SimpleMemoryAllocatorJUnitTest.java |   11 +-
 .../cli/shell/GfshHistoryJUnitTest.java         |    1 +
 .../test/dunit/standalone/DUnitLauncher.java    |    2 +-
 .../test/dunit/standalone/ProcessManager.java   |    2 +-
 .../test/junit/categories/ContainerTest.java    |   25 +
 .../test/junit/categories/HydraTest.java        |   24 +
 gradle/dependency-versions.properties           |    2 +-
 63 files changed, 4359 insertions(+), 4339 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/85db9bbc/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/DUnitLauncher.java
----------------------------------------------------------------------
diff --cc gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/DUnitLauncher.java
index 1358722,0000000..2a7f7e8
mode 100644,000000..100644
--- 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
@@@ -1,461 -1,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,
++        "[%level{lowerCase=true} %date{yyyy/MM/dd HH:mm:ss.SSS z} <%thread> tid=%tid]
%message%n%throwable%n", null, 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/85db9bbc/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/ProcessManager.java
----------------------------------------------------------------------
diff --cc gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/standalone/ProcessManager.java
index 7b053b6,0000000..854daa3
mode 100644,000000..100644
--- 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
@@@ -1,259 -1,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"
++      ChildVM.class.getName()
 +    };
 +  }
 +  
 +  /**
 +   * 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);
 +  }
 +}


Mime
View raw message