blob: 4f03dfb23fcdb2f5d14a5f193a0bbab4df12231a [file] [log] [blame]
/*=========================================================================
* Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
* This product is protected by U.S. and international copyright
* and intellectual property laws. Pivotal products are covered by
* one or more patents listed at http://www.pivotal.io/patents.
*=========================================================================
*/
package com.gemstone.gemfire.cache30;
import com.gemstone.gemfire.cache.*;
import java.util.concurrent.locks.Lock;
import dunit.*;
/**
* This class tests distributed locking of global region entries.
*/
public class GlobalLockingDUnitTest extends CacheTestCase {
public static Region region_testBug32356;
public GlobalLockingDUnitTest(String name) {
super(name);
}
/**
* Returns region attributes for a <code>GLOBAL</code> region
*/
protected RegionAttributes getGlobalAttrs() {
AttributesFactory factory = new AttributesFactory();
factory.setScope(Scope.GLOBAL);
return factory.create();
}
protected Region getOrCreateRootRegion() {
Region root = getRootRegion();
if (root == null) {
try {
root = createRootRegion(getGlobalAttrs());
} catch (RegionExistsException ex) {
fail("Huh?");
} catch (TimeoutException ex) {
fail(ex.toString());
}
}
return root;
}
////////////////////// Test Methods //////////////////////
/**
* Tests for 32356 R2 tryLock w/ 0 timeout broken in Distributed Lock Service
*/
public void testBug32356() throws Exception {
getLogWriter().fine("[testBug32356]");
Host host = Host.getHost(0);
final String name = this.getUniqueName();
final Object key = "32356";
// lock/unlock '32356' in all vms... (make all vms aware of token)
getLogWriter().fine("[testBug32356] lock/unlock '32356' in all vms");
for (int i = 0; i < 4; i++) {
final int vm = i;
host.getVM(vm).invoke(new CacheSerializableRunnable("testBug32356_step1") {
public void run2() throws CacheException {
region_testBug32356 =
getOrCreateRootRegion().createSubregion(name, getGlobalAttrs());
Lock lock = region_testBug32356.getDistributedLock(key);
lock.lock();
lock.unlock();
}
});
}
// attempt try-lock of zero wait time in all vms
getLogWriter().fine("[testBug32356] attempt try-lock of zero wait time in all vms");
for (int i = 0; i < 4; i++) {
final int vm = i;
host.getVM(vm).invoke(new CacheSerializableRunnable("testBug32356_step2") {
public void run2() throws CacheException {
Lock lock = region_testBug32356.getDistributedLock(key);
// bug 32356 should cause this to fail...
assertTrue("Found bug 32356", lock.tryLock());
lock.unlock();
}
});
}
}
public void testNonGlobalRegion() throws CacheException {
String name = this.getUniqueName();
AttributesFactory factory = new AttributesFactory(getGlobalAttrs());
factory.setScope(Scope.LOCAL);
Region region = getOrCreateRootRegion().createSubregion(name + "LOCAL", factory.create());
try {
region.getDistributedLock("obj");
fail("Should have thrown an IllegalStateException");
} catch (IllegalStateException ex) {
// pass...
}
factory.setScope(Scope.DISTRIBUTED_ACK);
region = getOrCreateRootRegion().createSubregion(name + "DACK", factory.create());
try {
region.getDistributedLock("obj");
fail("Should have thrown an IllegalStateException");
} catch (IllegalStateException ex) {
// pass...
}
factory.setScope(Scope.DISTRIBUTED_NO_ACK);
region = getOrCreateRootRegion().createSubregion(name + "DNOACK", factory.create());
try {
region.getDistributedLock("obj");
fail("Should have thrown an IllegalStateException");
} catch (IllegalStateException ex) {
// pass...
}
}
public void testSingleVMLockUnlock() throws CacheException {
String name = this.getUniqueName() + "-GLOBAL";
Region region = getOrCreateRootRegion().createSubregion(name, getGlobalAttrs());
Lock lock = region.getDistributedLock("obj");
lock.lock();
lock.unlock();
}
public void testIsLockGrantorAttribute() throws Exception {
String name = this.getUniqueName() + "-testIsLockGrantorAttribute";
AttributesFactory factory = new AttributesFactory(getGlobalAttrs());
factory.setLockGrantor(true);
Region region = getOrCreateRootRegion().createSubregion(
name, factory.create());
assertEquals(
"Setting isLockGrantor failed to result in becoming lock grantor",
true,
((com.gemstone.gemfire.internal.cache.DistributedRegion)
region).getLockService().isLockGrantor());
}
/**
* Get the lock in one VM, try to create in other
*/
public void testCreateLockTimeout() {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
final String name = this.getUniqueName();
final Object key = new Integer(5);
vm0.invoke(new CacheSerializableRunnable("Get lock") {
public void run2() throws CacheException {
Region r = getOrCreateRootRegion().createSubregion(name, getGlobalAttrs());
Lock lock = r.getDistributedLock(key);
lock.lock();
}
});
vm1.invoke(new CacheSerializableRunnable("Lock timeout creating entry") {
public void run2() throws CacheException {
getOrCreateRootRegion().getCache().setLockTimeout(2);
Region r = getOrCreateRootRegion().createSubregion(name, getGlobalAttrs());
try {
r.create(key, "the value");
fail("create() should have thrown TimeoutException");
} catch (TimeoutException ex) {
// pass
}
}
});
}
/**
* get the lock in one VM, try to put() in other
*/
public void testPutLockTimeout() {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
final String name = this.getUniqueName();
final Object key = new Integer(5);
vm0.invoke(new CacheSerializableRunnable("Get lock") {
public void run2() throws CacheException {
Region r = getOrCreateRootRegion().createSubregion(name, getGlobalAttrs());
Lock lock = r.getDistributedLock(key);
lock.lock();
}
});
vm1.invoke(new CacheSerializableRunnable("Lock timeout putting entry") {
public void run2() throws CacheException {
getOrCreateRootRegion().getCache().setLockTimeout(2);
Region r = getOrCreateRootRegion().createSubregion(name, getGlobalAttrs());
try {
r.put(key, "the value");
fail("put() should have thrown TimeoutException");
} catch (TimeoutException ex) {
// pass
}
}
});
}
/**
* get lock in one VM, try to invoke loader in other
*/
public void testLoadLockTimeout() {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
final String name = this.getUniqueName();
final Object key = new Integer(5);
// In first VM, get a lock on the entry
vm0.invoke(new CacheSerializableRunnable("Get lock") {
public void run2() throws CacheException {
Region r = getOrCreateRootRegion().createSubregion(name, getGlobalAttrs());
Lock lock = r.getDistributedLock(key);
lock.lock();
}
});
// In second VM, do a get that tries to invoke a loader
vm1.invoke(new CacheSerializableRunnable("Lock timeout local loader") {
public void run2() throws CacheException {
getOrCreateRootRegion().getCache().setLockTimeout(2);
Region r = getOrCreateRootRegion().createSubregion(name, getGlobalAttrs());
r.getAttributesMutator().setCacheLoader(new CacheLoader() {
public Object load(LoaderHelper helper)
throws CacheLoaderException {
throw new CacheLoaderException("Made it into the loader!");
}
public void close() {}
});
try {
r.get(key);
fail("get() should have thrown TimeoutException");
} catch (TimeoutException ex) {
// pass
}
}
});
}
/**
* get lock in one VM, try to invalidate in other
*/
public void testInvalidateLockTimeout() {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
final String name = this.getUniqueName();
final Object key = new Integer(5);
vm0.invoke(new CacheSerializableRunnable("Get lock") {
public void run2() throws CacheException {
Region r = getOrCreateRootRegion().createSubregion(name, getGlobalAttrs());
Lock lock = r.getDistributedLock(key);
lock.lock();
}
});
vm1.invoke(new CacheSerializableRunnable("Lock timeout invalidating entry") {
public void run2() throws CacheException {
getOrCreateRootRegion().getCache().setLockTimeout(2);
Region r = getOrCreateRootRegion().createSubregion(name, getGlobalAttrs());
try {
r.invalidate(key);
fail("invalidate() should have thrown TimeoutException");
} catch (TimeoutException ex) {
// pass
}
}
});
}
/**
* get lock in one VM, try to destroy in other
*/
public void testDestroyLockTimeout() {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
final String name = this.getUniqueName();
final Object key = new Integer(5);
vm0.invoke(new CacheSerializableRunnable("Get lock") {
public void run2() throws CacheException {
Region r = getOrCreateRootRegion().createSubregion(name, getGlobalAttrs());
Lock lock = r.getDistributedLock(key);
lock.lock();
r.put(key, "value");
}
});
vm1.invoke(new CacheSerializableRunnable("Lock timeout destroying entry") {
public void run2() throws CacheException {
getOrCreateRootRegion().getCache().setLockTimeout(2);
Region r = getOrCreateRootRegion().createSubregion(name, getGlobalAttrs());
r.get(key);
try {
r.destroy(key);
fail("destroy() should have thrown TimeoutException");
} catch (TimeoutException ex) {
// pass
}
}
});
}
/**
* get the lock, region.get(), region.put(), release lock
*/
public void testLockGetPut() throws CacheException {
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
final String name = this.getUniqueName() + "-GLOBAL";
final Object key = new Integer(5);
// First, create region & entry, and lock the entry, in Master VM
Region r = getOrCreateRootRegion().createSubregion(name, getGlobalAttrs());
Lock lock = r.getDistributedLock(key);
lock.lock();
r.create(key, "value 1");
assertEquals("value 1", r.get(key));
// Now, make sure a locking operation times out in another VM
vm0.invoke(new CacheSerializableRunnable("Unsuccessful locking operation") {
public void run2() throws CacheException {
try {
getOrCreateRootRegion().getCache().setLockTimeout(2);
Region r2 = getOrCreateRootRegion().createSubregion(name, getGlobalAttrs());
assertEquals("value 1", r2.get(key));
r2.put(key, "wrong value");
fail("put() should have thrown TimeoutException");
} catch (TimeoutException ex) {
// pass
}
}
});
// Now, in Master, do another locking operation, then release the lock
r.put(key, "value 2");
lock.unlock();
// Finally, successfully perform a locking in other VM
vm1.invoke(new CacheSerializableRunnable("Successful locking operation") {
public void run2() throws CacheException {
getOrCreateRootRegion().getCache().setLockTimeout(2);
Region r2 = getOrCreateRootRegion().createSubregion(name, getGlobalAttrs());
assertEquals("value 2", r2.get(key));
r2.put(key, "value 3");
}
});
assertEquals("value 3", r.get(key));
}
/**
* Test Region.getRegionDistributedLock(), calling lock() and then unlock()
*/
public void testRegionDistributedLockSimple() throws CacheException
{
final String name = this.getUniqueName();
Region r = getOrCreateRootRegion().createSubregion(name, getGlobalAttrs());
Lock lock = r.getRegionDistributedLock();
lock.lock();
lock.unlock();
}
}