package org.infinispan.jcache;
import static org.infinispan.jcache.util.JCacheTestingUtil.getEntryCount;
import static org.infinispan.jcache.util.JCacheTestingUtil.sleep;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.cache.Cache;
import javax.cache.configuration.FactoryBuilder;
import javax.cache.configuration.MutableCacheEntryListenerConfiguration;
import javax.cache.event.CacheEntryCreatedListener;
import javax.cache.event.CacheEntryEvent;
import javax.cache.event.CacheEntryEventFilter;
import javax.cache.event.CacheEntryListenerException;
import javax.cache.event.CacheEntryRemovedListener;
import javax.cache.event.CacheEntryUpdatedListener;
import javax.cache.processor.EntryProcessor;
import javax.cache.processor.EntryProcessorException;
import javax.cache.processor.MutableEntry;
import org.infinispan.test.MultipleCacheManagersTest;
import org.testng.annotations.Test;
/**
* Base class for clustered JCache tests. Implementations must provide cache references.
*
* @author Matej Cimbora
*/
@Test(testName = "org.infinispan.jcache.AbstractTwoCachesBasicOpsTest", groups = "functional")
public abstract class AbstractTwoCachesBasicOpsTest extends MultipleCacheManagersTest {
@Test
public void testCacheManagerXmlConfig(Method m) {
Cache<String, String> cache = getCache1(m);
cache.put("key1", "val1");
assertEquals(cache.get("key1"), "val1");
}
@Test
public void testMultipleCacheManagersXmlConfig(Method m) {
Cache<String, String> cache1 = getCache1(m);
Cache<String, String> cache2 = getCache2(m);
cache1.put("key1", "val1");
assertEquals(cache1.get("key1"), "val1");
assertEquals(cache2.get("key1"), "val1");
}
@Test
public void testRemove(Method m) {
Cache<String, String> cache1 = getCache1(m);
Cache<String, String> cache2 = getCache2(m);
cache1.put("key1", "val1");
assertTrue(cache1.containsKey("key1"));
assertTrue(cache2.containsKey("key1"));
cache2.remove("key1");
assertFalse(cache1.containsKey("key1"));
assertFalse(cache2.containsKey("key1"));
}
@Test
public void testRemoveAll(Method m) {
Cache<String, String> cache1 = getCache1(m);
Cache<String, String> cache2 = getCache2(m);
cache1.put("key1", "val1");
cache1.put("key2", "val2");
assertTrue(cache1.containsKey("key1"));
assertTrue(cache1.containsKey("key2"));
assertTrue(cache2.containsKey("key1"));
assertTrue(cache2.containsKey("key2"));
Set<String> keySet = new HashSet<>();
keySet.add("key1");
cache2.removeAll(keySet);
assertFalse(cache1.containsKey("key1"));
assertTrue(cache1.containsKey("key2"));
assertFalse(cache2.containsKey("key1"));
assertTrue(cache2.containsKey("key2"));
cache1.removeAll();
assertFalse(cache1.containsKey("key2"));
assertFalse(cache2.containsKey("key2"));
}
@Test
public void testPutAll(Method m) {
Cache<String, String> cache1 = getCache1(m);
Cache<String, String> cache2 = getCache2(m);
Map<String, String> entryMap = new HashMap<>();
entryMap.put("key1", "val1");
entryMap.put("key2", "val2");
cache1.putAll(entryMap);
assertTrue(cache1.containsKey("key1"));
assertTrue(cache1.containsKey("key2"));
assertTrue(cache2.containsKey("key1"));
assertTrue(cache2.containsKey("key2"));
}
@Test
public void testPutAllMapNullValuesNotAllowed(Method m) {
Cache<String, String> cache1 = getCache1(m);
Map<String, String> entryMap = new ConcurrentHashMap<>();
entryMap.put("key1", "val1");
entryMap.put("key2", "val2");
cache1.putAll(entryMap);
assertTrue(cache1.containsKey("key1"));
assertTrue(cache1.containsKey("key2"));
}
@Test (expectedExceptions = NullPointerException.class)
public void testPutAllNullMap(Method m) {
getCache1(m).putAll(null);
}
@Test (expectedExceptions = NullPointerException.class)
public void testPutAllMapWithNullKeys(Method m) {
Map<String, String> entryMap = new HashMap<>();
entryMap.put(null, "val1");
getCache1(m).putAll(entryMap);
}
@Test (expectedExceptions = NullPointerException.class)
public void testPutAllMapWithNullValues(Method m) {
Map<String, String> entryMap = new HashMap<>();
entryMap.put("key1", null);
getCache1(m).putAll(entryMap);
}
@Test
public void testPutIfAbsent(Method m) {
Cache<String, String> cache1 = getCache1(m);
Cache<String, String> cache2 = getCache2(m);
cache1.put("key1", "val1");
cache2.putIfAbsent("key1", "val3");
assertEquals(cache1.get("key1"), "val1");
assertEquals(cache2.get("key1"), "val1");
cache1.putIfAbsent("key2", "val2");
assertTrue(cache1.containsKey("key2"));
assertTrue(cache2.containsKey("key2"));
}
@Test
public void testGetAndPut(Method m) {
Cache<String, String> cache1 = getCache1(m);
Cache<String, String> cache2 = getCache2(m);
cache1.put("key1", "val1");
String result = cache2.getAndPut("key1", "val2");
assertEquals(result, "val1");
assertEquals(cache1.get("key1"), "val2");
assertEquals(cache2.get("key1"), "val2");
}
@Test
public void testGetAndRemove(Method m) {
Cache<String, String> cache1 = getCache1(m);
Cache<String, String> cache2 = getCache2(m);
cache1.put("key1", "val1");
String result = cache2.getAndRemove("key1");
assertEquals(result, "val1");
assertFalse(cache1.containsKey("key1"));
assertFalse(cache2.containsKey("key1"));
}
@Test
public void testGetAndReplace(Method m) {
Cache<String, String> cache1 = getCache1(m);
Cache<String, String> cache2 = getCache2(m);
cache1.put("key1", "val1");
String result = cache2.getAndReplace("key1", "val2");
assertEquals(result, "val1");
assertEquals(cache1.get("key1"), "val2");
assertEquals(cache2.get("key1"), "val2");
}
@Test
public void testGetAll(Method m) {
Cache<String, String> cache1 = getCache1(m);
Cache<String, String> cache2 = getCache2(m);
cache1.put("key1", "val1");
cache1.put("key2", "val2");
Set<String> keySet = new HashSet<>();
keySet.add("key1");
keySet.add("key2");
Map<String, String> result = cache2.getAll(keySet);
assertEquals(result.size(), 2);
assertTrue(result.containsKey("key1"));
assertTrue(result.containsKey("key2"));
result = cache1.getAll(keySet);
assertEquals(result.size(), 2);
assertTrue(result.containsKey("key1"));
assertTrue(result.containsKey("key2"));
}
@Test
public void testReplace(Method m) {
Cache<String, String> cache1 = getCache1(m);
Cache<String, String> cache2 = getCache2(m);
cache1.put("key1", "val1");
assertTrue(cache1.containsKey("key1"));
assertTrue(cache2.containsKey("key1"));
cache2.replace("key1", "val2");
assertEquals(cache1.get("key1"), "val2");
assertEquals(cache2.get("key1"), "val2");
cache1.replace("key1", "val2", "val3");
assertEquals(cache1.get("key1"), "val3");
assertEquals(cache2.get("key1"), "val3");
boolean result = cache2.replace("key1", "staleValue", "val4");
assertFalse(result);
assertEquals(cache1.get("key1"), "val3");
assertEquals(cache2.get("key1"), "val3");
}
@Test
public void testIterator(Method m) {
Cache<String, String> cache1 = getCache1(m);
Cache<String, String> cache2 = getCache2(m);
for (int i = 0; i < 5; i++) {
cache1.put(String.valueOf(i), "val");
}
assertEquals(getEntryCount(cache1.iterator()), 5);
assertEquals(getEntryCount(cache2.iterator()), 5);
}
@Test
public void testClusteredClear(Method m) {
Cache<String, String> cache1 = getCache1(m);
Cache<String, String> cache2 = getCache2(m);
cache1.put("key1", "val1");
cache1.put("key2", "val2");
cache2.clear();
assertNull(cache1.get("key1"));
assertNull(cache2.get("key1"));
assertNull(cache1.get("key2"));
assertNull(cache2.get("key2"));
}
@Test
public void testEntryProcessor(Method m) {
Cache<String, String> cache1 = getCache1(m);
Cache<String, String> cache2 = getCache2(m);
cache1.put("key1", "val1");
cache2.invoke("key1", new CustomEntryProcessor(), null);
assertEquals(cache1.get("key1"), "val1_processed");
assertEquals(cache2.get("key1"), "val1_processed");
}
@Test
public void testUpdatedListener(Method m) {
Cache<String, String> cache1 = getCache1(m);
Cache<String, String> cache2 = getCache2(m);
TestUpdatedListener listener = new TestUpdatedListener();
MutableCacheEntryListenerConfiguration conf = new MutableCacheEntryListenerConfiguration(FactoryBuilder.factoryOf(listener), null, false, false);
cache1.registerCacheEntryListener(conf);
cache1.put("key1", "val2");
cache2.put("key1", "val3");
sleep(1000);
assertEquals(listener.getInvocationCount(), 1);
listener.reset();
cache1.deregisterCacheEntryListener(conf);
cache2.put("key1", "val4");
sleep(1000);
assertEquals(listener.getInvocationCount(), 0);
}
@Test
public void testRemovedListener(Method m) {
Cache<String, String> cache1 = getCache1(m);
Cache<String, String> cache2 = getCache2(m);
TestRemovedListener listener = new TestRemovedListener();
MutableCacheEntryListenerConfiguration conf = new MutableCacheEntryListenerConfiguration(FactoryBuilder.factoryOf(listener), null, false, false);
cache1.registerCacheEntryListener(conf);
cache1.put("key1", "val3");
cache2.remove("key1");
sleep(1000);
assertEquals(listener.getInvocationCount(), 1);
listener.reset();
cache1.deregisterCacheEntryListener(conf);
cache1.put("key2", "val2");
cache2.remove("key2");
sleep(1000);
assertEquals(listener.getInvocationCount(), 0);
}
@Test
public void testCreatedListener(Method m) {
Cache<String, String> cache1 = getCache1(m);
Cache<String, String> cache2 = getCache2(m);
TestCreatedListener listener = new TestCreatedListener();
MutableCacheEntryListenerConfiguration conf = new MutableCacheEntryListenerConfiguration(FactoryBuilder.factoryOf(listener), null, false, false);
cache1.registerCacheEntryListener(conf);
cache2.put("key1", "val3");
sleep(1000);
assertEquals(listener.getInvocationCount(), 1);
listener.reset();
cache1.deregisterCacheEntryListener(conf);
cache2.put("key2", "val2");
sleep(1000);
assertEquals(listener.getInvocationCount(), 0);
}
@Test
public void testListenerDiscardingFilter(Method m) {
Cache<String, String> cache1 = getCache1(m);
Cache<String, String> cache2 = getCache2(m);
DiscardingCacheEntryEventFilter filter = new DiscardingCacheEntryEventFilter();
TestCreatedListener listener1 = new TestCreatedListener();
TestCreatedListener listener2 = new TestCreatedListener();
MutableCacheEntryListenerConfiguration conf1 = new MutableCacheEntryListenerConfiguration(FactoryBuilder.factoryOf(listener1), null, false, false);
MutableCacheEntryListenerConfiguration conf2 = new MutableCacheEntryListenerConfiguration(FactoryBuilder.factoryOf(listener2), FactoryBuilder.factoryOf(filter), false, false);
cache1.registerCacheEntryListener(conf1);
cache2.registerCacheEntryListener(conf2);
cache2.put("key1", "val3");
sleep(1000);
assertEquals(listener1.getInvocationCount(), 1);
assertEquals(listener2.getInvocationCount(), 0);
listener1.reset();
cache1.deregisterCacheEntryListener(conf1);
cache2.put("key2", "val2");
sleep(1000);
assertEquals(listener1.getInvocationCount(), 0);
}
private static class DiscardingCacheEntryEventFilter implements CacheEntryEventFilter, Serializable {
@Override
public boolean evaluate(CacheEntryEvent event) throws CacheEntryListenerException {
return false;
}
}
private static class TestUpdatedListener extends InvocationAwareListener implements CacheEntryUpdatedListener, Serializable {
@Override
public void onUpdated(Iterable iterable) throws CacheEntryListenerException {
Iterator iterator = iterable.iterator();
while (iterator.hasNext()) {
iterator.next();
invocationCount++;
}
}
}
private static class TestCreatedListener extends InvocationAwareListener implements CacheEntryCreatedListener, Serializable {
@Override
public void onCreated(Iterable iterable) throws CacheEntryListenerException {
Iterator iterator = iterable.iterator();
while (iterator.hasNext()) {
iterator.next();
invocationCount++;
}
}
}
private static class TestRemovedListener extends InvocationAwareListener implements CacheEntryRemovedListener, Serializable {
@Override
public void onRemoved(Iterable iterable) throws CacheEntryListenerException {
Iterator iterator = iterable.iterator();
while (iterator.hasNext()) {
iterator.next();
invocationCount++;
}
}
}
private abstract static class InvocationAwareListener {
protected int invocationCount;
public int getInvocationCount() {
return invocationCount;
}
public void reset() {
invocationCount = 0;
}
}
private static class CustomEntryProcessor implements EntryProcessor {
@Override
public Object process(MutableEntry entry, Object... arguments) throws EntryProcessorException {
entry.setValue(entry.getValue() + "_processed");
return entry;
}
}
public abstract Cache getCache1(Method m);
public abstract Cache getCache2(Method m);
}