blob: fdfebb57702b95edef38d94ca23bc9831031a4f4 [file] [log] [blame]
/*
* 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.internal.cache;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.apache.geode.InternalGemFireException;
import org.apache.geode.cache.AttributesFactory;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheException;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.CacheLoader;
import org.apache.geode.cache.CacheLoaderException;
import org.apache.geode.cache.EntryNotFoundException;
import org.apache.geode.cache.LoaderHelper;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.Scope;
import org.apache.geode.distributed.internal.ClusterDistributionManager;
import org.apache.geode.distributed.internal.InternalDistributedSystem;
import org.apache.geode.internal.Assert;
import org.apache.geode.test.dunit.Host;
import org.apache.geode.test.dunit.LogWriterUtils;
import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase;
import org.apache.geode.test.dunit.rules.ClusterStartupRule;
import org.apache.geode.test.dunit.rules.DistributedRule;
/**
* @deprecated Please use {@link DistributedRule} and Geode User APIs or {@link ClusterStartupRule}
* instead.
*/
@Deprecated
public abstract class DistributedCacheTestCase extends JUnit4DistributedTestCase {
/** The current cache in this VM */
protected static Cache cache = null;
@Override
public final void postSetUp() throws Exception {
setUpDistributedCacheTestCase(true);
}
/**
* Creates the {@link Cache} and root region in each remote VM and, if createLocalCache, in this
* VM.
*/
private final void setUpDistributedCacheTestCase(boolean createLocalCache) throws Exception {
if (createLocalCache) {
try {
remoteCreateCache();
assertTrue(cache != null);
} catch (Exception ex) {
String s = "While creating cache in this VM";
throw new InternalGemFireException(s, ex);
}
} else {
getSystem(); // make sure we have a connected DistributedSystem
}
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(DistributedCacheTestCase::remoteCreateCache);
}
}
}
/**
* Creates the root region in a remote VM
*/
private static void remoteCreateCache() throws Exception {
Assert.assertTrue(cache == null, "cache should be null");
DistributedCacheTestCase x = new DistributedCacheTestCase() {};
cache = CacheFactory.create(x.getSystem());
AttributesFactory factory = new AttributesFactory();
factory.setScope(Scope.DISTRIBUTED_NO_ACK);
cache.createRegion("root", factory.create());
}
/**
* Closes the cache in this VM and each remote VM
*/
@Override
public final void preTearDown() throws Exception {
StringBuilder problems = new StringBuilder();
if (cache != null) {
try {
if (remoteCloseCache()) {
problems.append("An exception occurred trying to close the cache.");
}
assertTrue(cache == null);
} catch (Exception ex) {
String s = "While closing the cache in this VM";
throw new InternalGemFireException(s, ex);
}
}
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);
boolean exceptionInThreads = vm.invoke(DistributedCacheTestCase::remoteCloseCache);
if (exceptionInThreads) {
String s = "An exception occurred in GemFire system";
problems.append(s);
}
}
}
assertEquals("Problems while tearing down", "", problems.toString().trim());
}
/**
* Closes the Cache for the current VM. Returns whether or not an exception occurred in the
* distribution manager to which this VM is attached. Note that the exception flag is cleared by
* this method.
*
* @see ClusterDistributionManager#exceptionInThreads()
*/
private static boolean remoteCloseCache() throws CacheException {
Assert.assertTrue(cache != null, "No cache on this VM?");
Assert.assertTrue(!cache.isClosed(), "Who closed my cache?");
InternalDistributedSystem system = (InternalDistributedSystem) cache.getDistributedSystem();
ClusterDistributionManager dm = (ClusterDistributionManager) system.getDistributionManager();
boolean exceptionInThreads = dm.exceptionInThreads();
dm.clearExceptionInThreads();
cache.close();
cache = null;
return exceptionInThreads;
}
/**
* Returns the root region of the cache. We assume that the {@link Cache} and the root region have
* already been created.
*/
protected static Region getRootRegion() throws CacheException {
if (cache == null) {
String s = "Cache not created yet!";
throw new IllegalStateException(s);
}
return cache.getRegion("root");
}
/**
* Return the distribution manager associate with the cache
*
* @since GemFire 2.1
*/
protected static ClusterDistributionManager getDistributionManager() {
if (cache == null) {
String s = "Cache not created yet!";
throw new IllegalStateException(s);
}
InternalDistributedSystem system =
(InternalDistributedSystem) cache.getDistributedSystem();
return (ClusterDistributionManager) system.getDistributionManager();
}
/**
* Creates a new sub-Region of the root Region in a remote VM with default scope, SCOPE_LOCAL.
*
* @param name The name of the newly-created sub-Region. It is recommended that the name of the
* Region be the {@link #getUniqueName()} of the test.
*/
protected static void remoteCreateRegion(String name) throws CacheException {
remoteCreateRegion(name, Scope.LOCAL);
}
/**
* Creates a new sub-Region of the root Region in a remote VM.
*
* @param name The name of the newly-created sub-Region. It is recommended that the name of the
* Region be the {@link #getUniqueName()} of the test.
* @param scope create the region attributes with this scope
*/
protected static void remoteCreateRegion(String name, Scope scope) throws CacheException {
Region root = getRootRegion();
AttributesFactory factory = new AttributesFactory();
factory.setScope(scope);
Region newRegion = root.createSubregion(name, factory.create());
LogWriterUtils.getLogWriter().info("Created Region '" + newRegion.getFullPath() + "'");
}
/**
* Defines an entry in the Region with the given name and scope.
*
* @param regionName The name of a region that is a sub-region of the root region, or a global
* name
* @param entryName Must be {@link java.io.Serializable}
*/
protected static void remoteDefineEntry(String regionName, String entryName, Scope scope)
throws CacheException {
remoteDefineEntry(regionName, entryName, scope, true);
}
/**
* Defines an entry in the Region with the given name and scope. In 3.0 this method create a
* subregion named <code>entryName</code> (with the appropriate attributes) that contains an entry
* named <code>entryName</code>.
*
* @param regionName The name of a region that is a sub-region of the root region, or a global
* name
* @param entryName Must be {@link java.io.Serializable}
* @param doNetSearch Will the distributed region perform a netSearch when looking for objects? If
* <code>false</code> a {@link CacheException} will be thrown if an entry in the region is
* asked for and it not there.
*/
protected static void remoteDefineEntry(String regionName, String entryName, Scope scope,
boolean doNetSearch) throws CacheException {
Region root = getRootRegion();
Region region = root.getSubregion(regionName);
AttributesFactory factory = new AttributesFactory();
factory.setScope(scope);
if (!doNetSearch) {
factory.setCacheLoader(new CacheLoader() {
@Override
public Object load(LoaderHelper helper) throws CacheLoaderException {
String s = "Should not be loading \"" + helper.getKey() + "\" in \""
+ helper.getRegion().getFullPath() + "\"";
throw new CacheLoaderException(s);
}
@Override
public void close() {}
});
}
Region sub = region.createSubregion(entryName, factory.create());
sub.create(entryName, null);
LogWriterUtils.getLogWriter()
.info("Defined Entry named '" + entryName + "' in region '" + sub.getFullPath() + "'");
}
/**
* Puts (or creates) a value in a subregion of <code>region</code> named <code>entryName</code>.
*/
protected static void remotePut(String regionName, String entryName, Object value, Scope scope)
throws CacheException {
Region root = getRootRegion();
Region region = root.getSubregion(regionName);
Region sub = region.getSubregion(entryName);
if (sub == null) {
AttributesFactory factory = new AttributesFactory();
factory.setScope(scope);
sub = region.createSubregion(entryName, factory.create());
}
sub.put(entryName, value);
LogWriterUtils.getLogWriter().info("Put value " + value + " in entry " + entryName
+ " in region '" + region.getFullPath() + "'");
}
/**
* Does a put with the given value, defining a DISTRIBUTED_NO_ACK entry in the Region with the
* given name.
*
* @param regionName The name of a region that is a sub-region of the root region, or a global
* name
* @param entryName Must be {@link java.io.Serializable}
*/
protected static void remotePutDistributed(String regionName, String entryName, Object value)
throws CacheException {
remotePut(regionName, entryName, value, Scope.DISTRIBUTED_NO_ACK);
}
/**
* Replaces the value of an entry in a region in a remote VM
*
* @param regionName The name of a region that is a sub-region of the root region
* @param entryName Must be {@link java.io.Serializable}
* @param value The value used to replace
*/
protected static void remoteReplace(String regionName, String entryName, Object value)
throws CacheException {
Region root = getRootRegion();
Region region = root.getSubregion(regionName);
Region sub = region.getSubregion(entryName);
if (sub == null) {
String s = "Entry \"" + entryName + "\" does not exist";
throw new EntryNotFoundException(s);
}
sub.put(entryName, value);
LogWriterUtils.getLogWriter().info("Replaced value " + value + "in entry " + entryName
+ " in region '" + region.getFullPath() + "'");
}
/**
* Invalidates the value of an entry in a region in a remote VM
*
* @param regionName The name of a region that is a sub-region of the root region
* @param entryName Must be {@link java.io.Serializable}
*/
protected static void remoteInvalidate(String regionName, String entryName)
throws CacheException {
Region root = getRootRegion();
Region region = root.getSubregion(regionName);
Region sub = region.getSubregion(entryName);
if (sub == null) {
String s = "Entry \"" + entryName + "\" does not exist";
throw new EntryNotFoundException(s);
}
sub.invalidate(entryName);
}
/**
* Destroys the value of an entry in a region in a remote VM
*
* @param regionName The name of a region that is a sub-region of the root region
* @param entryName Must be {@link java.io.Serializable}
*/
protected static void remoteDestroy(String regionName, String entryName) throws CacheException {
Region root = getRootRegion();
Region region = root.getSubregion(regionName);
Region sub = region.getSubregion(entryName);
if (sub == null) {
String s = "Entry \"" + entryName + "\" does not exist";
throw new EntryNotFoundException(s);
}
assertNotNull(sub.getEntry(entryName));
sub.destroy(entryName);
assertNull(sub.getEntry(entryName));
}
/**
* Asserts that the value of an entry in a region is what we expect it to be.
*
* @param regionName The name of a region that is a sub-region of the root region
* @param entryName Must be {@link java.io.Serializable}
*/
protected static void remoteAssertEntryValue(String regionName, String entryName, Object expected)
throws CacheException {
Region root = getRootRegion();
Region region = root.getSubregion(regionName);
Region sub = region.getSubregion(entryName);
if (sub == null) {
String s = "Entry \"" + entryName + "\" does not exist";
throw new EntryNotFoundException(s);
}
assertEquals(expected, sub.get(entryName));
}
/**
* Assumes there is only one host, and invokes the given method in every VM that host knows about.
*/
public void forEachVMInvoke(String methodName, Object[] args) {
forEachVMInvoke(getClass(), methodName, args);
}
/**
* Assumes there is only one host, and invokes the given method in every VM that host knows about.
*/
public void forEachVMInvoke(Class<?> targetClass, String methodName, Object[] args) {
Host host = Host.getHost(0);
int vmCount = host.getVMCount();
for (int i = 0; i < vmCount; i++) {
LogWriterUtils.getLogWriter().info("Invoking " + methodName + "on VM#" + i);
host.getVM(i).invoke(targetClass, methodName, args);
}
}
}