blob: 5fdff7b475bc3f941016adadf57d49d6d69f204a [file] [log] [blame]
package brooklyn.internal.storage.impl;
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.util.AbstractMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import brooklyn.internal.storage.BrooklynStorage;
import brooklyn.internal.storage.DataGrid;
import brooklyn.internal.storage.Reference;
import com.beust.jcommander.internal.Lists;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
public class BrooklynStorageImplTest {
private DataGrid datagrid;
private BrooklynStorage storage;
@BeforeMethod(alwaysRun=true)
public void setUp() throws Exception {
// TODO Note that InmemoryDatagrid's ConcurrentMap currently returns snapshot for entrySet() and values()
// so the tests here aren't particularly good for confirming it'll work against a real datagrid...
datagrid = new InmemoryDatagrid();
storage = new BrooklynStorageImpl(datagrid);
}
@Test
public void testReferenceGetAndSet() throws Exception {
Reference<Object> ref = storage.getReference("mykey");
assertNull(ref.get());
assertTrue(ref.isNull());
assertFalse(ref.contains("different"));
assertTrue(ref.contains(null));
ref.set("myval");
assertEqualsCommutative(ref.get(), storage.getReference("mykey").get(), "myval");
assertFalse(ref.isNull());
assertFalse(ref.contains("different"));
assertTrue(ref.contains("myval"));
ref.clear();
assertNull(ref.get());
}
@Test
public void testReferenceAcceptsNullValue() throws Exception {
Reference<Object> ref = storage.getReference("mykey");
ref.set(null);
assertNull(ref.get());
assertTrue(ref.isNull());
assertTrue(ref.contains(null));
}
@Test
public void testCreateMapReturnsSameEachTime() throws Exception {
storage.getMap("mykey").put("k1", "v1");
assertEqualsCommutative(storage.getMap("mykey"), ImmutableMap.of("k1", "v1"));
}
@Test
public void testMapOperations() throws Exception {
Map<Object, Object> map = storage.getMap("mykey");
map.put("k1", "v1");
assertEqualsCommutative(map, storage.getMap("mykey"), ImmutableMap.of("k1", "v1"));
assertEqualsCommutative(map.keySet(), storage.getMap("mykey").keySet(), ImmutableSet.of("k1"));
assertEqualsCommutative(ImmutableList.copyOf(map.values()), ImmutableList.copyOf(storage.getMap("mykey").values()), ImmutableList.of("v1"));
assertEquals(map.size(), 1);
assertEquals(map.get("k1"), "v1");
assertTrue(map.containsKey("k1"));
assertTrue(map.containsValue("v1"));
assertFalse(map.containsKey("notthere"));
assertFalse(map.containsValue("notthere"));
assertFalse(map.isEmpty());
assertEqualsCommutative(map, storage.getMap("mykey"), ImmutableMap.of("k1", "v1"));
map.put("k1", "v2");
assertEquals(map.get("k1"), "v2");
assertEquals(map.size(), 1);
assertEqualsCommutative(map, storage.getMap("mykey"), ImmutableMap.of("k1", "v2"));
map.remove("k1");
assertTrue(map.isEmpty());
assertEquals(map.size(), 0);
assertEquals(map.get("k1"), null);
assertEqualsCommutative(map, storage.getMap("mykey"), ImmutableMap.of());
map.putAll(ImmutableMap.of("k1", "v3", "k2", "v4"));
assertEqualsCommutative(map, storage.getMap("mykey"), ImmutableMap.of("k1", "v3", "k2", "v4"));
map.clear();
assertEquals(map.size(), 0);
assertEqualsCommutative(map, storage.getMap("mykey"), ImmutableMap.of());
}
// TODO InmemoryDatagrid's map.entrySet() returns an immutable snapshot
// Want to test against a real datagrid instead.
@Test(enabled=false)
public void testMapEntrySetIterator() throws Exception {
Map<Object,Object> map = storage.getMap("mykey");
map.put("k1", "v1");
assertEquals(iteratorToList(map.entrySet().iterator()), ImmutableList.of(newMapEntry("k1", "v1")));
// Remove entry while iterating; will use snapshot so still contain k1
Iterator<Map.Entry<Object, Object>> iter1 = map.entrySet().iterator();
assertTrue(iter1.hasNext());
map.remove("k1");
assertEquals(iteratorToList(iter1), ImmutableList.of(newMapEntry("k1", "v1")));
// iter.remove removes value
map.clear();
map.put("k1", "v1"); map.put("k2", "v2");
Iterator<Map.Entry<Object, Object>> iter2 = map.entrySet().iterator();
assertEquals(newMapEntry("k1", "v1"), iter2.next());
iter2.remove();
assertEquals(newMapEntry("k2", "v2"), iter2.next());
assertEqualsCommutative(map, storage.getMap("mykey"), ImmutableMap.of("k2", "v2"));
// iter.remove when value has already been removed
map.clear();
map.put("k1", "v1"); map.put("k2", "v2");
Iterator<Map.Entry<Object, Object>> iter3 = map.entrySet().iterator();
assertEquals(newMapEntry("k1", "v1"), iter3.next());
map.remove("k1");
iter3.remove();
assertEquals(newMapEntry("k2", "v2"), iter3.next());
assertEqualsCommutative(map, storage.getMap("mykey"), ImmutableMap.of("k2", "v2"));
// iter.remove when value has already been removed, but was then re-added!
// TODO is this really the desired behaviour?
map.clear();
map.put("k1", "v1"); map.put("k2", "v2");
Iterator<Map.Entry<Object, Object>> iter4 = map.entrySet().iterator();
assertEquals(newMapEntry("k1", "v1"), iter4.next());
map.remove("k1");
map.put("k1", "v1b");
iter4.remove();
assertEquals(newMapEntry("k2", "v2"), iter4.next());
assertEqualsCommutative(map, storage.getMap("mykey"), ImmutableMap.of("k2", "v2"));
}
@Test
public void testMapKeySetIterator() throws Exception {
Map<Object,Object> map = storage.getMap("mykey");
map.put("k1", "v1");
assertEquals(iteratorToList(map.keySet().iterator()), ImmutableList.of("k1"));
// Remove key while iterating; will use snapshot so still contain k1
Iterator<Object> iter1 = map.keySet().iterator();
assertTrue(iter1.hasNext());
map.remove("k1");
assertEquals(iteratorToList(iter1), ImmutableList.of("k1"));
// iter.remove removes value
map.clear();
map.put("k1", "v1"); map.put("k2", "v2");
Iterator<Object> iter2 = map.keySet().iterator();
assertEquals("k1", iter2.next());
iter2.remove();
assertEquals("k2", iter2.next());
assertEqualsCommutative(map, storage.getMap("mykey"), ImmutableMap.of("k2", "v2"));
// iter.remove when value has already been removed
map.clear();
map.put("k1", "v1"); map.put("k2", "v2");
Iterator<Object> iter3 = map.keySet().iterator();
assertEquals("k1", iter3.next());
map.remove("k1");
iter3.remove();
assertEquals("k2", iter3.next());
assertEqualsCommutative(map, storage.getMap("mykey"), ImmutableMap.of("k2", "v2"));
// iter.remove when value has already been removed, but was then re-added!
// TODO is this really the desired behaviour?
map.clear();
map.put("k1", "v1"); map.put("k2", "v2");
Iterator<Object> iter4 = map.keySet().iterator();
assertEquals("k1", iter4.next());
map.remove("k1");
map.put("k1", "v1b");
iter4.remove();
assertEquals("k2", iter4.next());
assertEqualsCommutative(map, storage.getMap("mykey"), ImmutableMap.of("k2", "v2"));
}
// TODO InmemoryDatagrid.getMap().values() returning snapshot, so iter.remove not supported.
// Want to test against a real datagrid instead.
@Test(enabled=false)
public void testMapValuesIterator() throws Exception {
Map<Object,Object> map = storage.getMap("mykey");
map.put("k1", "v1");
assertEquals(ImmutableList.copyOf(iteratorToList(map.values().iterator())), ImmutableList.of("v1"));
// Remove key while iterating; will use snapshot so still contain k1
Iterator<Object> iter1 = map.values().iterator();
assertTrue(iter1.hasNext());
map.remove("v1");
assertEquals(ImmutableList.copyOf(iteratorToList(iter1)), ImmutableList.of("v1"));
// iter.remove removes value
map.clear();
map.put("k1", "v1"); map.put("k2", "v2");
Iterator<Object> iter2 = map.values().iterator();
assertEquals("v1", iter2.next());
iter2.remove();
assertEquals("v2", iter2.next());
assertEqualsCommutative(map, storage.getMap("mykey"), ImmutableMap.of("k2", "v2"));
// iter.remove when value has already been removed
map.clear();
map.put("k1", "v1"); map.put("k2", "v2");
Iterator<Object> iter3 = map.values().iterator();
assertEquals("v1", iter3.next());
map.remove("k1");
iter3.remove();
assertEquals("v2", iter3.next());
assertEqualsCommutative(map, storage.getMap("mykey"), ImmutableMap.of("k2", "v2"));
// iter.remove when value has already been removed, but was then re-added!
// TODO is this really the desired behaviour?
map.clear();
map.put("k1", "v1"); map.put("k2", "v2");
Iterator<Object> iter4 = map.values().iterator();
assertEquals("v1", iter4.next());
map.remove("k1");
map.put("k1", "v1b");
iter4.remove();
assertEquals("v2", iter4.next());
assertEqualsCommutative(map, storage.getMap("mykey"), ImmutableMap.of("k2", "v2"));
}
private void assertEqualsCommutative(Object o1, Object o2) {
assertEquals(o1, o2);
assertEquals(o2, o1);
}
private void assertEqualsCommutative(Object o1, Object o2, Object o3) {
assertEquals(o1, o3);
assertEquals(o3, o1);
assertEquals(o2, o3);
assertEquals(o3, o2);
}
private <T> List<T> iteratorToList(Iterator<T> iter) {
List<T> result = Lists.newArrayList();
while (iter.hasNext()) {
result.add(iter.next());
}
return result;
}
private <K,V> Map.Entry<K,V> newMapEntry(K k, V v) {
return new AbstractMap.SimpleEntry<K, V>(k, v);
}
}