Return-Path: X-Original-To: apmail-geode-commits-archive@minotaur.apache.org Delivered-To: apmail-geode-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id A839418454 for ; Thu, 11 Feb 2016 00:39:07 +0000 (UTC) Received: (qmail 24598 invoked by uid 500); 11 Feb 2016 00:39:07 -0000 Delivered-To: apmail-geode-commits-archive@geode.apache.org Received: (qmail 24566 invoked by uid 500); 11 Feb 2016 00:39:07 -0000 Mailing-List: contact commits-help@geode.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@geode.incubator.apache.org Delivered-To: mailing list commits@geode.incubator.apache.org Received: (qmail 24550 invoked by uid 99); 11 Feb 2016 00:39:07 -0000 Received: from Unknown (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 11 Feb 2016 00:39:07 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id F36F5C0CEC for ; Thu, 11 Feb 2016 00:39:06 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -3.549 X-Spam-Level: X-Spam-Status: No, score=-3.549 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-0.329] autolearn=disabled Received: from mx1-us-west.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id i_SLP-rBAsmd for ; Thu, 11 Feb 2016 00:38:45 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-us-west.apache.org (ASF Mail Server at mx1-us-west.apache.org) with SMTP id 57E472158E for ; Thu, 11 Feb 2016 00:38:36 +0000 (UTC) Received: (qmail 20414 invoked by uid 99); 11 Feb 2016 00:38:36 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 11 Feb 2016 00:38:36 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 149DDE0577; Thu, 11 Feb 2016 00:38:36 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: dschneider@apache.org To: commits@geode.incubator.apache.org Date: Thu, 11 Feb 2016 00:38:46 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [12/61] [abbrv] [partial] incubator-geode git commit: GEODE-773: Extract static methods from DistributedTestCase http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/820cfd63/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/DistributedTestCase.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/DistributedTestCase.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/DistributedTestCase.java index 2bf013d..65224e8 100755 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/DistributedTestCase.java +++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/DistributedTestCase.java @@ -16,26 +16,16 @@ */ package com.gemstone.gemfire.test.dunit; -import java.io.File; -import java.io.PrintWriter; -import java.io.Serializable; -import java.io.StringWriter; -import java.net.UnknownHostException; import java.text.DecimalFormat; -import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Map; import java.util.Properties; -import java.util.Random; -import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.Set; -import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.junit.experimental.categories.Category; -import com.gemstone.gemfire.InternalGemFireError; -import com.gemstone.gemfire.LogWriter; import com.gemstone.gemfire.SystemFailure; import com.gemstone.gemfire.admin.internal.AdminDistributedSystemImpl; import com.gemstone.gemfire.cache.Cache; @@ -49,37 +39,22 @@ import com.gemstone.gemfire.cache30.MultiVMRegionTestCase; import com.gemstone.gemfire.cache30.RegionTestCase; import com.gemstone.gemfire.distributed.DistributedSystem; import com.gemstone.gemfire.distributed.internal.DistributionConfig; -import com.gemstone.gemfire.distributed.internal.DistributionConfigImpl; import com.gemstone.gemfire.distributed.internal.DistributionMessageObserver; import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem; import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem.CreationStackGenerator; -import com.gemstone.gemfire.distributed.internal.membership.gms.MembershipManagerHelper; -import com.gemstone.gemfire.internal.InternalDataSerializer; -import com.gemstone.gemfire.internal.InternalInstantiator; -import com.gemstone.gemfire.internal.OSProcess; import com.gemstone.gemfire.internal.SocketCreator; import com.gemstone.gemfire.internal.admin.ClientStatsManager; import com.gemstone.gemfire.internal.cache.DiskStoreObserver; import com.gemstone.gemfire.internal.cache.GemFireCacheImpl; import com.gemstone.gemfire.internal.cache.HARegion; import com.gemstone.gemfire.internal.cache.InitialImageOperation; -import com.gemstone.gemfire.internal.cache.LocalRegion; import com.gemstone.gemfire.internal.cache.PartitionedRegion; import com.gemstone.gemfire.internal.cache.tier.InternalClientMembership; import com.gemstone.gemfire.internal.cache.tier.sockets.CacheServerTestUtil; import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID; -import com.gemstone.gemfire.internal.cache.tier.sockets.DataSerializerPropogationDUnitTest; import com.gemstone.gemfire.internal.cache.xmlcache.CacheCreation; -import com.gemstone.gemfire.internal.logging.InternalLogWriter; -import com.gemstone.gemfire.internal.logging.LocalLogWriter; import com.gemstone.gemfire.internal.logging.LogService; -import com.gemstone.gemfire.internal.logging.LogWriterFactory; -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.internal.util.Callable; import com.gemstone.gemfire.management.internal.cli.LogWrapper; -import com.jayway.awaitility.Awaitility; import com.gemstone.gemfire.test.dunit.standalone.DUnitLauncher; import com.gemstone.gemfire.test.junit.categories.DistributedTest; @@ -100,49 +75,17 @@ import junit.framework.TestCase; @Category(DistributedTest.class) @SuppressWarnings("serial") public abstract class DistributedTestCase extends TestCase implements java.io.Serializable { - private static final Logger logger = LogService.getLogger(); - private static final LogWriterLogger oldLogger = LogWriterLogger.create(logger); - private static final LinkedHashSet testHistory = new LinkedHashSet(); - - private static void setUpCreationStackGenerator() { - // the following is moved from InternalDistributedSystem to fix #51058 - InternalDistributedSystem.TEST_CREATION_STACK_GENERATOR.set( - new CreationStackGenerator() { - @Override - public Throwable generateCreationStack(final DistributionConfig config) { - final StringBuilder sb = new StringBuilder(); - final String[] validAttributeNames = config.getAttributeNames(); - for (int i = 0; i < validAttributeNames.length; i++) { - final String attName = validAttributeNames[i]; - final Object actualAtt = config.getAttributeObject(attName); - String actualAttStr = actualAtt.toString(); - sb.append(" "); - sb.append(attName); - sb.append("=\""); - if (actualAtt.getClass().isArray()) { - actualAttStr = InternalDistributedSystem.arrayToString(actualAtt); - } - sb.append(actualAttStr); - sb.append("\""); - sb.append("\n"); - } - return new Throwable("Creating distributed system with the following configuration:\n" + sb.toString()); - } - }); - } - private static void tearDownCreationStackGenerator() { - InternalDistributedSystem.TEST_CREATION_STACK_GENERATOR.set(InternalDistributedSystem.DEFAULT_CREATION_STACK_GENERATOR); - } + private static final Logger logger = LogService.getLogger(); + private static final Set testHistory = new LinkedHashSet(); + /** This VM's connection to the distributed system */ public static InternalDistributedSystem system; private static Class lastSystemCreatedInTest; private static Properties lastSystemProperties; - public static volatile String testName; + private static volatile String testMethodName; - private static ConcurrentLinkedQueue expectedExceptions = new ConcurrentLinkedQueue(); - /** For formatting timing info */ private static final DecimalFormat format = new DecimalFormat("###.###"); @@ -150,315 +93,25 @@ public abstract class DistributedTestCase extends TestCase implements java.io.Se public static final boolean logPerTest = Boolean.getBoolean("dunitLogPerTest"); - /////////////////////// Utility Methods /////////////////////// - - public void attachDebugger(VM vm, final String msg) { - vm.invoke(new SerializableRunnable("Attach Debugger") { - public void run() { - com.gemstone.gemfire.internal.util.DebuggerSupport. - waitForJavaDebugger(getSystem().getLogWriter().convertToLogWriterI18n(), msg); - } - }); - } - - - /** - * Invokes a SerializableRunnable in every VM that - * DUnit knows about. - * - * @see VM#invoke(SerializableRunnableIF) - */ - public static void invokeInEveryVM(SerializableRunnable work) { - for (int h = 0; h < Host.getHostCount(); h++) { - Host host = Host.getHost(h); - - for (int v = 0; v < host.getVMCount(); v++) { - VM vm = host.getVM(v); - vm.invoke(work); - } - } - } - - public static void invokeInLocator(SerializableRunnable work) { - Host.getLocator().invoke(work); - } - - /** - * Invokes a SerializableCallable in every VM that - * DUnit knows about. - * - * @return a Map of results, where the key is the VM and the value is the result - * @see VM#invoke(SerializableCallableIF) - */ - protected static Map invokeInEveryVM(SerializableCallable work) { - HashMap ret = new HashMap(); - for (int h = 0; h < Host.getHostCount(); h++) { - Host host = Host.getHost(h); - for (int v = 0; v < host.getVMCount(); v++) { - VM vm = host.getVM(v); - ret.put(vm, vm.invoke(work)); - } - } - return ret; - } - - /** - * Invokes a method in every remote VM that DUnit knows about. - * - * @see VM#invoke(Class, String) - */ - protected static void invokeInEveryVM(Class c, String method) { - for (int h = 0; h < Host.getHostCount(); h++) { - Host host = Host.getHost(h); - - for (int v = 0; v < host.getVMCount(); v++) { - VM vm = host.getVM(v); - vm.invoke(c, method); - } - } - } - - /** - * Invokes a method in every remote VM that DUnit knows about. - * - * @see VM#invoke(Class, String) - */ - protected static void invokeInEveryVM(Class c, String method, Object[] methodArgs) { - for (int h = 0; h < Host.getHostCount(); h++) { - Host host = Host.getHost(h); - - for (int v = 0; v < host.getVMCount(); v++) { - VM vm = host.getVM(v); - vm.invoke(c, method, methodArgs); - } - } - } - - /** - * The number of milliseconds to try repeating validation code in the - * event that AssertionFailedError is thrown. For ACK scopes, no - * repeat should be necessary. - */ - protected long getRepeatTimeoutMs() { - return 0; - } - - protected void invokeRepeatingIfNecessary(VM vm, RepeatableRunnable task) { - vm.invokeRepeatingIfNecessary(task, getRepeatTimeoutMs()); - } - - /** - * Invokes a SerializableRunnable in every VM that - * DUnit knows about. If work.run() throws an assertion failure, - * its execution is repeated, until no assertion failure occurs or - * repeatTimeout milliseconds have passed. - * - * @see VM#invoke(SerializableRunnableIF) - */ - protected void invokeInEveryVMRepeatingIfNecessary(RepeatableRunnable work) { - for (int h = 0; h < Host.getHostCount(); h++) { - Host host = Host.getHost(h); - - for (int v = 0; v < host.getVMCount(); v++) { - VM vm = host.getVM(v); - vm.invokeRepeatingIfNecessary(work, getRepeatTimeoutMs()); - } - } - } - - /** Return the total number of VMs on all hosts */ - protected static int getVMCount() { - int count = 0; - for (int h = 0; h < Host.getHostCount(); h++) { - Host host = Host.getHost(h); - count += host.getVMCount(); - } - return count; - } - - - /** print a stack dump for this vm - @author bruce - @since 5.0 - */ - public static void dumpStack() { - com.gemstone.gemfire.internal.OSProcess.printStacks(0, false); - } - - /** print a stack dump for the given vm - @author bruce - @since 5.0 - */ - public static void dumpStack(VM vm) { - vm.invoke(com.gemstone.gemfire.test.dunit.DistributedTestCase.class, "dumpStack"); - } - - /** print stack dumps for all vms on the given host - @author bruce - @since 5.0 - */ - public static void dumpStack(Host host) { - for (int v=0; v < host.getVMCount(); v++) { - host.getVM(v).invoke(com.gemstone.gemfire.test.dunit.DistributedTestCase.class, "dumpStack"); - } - } - - /** print stack dumps for all vms - @author bruce - @since 5.0 - */ - public static void dumpAllStacks() { - for (int h=0; h < Host.getHostCount(); h++) { - dumpStack(Host.getHost(h)); - } - } - - - public static String noteTiming(long operations, String operationUnit, - long beginTime, long endTime, - String timeUnit) - { - long delta = endTime - beginTime; - StringBuffer sb = new StringBuffer(); - sb.append(" Performed "); - sb.append(operations); - sb.append(" "); - sb.append(operationUnit); - sb.append(" in "); - sb.append(delta); - sb.append(" "); - sb.append(timeUnit); - sb.append("\n"); - - double ratio = ((double) operations) / ((double) delta); - sb.append(" "); - sb.append(format.format(ratio)); - sb.append(" "); - sb.append(operationUnit); - sb.append(" per "); - sb.append(timeUnit); - sb.append("\n"); - - ratio = ((double) delta) / ((double) operations); - sb.append(" "); - sb.append(format.format(ratio)); - sb.append(" "); - sb.append(timeUnit); - sb.append(" per "); - sb.append(operationUnit); - sb.append("\n"); - - return sb.toString(); - } - - /** - * Creates a new LogWriter and adds it to the config properties. The config - * can then be used to connect to DistributedSystem, thus providing early - * access to the LogWriter before connecting. This call does not connect - * to the DistributedSystem. It simply creates and returns the LogWriter - * that will eventually be used by the DistributedSystem that connects using - * config. - * - * @param config the DistributedSystem config properties to add LogWriter to - * @return early access to the DistributedSystem LogWriter - */ - protected static LogWriter createLogWriter(Properties config) { // TODO:LOG:CONVERT: this is being used for ExpectedExceptions - Properties nonDefault = config; - if (nonDefault == null) { - nonDefault = new Properties(); - } - addHydraProperties(nonDefault); - - DistributionConfig dc = new DistributionConfigImpl(nonDefault); - LogWriter logger = LogWriterFactory.createLogWriterLogger( - false/*isLoner*/, false/*isSecurityLog*/, dc, - false); - - // if config was non-null, then these will be added to it... - nonDefault.put(DistributionConfig.LOG_WRITER_NAME, logger); - - return logger; - } - - /** - * Fetches the GemFireDescription for this test and adds its - * DistributedSystem properties to the provided props parameter. - * - * @param config the properties to add hydra's test properties to - */ - protected static void addHydraProperties(Properties config) { - Properties p = DUnitEnv.get().getDistributedSystemProperties(); - for (Iterator iter = p.entrySet().iterator(); - iter.hasNext(); ) { - Map.Entry entry = (Map.Entry) iter.next(); - String key = (String) entry.getKey(); - String value = (String) entry.getValue(); - if (config.getProperty(key) == null) { - config.setProperty(key, value); - } - } - } - - //////////////////////// Constructors //////////////////////// - /** * Creates a new DistributedTestCase test with the * given name. */ - public DistributedTestCase(String name) { + public DistributedTestCase(final String name) { super(name); DUnitLauncher.launchIfNeeded(); } - /////////////////////// Instance Methods /////////////////////// - - - protected Class getTestClass() { - Class clazz = getClass(); - while (clazz.getDeclaringClass() != null) { - clazz = clazz.getDeclaringClass(); - } - return clazz; - } - + //--------------------------------------------------------------------------- + // methods for tests + //--------------------------------------------------------------------------- - /** - * This finds the log level configured for the test run. It should be used - * when creating a new distributed system if you want to specify a log level. - * @return the dunit log-level setting - */ - public static String getDUnitLogLevel() { - Properties p = DUnitEnv.get().getDistributedSystemProperties(); - String result = p.getProperty(DistributionConfig.LOG_LEVEL_NAME); - if (result == null) { - result = ManagerLogWriter.levelToString(DistributionConfig.DEFAULT_LOG_LEVEL); - } - return result; - } - - public final static Properties getAllDistributedSystemProperties(Properties props) { - Properties p = DUnitEnv.get().getDistributedSystemProperties(); - - // our tests do not expect auto-reconnect to be on by default - if (!p.contains(DistributionConfig.DISABLE_AUTO_RECONNECT_NAME)) { - p.put(DistributionConfig.DISABLE_AUTO_RECONNECT_NAME, "true"); - } - - for (Iterator iter = props.entrySet().iterator(); - iter.hasNext(); ) { - Map.Entry entry = (Map.Entry) iter.next(); - String key = (String) entry.getKey(); - Object value = entry.getValue(); - p.put(key, value); - } - return p; - } - - public void setSystem(Properties props, DistributedSystem ds) { + public final void setSystem(final Properties props, final DistributedSystem ds) { // TODO: override getDistributedSystemProperties and then delete system = (InternalDistributedSystem)ds; lastSystemProperties = props; - lastSystemCreatedInTest = getTestClass(); + lastSystemCreatedInTest = getClass(); // used to be getDeclaringClass() } + /** * Returns this VM's connection to the distributed system. If * necessary, the connection will be lazily created using the given @@ -470,17 +123,17 @@ public abstract class DistributedTestCase extends TestCase implements java.io.Se * see hydra.DistributedConnectionMgr#connect * @since 3.0 */ - public /*final*/ InternalDistributedSystem getSystem(Properties props) { + public /*final*/ InternalDistributedSystem getSystem(final Properties props) { // TODO: make final // Setting the default disk store name is now done in setUp if (system == null) { system = InternalDistributedSystem.getAnyInstance(); } if (system == null || !system.isConnected()) { // Figure out our distributed system properties - Properties p = getAllDistributedSystemProperties(props); - lastSystemCreatedInTest = getTestClass(); + Properties p = DistributedTestUtils.getAllDistributedSystemProperties(props); + lastSystemCreatedInTest = getClass(); // used to be getDeclaringClass() if (logPerTest) { - String testMethod = getTestName(); + String testMethod = getTestMethodName(); String testName = lastSystemCreatedInTest.getName() + '-' + testMethod; String oldLogFile = p.getProperty(DistributionConfig.LOG_FILE_NAME); p.put(DistributionConfig.LOG_FILE_NAME, @@ -493,11 +146,11 @@ public abstract class DistributedTestCase extends TestCase implements java.io.Se lastSystemProperties = p; } else { boolean needNewSystem = false; - if(!getTestClass().equals(lastSystemCreatedInTest)) { - Properties newProps = getAllDistributedSystemProperties(props); + if(!getClass().equals(lastSystemCreatedInTest)) { // used to be getDeclaringClass() + Properties newProps = DistributedTestUtils.getAllDistributedSystemProperties(props); needNewSystem = !newProps.equals(lastSystemProperties); if(needNewSystem) { - getLogWriter().info( + LogWriterUtils.getLogWriter().info( "Test class has changed and the new DS properties are not an exact match. " + "Forcing DS disconnect. Old props = " + lastSystemProperties + "new props=" + newProps); @@ -511,7 +164,7 @@ public abstract class DistributedTestCase extends TestCase implements java.io.Se String value = (String) entry.getValue(); if (!value.equals(activeProps.getProperty(key))) { needNewSystem = true; - getLogWriter().info("Forcing DS disconnect. For property " + key + LogWriterUtils.getLogWriter().info("Forcing DS disconnect. For property " + key + " old value = " + activeProps.getProperty(key) + " new value = " + value); break; @@ -521,7 +174,7 @@ public abstract class DistributedTestCase extends TestCase implements java.io.Se if(needNewSystem) { // the current system does not meet our needs to disconnect and // call recursively to get a new system. - getLogWriter().info("Disconnecting from current DS in order to make a new one"); + LogWriterUtils.getLogWriter().info("Disconnecting from current DS in order to make a new one"); disconnectFromDS(); getSystem(props); } @@ -529,56 +182,6 @@ public abstract class DistributedTestCase extends TestCase implements java.io.Se return system; } - - /** - * Crash the cache in the given VM in such a way that it immediately stops communicating with - * peers. This forces the VM's membership manager to throw a ForcedDisconnectException by - * forcibly terminating the JGroups protocol stack with a fake EXIT event.

- * - * NOTE: if you use this method be sure that you clean up the VM before the end of your - * test with disconnectFromDS() or disconnectAllFromDS(). - */ - public boolean crashDistributedSystem(VM vm) { - return (Boolean)vm.invoke(new SerializableCallable("crash distributed system") { - public Object call() throws Exception { - DistributedSystem msys = InternalDistributedSystem.getAnyInstance(); - crashDistributedSystem(msys); - return true; - } - }); - } - - /** - * Crash the cache in the given VM in such a way that it immediately stops communicating with - * peers. This forces the VM's membership manager to throw a ForcedDisconnectException by - * forcibly terminating the JGroups protocol stack with a fake EXIT event.

- * - * NOTE: if you use this method be sure that you clean up the VM before the end of your - * test with disconnectFromDS() or disconnectAllFromDS(). - */ - public void crashDistributedSystem(final DistributedSystem msys) { - MembershipManagerHelper.crashDistributedSystem(msys); - MembershipManagerHelper.inhibitForcedDisconnectLogging(false); - WaitCriterion wc = new WaitCriterion() { - public boolean done() { - return !msys.isConnected(); - } - public String description() { - return "waiting for distributed system to finish disconnecting: " + msys; - } - }; -// try { - waitForCriterion(wc, 10000, 1000, true); -// } finally { -// dumpMyThreads(getLogWriter()); -// } - } - - private String getDefaultDiskStoreName() { - String vmid = System.getProperty("vmid"); - return "DiskStore-" + vmid + "-"+ getTestClass().getCanonicalName() + "." + getTestName(); - } - /** * Returns this VM's connection to the distributed system. If * necessary, the connection will be lazily created using the @@ -590,7 +193,7 @@ public abstract class DistributedTestCase extends TestCase implements java.io.Se * @since 3.0 */ public final InternalDistributedSystem getSystem() { - return getSystem(this.getDistributedSystemProperties()); + return getSystem(getDistributedSystemProperties()); } /** @@ -600,7 +203,7 @@ public abstract class DistributedTestCase extends TestCase implements java.io.Se * @since 6.5 */ public final InternalDistributedSystem getLonerSystem() { - Properties props = this.getDistributedSystemProperties(); + Properties props = getDistributedSystemProperties(); props.put(DistributionConfig.MCAST_PORT_NAME, "0"); props.put(DistributionConfig.LOCATORS_NAME, ""); return getSystem(props); @@ -612,7 +215,7 @@ public abstract class DistributedTestCase extends TestCase implements java.io.Se * Added specifically to test scenario of defect #47181. */ public final InternalDistributedSystem getLonerSystemWithEnforceUniqueHost() { - Properties props = this.getDistributedSystemProperties(); + Properties props = getDistributedSystemProperties(); props.put(DistributionConfig.MCAST_PORT_NAME, "0"); props.put(DistributionConfig.LOCATORS_NAME, ""); props.put(DistributionConfig.ENFORCE_UNIQUE_HOST_NAME, "true"); @@ -641,227 +244,16 @@ public abstract class DistributedTestCase extends TestCase implements java.io.Se return new Properties(); } - /** - * Sets up the test (noop). - */ - @Override - public void setUp() throws Exception { - logTestHistory(); - setUpCreationStackGenerator(); - testName = getName(); - System.setProperty(HoplogConfig.ALLOW_LOCAL_HDFS_PROP, "true"); - - if (testName != null) { - GemFireCacheImpl.setDefaultDiskStoreName(getDefaultDiskStoreName()); - String baseDefaultDiskStoreName = getTestClass().getCanonicalName() + "." + getTestName(); - for (int h = 0; h < Host.getHostCount(); h++) { - Host host = Host.getHost(h); - for (int v = 0; v < host.getVMCount(); v++) { - VM vm = host.getVM(v); - String vmDefaultDiskStoreName = "DiskStore-" + h + "-" + v + "-" + baseDefaultDiskStoreName; - vm.invoke(DistributedTestCase.class, "perVMSetUp", new Object[] {testName, vmDefaultDiskStoreName}); - } - } - } - System.out.println("\n\n[setup] START TEST " + getClass().getSimpleName()+"."+testName+"\n\n"); - } - - /** - * Write a message to the log about what tests have ran previously. This - * makes it easier to figure out if a previous test may have caused problems - */ - private void logTestHistory() { - String classname = getClass().getSimpleName(); - testHistory.add(classname); - System.out.println("Previously run tests: " + testHistory); - } - - public static void perVMSetUp(String name, String defaultDiskStoreName) { - setTestName(name); - GemFireCacheImpl.setDefaultDiskStoreName(defaultDiskStoreName); - System.setProperty(HoplogConfig.ALLOW_LOCAL_HDFS_PROP, "true"); - } - public static void setTestName(String name) { - testName = name; - } - - public static String getTestName() { - return testName; - } - - /** - * For logPerTest to work, we have to disconnect from the DS, but all - * subclasses do not call super.tearDown(). To prevent this scenario - * this method has been declared final. Subclasses must now override - * {@link #tearDown2()} instead. - * @throws Exception - */ - @Override - public final void tearDown() throws Exception { - tearDownCreationStackGenerator(); - tearDown2(); - realTearDown(); - tearDownAfter(); - } - - /** - * Tears down the test. This method is called by the final {@link #tearDown()} method and should be overridden to - * perform actual test cleanup and release resources used by the test. The tasks executed by this method are - * performed before the DUnit test framework using Hydra cleans up the client VMs. - *

- * @throws Exception if the tear down process and test cleanup fails. - * @see #tearDown - * @see #tearDownAfter() - */ - // TODO rename this method to tearDownBefore and change the access modifier to protected! - public void tearDown2() throws Exception { - } - - protected void realTearDown() throws Exception { - if (logPerTest) { - disconnectFromDS(); - invokeInEveryVM(DistributedTestCase.class, "disconnectFromDS"); - } - cleanupAllVms(); - } - - /** - * Tears down the test. Performs additional tear down tasks after the DUnit tests framework using Hydra cleans up - * the client VMs. This method is called by the final {@link #tearDown()} method and should be overridden to perform - * post tear down activities. - *

- * @throws Exception if the test tear down process fails. - * @see #tearDown() - * @see #tearDown2() - */ - protected void tearDownAfter() throws Exception { - } - - public static void cleanupAllVms() - { - cleanupThisVM(); - invokeInEveryVM(DistributedTestCase.class, "cleanupThisVM"); - invokeInLocator(new SerializableRunnable() { - public void run() { - DistributionMessageObserver.setInstance(null); - unregisterInstantiatorsInThisVM(); - } - }); - DUnitLauncher.closeAndCheckForSuspects(); - } - - - private static void cleanupThisVM() { - closeCache(); - - SocketCreator.resolve_dns = true; - SocketCreator.resetHostNameCache(); - CacheCreation.clearThreadLocals(); - System.getProperties().remove("gemfire.log-level"); - System.getProperties().remove("jgroups.resolve_dns"); - InitialImageOperation.slowImageProcessing = 0; - DistributionMessageObserver.setInstance(null); - QueryTestUtils.setCache(null); - CacheServerTestUtil.clearCacheReference(); - RegionTestCase.preSnapshotRegion = null; - GlobalLockingDUnitTest.region_testBug32356 = null; - LogWrapper.close(); - ClientProxyMembershipID.system = null; - MultiVMRegionTestCase.CCRegion = null; - InternalClientMembership.unregisterAllListeners(); - ClientStatsManager.cleanupForTests(); - ClientServerTestCase.AUTO_LOAD_BALANCE = false; - unregisterInstantiatorsInThisVM(); - DistributionMessageObserver.setInstance(null); - QueryObserverHolder.reset(); - DiskStoreObserver.setInstance(null); - - if (InternalDistributedSystem.systemAttemptingReconnect != null) { - InternalDistributedSystem.systemAttemptingReconnect.stopReconnecting(); - } - ExpectedException ex; - while((ex = expectedExceptions.poll()) != null) { - ex.remove(); - } - } - - private static void closeCache() { - GemFireCacheImpl cache = GemFireCacheImpl.getInstance(); - if(cache != null && !cache.isClosed()) { - destroyRegions(cache); - cache.close(); - } - } - - protected static final void destroyRegions(Cache cache) - throws InternalGemFireError, Error, VirtualMachineError { - if (cache != null && !cache.isClosed()) { - //try to destroy the root regions first so that - //we clean up any persistent files. - for (Iterator itr = cache.rootRegions().iterator(); itr.hasNext();) { - Region root = (Region)itr.next(); - //for colocated regions you can't locally destroy a partitioned - //region. - if(root.isDestroyed() || root instanceof HARegion || root instanceof PartitionedRegion) { - continue; - } - try { - root.localDestroyRegion("teardown"); - } - catch (VirtualMachineError e) { - SystemFailure.initiateFailure(e); - throw e; - } - catch (Throwable t) { - getLogWriter().error(t); - } - } - } - } - - - public static void unregisterAllDataSerializersFromAllVms() - { - unregisterDataSerializerInThisVM(); - invokeInEveryVM(new SerializableRunnable() { - public void run() { - unregisterDataSerializerInThisVM(); - } - }); - invokeInLocator(new SerializableRunnable() { - public void run() { - unregisterDataSerializerInThisVM(); - } - }); - } - - public static void unregisterInstantiatorsInThisVM() { - // unregister all the instantiators - InternalInstantiator.reinitialize(); - assertEquals(0, InternalInstantiator.getInstantiators().length); - } - - public static void unregisterDataSerializerInThisVM() - { - DataSerializerPropogationDUnitTest.successfullyLoadedTestDataSerializer = false; - // unregister all the Dataserializers - InternalDataSerializer.reinitialize(); - // ensure that all are unregistered - assertEquals(0, InternalDataSerializer.getSerializers().length); - } - - - protected static void disconnectAllFromDS() { + public static void disconnectAllFromDS() { disconnectFromDS(); - invokeInEveryVM(DistributedTestCase.class, - "disconnectFromDS"); + Invoke.invokeInEveryVM(()->disconnectFromDS()); } /** * Disconnects this VM from the distributed system */ public static void disconnectFromDS() { - testName = null; + setTestMethodName(null); GemFireCacheImpl.testCacheXml = null; if (system != null) { system.disconnect(); @@ -875,560 +267,266 @@ public abstract class DistributedTestCase extends TestCase implements java.io.Se } try { ds.disconnect(); - } - catch (Exception e) { + } catch (Exception e) { // ignore } } - { - AdminDistributedSystemImpl ads = - AdminDistributedSystemImpl.getConnectedInstance(); - if (ads != null) {// && ads.isConnected()) { - ads.disconnect(); - } + AdminDistributedSystemImpl ads = AdminDistributedSystemImpl.getConnectedInstance(); + if (ads != null) {// && ads.isConnected()) { + ads.disconnect(); } } - /** - * Strip the package off and gives just the class name. - * Needed because of Windows file name limits. - */ - private String getShortClassName() { - String result = this.getClass().getName(); - int idx = result.lastIndexOf('.'); - if (idx != -1) { - result = result.substring(idx+1); - } - return result; - } + //--------------------------------------------------------------------------- + // name methods + //--------------------------------------------------------------------------- - /** get the host name to use for a server cache in client/server dunit - * testing - * @param host - * @return the host name - */ - public static String getServerHostName(Host host) { - return System.getProperty("gemfire.server-bind-address") != null? - System.getProperty("gemfire.server-bind-address") - : host.getHostName(); + public static String getTestMethodName() { + return testMethodName; } - /** get the IP literal name for the current host, use this instead of - * "localhost" to avoid IPv6 name resolution bugs in the JDK/machine config. - * @return an ip literal, this method honors java.net.preferIPvAddresses - */ - public static String getIPLiteral() { - try { - return SocketCreator.getLocalHost().getHostAddress(); - } catch (UnknownHostException e) { - throw new Error("problem determining host IP address", e); - } + public static void setTestMethodName(final String testMethodName) { // TODO: delete + DistributedTestCase.testMethodName = testMethodName; } - - - /** - * Get the port that the standard dunit locator is listening on. - * @return - */ - public static int getDUnitLocatorPort() { - return DUnitEnv.get().getLocatorPort(); - } - /** * Returns a unique name for this test method. It is based on the * name of the class as well as the name of the method. */ public String getUniqueName() { - return getShortClassName() + "_" + this.getName(); - } - - /** - * Returns a LogWriter for logging information - * @deprecated Use a static logger from the log4j2 LogService.getLogger instead. - */ - @Deprecated - public static InternalLogWriter getLogWriter() { - return oldLogger; + return getClass().getSimpleName() + "_" + getName(); } + //--------------------------------------------------------------------------- + // setup methods + //--------------------------------------------------------------------------- + /** - * Helper method that causes this test to fail because of the given - * exception. + * Sets up the DistributedTestCase. + *

+ * Do not override this method. Override {@link #preSetUp()} with work that + * needs to occur before setUp() or override {@link #postSetUp()} with work + * that needs to occur after setUp(). */ - public static void fail(String message, Throwable ex) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw, true); - pw.print(message); - pw.print(": "); - ex.printStackTrace(pw); - fail(sw.toString()); - } - - // utility methods - - /** pause for a default interval */ - protected void pause() { - pause(250); + @Override + public void setUp() throws Exception { + preSetUp(); + setUpDistributedTestCase(); + postSetUp(); } - + /** - * Use of this function indicates a place in the tests tree where t - * he use of Thread.sleep() is - * highly questionable. + * Sets up DistributedTest in controller and remote VMs. This includes the + * defining the test name, setting the default disk store name, logging the + * test history, and capturing a creation stack for detecting the source of + * incompatible DistributedSystem connections. *

- * Some places in the system, especially those that test expirations and other - * timeouts, have a very good reason to call {@link Thread#sleep(long)}. The - * other places are marked by the use of this method. - * - * @param ms + * Do not override this method. */ - static public final void staticPause(int ms) { -// getLogWriter().info("FIXME: Pausing for " + ms + " ms..."/*, new Exception()*/); - final long target = System.currentTimeMillis() + ms; - try { - for (;;) { - long msLeft = target - System.currentTimeMillis(); - if (msLeft <= 0) { - break; - } - Thread.sleep(msLeft); + private final void setUpDistributedTestCase() { + final String className = getClass().getCanonicalName(); + final String methodName = getName(); + + logTestHistory(); + + setUpVM(methodName, getDefaultDiskStoreName(0, -1, className, methodName)); + + for (int hostIndex = 0; hostIndex < Host.getHostCount(); hostIndex++) { + Host host = Host.getHost(hostIndex); + for (int vmIndex = 0; vmIndex < host.getVMCount(); vmIndex++) { + final String vmDefaultDiskStoreName = getDefaultDiskStoreName(hostIndex, vmIndex, className, methodName); + host.getVM(vmIndex).invoke(()->setUpVM(methodName, vmDefaultDiskStoreName)); } } - catch (InterruptedException e) { - fail("interrupted", e); - } + logTestStart(); } - + /** - * Blocks until the clock used for expiration moves forward. - * @return the last time stamp observed + * preSetUp() is invoked before {@link #setUpDistributedTestCase()}. + *

+ * Override this as needed. Default implementation is empty. */ - public static final long waitForExpiryClockToChange(LocalRegion lr) { - return waitForExpiryClockToChange(lr, lr.cacheTimeMillis()); + protected void preSetUp() throws Exception { } + /** - * Blocks until the clock used for expiration moves forward. - * @param baseTime the timestamp that the clock must exceed - * @return the last time stamp observed + * postSetUp() is invoked after {@link #setUpDistributedTestCase()}. + *

+ * Override this as needed. Default implementation is empty. */ - public static final long waitForExpiryClockToChange(LocalRegion lr, final long baseTime) { - long nowTime; - do { - Thread.yield(); - nowTime = lr.cacheTimeMillis(); - } while ((nowTime - baseTime) <= 0L); - return nowTime; + protected void postSetUp() throws Exception { } - /** pause for specified ms interval - * Make sure system clock has advanced by the specified number of millis before - * returning. - */ - public static final void pause(int ms) { - LogWriter log = getLogWriter(); - if (ms >= 1000 || log.fineEnabled()) { // check for fine but log at info - getLogWriter().info("Pausing for " + ms + " ms..."/*, new Exception()*/); - } - final long target = System.currentTimeMillis() + ms; - try { - for (;;) { - long msLeft = target - System.currentTimeMillis(); - if (msLeft <= 0) { - break; - } - Thread.sleep(msLeft); - } - } - catch (InterruptedException e) { - fail("interrupted", e); - } + private static String getDefaultDiskStoreName(final int hostIndex, final int vmIndex, final String className, final String methodName) { + return "DiskStore-" + String.valueOf(hostIndex) + "-" + String.valueOf(vmIndex) + "-" + className + "." + methodName; // used to be getDeclaringClass() } - public interface WaitCriterion { - public boolean done(); - public String description(); - } - - public interface WaitCriterion2 extends WaitCriterion { - /** - * If this method returns true then quit waiting even if we are not done. - * This allows a wait to fail early. - */ - public boolean stopWaiting(); + private static void setUpVM(final String methodName, final String defaultDiskStoreName) { + setTestMethodName(methodName); + GemFireCacheImpl.setDefaultDiskStoreName(defaultDiskStoreName); + System.setProperty(HoplogConfig.ALLOW_LOCAL_HDFS_PROP, "true"); + setUpCreationStackGenerator(); } - /** - * If true, we randomize the amount of time we wait before polling a - * {@link WaitCriterion}. - */ - static private final boolean USE_JITTER = true; - static private final Random jitter = new Random(); - - /** - * Return a jittered interval up to a maximum of ms - * milliseconds, inclusive. - * - * The result is bounded by 50 ms as a minimum and 5000 ms as a maximum. - * - * @param ms total amount of time to wait - * @return randomized interval we should wait - */ - private static int jitterInterval(long ms) { - final int minLegal = 50; - final int maxLegal = 5000; - if (ms <= minLegal) { - return (int)ms; // Don't ever jitter anything below this. - } - - int maxReturn = maxLegal; - if (ms < maxLegal) { - maxReturn = (int)ms; - } - - return minLegal + jitter.nextInt(maxReturn - minLegal + 1); + private void logTestStart() { + System.out.println("\n\n[setup] START TEST " + getClass().getSimpleName()+"."+testMethodName+"\n\n"); } - /** - * Wait until given criterion is met - * @param ev criterion to wait on - * @param ms total time to wait, in milliseconds - * @param interval pause interval between waits - * @param throwOnTimeout if false, don't generate an error - * @deprecated Use {@link Awaitility} instead. - */ - @Deprecated - static public void waitForCriterion(WaitCriterion ev, long ms, - long interval, boolean throwOnTimeout) { - long waitThisTime; - if (USE_JITTER) { - waitThisTime = jitterInterval(interval); - } - else { - waitThisTime = interval; - } - final long tilt = System.currentTimeMillis() + ms; - for (;;) { -// getLogWriter().info("Testing to see if event has occurred: " + ev.description()); - if (ev.done()) { - return; // success - } - if (ev instanceof WaitCriterion2) { - WaitCriterion2 ev2 = (WaitCriterion2)ev; - if (ev2.stopWaiting()) { - if (throwOnTimeout) { - fail("stopWaiting returned true: " + ev.description()); + private static void setUpCreationStackGenerator() { + // the following is moved from InternalDistributedSystem to fix #51058 + InternalDistributedSystem.TEST_CREATION_STACK_GENERATOR.set( + new CreationStackGenerator() { + @Override + public Throwable generateCreationStack(final DistributionConfig config) { + final StringBuilder sb = new StringBuilder(); + final String[] validAttributeNames = config.getAttributeNames(); + for (int i = 0; i < validAttributeNames.length; i++) { + final String attName = validAttributeNames[i]; + final Object actualAtt = config.getAttributeObject(attName); + String actualAttStr = actualAtt.toString(); + sb.append(" "); + sb.append(attName); + sb.append("=\""); + if (actualAtt.getClass().isArray()) { + actualAttStr = InternalDistributedSystem.arrayToString(actualAtt); } - return; - } - } - - // Calculate time left - long timeLeft = tilt - System.currentTimeMillis(); - if (timeLeft <= 0) { - if (!throwOnTimeout) { - return; // not an error, but we're done + sb.append(actualAttStr); + sb.append("\""); + sb.append("\n"); } - fail("Event never occurred after " + ms + " ms: " + ev.description()); - } - - if (waitThisTime > timeLeft) { - waitThisTime = timeLeft; - } - - // Wait a little bit - Thread.yield(); - try { -// getLogWriter().info("waiting " + waitThisTime + "ms for " + ev.description()); - Thread.sleep(waitThisTime); - } catch (InterruptedException e) { - fail("interrupted"); + return new Throwable("Creating distributed system with the following configuration:\n" + sb.toString()); } - } + }); } - + /** - * Wait on a mutex. This is done in a loop in order to address the - * "spurious wakeup" "feature" in Java. - * @param ev condition to test - * @param mutex object to lock and wait on - * @param ms total amount of time to wait - * @param interval interval to pause for the wait - * @param throwOnTimeout if false, no error is thrown. + * Write a message to the log about what tests have ran previously. This + * makes it easier to figure out if a previous test may have caused problems */ - static public void waitMutex(WaitCriterion ev, Object mutex, long ms, - long interval, boolean throwOnTimeout) { - final long tilt = System.currentTimeMillis() + ms; - long waitThisTime; - if (USE_JITTER) { - waitThisTime = jitterInterval(interval); - } - else { - waitThisTime = interval; - } - synchronized (mutex) { - for (;;) { - if (ev.done()) { - break; - } - - long timeLeft = tilt - System.currentTimeMillis(); - if (timeLeft <= 0) { - if (!throwOnTimeout) { - return; // not an error, but we're done - } - fail("Event never occurred after " + ms + " ms: " + ev.description()); - } - - if (waitThisTime > timeLeft) { - waitThisTime = timeLeft; - } - - try { - mutex.wait(waitThisTime); - } catch (InterruptedException e) { - fail("interrupted"); - } - } // for - } // synchronized + private void logTestHistory() { + String classname = getClass().getSimpleName(); + testHistory.add(classname); + System.out.println("Previously run tests: " + testHistory); } + //--------------------------------------------------------------------------- + // teardown methods + //--------------------------------------------------------------------------- + /** - * Wait for a thread to join - * @param t thread to wait on - * @param ms maximum time to wait - * @throws AssertionError if the thread does not terminate + * Tears down the DistributedTestCase. + *

+ * Do not override this method. Override {@link #preTearDown()} with work that + * needs to occur before tearDown() or override {@link #postTearDown()} with work + * that needs to occur after tearDown(). */ - static public void join(Thread t, long ms, LogWriter logger) { - final long tilt = System.currentTimeMillis() + ms; - final long incrementalWait; - if (USE_JITTER) { - incrementalWait = jitterInterval(ms); - } - else { - incrementalWait = ms; // wait entire time, no looping. - } - final long start = System.currentTimeMillis(); - for (;;) { - // I really do *not* understand why this check is necessary - // but it is, at least with JDK 1.6. According to the source code - // and the javadocs, one would think that join() would exit immediately - // if the thread is dead. However, I can tell you from experimentation - // that this is not the case. :-( djp 2008-12-08 - if (!t.isAlive()) { - break; - } - try { - t.join(incrementalWait); - } catch (InterruptedException e) { - fail("interrupted"); - } - if (System.currentTimeMillis() >= tilt) { - break; - } - } // for - if (logger == null) { - logger = new LocalLogWriter(LogWriterImpl.INFO_LEVEL, System.out); - } - if (t.isAlive()) { - logger.info("HUNG THREAD"); - dumpStackTrace(t, t.getStackTrace(), logger); - dumpMyThreads(logger); - t.interrupt(); // We're in trouble! - fail("Thread did not terminate after " + ms + " ms: " + t); -// getLogWriter().warning("Thread did not terminate" -// /* , new Exception()*/ -// ); - } - long elapsedMs = (System.currentTimeMillis() - start); - if (elapsedMs > 0) { - String msg = "Thread " + t + " took " - + elapsedMs - + " ms to exit."; - logger.info(msg); - } + @Override + public final void tearDown() throws Exception { + preTearDown(); + tearDownDistributedTestCase(); + postTearDown(); } - public static void dumpStackTrace(Thread t, StackTraceElement[] stack, LogWriter logger) { - StringBuilder msg = new StringBuilder(); - msg.append("Thread=<") - .append(t) - .append("> stackDump:\n"); - for (int i=0; i < stack.length; i++) { - msg.append("\t") - .append(stack[i]) - .append("\n"); + private final void tearDownDistributedTestCase() throws Exception { + Invoke.invokeInEveryVM(()->tearDownCreationStackGenerator()); + if (logPerTest) { + disconnectFromDS(); + Invoke.invokeInEveryVM(()->disconnectFromDS()); } - logger.info(msg.toString()); + cleanupAllVms(); } + /** - * Dump all thread stacks + * preTearDown() is invoked before {@link #tearDownDistributedTestCase()}. + *

+ * Override this as needed. Default implementation is empty. */ - public static void dumpMyThreads(LogWriter logger) { - OSProcess.printStacks(0, false); + protected void preTearDown() throws Exception { } /** - * A class that represents an currently logged expected exception, which - * should be removed - * - * @author Mitch Thomas - * @since 5.7bugfix + * postTearDown() is invoked after {@link #tearDownDistributedTestCase()}. + *

+ * Override this as needed. Default implementation is empty. */ - public static class ExpectedException implements Serializable { - private static final long serialVersionUID = 1L; - - final String ex; - - final transient VM v; - - public ExpectedException(String exception) { - this.ex = exception; - this.v = null; - } - - ExpectedException(String exception, VM vm) { - this.ex = exception; - this.v = vm; - } - - public String getRemoveString() { - return "" + ex + ""; - } - - public String getAddString() { - return "" + ex + ""; - } + protected void postTearDown() throws Exception { + } + + public static void cleanupAllVms() { // TODO: make private + tearDownVM(); + Invoke.invokeInEveryVM(()->tearDownVM()); + Invoke.invokeInLocator(()->{ + DistributionMessageObserver.setInstance(null); + DistributedTestUtils.unregisterInstantiatorsInThisVM(); + }); + DUnitLauncher.closeAndCheckForSuspects(); + } - public void remove() { - SerializableRunnable removeRunnable = new SerializableRunnable( - "removeExpectedExceptions") { - public void run() { - final String remove = getRemoveString(); - final InternalDistributedSystem sys = InternalDistributedSystem - .getConnectedInstance(); - if (sys != null) { - sys.getLogWriter().info(remove); - } - try { - getLogWriter().info(remove); - } catch (Exception noHydraLogger) { - } + private static void tearDownVM() { + closeCache(); - logger.info(remove); - } - }; + // keep alphabetized to detect duplicate lines + CacheCreation.clearThreadLocals(); + CacheServerTestUtil.clearCacheReference(); + ClientProxyMembershipID.system = null; + ClientServerTestCase.AUTO_LOAD_BALANCE = false; + ClientStatsManager.cleanupForTests(); + DiskStoreObserver.setInstance(null); + DistributedTestUtils.unregisterInstantiatorsInThisVM(); + DistributionMessageObserver.setInstance(null); + GlobalLockingDUnitTest.region_testBug32356 = null; + InitialImageOperation.slowImageProcessing = 0; + InternalClientMembership.unregisterAllListeners(); + LogWrapper.close(); + MultiVMRegionTestCase.CCRegion = null; + QueryObserverHolder.reset(); + QueryTestUtils.setCache(null); + RegionTestCase.preSnapshotRegion = null; + SocketCreator.resetHostNameCache(); + SocketCreator.resolve_dns = true; - if (this.v != null) { - v.invoke(removeRunnable); - } - else { - invokeInEveryVM(removeRunnable); - } - String s = getRemoveString(); - LogManager.getLogger(LogService.BASE_LOGGER_NAME).info(s); - // log it locally - final InternalDistributedSystem sys = InternalDistributedSystem - .getConnectedInstance(); - if (sys != null) { // avoid creating a system - sys.getLogWriter().info(s); - } - getLogWriter().info(s); + // clear system properties -- keep alphabetized + System.clearProperty("gemfire.log-level"); + System.clearProperty(HoplogConfig.ALLOW_LOCAL_HDFS_PROP); + System.clearProperty("jgroups.resolve_dns"); + + if (InternalDistributedSystem.systemAttemptingReconnect != null) { + InternalDistributedSystem.systemAttemptingReconnect.stopReconnecting(); } + + IgnoredException.removeAllExpectedExceptions(); } - /** - * Log in all VMs, in both the test logger and the GemFire logger the - * expected exception string to prevent grep logs from complaining. The - * expected string is used by the GrepLogs utility and so can contain - * regular expression characters. - * - * If you do not remove the expected exception, it will be removed at the - * end of your test case automatically. - * - * @since 5.7bugfix - * @param exception - * the exception string to expect - * @return an ExpectedException instance for removal - */ - public static ExpectedException addExpectedException(final String exception) { - return addExpectedException(exception, null); - } - - /** - * Log in all VMs, in both the test logger and the GemFire logger the - * expected exception string to prevent grep logs from complaining. The - * expected string is used by the GrepLogs utility and so can contain - * regular expression characters. - * - * @since 5.7bugfix - * @param exception - * the exception string to expect - * @param v - * the VM on which to log the expected exception or null for all VMs - * @return an ExpectedException instance for removal purposes - */ - public static ExpectedException addExpectedException(final String exception, - VM v) { - final ExpectedException ret; - if (v != null) { - ret = new ExpectedException(exception, v); - } - else { - ret = new ExpectedException(exception); + private static void closeCache() { + GemFireCacheImpl cache = GemFireCacheImpl.getInstance(); + if (cache != null && !cache.isClosed()) { + destroyRegions(cache); + cache.close(); } - // define the add and remove expected exceptions - final String add = ret.getAddString(); - SerializableRunnable addRunnable = new SerializableRunnable( - "addExpectedExceptions") { - public void run() { - final InternalDistributedSystem sys = InternalDistributedSystem - .getConnectedInstance(); - if (sys != null) { - sys.getLogWriter().info(add); + } + + protected static final void destroyRegions(final Cache cache) { // TODO: make private + if (cache != null && !cache.isClosed()) { + // try to destroy the root regions first so that we clean up any persistent files. + for (Iterator itr = cache.rootRegions().iterator(); itr.hasNext();) { + Region root = (Region)itr.next(); + String regionFullPath = root == null ? null : root.getFullPath(); + // for colocated regions you can't locally destroy a partitioned region. + if(root.isDestroyed() || root instanceof HARegion || root instanceof PartitionedRegion) { + continue; } try { - getLogWriter().info(add); - } catch (Exception noHydraLogger) { + root.localDestroyRegion("teardown"); + } catch (Throwable t) { + logger.error("Failure during tearDown destroyRegions for " + regionFullPath, t); } - - logger.info(add); - } - }; - if (v != null) { - v.invoke(addRunnable); - } - else { - invokeInEveryVM(addRunnable); - } - - LogManager.getLogger(LogService.BASE_LOGGER_NAME).info(add); - // Log it locally too - final InternalDistributedSystem sys = InternalDistributedSystem - .getConnectedInstance(); - if (sys != null) { // avoid creating a cache - sys.getLogWriter().info(add); - } - getLogWriter().info(add); - expectedExceptions.add(ret); - return ret; - } - - /** - * delete locator state files. Use this after getting a random port - * to ensure that an old locator state file isn't picked up by the - * new locator you're starting. - * @param ports - */ - public void deleteLocatorStateFile(int... ports) { - for (int i=0; iDistributedTestUtils provides static utility methods that + * affect the runtime environment or artifacts generated by a DistributedTest. + * + * These methods can be used directly: DistributedTestUtils.crashDistributedSystem(...), + * however, they are intended to be referenced through static import: + * + *

+ * import static com.gemstone.gemfire.test.dunit.DistributedTestUtils.*;
+ *    ...
+ *    crashDistributedSystem(...);
+ * 
+ * + * Extracted from DistributedTestCase. + */ +public class DistributedTestUtils { + + protected DistributedTestUtils() { + } + + /** + * Fetches the GemFireDescription for this test and adds its + * DistributedSystem properties to the provided props parameter. + * + * @param properties the properties to add hydra's test properties to + */ + public static void addHydraProperties(final Properties properties) { + Properties dsProperties = DUnitEnv.get().getDistributedSystemProperties(); + for (Iterator> iter = dsProperties.entrySet().iterator(); iter.hasNext();) { + Map.Entry entry = iter.next(); + String key = (String) entry.getKey(); + String value = (String) entry.getValue(); + if (properties.getProperty(key) == null) { + properties.setProperty(key, value); + } + } + } + + /** + * Crash the cache in the given VM in such a way that it immediately stops communicating with + * peers. This forces the VM's membership manager to throw a ForcedDisconnectException by + * forcibly terminating the JGroups protocol stack with a fake EXIT event.

+ * + * NOTE: if you use this method be sure that you clean up the VM before the end of your + * test with disconnectFromDS() or disconnectAllFromDS(). + */ + public static void crashDistributedSystem(final DistributedSystem system) { + MembershipManagerHelper.crashDistributedSystem(system); + MembershipManagerHelper.inhibitForcedDisconnectLogging(false); + WaitCriterion wc = new WaitCriterion() { + public boolean done() { + return !system.isConnected(); + } + public String description() { + return "Waiting for distributed system to finish disconnecting: " + system; + } + }; + Wait.waitForCriterion(wc, 10000, 1000, true); + } + + /** + * Crash the cache in the given VM in such a way that it immediately stops communicating with + * peers. This forces the VM's membership manager to throw a ForcedDisconnectException by + * forcibly terminating the JGroups protocol stack with a fake EXIT event.

+ * + * NOTE: if you use this method be sure that you clean up the VM before the end of your + * test with disconnectFromDS() or disconnectAllFromDS(). + */ + public static boolean crashDistributedSystem(final VM vm) { + return vm.invoke(()->{ + DistributedSystem system = InternalDistributedSystem.getAnyInstance(); + crashDistributedSystem(system); + return true; + } + ); + } + + /** + * Delete locator state files. Use this after getting a random port + * to ensure that an old locator state file isn't picked up by the + * new locator you're starting. + */ + public static void deleteLocatorStateFile(final int... ports) { + for (int index = 0; index < ports.length; index++) { + File stateFile = new File("locator"+ports[index]+"view.dat"); + if (stateFile.exists()) { + stateFile.delete(); + } + } + } + + public final static Properties getAllDistributedSystemProperties(final Properties properties) { + Properties dsProperties = DUnitEnv.get().getDistributedSystemProperties(); + + // our tests do not expect auto-reconnect to be on by default + if (!dsProperties.contains(DistributionConfig.DISABLE_AUTO_RECONNECT_NAME)) { + dsProperties.put(DistributionConfig.DISABLE_AUTO_RECONNECT_NAME, "true"); + } + + for (Iterator> iterator = properties.entrySet().iterator(); iterator.hasNext();) { + Map.Entry entry = iterator.next(); + String key = (String) entry.getKey(); + Object value = entry.getValue(); + dsProperties.put(key, value); + } + return dsProperties; + } + + /** + * Get the port that the standard dunit locator is listening on. + */ + public static int getDUnitLocatorPort() { + return DUnitEnv.get().getLocatorPort(); + } + + public static void unregisterAllDataSerializersFromAllVms() { + DistributedTestUtils.unregisterDataSerializerInThisVM(); + Invoke.invokeInEveryVM(()->unregisterDataSerializerInThisVM()); + Invoke.invokeInLocator(()->unregisterDataSerializerInThisVM()); + } + + public static void unregisterDataSerializerInThisVM() { + // TODO:KIRK: delete DataSerializerPropogationDUnitTest.successfullyLoadedTestDataSerializer = false; + // unregister all the Dataserializers + InternalDataSerializer.reinitialize(); + // ensure that all are unregistered + assertEquals(0, InternalDataSerializer.getSerializers().length); + } + + public static void unregisterInstantiatorsInThisVM() { + // unregister all the instantiators + InternalInstantiator.reinitialize(); + assertEquals(0, InternalInstantiator.getInstantiators().length); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/820cfd63/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/Host.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/Host.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/Host.java index 4ec6165..95d6f0d 100644 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/Host.java +++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/Host.java @@ -16,6 +16,7 @@ */ package com.gemstone.gemfire.test.dunit; +import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -33,9 +34,9 @@ import com.gemstone.gemfire.test.dunit.standalone.RemoteDUnitVMIF; * started on other hosts via additional Hydra configuration.

* * @author David Whitlock - * */ -public abstract class Host implements java.io.Serializable { +@SuppressWarnings("serial") +public abstract class Host implements Serializable { /** The available hosts */ protected static List hosts = new ArrayList(); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/820cfd63/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/IgnoredException.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/IgnoredException.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/IgnoredException.java new file mode 100755 index 0000000..d0cead6 --- /dev/null +++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/IgnoredException.java @@ -0,0 +1,200 @@ +/* + * 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; + +import java.io.Serializable; +import java.util.concurrent.ConcurrentLinkedQueue; + +import org.apache.logging.log4j.Logger; + +import com.gemstone.gemfire.distributed.DistributedSystem; +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem; +import com.gemstone.gemfire.internal.logging.LogService; + +/** + * IgnoredException provides static utility methods that + * will log messages to add or remove IgnoredExceptions. + * Each IgnoredException allows you to specify a suspect string + * that will be ignored by the GrepLogs utility which is run + * after each DistributedTest test method. + * + * These methods can be used directly: + * IgnoredException.addIgnoredException(...), + * however, they are intended to be referenced through static import: + * + *
+ * import static com.gemstone.gemfire.test.dunit.IgnoredException.*;
+ *    ...
+ *    addIgnoredException(...);
+ * 
+ * + * A test should use addIgnoredException(...) before executing + * the code that will potentially log the suspect string. The test should + * then remove() the IgnoredException immediately + * after. Note that DistributedTestCase.tearDown() will + * automatically remove all current IgnoredExceptions by + * invoking removeAllIgnoredExceptions. + * + * A suspect string is typically an Exception class and/or message string. + * + * The GrepLogs utility is part of Hydra which is not included + * in Apache Geode. The Hydra class which consumes logs and reports suspect + * strings is batterytest.greplogs.GrepLogs. + * + * Extracted from DistributedTestCase. + * + * @author Mitch Thomas + * @since 5.7bugfix + */ +@SuppressWarnings("serial") +public class IgnoredException implements Serializable { + + private static final Logger logger = LogService.getLogger(); + + private final String suspectString; + + private final transient VM vm; + + private static ConcurrentLinkedQueue ignoredExceptions = new ConcurrentLinkedQueue(); + + public IgnoredException(final String suspectString) { + this.suspectString = suspectString; + this.vm = null; + } + + IgnoredException(final String suspectString, final VM vm) { + this.suspectString = suspectString; + this.vm = vm; + } + + String suspectString() { + return this.suspectString; + } + + VM vm() { + return this.vm; + } + + public String getRemoveMessage() { + return "" + this.suspectString + ""; + } + + public String getAddMessage() { + return "" + this.suspectString + ""; + } + + public void remove() { + final String removeMessage = getRemoveMessage(); + + @SuppressWarnings("serial") + SerializableRunnable removeRunnable = new SerializableRunnable(IgnoredException.class.getSimpleName()+" remove") { + public void run() { + // TODO: delete use of system.getLogWriter + DistributedSystem system = InternalDistributedSystem.getConnectedInstance(); + if (system != null) { + system.getLogWriter().info(removeMessage); + } + + // TODO: delete use of LogWriterUtils + try { + LogWriterUtils.getLogWriter().info(removeMessage); + } catch (Exception noHydraLogger) { + } + + logger.info(removeMessage); + } + }; + + removeRunnable.run(); + + if (this.vm != null) { + vm.invoke(removeRunnable); + } else { + Invoke.invokeInEveryVM(removeRunnable); + } + } + + public static void removeAllExpectedExceptions() { + IgnoredException ignoredException; + while ((ignoredException = ignoredExceptions.poll()) != null) { + ignoredException.remove(); + } + } + + /** + * Log in all VMs, in both the test logger and the GemFire logger the + * ignored exception string to prevent grep logs from complaining. The + * suspect string is used by the GrepLogs utility and so can contain + * regular expression characters. + * + * @since 5.7bugfix + * @param suspectString the exception string to expect + * @param vm the VM on which to log the expected exception or null for all VMs + * @return an IgnoredException instance for removal purposes + */ + public static IgnoredException addIgnoredException(final String suspectString, final VM vm) { + final IgnoredException ignoredException = new IgnoredException(suspectString, vm); + final String addMessage = ignoredException.getAddMessage(); + + @SuppressWarnings("serial") + SerializableRunnable addRunnable = new SerializableRunnable(IgnoredException.class.getSimpleName()+" addIgnoredException") { + public void run() { + // TODO: delete use of system.getLogWriter + DistributedSystem system = InternalDistributedSystem.getConnectedInstance(); + if (system != null) { + system.getLogWriter().info(addMessage); + } + + // TODO: delete use of LogWriterUtils + try { + LogWriterUtils.getLogWriter().info(addMessage); + } catch (Exception noHydraLogger) { + } + + logger.info(addMessage); + } + }; + + addRunnable.run(); + + if (vm != null) { + vm.invoke(addRunnable); + } else { + Invoke.invokeInEveryVM(addRunnable); + } + + ignoredExceptions.add(ignoredException); + return ignoredException; + } + + /** + * Log in all VMs, in both the test logger and the GemFire logger the + * ignored exception string to prevent grep logs from complaining. The + * suspect string is used by the GrepLogs utility and so can contain + * regular expression characters. + * + * If you do not remove the ignored exception, it will be removed at the + * end of your test case automatically. + * + * @since 5.7bugfix + * @param suspectString the exception string to expect + * @return an IgnoredException instance for removal + */ + public static IgnoredException addIgnoredException(final String suspectString) { + return addIgnoredException(suspectString, null); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/820cfd63/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/Invoke.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/Invoke.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/Invoke.java new file mode 100755 index 0000000..5a4ca15 --- /dev/null +++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/Invoke.java @@ -0,0 +1,160 @@ +/* + * 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; + +import java.util.HashMap; +import java.util.Map; + +/** + * Invoke provides static utility methods that allow a + * DistributedTest to invoke a SerializableRunnable + * or SerializableCallable in a remote test VM. + * + * These methods can be used directly: Invoke.invokeInEveryVM(...), + * however, they are intended to be referenced through static import: + * + *
+ * import static com.gemstone.gemfire.test.dunit.Invoke.*;
+ *    ...
+ *    invokeInEveryVM(...);
+ * 
+ * + * Extracted from DistributedTestCase. + */ +public class Invoke { + + protected Invoke() { + } + + /** + * Invokes a SerializableRunnable in every VM that + * DUnit knows about. + *

+ * Note: this does NOT include the controller VM or locator VM. + * + * @see VM#invoke(SerializableRunnableIF) + */ + public static void invokeInEveryVM(final SerializableRunnableIF runnable) { + for (int hostIndex = 0; hostIndex < Host.getHostCount(); hostIndex++) { + Host host = Host.getHost(hostIndex); + + for (int vmIndex = 0; vmIndex < host.getVMCount(); vmIndex++) { + VM vm = host.getVM(vmIndex); + vm.invoke(runnable); + } + } + } + + /** + * Invokes a method in every remote VM that DUnit knows about. + * + * @see VM#invoke(Class, String) + * @deprecated Please use {@link #invokeInEveryVM(SerializableRunnableIF)} or another non-deprecated method in Invoke instead. + */ + @Deprecated + public static void invokeInEveryVM(final Class targetClass, final String targetMethod) { + for (int hostIndex = 0; hostIndex < Host.getHostCount(); hostIndex++) { + Host host = Host.getHost(hostIndex); + + for (int vmIndex = 0; vmIndex < host.getVMCount(); vmIndex++) { + VM vm = host.getVM(vmIndex); + vm.invoke(targetClass, targetMethod); + } + } + } + + /** + * Invokes a method in every remote VM that DUnit knows about. + * + * @see VM#invoke(Class, String) + * @deprecated Please use {@link #invokeInEveryVM(SerializableRunnableIF)} or another non-deprecated method in Invoke instead. + */ + public static void invokeInEveryVM(final Class targetClass, final String targetMethod, final Object[] methodArgs) { + for (int hostIndex = 0; hostIndex < Host.getHostCount(); hostIndex++) { + Host host = Host.getHost(hostIndex); + + for (int vmIndex = 0; vmIndex < host.getVMCount(); vmIndex++) { + VM vm = host.getVM(vmIndex); + vm.invoke(targetClass, targetMethod, methodArgs); + } + } + } + + /** + * Invokes a SerializableCallable in every VM that + * DUnit knows about. + * + * @return a Map of results, where the key is the VM and the value is the result for that VM + * @see VM#invoke(SerializableCallableIF) + */ + public static Map invokeInEveryVM(final SerializableCallableIF callable) { + Map ret = new HashMap(); + for (int h = 0; h < Host.getHostCount(); h++) { + Host host = Host.getHost(h); + for (int v = 0; v < host.getVMCount(); v++) { + VM vm = host.getVM(v); + ret.put(vm, vm.invoke(callable)); + } + } + return ret; + } + + public static void invokeInLocator(final SerializableRunnableIF runnable) { + Host.getLocator().invoke(runnable); + } + + /** + * @deprecated Please use {@link com.jayway.awaitility.Awaitility} with {@link #invokeInEveryVM(SerializableCallableIF)} instead. + */ + public static void invokeRepeatingIfNecessary(final VM vm, final RepeatableRunnable runnable) { + vm.invokeRepeatingIfNecessary(runnable, 0); + } + + /** + * @deprecated Please use {@link com.jayway.awaitility.Awaitility} with {@link #invokeInEveryVM(SerializableCallableIF)} instead. + */ + public static void invokeRepeatingIfNecessary(final VM vm, final RepeatableRunnable runnable, final long repeatTimeoutMs) { + vm.invokeRepeatingIfNecessary(runnable, repeatTimeoutMs); + } + + /** + * @deprecated Please use {@link com.jayway.awaitility.Awaitility} with {@link #invokeInEveryVM(SerializableCallableIF)} instead. + */ + public static void invokeInEveryVMRepeatingIfNecessary(final RepeatableRunnable runnable) { + Invoke.invokeInEveryVMRepeatingIfNecessary(runnable, 0); + } + + /** + * Invokes a SerializableRunnable in every VM that + * DUnit knows about. If run() throws an assertion failure, + * its execution is repeated, until no assertion failure occurs or + * repeatTimeoutMs milliseconds have passed. + * + * @see VM#invoke(RepeatableRunnable) + * @deprecated Please use {@link com.jayway.awaitility.Awaitility} with {@link #invokeInEveryVM(SerializableCallableIF)} instead. + */ + public static void invokeInEveryVMRepeatingIfNecessary(final RepeatableRunnable runnable, final long repeatTimeoutMs) { + for (int h = 0; h < Host.getHostCount(); h++) { + Host host = Host.getHost(h); + + for (int v = 0; v < host.getVMCount(); v++) { + VM vm = host.getVM(v); + vm.invokeRepeatingIfNecessary(runnable, repeatTimeoutMs); + } + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/820cfd63/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/Jitter.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/Jitter.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/Jitter.java new file mode 100755 index 0000000..08fe71a --- /dev/null +++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/Jitter.java @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gemstone.gemfire.test.dunit; + +import java.util.Random; + +/** + * Extracted from DistributedTestCase + */ +class Jitter { + + /** + * If true, we randomize the amount of time we wait before polling a + * {@link WaitCriterion}. + */ + private static final boolean USE_JITTER = true; + + private static final Random jitter = new Random(); + + protected Jitter() { + } + + /** + * Returns an adjusted interval from minimum()intervalMillis milliseconds. If jittering is disabled then + * the value returned will be equal to intervalMillis. + * + * @param intervalMillis + * @return adjust milliseconds to use as interval for WaitCriteria polling + */ + static long jitterInterval(long intervalMillis) { + if (USE_JITTER) { + return adjustIntervalIfJitterIsEnabled(intervalMillis); + } else { + return intervalMillis; + } + } + + static int minimum() { + return 10; + } + + static int maximum() { + return 5000; + } + + /** + * If jittering is enabled then returns a jittered interval up to a maximum + * of intervalMillis milliseconds, inclusive. + * + * If jittering is disabled then returns intervalMillis. + * + * The result is bounded by 50 ms as a minimum and 5000 ms as a maximum. + * + * @param ms total amount of time to wait + * @return randomized interval we should wait + */ + private static int adjustIntervalIfJitterIsEnabled(final long intervalMillis) { + final int minLegal = minimum(); + final int maxLegal = maximum(); + + if (intervalMillis <= minLegal) { + return (int)intervalMillis; // Don't ever jitter anything below this. + } + + int maxValue = maxLegal; + if (intervalMillis < maxLegal) { + maxValue = (int)intervalMillis; + } + + return minLegal + jitter.nextInt(maxValue - minLegal + 1); + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/820cfd63/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/LogWriterUtils.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/LogWriterUtils.java b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/LogWriterUtils.java new file mode 100755 index 0000000..9556af2 --- /dev/null +++ b/gemfire-core/src/test/java/com/gemstone/gemfire/test/dunit/LogWriterUtils.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gemstone.gemfire.test.dunit; + +import java.util.Properties; + +import org.apache.logging.log4j.Logger; + +import com.gemstone.gemfire.LogWriter; +import com.gemstone.gemfire.distributed.internal.DistributionConfig; +import com.gemstone.gemfire.distributed.internal.DistributionConfigImpl; +import com.gemstone.gemfire.internal.logging.InternalLogWriter; +import com.gemstone.gemfire.internal.logging.LogService; +import com.gemstone.gemfire.internal.logging.LogWriterFactory; +import com.gemstone.gemfire.internal.logging.ManagerLogWriter; +import com.gemstone.gemfire.internal.logging.log4j.LogWriterLogger; + +/** + * LogWriterUtils provides static utility methods to access a + * LogWriter within a test. + * + * These methods can be used directly: LogWriterUtils.getLogWriter(...), + * however, they are intended to be referenced through static import: + * + *

+ * import static com.gemstone.gemfire.test.dunit.LogWriterUtils.*;
+ *    ...
+ *    LogWriter logWriter = getLogWriter(...);
+ * 
+ * + * Extracted from DistributedTestCase. + * + * @deprecated Please use a Logger from {@link LogService#getLogger()} instead. + */ +@Deprecated +public class LogWriterUtils { + + private static final Logger logger = LogService.getLogger(); + private static final LogWriterLogger oldLogger = LogWriterLogger.create(logger); + + protected LogWriterUtils() { + } + + /** + * Returns a LogWriter for logging information + * + * @deprecated Please use a Logger from {@link LogService#getLogger()} instead. + */ + public static InternalLogWriter getLogWriter() { + return LogWriterUtils.oldLogger; + } + + /** + * Creates a new LogWriter and adds it to the config properties. The config + * can then be used to connect to DistributedSystem, thus providing early + * access to the LogWriter before connecting. This call does not connect + * to the DistributedSystem. It simply creates and returns the LogWriter + * that will eventually be used by the DistributedSystem that connects using + * config. + * + * @param properties the DistributedSystem config properties to add LogWriter to + * @return early access to the DistributedSystem LogWriter + * @deprecated Please use a Logger from {@link LogService#getLogger()} instead. + */ + public static LogWriter createLogWriter(final Properties properties) { + Properties nonDefault = properties; + if (nonDefault == null) { + nonDefault = new Properties(); + } + DistributedTestUtils.addHydraProperties(nonDefault); + + DistributionConfig dc = new DistributionConfigImpl(nonDefault); + LogWriter logger = LogWriterFactory.createLogWriterLogger( + false/*isLoner*/, false/*isSecurityLog*/, dc, + false); + + // if config was non-null, then these will be added to it... + nonDefault.put(DistributionConfig.LOG_WRITER_NAME, logger); + + return logger; + } + + /** + * This finds the log level configured for the test run. It should be used + * when creating a new distributed system if you want to specify a log level. + * + * @return the dunit log-level setting + */ + public static String getDUnitLogLevel() { + Properties dsProperties = DUnitEnv.get().getDistributedSystemProperties(); + String result = dsProperties.getProperty(DistributionConfig.LOG_LEVEL_NAME); + if (result == null) { + result = ManagerLogWriter.levelToString(DistributionConfig.DEFAULT_LOG_LEVEL); + } + return result; + } +}