package org.infinispan.lock; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertTrue; import static org.testng.AssertJUnit.fail; import org.infinispan.commands.write.PutKeyValueCommand; import org.infinispan.configuration.cache.CacheMode; import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.context.InvocationContext; import org.infinispan.distribution.MagicKey; import org.infinispan.interceptors.base.BaseCustomInterceptor; import org.infinispan.interceptors.locking.NonTransactionalLockingInterceptor; import org.infinispan.test.MultipleCacheManagersTest; import org.infinispan.test.TestingUtil; import org.infinispan.util.concurrent.locks.LockManager; import org.testng.annotations.Test; /** * Tests if the {@link org.infinispan.remoting.inboundhandler.NonTotalOrderPerCacheInboundInvocationHandler} releases * locks if an exception occurs before the locking interceptor. * * @author Pedro Ruivo * @since 8.1 */ @Test(groups = "functional", testName = "lock.SimpleRemoteLockTest") public class SimpleRemoteLockTest extends MultipleCacheManagersTest { @Override protected void createCacheManagers() throws Throwable { ConfigurationBuilder builder = getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, false); builder.clustering().hash().numOwners(1); builder.clustering().stateTransfer().fetchInMemoryState(false); builder.customInterceptors().addInterceptor().before(NonTransactionalLockingInterceptor.class).interceptorClass(ExceptionInRemotePutInterceptor.class); createClusteredCaches(2, builder); } public void testExceptionBeforeLockingInterceptor() { final Object key = new MagicKey(cache(1)); final LockManager lockManager = TestingUtil.extractLockManager(cache(1)); assertFalse(lockManager.isLocked(key)); try { cache(0).put(key, "foo"); fail("Exception expected!"); } catch (Exception e) { //expected assertEquals("Induced Exception!", e.getCause().getMessage()); } //it sends the reply before invoke the finally. So, we need to use eventually :) eventually(() -> !lockManager.isLocked(key)); } public static class ExceptionInRemotePutInterceptor extends BaseCustomInterceptor { @Override public Object visitPutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable { if (ctx.isOriginLocal()) { return invokeNextInterceptor(ctx, command); } assertTrue(TestingUtil.extractLockManager(cache).isLocked(command.getKey())); throw new RuntimeException("Induced Exception!"); } } }