package org.infinispan.api.mvcc; import static org.testng.AssertJUnit.assertEquals; import java.util.function.Consumer; import org.infinispan.Cache; import org.infinispan.configuration.cache.CacheMode; import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.distribution.MagicKey; import org.infinispan.test.MultipleCacheManagersTest; import org.infinispan.test.fwk.CleanupAfterMethod; import org.infinispan.transaction.LockingMode; import org.infinispan.transaction.TransactionProtocol; import org.testng.annotations.Test; @Test(groups = "functional", testName = "api.mvcc.PutForExternalReadLockCleanupTest") @CleanupAfterMethod public class PutForExternalReadLockCleanupTest extends MultipleCacheManagersTest { private static final String VALUE = "v"; private static final Consumer<ConfigurationBuilder> ENABLE_L1 = c -> c.clustering().l1().enable(); private String name; private Consumer<ConfigurationBuilder> amendConfiguration; @Override public Object[] factory() { return new Object[] { new PutForExternalReadLockCleanupTest("NonTx").transactional(false), new PutForExternalReadLockCleanupTest("Optimistic").transactional(true).lockingMode(LockingMode.OPTIMISTIC), new PutForExternalReadLockCleanupTest("Pessimistic").transactional(true).lockingMode(LockingMode.PESSIMISTIC), new PutForExternalReadLockCleanupTest("TotalOrder").transactional(true).totalOrder(true), new PutForExternalReadLockCleanupTest("NonTxL1", ENABLE_L1).transactional(false), new PutForExternalReadLockCleanupTest("OptimisticL1", ENABLE_L1).transactional(true).lockingMode(LockingMode.OPTIMISTIC), new PutForExternalReadLockCleanupTest("PessimisticL1", ENABLE_L1).transactional(true).lockingMode(LockingMode.PESSIMISTIC), new PutForExternalReadLockCleanupTest("TotalOrderL1", ENABLE_L1).transactional(true).totalOrder(true), }; } public PutForExternalReadLockCleanupTest() {} private PutForExternalReadLockCleanupTest(String name) { this(name, c -> {}); } private PutForExternalReadLockCleanupTest(String name, Consumer<ConfigurationBuilder> amendConfiguration) { this.name = name; this.amendConfiguration = amendConfiguration; } @Override protected String parameters() { return "[" + name + "]"; } public void testLockCleanupOnBackup() { doTest(false); } public void testLockCleanuponOwner() { doTest(true); } @Override protected void createCacheManagers() { ConfigurationBuilder c = getDefaultClusteredCacheConfig(CacheMode.DIST_SYNC, transactional); c.clustering().hash().numSegments(10).numOwners(1); c.clustering().l1().disable(); if (totalOrder != null && totalOrder.booleanValue()) { c.transaction().transactionProtocol(TransactionProtocol.TOTAL_ORDER); } amendConfiguration.accept(c); createClusteredCaches(2, c); } private void doTest(boolean owner) { final Cache<MagicKey, String> cache1 = cache(0); final Cache<MagicKey, String> cache2 = cache(1); final MagicKey magicKey = new MagicKey(cache1); if (owner) { cache1.putForExternalRead(magicKey, VALUE); } else { cache2.putForExternalRead(magicKey, VALUE); } eventually(new Condition() { @Override public boolean isSatisfied() throws Exception { return cache1.containsKey(magicKey) && cache2.containsKey(magicKey); } }); assertEquals(VALUE, cache1.get(magicKey)); assertEquals(VALUE, cache2.get(magicKey)); assertNotLocked(magicKey); } }