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);
}
}