package org.krakenapps.util; import static org.junit.Assert.*; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import org.junit.*; public class DirectoryMapTest { @Test public void testGetAndPutInRoot() { DirectoryMap<String> map = new DirectoryMap<String>(); assertEquals(null, map.get("key that doesn't exist")); assertEquals(null, map.put("rootfile.txt", "'rootfile.txt' contents")); assertEquals("'rootfile.txt' contents", map.get("rootfile.txt")); } @Test public void testGetAnoPutInSubdir() { DirectoryMap<Object> map = new DirectoryMap<Object>(); Object o = new Object(); assertEquals(null, map.put("subdir/subdirObj.obj", o)); assertEquals(o, map.get("subdir/subdirObj.obj")); } @Test public void testPutIfAbsent() { DirectoryMap<Object> map = new DirectoryMap<Object>(); Object o = new Object() { @Override public String toString(){ return "Initial Object."; } } ; assertEquals(null, map.putIfAbsent("subdir/1.obj", o)); assertEquals(o, map.get("subdir/1.obj")); Object o2 = new Object(); assertEquals(o, map.putIfAbsent("subdir/1.obj", o2)); assertEquals(o, map.get("subdir/1.obj")); } @Test public void testEntrySet() { DirectoryMap<Object> map = new DirectoryMap<Object>(); Object o0 = new Object() { @Override public String toString() { return "'Object #0'"; } }; Object o1 = new Object() { @Override public String toString() { return "'Object #1'"; } }; Object o2 = new Object() { @Override public String toString() { return "'Object #2'"; } }; assertEquals(null, map.put("root.obj", o0)); assertEquals(null, map.put("subdir/1.obj", o1)); assertEquals(null, map.put("subdir/2.obj", o2)); Set<Entry<String, Object>> set = map.entrySet("*"); assertEquals(3, set.size()); set = map.entrySet("root.obj"); Iterator<Entry<String, Object>> iter = set.iterator(); Entry<String, Object> item = iter.next(); assertEquals("root.obj", item.getKey()); assertEquals(o0, item.getValue()); assertEquals(1, set.size()); set = map.entrySet("*.obj"); iter = set.iterator(); assertTrue(iter.hasNext()); item = iter.next(); assertEquals("root.obj", item.getKey()); assertEquals(o0, item.getValue()); assertEquals(1, set.size()); assertFalse(iter.hasNext()); set = map.entrySet("*.else"); iter = set.iterator(); assertFalse(iter.hasNext()); set = map.entrySet("subdir/1.obj"); iter = set.iterator(); assertTrue(iter.hasNext()); item = iter.next(); assertEquals("subdir/1.obj", item.getKey()); assertEquals(o1, item.getValue()); assertEquals(1, set.size()); assertFalse(iter.hasNext()); set = map.entrySet("subdir/*.obj"); iter = set.iterator(); assertTrue(iter.hasNext()); item = iter.next(); assertEquals(2, set.size()); assertTrue(iter.hasNext()); assertEquals(null, map.put("subdir2/1.obj", o1)); assertEquals(null, map.put("subdir3/1.obj", o1)); assertEquals(null, map.put("subdir4/1.obj", o1)); assertEquals(null, map.put("subdir5/1.obj", o1)); set = map.entrySet("*/1.obj"); Set<String> expected = new HashSet<String>(); expected.add("subdir/1.obj"); expected.add("subdir2/1.obj"); expected.add("subdir3/1.obj"); expected.add("subdir4/1.obj"); expected.add("subdir5/1.obj"); Set<String> result = new HashSet<String>(); for (Entry<String, Object> e : set) result.add(e.getKey()); assertEquals(expected, result); set = map.entrySet(); int count = 0; for (iter = set.iterator(); iter.hasNext(); iter.next()) count++; assertEquals(map.size(), count); } @Test public void testEntrySetWithDeepSearch() { DirectoryMap<String> map = new DirectoryMap<String>(); assertEquals(null, map.put("A/1.obj", "OBJECT#1")); assertEquals(null, map.put("A/B/2.obj", "OBJECT#2")); assertEquals(null, map.put("A/B/C/3.obj", "OBJECT#3")); assertEquals(null, map.put("A/C/D/4.obj", "OBJECT#4")); assertEquals(null, map.put("B/C/D/4.obj", "OBJECT#5")); Set<String> expected = new HashSet<String>(); expected.add("OBJECT#1"); expected.add("OBJECT#2"); expected.add("OBJECT#3"); expected.add("OBJECT#4"); Set<Entry<String, String>> set = map.entrySet("A/*"); Set<String> result = new HashSet<String>(); for(Entry<String, String> e: set) { result.add(e.getValue()); } assertEquals(expected, result); } @Test public void testGetItems() { DirectoryMap<String> map = new DirectoryMap<String>(); assertEquals(null, map.put("A/1.obj", "OBJECT#1")); assertEquals(null, map.put("A/B/2.obj", "OBJECT#2")); assertEquals(null, map.put("A/B/C/3.obj", "OBJECT#3")); assertEquals(null, map.put("A/C/D/4.obj", "OBJECT#4")); assertEquals(null, map.put("B/C/D/4.obj", "OBJECT#5")); Set<Entry<String, String>> items = map.getItems("A/B/"); Entry<String, String> pair = items.iterator().next(); assertEquals("OBJECT#2", pair.getValue()); } @Test public void testRemoveObject() { DirectoryMap<Object> map = new DirectoryMap<Object>(); Object o0 = new Object() { @Override public String toString() { return "'Object #0'"; } }; Object o1 = new Object() { @Override public String toString() { return "'Object #1'"; } }; Object o2 = new Object() { @Override public String toString() { return "'Object #2'"; } }; assertEquals(null, map.put("root.obj", o0)); assertEquals(null, map.put("subdir/1.obj", o1)); assertEquals(null, map.put("subdir/2.obj", o2)); assertEquals(null, map.remove("nodir/1.obj")); assertEquals(o1, map.remove("subdir/1.obj")); } @Test public void testRemoveObjectObject() { DirectoryMap<Object> map = new DirectoryMap<Object>(); Object o0 = new Object() { @Override public String toString() { return "'Object #0'"; } }; Object o1 = new Object() { @Override public String toString() { return "'Object #1'"; } }; Object o2 = new Object() { @Override public String toString() { return "'Object #2'"; } }; assertEquals(null, map.put("root.obj", o0)); assertEquals(null, map.put("subdir/1.obj", o1)); assertEquals(null, map.put("subdir/2.obj", o2)); assertEquals(false, map.remove("nodir/1.obj", o1)); assertEquals(false, map.remove("subdir/1.obj", o2)); assertEquals(true, map.remove("root.obj", o0)); assertEquals(true, map.remove("subdir/1.obj", o1)); } @Test public void testReplaceStringT() { DirectoryMap<Object> map = new DirectoryMap<Object>(); Object o0 = new Object() { @Override public String toString() { return "'Object #0'"; } }; Object o1 = new Object() { @Override public String toString() { return "'Object #1'"; } }; Object o2 = new Object() { @Override public String toString() { return "'Object #2'"; } }; assertEquals(null, map.put("root.obj", o0)); assertEquals(null, map.replace("subdir/1.obj", o2)); assertEquals(null, map.put("subdir/1.obj", o1)); assertEquals(null, map.put("subdir/2.obj", o2)); assertEquals(o1, map.replace("subdir/1.obj", o2)); } @Test public void testReplaceStringTT() { DirectoryMap<Object> map = new DirectoryMap<Object>(); Object o0 = new Object() { @Override public String toString() { return "'Object #0'"; } }; Object o1 = new Object() { @Override public String toString() { return "'Object #1'"; } }; Object o2 = new Object() { @Override public String toString() { return "'Object #2'"; } }; assertEquals(null, map.put("root.obj", o0)); assertEquals(false, map.replace("subdir/1.obj", o1, o2)); assertEquals(null, map.put("subdir/1.obj", o1)); assertEquals(null, map.put("subdir/2.obj", o2)); assertEquals(false, map.replace("subdir/1.obj", o2, o1)); assertEquals(true, map.replace("subdir/1.obj", o1, o2)); } @Test public void testIsEmpty() { DirectoryMap<Object> map = new DirectoryMap<Object>(); assertTrue(map.isEmpty()); Object o0 = new Object() { @Override public String toString() { return "'Object #0'"; } }; assertEquals(null, map.put("root.obj", o0)); assertFalse(map.isEmpty()); assertEquals(o0, map.remove("root.obj")); assertTrue(map.isEmpty()); } @Test public void testClear() { DirectoryMap<Object> map = new DirectoryMap<Object>(); Object o0 = new Object() { @Override public String toString() { return "'Object #0'"; } }; Object o1 = new Object() { @Override public String toString() { return "'Object #1'"; } }; Object o2 = new Object() { @Override public String toString() { return "'Object #2'"; } }; assertEquals(null, map.put("root.obj", o0)); assertEquals(null, map.put("subdir/1.obj", o1)); assertEquals(null, map.put("subdir/2.obj", o2)); assertFalse(map.isEmpty()); map.clear(); assertTrue(map.isEmpty()); } @Test public void testContainsKey() { DirectoryMap<Object> map = new DirectoryMap<Object>(); Object o0 = new Object() { @Override public String toString() { return "'Object #0'"; } }; Object o1 = new Object() { @Override public String toString() { return "'Object #1'"; } }; Object o2 = new Object() { @Override public String toString() { return "'Object #2'"; } }; assertEquals(null, map.put("root.obj", o0)); assertFalse(map.containsKey("subdir/1.obj")); assertEquals(null, map.put("subdir/1.obj", o1)); assertEquals(null, map.put("subdir/2.obj", o2)); assertTrue(map.containsKey("subdir/1.obj")); } @Test public void testContainsValue() { DirectoryMap<Object> map = new DirectoryMap<Object>(); Object o0 = new Object() { @Override public String toString() { return "'Object #0'"; } }; Object o1 = new Object() { @Override public String toString() { return "'Object #1'"; } }; Object o2 = new Object() { @Override public String toString() { return "'Object #2'"; } }; assertEquals(null, map.put("root.obj", o0)); assertFalse(map.containsValue(o1)); assertEquals(null, map.put("subdir/1.obj", o1)); assertEquals(null, map.put("subdir/2.obj", o2)); assertTrue(map.containsValue(o1)); } @Test public void testKeySet() { DirectoryMap<Object> map = new DirectoryMap<Object>(); Object o0 = new Object() { @Override public String toString() { return "'Object #0'"; } }; Object o1 = new Object() { @Override public String toString() { return "'Object #1'"; } }; Object o2 = new Object() { @Override public String toString() { return "'Object #2'"; } }; assertEquals(null, map.put("root.obj", o0)); assertEquals(null, map.put("subdir/1.obj", o1)); assertEquals(null, map.put("subdir/2.obj", o2)); Set<String> expected = new HashSet<String>(Arrays.asList("root.obj", "subdir/1.obj", "subdir/2.obj")); Set<String> set = map.keySet(); assertEquals(expected, set); } @Test public void testPutAll() { Object o0 = new Object() { @Override public String toString() { return "'Object #0'"; } }; Object o1 = new Object() { @Override public String toString() { return "'Object #1'"; } }; Object o2 = new Object() { @Override public String toString() { return "'Object #2'"; } }; DirectoryMap<Object> expected = new DirectoryMap<Object>(); assertEquals(null, expected.put("root.obj", o0)); assertEquals(null, expected.put("subdir/1.obj", o1)); assertEquals(null, expected.put("subdir/2.obj", o2)); DirectoryMap<Object> map = new DirectoryMap<Object>(); assertEquals(null, map.put("root.obj", o0)); Map<String, Object> addenda = new HashMap<String, Object>(); assertEquals(null, addenda.put("subdir/1.obj", o1)); assertEquals(null, addenda.put("subdir/2.obj", o2)); map.putAll(addenda); assertEquals(expected.entrySet(), map.entrySet()); } @Test public void testValues() { DirectoryMap<Object> map = new DirectoryMap<Object>(); Object o0 = new Object() { @Override public String toString() { return "'Object #0'"; } }; Object o1 = new Object() { @Override public String toString() { return "'Object #1'"; } }; Object o2 = new Object() { @Override public String toString() { return "'Object #2'"; } }; assertEquals(null, map.put("root.obj", o0)); assertEquals(null, map.put("subdir/1.obj", o1)); assertEquals(null, map.put("subdir/2.obj", o2)); assertEquals(new HashSet<Object>(Arrays.asList(o0, o1, o2)), new HashSet<Object>(map.values())); } @Test public void testRemoveAll() { DirectoryMap<String> map = new DirectoryMap<String>(); ReferenceQueue<String> queue = new ReferenceQueue<String>(); String c = new String("C RRD"); String d = new String("D RRD"); MarkedWeakReference cRef = new MarkedWeakReference("c.rrd", new String("C RRD"), queue); MarkedWeakReference dRef = new MarkedWeakReference("d.rrd", new String("D RRD"), queue); assertEquals(null, map.put("A/B/c.rrd", c)); assertEquals(null, map.put("A/B/d.rrd", d)); assertTrue(map.removeNode("A/B")); while(cRef.get() != null || dRef.get()!=null) { System.gc(); } assertFalse(map.containsKey("A/B/c.rrd")); assertFalse(map.containsKey("A/B/d.rrd")); MarkedWeakReference ref = null; try{ while(true) { try { ref = (MarkedWeakReference) queue.remove(100); } catch (IllegalArgumentException e) { e.printStackTrace(); } if (ref==null) break; assertNull(ref.get()); assertTrue("c.rrd".equals(ref.mark) || "d.rrd".equals(ref.mark)); } } catch (InterruptedException e) { e.printStackTrace(); } } private class MarkedWeakReference extends WeakReference<String> { public String mark; public MarkedWeakReference(String mark, String referent, ReferenceQueue<? super String> q) { super(referent, q); this.mark = mark; } @Override public String toString() { return mark; } } @Ignore @Test public void testConcurrency() { final DirectoryMap<Object> map = new DirectoryMap<Object>(); final Object o0 = new Object() { @Override public String toString() { return "'Object #0'"; } }; final Object o1 = new Object() { @Override public String toString() { return "'Object #1'"; } }; final Object o2 = new Object() { @Override public String toString() { return "'Object #2'"; } }; assertEquals(null, map.put("root.obj", o0)); // assertEquals(null, map.put("subdir/1.obj", o1)); assertEquals(null, map.put("subdir/2.obj", o2)); Runnable r1 = new Runnable() { @Override public void run() { assertEquals(o1, map.remove("subdir/1.obj")); } }; Runnable r2 = new Runnable() { @Override public void run() { assertEquals(o2, map.remove("subdir/2.obj")); } }; Thread t; for (int i = 0; i < 10000; i++) { t = new Thread(r2); t.start(); assertEquals(null, map.put("subdir/1.obj", o1)); try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } t = new Thread(r1); t.start(); assertEquals(null, map.put("subdir/2.obj", o2)); try { t.join(); } catch (InterruptedException e) { e.printStackTrace(); } } } }