/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.geode.test.dunit;
import org.apache.geode.distributed.DistributedSystem;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
import org.apache.geode.distributed.internal.membership.gms.MembershipManagerHelper;
import org.apache.geode.internal.InternalDataSerializer;
import org.apache.geode.internal.InternalInstantiator;
import java.io.File;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import static org.junit.Assert.assertEquals;
import static org.apache.geode.distributed.ConfigurationProperties.*;
/**
* <code>DistributedTestUtils</code> provides static utility methods that affect the runtime
* environment or artifacts generated by a DistributedTest.
*
* These methods can be used directly:
* <code>DistributedTestUtils.crashDistributedSystem(...)</code>, however, they are intended to be
* referenced through static import:
*
* <pre>
* import static org.apache.geode.test.dunit.DistributedTestUtils.*;
* ...
* crashDistributedSystem(...);
* </pre>
*
* 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<Map.Entry<Object, Object>> iter = dsProperties.entrySet().iterator(); iter
.hasNext();) {
Map.Entry<Object, Object> 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.
* <p>
*
* 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.
* <p>
*
* 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(DISABLE_AUTO_RECONNECT)) {
dsProperties.put(DISABLE_AUTO_RECONNECT, "true");
}
for (Iterator<Map.Entry<Object, Object>> iterator = properties.entrySet().iterator(); iterator
.hasNext();) {
Map.Entry<Object, Object> entry = iterator.next();
String key = (String) entry.getKey();
Object value = entry.getValue();
dsProperties.put(key, value);
}
System.out.println("distributed system properties: " + dsProperties);
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);
}
}