/* * Copyright (C) 2010 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.google.common.collect; import com.google.common.collect.Synchronized.SynchronizedNavigableMap; import com.google.common.collect.Synchronized.SynchronizedNavigableSet; import com.google.common.collect.Synchronized.SynchronizedSortedMap; import com.google.common.collect.testing.NavigableMapTestSuiteBuilder; import com.google.common.collect.testing.SafeTreeMap; import com.google.common.collect.testing.TestStringSortedMapGenerator; import com.google.common.collect.testing.features.CollectionFeature; import com.google.common.collect.testing.features.CollectionSize; import com.google.common.collect.testing.features.MapFeature; import com.google.common.testing.SerializableTester; import junit.framework.TestSuite; import java.io.Serializable; import java.util.Comparator; import java.util.Map; import java.util.Map.Entry; import java.util.NavigableMap; import java.util.NavigableSet; import java.util.SortedMap; /** * Tests for {@link Maps#synchronizedNavigableMap(NavigableMap)}. * * @author Louis Wasserman */ public class SynchronizedNavigableMapTest extends SynchronizedMapTest { @Override protected <K, V> NavigableMap<K, V> create() { @SuppressWarnings("unchecked") NavigableMap<K, V> innermost = new SafeTreeMap<K, V>( (Comparator<? super K>) Ordering.natural().nullsFirst()); TestMap<K, V> inner = new TestMap<K, V>(innermost, mutex); NavigableMap<K, V> outer = Synchronized.navigableMap(inner, mutex); return outer; } static class TestEntry<K, V> extends ForwardingMapEntry<K, V> implements Serializable { private final Entry<K, V> delegate; private final Object mutex; TestEntry(Entry<K, V> delegate, Object mutex) { this.delegate = delegate; this.mutex = mutex; } @Override protected Entry<K, V> delegate() { return delegate; } @Override public boolean equals(Object object) { assertTrue(Thread.holdsLock(mutex)); return super.equals(object); } @Override public K getKey() { assertTrue(Thread.holdsLock(mutex)); return super.getKey(); } @Override public V getValue() { assertTrue(Thread.holdsLock(mutex)); return super.getValue(); } @Override public int hashCode() { assertTrue(Thread.holdsLock(mutex)); return super.hashCode(); } @Override public V setValue(V value) { assertTrue(Thread.holdsLock(mutex)); return super.setValue(value); } private static final long serialVersionUID = 0; } static class TestMap<K, V> extends SynchronizedMapTest.TestMap<K, V> implements NavigableMap<K, V> { public TestMap(NavigableMap<K, V> delegate, Object mutex) { super(delegate, mutex); } @Override protected NavigableMap<K, V> delegate() { return (NavigableMap<K, V>) super.delegate(); } @Override public Entry<K, V> ceilingEntry(K key) { assertTrue(Thread.holdsLock(mutex)); return delegate().ceilingEntry(key); } @Override public K ceilingKey(K key) { assertTrue(Thread.holdsLock(mutex)); return delegate().ceilingKey(key); } @Override public NavigableSet<K> descendingKeySet() { assertTrue(Thread.holdsLock(mutex)); return delegate().descendingKeySet(); } @Override public NavigableMap<K, V> descendingMap() { assertTrue(Thread.holdsLock(mutex)); return delegate().descendingMap(); } @Override public Entry<K, V> firstEntry() { assertTrue(Thread.holdsLock(mutex)); return delegate().firstEntry(); } @Override public Entry<K, V> floorEntry(K key) { assertTrue(Thread.holdsLock(mutex)); return delegate().floorEntry(key); } @Override public K floorKey(K key) { assertTrue(Thread.holdsLock(mutex)); return delegate().floorKey(key); } @Override public NavigableMap<K, V> headMap(K toKey, boolean inclusive) { assertTrue(Thread.holdsLock(mutex)); return delegate().headMap(toKey, inclusive); } @Override public SortedMap<K, V> headMap(K toKey) { return headMap(toKey, false); } @Override public Entry<K, V> higherEntry(K key) { assertTrue(Thread.holdsLock(mutex)); return delegate().higherEntry(key); } @Override public K higherKey(K key) { assertTrue(Thread.holdsLock(mutex)); return delegate().higherKey(key); } @Override public Entry<K, V> lastEntry() { assertTrue(Thread.holdsLock(mutex)); return delegate().lastEntry(); } @Override public Entry<K, V> lowerEntry(K key) { assertTrue(Thread.holdsLock(mutex)); return delegate().lowerEntry(key); } @Override public K lowerKey(K key) { assertTrue(Thread.holdsLock(mutex)); return delegate().lowerKey(key); } @Override public NavigableSet<K> navigableKeySet() { assertTrue(Thread.holdsLock(mutex)); return delegate().navigableKeySet(); } @Override public Entry<K, V> pollFirstEntry() { assertTrue(Thread.holdsLock(mutex)); return delegate().pollFirstEntry(); } @Override public Entry<K, V> pollLastEntry() { assertTrue(Thread.holdsLock(mutex)); return delegate().pollLastEntry(); } @Override public NavigableMap<K, V> subMap( K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { assertTrue(Thread.holdsLock(mutex)); return delegate().subMap(fromKey, fromInclusive, toKey, toInclusive); } @Override public SortedMap<K, V> subMap(K fromKey, K toKey) { return delegate().subMap(fromKey, true, toKey, false); } @Override public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) { assertTrue(Thread.holdsLock(mutex)); return delegate().tailMap(fromKey, inclusive); } @Override public SortedMap<K, V> tailMap(K fromKey) { return tailMap(fromKey, true); } @Override public Comparator<? super K> comparator() { assertTrue(Thread.holdsLock(mutex)); return delegate().comparator(); } @Override public K firstKey() { assertTrue(Thread.holdsLock(mutex)); return delegate().firstKey(); } @Override public K lastKey() { assertTrue(Thread.holdsLock(mutex)); return delegate().lastKey(); } private static final long serialVersionUID = 0; } public static TestSuite suite() { TestSuite suite = new TestSuite(); suite.addTestSuite(SynchronizedNavigableMapTest.class); suite.addTest( NavigableMapTestSuiteBuilder.using(new TestStringSortedMapGenerator() { private final Object mutex = new Integer(1); @Override protected Map<String, String> create( Entry<String, String>[] entries) { NavigableMap<String, String> innermost = new SafeTreeMap<String, String>(); for (Entry<String, String> entry : entries) { innermost.put(entry.getKey(), entry.getValue()); } TestMap<String, String> inner = new TestMap<String, String>(innermost, mutex); NavigableMap<String, String> outer = Synchronized.navigableMap(inner, mutex); return outer; } }).named("Maps.synchronizedNavigableMap[SafeTreeMap]") .withFeatures(CollectionSize.ANY, CollectionFeature.KNOWN_ORDER, MapFeature.GENERAL_PURPOSE, MapFeature.ALLOWS_NULL_VALUES) .createTestSuite()); return suite; } public void testComparator() { create().comparator(); } public void testCeilingEntry() { create().ceilingEntry("a"); } public void testCeilingKey() { create().ceilingKey("a"); } public void testDescendingKeySet() { NavigableMap<String, Integer> map = create(); NavigableSet<String> descendingKeySet = map.descendingKeySet(); assertTrue(descendingKeySet instanceof SynchronizedNavigableSet); assertSame( mutex, ((SynchronizedNavigableSet<String>) descendingKeySet).mutex); } public void testDescendingMap() { NavigableMap<String, Integer> map = create(); NavigableMap<String, Integer> descendingMap = map.descendingMap(); assertTrue(descendingMap instanceof SynchronizedNavigableMap); assertSame(mutex, ((SynchronizedNavigableMap<String, Integer>) descendingMap).mutex); } public void testFirstEntry() { create().firstEntry(); } public void testFirstKey() { NavigableMap<String, Integer> map = create(); map.put("a", 1); map.firstKey(); } public void testFloorEntry() { create().floorEntry("a"); } public void testFloorKey() { create().floorKey("a"); } public void testHeadMap_K() { NavigableMap<String, Integer> map = create(); SortedMap<String, Integer> headMap = map.headMap("a"); assertTrue(headMap instanceof SynchronizedSortedMap); assertSame(mutex, ((SynchronizedSortedMap<String, Integer>) headMap).mutex); } public void testHeadMap_K_B() { NavigableMap<String, Integer> map = create(); NavigableMap<String, Integer> headMap = map.headMap("a", true); assertTrue(headMap instanceof SynchronizedNavigableMap); assertSame( mutex, ((SynchronizedNavigableMap<String, Integer>) headMap).mutex); } public void testHigherEntry() { create().higherEntry("a"); } public void testHigherKey() { create().higherKey("a"); } public void testLastEntry() { create().lastEntry(); } public void testLastKey() { NavigableMap<String, Integer> map = create(); map.put("a", 1); map.lastKey(); } public void testLowerEntry() { create().lowerEntry("a"); } public void testLowerKey() { create().lowerKey("a"); } public void testNavigableKeySet() { NavigableMap<String, Integer> map = create(); NavigableSet<String> navigableKeySet = map.navigableKeySet(); assertTrue(navigableKeySet instanceof SynchronizedNavigableSet); assertSame( mutex, ((SynchronizedNavigableSet<String>) navigableKeySet).mutex); } public void testPollFirstEntry() { create().pollFirstEntry(); } public void testPollLastEntry() { create().pollLastEntry(); } public void testSubMap_K_K() { NavigableMap<String, Integer> map = create(); SortedMap<String, Integer> subMap = map.subMap("a", "b"); assertTrue(subMap instanceof SynchronizedSortedMap); assertSame(mutex, ((SynchronizedSortedMap<String, Integer>) subMap).mutex); } public void testSubMap_K_B_K_B() { NavigableMap<String, Integer> map = create(); NavigableMap<String, Integer> subMap = map.subMap("a", true, "b", false); assertTrue(subMap instanceof SynchronizedNavigableMap); assertSame( mutex, ((SynchronizedNavigableMap<String, Integer>) subMap).mutex); } public void testTailMap_K() { NavigableMap<String, Integer> map = create(); SortedMap<String, Integer> subMap = map.tailMap("a"); assertTrue(subMap instanceof SynchronizedSortedMap); assertSame(mutex, ((SynchronizedSortedMap<String, Integer>) subMap).mutex); } public void testTailMap_K_B() { NavigableMap<String, Integer> map = create(); NavigableMap<String, Integer> subMap = map.tailMap("a", true); assertTrue(subMap instanceof SynchronizedNavigableMap); assertSame( mutex, ((SynchronizedNavigableMap<String, Integer>) subMap).mutex); } @Override public void testSerialization() { SerializableTester.reserializeAndAssert(create()); } }