package org.infinispan.tx.lockreordering;
import org.infinispan.Cache;
import org.infinispan.commons.hash.MurmurHash2;
import org.infinispan.config.Configuration;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.test.SingleCacheManagerTest;
import org.infinispan.test.fwk.TestCacheManagerFactory;
import org.testng.annotations.Test;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CyclicBarrier;
/**
* @author Mircea Markus
* @since 5.1
*/
@Test (groups = "functional", testName = "tx.lockreordering.LocalLockReorderingTest")
public class LocalLockReorderingTest extends SingleCacheManagerTest {
private List<Integer> keys;
@Override
protected EmbeddedCacheManager createCacheManager() throws Exception {
final Configuration c = getDefaultStandaloneConfig(true);
c.fluent().transaction().cacheStopTimeout(1);
keys = generateKeys();
return TestCacheManagerFactory.createCacheManager(c);
}
public void testWithPut(Method m) throws Exception {
runTest(StresserThread.PUT_PERFORMER, cache, cache, keys, getThreadName(m));
}
public void testWithRemove(Method m) throws InterruptedException {
runTest(StresserThread.REMOVE_PERFORMER, cache, cache, keys, getThreadName(m));
}
public void testWithPutAll(Method m) throws InterruptedException {
runTest(StresserThread.PUT_ALL_PERFORMER, cache, cache, keys, getThreadName(m));
}
public void testMixed(Method m) throws InterruptedException {
runTest(StresserThread.MIXED_OPS_PERFORMER, cache, cache, keys, getThreadName(m));
}
static void runTest(StresserThread.OperationsPerformer ops, Cache c1, Cache c2, List keys, String threadNamePrefix) throws InterruptedException {
CyclicBarrier beforeCommit = new CyclicBarrier(2);
StresserThread st1 = new StresserThread(c1, keys, "t1", ops, beforeCommit, threadNamePrefix + "-1");
final ArrayList reversedKeys = new ArrayList(keys);
Collections.reverse(reversedKeys);
StresserThread st2 = new StresserThread(c2, reversedKeys, "t2", ops, beforeCommit, threadNamePrefix+"-2");
st1.start();
st2.start();
st1.join();
st2.join();
assert !st1.isError();
assert !st2.isError();
}
static List<Integer> generateKeys() {
List<Integer> keys;
/** this is what's used for inducing ordering */
MurmurHash2 hashFunction = new MurmurHash2();
keys = new ArrayList<Integer>(2);
int count = 0;
keys.add(count);
while (keys.size() < 2) {
final int hash = hashFunction.hash(++count);
if (!keys.contains(hash)) keys.add(count);
}
return keys;
}
private String getThreadName(Method m) {
return getClass().getSimpleName() + "." +m.getName();
}
}