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