package org.infinispan.api; import static org.infinispan.test.Exceptions.expectException; import static org.infinispan.test.TestingUtil.assertNoLocks; import static org.infinispan.test.TestingUtil.createMapEntry; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; import static org.testng.AssertJUnit.assertEquals; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Function; import org.infinispan.commons.util.ObjectDuplicator; import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.lifecycle.ComponentStatus; import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.test.SingleCacheManagerTest; import org.infinispan.test.TestingUtil; import org.infinispan.test.fwk.TestCacheManagerFactory; import org.testng.annotations.Test; /** * @author Mircea Markus * @since 5.1 */ @Test(groups = "functional", testName = "api.APINonTxTest") public class APINonTxTest extends SingleCacheManagerTest { @Override protected EmbeddedCacheManager createCacheManager() throws Exception { // start a single cache instance ConfigurationBuilder c = getDefaultStandaloneCacheConfig(false); EmbeddedCacheManager cm = TestCacheManagerFactory.createCacheManager(false); cm.defineConfiguration("test", c.build()); cache = cm.getCache("test"); return cm; } public void testConvenienceMethods() { String key = "key", value = "value"; Map<String, String> data = new HashMap<>(); data.put(key, value); assertNull(cache.get(key)); assertCacheIsEmpty(); cache.put(key, value); assertEquals(value, cache.get(key)); assertTrue(cache.keySet().contains(key)); assertTrue(cache.values().contains(value)); assertCacheSize(1); cache.remove(key); assertNull(cache.get(key)); assertCacheIsEmpty(); cache.putAll(data); assertEquals(value, cache.get(key)); assertTrue(cache.keySet().contains(key)); assertTrue(cache.values().contains(value)); assertCacheSize(1); } public void testStopClearsData() throws Exception { String key = "key", value = "value"; cache.put(key, value); assertEquals(value, cache.get(key)); assertCacheSize(1); assertTrue(cache.keySet().contains(key)); assertTrue(cache.values().contains(value)); cache.stop(); assertEquals(ComponentStatus.TERMINATED, cache.getStatus()); cache.start(); assertFalse(cache.containsKey(key)); assertFalse(cache.keySet().contains(key)); assertFalse(cache.values().contains(value)); assertCacheIsEmpty(); } /** * Tests basic eviction */ public void testEvict() { String key1 = "keyOne", key2 = "keyTwo", value = "value"; cache.put(key1, value); cache.put(key2, value); assertTrue(cache.containsKey(key1)); assertTrue(cache.containsKey(key2)); assertCacheSize(2); assertTrue(cache.keySet().contains(key1)); assertTrue(cache.keySet().contains(key2)); assertTrue(cache.values().contains(value)); // evict two cache.evict(key2); assertTrue(cache.containsKey(key1)); assertFalse(cache.containsKey(key2)); assertCacheSize(1); assertTrue(cache.keySet().contains(key1)); assertFalse(cache.keySet().contains(key2)); assertTrue(cache.values().contains(value)); cache.evict(key1); assertFalse(cache.containsKey(key1)); assertFalse(cache.containsKey(key2)); assertFalse(cache.keySet().contains(key1)); assertFalse(cache.keySet().contains(key2)); assertFalse(cache.values().contains(value)); assertCacheIsEmpty(); } public void testUnsupportedKeyValueCollectionOperationsAddMethod() { final String key1 = "1", value1 = "one", key2 = "2", value2 = "two", key3 = "3", value3 = "three"; Map<String, String> m = new HashMap<>(); m.put(key1, value1); m.put(key2, value2); m.put(key3, value3); cache.putAll(m); Set<Object> keys = cache.keySet(); Collection<Object> values = cache.values(); //noinspection unchecked Collection<Object>[] collections = new Collection[]{keys, values}; Object newObj = new Object(); List<Object> newObjCol = new ArrayList<>(); newObjCol.add(newObj); for (Collection<Object> col : collections) { expectException(UnsupportedOperationException.class, () -> col.add(newObj)); expectException(UnsupportedOperationException.class, () -> col.addAll(newObjCol)); } } @Test(expectedExceptions = UnsupportedOperationException.class) public void testAddMethodsForEntryCollection() { final String key1 = "1", value1 = "one", key2 = "2", value2 = "two", key3 = "3", value3 = "three"; Map<String, String> m = new HashMap<>(); m.put(key1, value1); m.put(key2, value2); m.put(key3, value3); cache.putAll(m); Set<Map.Entry<Object, Object>> entries = cache.entrySet(); entries.add(createMapEntry("4", "four")); } public void testRemoveMethodOfKeyValueEntryCollections() { final String key1 = "1", value1 = "one", key2 = "2", value2 = "two", key3 = "3", value3 = "three"; Map<String, String> m = new HashMap<>(); m.put(key1, value1); m.put(key2, value2); m.put(key3, value3); cache.putAll(m); Set<Object> keys = cache.keySet(); keys.remove(key1); assertCacheSize(2); Collection<Object> values = cache.values(); values.remove(value2); assertCacheSize(1); Set<Map.Entry<Object, Object>> entries = cache.entrySet(); entries.remove(TestingUtil.<Object, Object>createMapEntry(key3, value3)); assertCacheIsEmpty(); } public void testClearMethodOfKeyCollection() { final String key1 = "1", value1 = "one", key2 = "2", value2 = "two", key3 = "3", value3 = "three"; Map<String, String> m = new HashMap<>(); m.put(key1, value1); m.put(key2, value2); m.put(key3, value3); cache.putAll(m); Set<Object> keys = cache.keySet(); keys.clear(); assertCacheIsEmpty(); } public void testClearMethodOfValuesCollection() { final String key1 = "1", value1 = "one", key2 = "2", value2 = "two", key3 = "3", value3 = "three"; Map<String, String> m = new HashMap<>(); m.put(key1, value1); m.put(key2, value2); m.put(key3, value3); cache.putAll(m); Collection<Object> values = cache.values(); values.clear(); assertCacheIsEmpty(); } public void testClearMethodOfEntryCollection() { final String key1 = "1", value1 = "one", key2 = "2", value2 = "two", key3 = "3", value3 = "three"; Map<String, String> m = new HashMap<>(); m.put(key1, value1); m.put(key2, value2); m.put(key3, value3); cache.putAll(m); Set<Map.Entry<Object, Object>> entries = cache.entrySet(); entries.clear(); assertCacheIsEmpty(); } public void testRemoveAllMethodOfKeyCollection() { final String key1 = "1", value1 = "one", key2 = "2", value2 = "two", key3 = "3", value3 = "three"; Map<String, String> m = new HashMap<>(); m.put(key1, value1); m.put(key2, value2); m.put(key3, value3); cache.putAll(m); List<String> keyCollection = new ArrayList<>(2); keyCollection.add(key2); keyCollection.add(key3); Collection<Object> keys = cache.keySet(); keys.removeAll(keyCollection); assertCacheSize(1); } public void testRemoveAllMethodOfValuesCollection() { final String key1 = "1", value1 = "one", key2 = "2", value2 = "two", key3 = "3", value3 = "three"; Map<String, String> m = new HashMap<>(); m.put(key1, value1); m.put(key2, value2); m.put(key3, value3); cache.putAll(m); List<String> valueCollection = new ArrayList<>(2); valueCollection.add(value1); valueCollection.add(value2); Collection<Object> values = cache.values(); values.removeAll(valueCollection); assertCacheSize(1); } public void testRemoveAllMethodOfEntryCollection() { final String key1 = "1", value1 = "one", key2 = "2", value2 = "two", key3 = "3", value3 = "three"; Map<String, String> m = new HashMap<>(); m.put(key1, value1); m.put(key2, value2); m.put(key3, value3); cache.putAll(m); List<Map.Entry> entryCollection = new ArrayList<>(2); entryCollection.add(createMapEntry(key1, value1)); entryCollection.add(createMapEntry(key3, value3)); Set<Map.Entry<Object, Object>> entries = cache.entrySet(); entries.removeAll(entryCollection); assertCacheSize(1); } public void testRetainAllMethodOfKeyCollection() { final String key1 = "1", value1 = "one", key2 = "2", value2 = "two", key3 = "3", value3 = "three"; Map<String, String> m = new HashMap<>(); m.put(key1, value1); m.put(key2, value2); m.put(key3, value3); cache.putAll(m); List<String> keyCollection = new ArrayList<>(2); keyCollection.add(key2); keyCollection.add(key3); keyCollection.add("6"); Collection<Object> keys = cache.keySet(); keys.retainAll(keyCollection); assertCacheSize(2); } public void testRetainAllMethodOfValuesCollection() { final String key1 = "1", value1 = "one", key2 = "2", value2 = "two", key3 = "3", value3 = "three"; Map<String, String> m = new HashMap<>(); m.put(key1, value1); m.put(key2, value2); m.put(key3, value3); cache.putAll(m); List<String> valueCollection = new ArrayList<>(2); valueCollection.add(value1); valueCollection.add(value2); valueCollection.add("5"); Collection<Object> values = cache.values(); values.retainAll(valueCollection); assertCacheSize(2); } public void testRetainAllMethodOfEntryCollection() { final String key1 = "1", value1 = "one", key2 = "2", value2 = "two", key3 = "3", value3 = "three"; Map<String, String> m = new HashMap<>(); m.put(key1, value1); m.put(key2, value2); m.put(key3, value3); cache.putAll(m); List<Map.Entry> entryCollection = new ArrayList<>(3); entryCollection.add(createMapEntry(key1, value1)); entryCollection.add(createMapEntry(key3, value3)); entryCollection.add(createMapEntry("4", "5")); Set<Map.Entry<Object, Object>> entries = cache.entrySet(); entries.retainAll(entryCollection); assertCacheSize(2); } public void testEntrySetValueFromEntryCollections() { final String key1 = "1", value1 = "one", key2 = "2", value2 = "two", key3 = "3", value3 = "three"; Map<String, String> m = new HashMap<>(); m.put(key1, value1); m.put(key2, value2); m.put(key3, value3); cache.putAll(m); Set<Map.Entry<Object, Object>> entries = cache.entrySet(); Object newObj = new Object(); for (Map.Entry<Object, Object> entry : entries) { entry.setValue(newObj); } assertCacheSize(3); assertEquals(newObj, cache.get(key1)); assertEquals(newObj, cache.get(key2)); assertEquals(newObj, cache.get(key3)); } public void testKeyValueEntryCollections() { String key1 = "1", value1 = "one", key2 = "2", value2 = "two", key3 = "3", value3 = "three"; Map<String, String> m = new HashMap<>(); m.put(key1, value1); m.put(key2, value2); m.put(key3, value3); cache.putAll(m); assertCacheSize(3); Set<Object> expKeys = new HashSet<>(); expKeys.add(key1); expKeys.add(key2); expKeys.add(key3); Set<Object> expValues = new HashSet<>(); expValues.add(value1); expValues.add(value2); expValues.add(value3); Set expKeyEntries = ObjectDuplicator.duplicateSet(expKeys); Set expValueEntries = ObjectDuplicator.duplicateSet(expValues); Set<Object> keys = cache.keySet(); for (Object key : keys) { assertTrue(expKeys.remove(key)); } assertTrue(expKeys.isEmpty(), "Did not see keys " + expKeys + " in iterator!"); Collection<Object> values = cache.values(); for (Object value : values) { assertTrue(expValues.remove(value)); } assertTrue(expValues.isEmpty(), "Did not see keys " + expValues + " in iterator!"); Set<Map.Entry<Object, Object>> entries = cache.entrySet(); for (Map.Entry entry : entries) { assertTrue(expKeyEntries.remove(entry.getKey())); assertTrue(expValueEntries.remove(entry.getValue())); } assertTrue(expKeyEntries.isEmpty(), "Did not see keys " + expKeyEntries + " in iterator!"); assertTrue(expValueEntries.isEmpty(), "Did not see keys " + expValueEntries + " in iterator!"); } public void testSizeAndContents() throws Exception { String key = "key", value = "value"; assertCacheIsEmpty(); assertFalse(cache.containsKey(key)); assertFalse(cache.keySet().contains(key)); assertFalse(cache.values().contains(value)); cache.put(key, value); assertCacheSize(1); assertTrue(cache.containsKey(key)); assertTrue(cache.containsKey(key)); assertTrue(cache.keySet().contains(key)); assertTrue(cache.values().contains(value)); assertEquals(value, cache.remove(key)); assertTrue(cache.isEmpty()); assertCacheIsEmpty(); assertFalse(cache.containsKey(key)); assertFalse(cache.keySet().contains(key)); assertFalse(cache.values().contains(value)); Map<String, String> m = new HashMap<>(); m.put("1", "one"); m.put("2", "two"); m.put("3", "three"); cache.putAll(m); assertEquals("one", cache.get("1")); assertEquals("two", cache.get("2")); assertEquals("three", cache.get("3")); assertCacheSize(3); m = new HashMap<>(); m.put("1", "newvalue"); m.put("4", "four"); cache.putAll(m); assertEquals("newvalue", cache.get("1")); assertEquals("two", cache.get("2")); assertEquals("three", cache.get("3")); assertEquals("four", cache.get("4")); assertCacheSize(4); } public void testConcurrentMapMethods() { assertNull(cache.putIfAbsent("A", "B")); assertEquals("B", cache.putIfAbsent("A", "C")); assertEquals("B", cache.get("A")); assertFalse(cache.remove("A", "C")); assertTrue(cache.containsKey("A")); assertTrue(cache.remove("A", "B")); assertFalse(cache.containsKey("A")); cache.put("A", "B"); assertFalse(cache.replace("A", "D", "C")); assertEquals("B", cache.get("A")); assertTrue(cache.replace("A", "B", "C")); assertEquals("C", cache.get("A")); assertEquals("C", cache.replace("A", "X")); assertNull(cache.replace("X", "A")); assertFalse(cache.containsKey("X")); } public void testPutNullKeyParameter() { expectException(NullPointerException.class, () -> cache.put(null, null)); } public void testPutNullValueParameter() { expectException(NullPointerException.class, () -> cache.put("hello", null)); } @SuppressWarnings("ConstantConditions") public void testReplaceNullKeyParameter() { expectException(NullPointerException.class, "Null keys are not supported!", () -> cache.replace(null, "X")); expectException(NullPointerException.class, "Null keys are not supported!", () -> cache.replace(null, "X", "Y")); } @SuppressWarnings("ConstantConditions") public void testReplaceNullValueParameter() { expectException(NullPointerException.class, "Null values are not supported!", () -> cache.replace("hello", null, "X")); expectException(NullPointerException.class, "Null values are not supported!", () -> cache.replace("hello", "X", null)); } public void testPutIfAbsentLockCleanup() { assertNoLocks(cache); cache.put("key", "value"); assertNoLocks(cache); // This call should fail. cache.putForExternalRead("key", "value2"); assertNoLocks(cache); assertEquals("value", cache.get("key")); } private void assertCacheIsEmpty() { assertCacheSize(0); } private void assertCacheSize(int expectedSize) { assertEquals(expectedSize, cache.size()); assertEquals(expectedSize, cache.keySet().size()); assertEquals(expectedSize, cache.values().size()); assertEquals(expectedSize, cache.entrySet().size()); boolean isEmpty = expectedSize == 0; assertEquals(isEmpty, cache.isEmpty()); assertEquals(isEmpty, cache.keySet().isEmpty()); assertEquals(isEmpty, cache.values().isEmpty()); assertEquals(isEmpty, cache.entrySet().isEmpty()); } public void testGetOrDefault() { cache.put("A", "B"); assertEquals("K", cache.getOrDefault("Not there", "K")); } public void testMerge() throws Exception { cache.put("A", "B"); // replace cache.merge("A", "C", (oldValue, newValue) -> "" + oldValue + newValue); assertEquals("BC", cache.get("A")); // remove if null value after remapping cache.merge("A", "C", (oldValue, newValue) -> null); assertEquals(null, cache.get("A")); // put if absent cache.merge("F", "42", (oldValue, newValue) -> "" + oldValue + newValue); assertEquals("42", cache.get("F")); } public void testForEach() { cache.put("A", "B"); cache.put("C", "D"); List<String> values = new ArrayList<>(); BiConsumer<? super Object, ? super Object> collectKeyValues = (k, v) -> values.add("hello_" + k.toString() + v.toString()); cache.forEach(collectKeyValues); assertEquals(2, values.size()); assertEquals("hello_AB", values.get(0)); assertEquals("hello_CD", values.get(1)); } public void testComputeIfAbsent() { Function<Object, String> mappingFunction = k -> k + " world"; assertEquals("hello world", cache.computeIfAbsent("hello", mappingFunction)); assertEquals("hello world", cache.get("hello")); Function<Object, String> functionAfterPut = k -> k + " happy"; // hello already exists so nothing should happen assertEquals("hello world", cache.computeIfAbsent("hello", functionAfterPut)); assertEquals("hello world", cache.get("hello")); Function<Object, String> functionMapsToNull = k -> null; assertNull( cache.computeIfAbsent("kaixo", functionMapsToNull), "with function mapping to null returns null"); assertNull(cache.get("kaixo"), "the key does not exist"); } public void testComputeIfPresent() { BiFunction<Object, Object, String> mappingFunction = (k, v) -> "hello_" + k + ":" + v; cache.put("es", "hola"); assertEquals("hello_es:hola", cache.computeIfPresent("es", mappingFunction)); assertEquals("hello_es:hola", cache.get("es")); BiFunction<Object, Object, String> mappingForNotPresentKey = (k, v) -> "absent_" + k + ":" + v; assertNull(cache.computeIfPresent("fr", mappingForNotPresentKey), "unexisting key should return null"); assertNull(cache.get("fr"), "unexisting key should return null"); BiFunction<Object, Object, String> mappingToNull = (k, v) -> null; assertNull(cache.computeIfPresent("es", mappingToNull), "mapping to null returns null"); assertNull(cache.get("es"), "the key is removed"); } public void testCompute() { BiFunction<Object, Object, String> mappingFunction = (k, v) -> "hello_" + k + ":" + v; cache.put("es", "hola"); assertEquals("hello_es:hola", cache.compute("es", mappingFunction)); assertEquals("hello_es:hola", cache.get("es")); BiFunction<Object, Object, String> mappingForNotPresentKey = (k, v) -> "absent_" + k + ":" + v; assertEquals("absent_fr:null", cache.compute("fr", mappingForNotPresentKey)); assertEquals("absent_fr:null", cache.get("fr")); BiFunction<Object, Object, String> mappingToNull = (k, v) -> null; assertNull(cache.compute("es", mappingToNull), "mapping to null returns null"); assertNull(cache.get("es"), "the key is removed"); } public void testReplaceAll() { BiFunction<Object, Object, String> mappingFunction = (k, v) -> "hello_" + k + ":" + v; cache.put("es", "hola"); cache.put("cz", "ahoj"); cache.replaceAll(mappingFunction); assertEquals("hello_es:hola", cache.get("es")); assertEquals("hello_cz:ahoj", cache.get("cz")); BiFunction<Object, Object, String> mappingToNull = (k, v) -> null; expectException(NullPointerException.class, () -> cache.replaceAll(mappingToNull)); assertEquals("hello_es:hola", cache.get("es")); assertEquals("hello_cz:ahoj", cache.get("cz")); } public void testFalseEqualsKey() { assertNull(cache.get(new FalseEqualsKey("boo", 1))); cache.put(new FalseEqualsKey("boo", 1), "blah"); assertNull(cache.get(new FalseEqualsKey("boo", 1))); } static class FalseEqualsKey { final String name; final int value; FalseEqualsKey(String name, int value) { this.name = name; this.value = value; } @Override public int hashCode() { return 0; } @Override public boolean equals(Object obj) { return false; } } }