1 /* 2 * Copyright (C) 2010 The Guava Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.common.collect; 18 19 import com.google.common.collect.Synchronized.SynchronizedNavigableMap; 20 import com.google.common.collect.Synchronized.SynchronizedNavigableSet; 21 import com.google.common.collect.Synchronized.SynchronizedSortedMap; 22 import com.google.common.collect.testing.NavigableMapTestSuiteBuilder; 23 import com.google.common.collect.testing.SafeTreeMap; 24 import com.google.common.collect.testing.TestStringSortedMapGenerator; 25 import com.google.common.collect.testing.features.CollectionFeature; 26 import com.google.common.collect.testing.features.CollectionSize; 27 import com.google.common.collect.testing.features.MapFeature; 28 import com.google.common.testing.SerializableTester; 29 import java.io.Serializable; 30 import java.util.Comparator; 31 import java.util.Map.Entry; 32 import java.util.NavigableMap; 33 import java.util.NavigableSet; 34 import java.util.SortedMap; 35 import junit.framework.TestSuite; 36 37 /** 38 * Tests for {@link Maps#synchronizedNavigableMap(NavigableMap)}. 39 * 40 * @author Louis Wasserman 41 */ 42 public class SynchronizedNavigableMapTest extends SynchronizedMapTest { 43 @Override create()44 protected <K, V> NavigableMap<K, V> create() { 45 @SuppressWarnings("unchecked") 46 NavigableMap<K, V> innermost = 47 new SafeTreeMap<>((Comparator<? super K>) Ordering.natural().nullsFirst()); 48 TestMap<K, V> inner = new TestMap<>(innermost, mutex); 49 NavigableMap<K, V> outer = Synchronized.navigableMap(inner, mutex); 50 return outer; 51 } 52 53 static class TestEntry<K, V> extends ForwardingMapEntry<K, V> implements Serializable { 54 private final Entry<K, V> delegate; 55 private final Object mutex; 56 TestEntry(Entry<K, V> delegate, Object mutex)57 TestEntry(Entry<K, V> delegate, Object mutex) { 58 this.delegate = delegate; 59 this.mutex = mutex; 60 } 61 62 @Override delegate()63 protected Entry<K, V> delegate() { 64 return delegate; 65 } 66 67 @Override equals(Object object)68 public boolean equals(Object object) { 69 assertTrue(Thread.holdsLock(mutex)); 70 return super.equals(object); 71 } 72 73 @Override getKey()74 public K getKey() { 75 assertTrue(Thread.holdsLock(mutex)); 76 return super.getKey(); 77 } 78 79 @Override getValue()80 public V getValue() { 81 assertTrue(Thread.holdsLock(mutex)); 82 return super.getValue(); 83 } 84 85 @Override hashCode()86 public int hashCode() { 87 assertTrue(Thread.holdsLock(mutex)); 88 return super.hashCode(); 89 } 90 91 @Override setValue(V value)92 public V setValue(V value) { 93 assertTrue(Thread.holdsLock(mutex)); 94 return super.setValue(value); 95 } 96 97 private static final long serialVersionUID = 0; 98 } 99 100 static class TestMap<K, V> extends SynchronizedMapTest.TestMap<K, V> 101 implements NavigableMap<K, V> { 102 TestMap(NavigableMap<K, V> delegate, Object mutex)103 public TestMap(NavigableMap<K, V> delegate, Object mutex) { 104 super(delegate, mutex); 105 } 106 107 @Override delegate()108 protected NavigableMap<K, V> delegate() { 109 return (NavigableMap<K, V>) super.delegate(); 110 } 111 112 @Override ceilingEntry(K key)113 public Entry<K, V> ceilingEntry(K key) { 114 assertTrue(Thread.holdsLock(mutex)); 115 return delegate().ceilingEntry(key); 116 } 117 118 @Override ceilingKey(K key)119 public K ceilingKey(K key) { 120 assertTrue(Thread.holdsLock(mutex)); 121 return delegate().ceilingKey(key); 122 } 123 124 @Override descendingKeySet()125 public NavigableSet<K> descendingKeySet() { 126 assertTrue(Thread.holdsLock(mutex)); 127 return delegate().descendingKeySet(); 128 } 129 130 @Override descendingMap()131 public NavigableMap<K, V> descendingMap() { 132 assertTrue(Thread.holdsLock(mutex)); 133 return delegate().descendingMap(); 134 } 135 136 @Override firstEntry()137 public Entry<K, V> firstEntry() { 138 assertTrue(Thread.holdsLock(mutex)); 139 return delegate().firstEntry(); 140 } 141 142 @Override floorEntry(K key)143 public Entry<K, V> floorEntry(K key) { 144 assertTrue(Thread.holdsLock(mutex)); 145 return delegate().floorEntry(key); 146 } 147 148 @Override floorKey(K key)149 public K floorKey(K key) { 150 assertTrue(Thread.holdsLock(mutex)); 151 return delegate().floorKey(key); 152 } 153 154 @Override headMap(K toKey, boolean inclusive)155 public NavigableMap<K, V> headMap(K toKey, boolean inclusive) { 156 assertTrue(Thread.holdsLock(mutex)); 157 return delegate().headMap(toKey, inclusive); 158 } 159 160 @Override headMap(K toKey)161 public SortedMap<K, V> headMap(K toKey) { 162 return headMap(toKey, false); 163 } 164 165 @Override higherEntry(K key)166 public Entry<K, V> higherEntry(K key) { 167 assertTrue(Thread.holdsLock(mutex)); 168 return delegate().higherEntry(key); 169 } 170 171 @Override higherKey(K key)172 public K higherKey(K key) { 173 assertTrue(Thread.holdsLock(mutex)); 174 return delegate().higherKey(key); 175 } 176 177 @Override lastEntry()178 public Entry<K, V> lastEntry() { 179 assertTrue(Thread.holdsLock(mutex)); 180 return delegate().lastEntry(); 181 } 182 183 @Override lowerEntry(K key)184 public Entry<K, V> lowerEntry(K key) { 185 assertTrue(Thread.holdsLock(mutex)); 186 return delegate().lowerEntry(key); 187 } 188 189 @Override lowerKey(K key)190 public K lowerKey(K key) { 191 assertTrue(Thread.holdsLock(mutex)); 192 return delegate().lowerKey(key); 193 } 194 195 @Override navigableKeySet()196 public NavigableSet<K> navigableKeySet() { 197 assertTrue(Thread.holdsLock(mutex)); 198 return delegate().navigableKeySet(); 199 } 200 201 @Override pollFirstEntry()202 public Entry<K, V> pollFirstEntry() { 203 assertTrue(Thread.holdsLock(mutex)); 204 return delegate().pollFirstEntry(); 205 } 206 207 @Override pollLastEntry()208 public Entry<K, V> pollLastEntry() { 209 assertTrue(Thread.holdsLock(mutex)); 210 return delegate().pollLastEntry(); 211 } 212 213 @Override subMap( K fromKey, boolean fromInclusive, K toKey, boolean toInclusive)214 public NavigableMap<K, V> subMap( 215 K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { 216 assertTrue(Thread.holdsLock(mutex)); 217 return delegate().subMap(fromKey, fromInclusive, toKey, toInclusive); 218 } 219 220 @Override subMap(K fromKey, K toKey)221 public SortedMap<K, V> subMap(K fromKey, K toKey) { 222 return delegate().subMap(fromKey, true, toKey, false); 223 } 224 225 @Override tailMap(K fromKey, boolean inclusive)226 public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) { 227 assertTrue(Thread.holdsLock(mutex)); 228 return delegate().tailMap(fromKey, inclusive); 229 } 230 231 @Override tailMap(K fromKey)232 public SortedMap<K, V> tailMap(K fromKey) { 233 return tailMap(fromKey, true); 234 } 235 236 @Override comparator()237 public Comparator<? super K> comparator() { 238 assertTrue(Thread.holdsLock(mutex)); 239 return delegate().comparator(); 240 } 241 242 @Override firstKey()243 public K firstKey() { 244 assertTrue(Thread.holdsLock(mutex)); 245 return delegate().firstKey(); 246 } 247 248 @Override lastKey()249 public K lastKey() { 250 assertTrue(Thread.holdsLock(mutex)); 251 return delegate().lastKey(); 252 } 253 254 private static final long serialVersionUID = 0; 255 } 256 suite()257 public static TestSuite suite() { 258 TestSuite suite = new TestSuite(); 259 suite.addTestSuite(SynchronizedNavigableMapTest.class); 260 suite.addTest( 261 NavigableMapTestSuiteBuilder.using( 262 new TestStringSortedMapGenerator() { 263 private final Object mutex = new Integer(1); 264 265 @Override 266 protected SortedMap<String, String> create(Entry<String, String>[] entries) { 267 NavigableMap<String, String> innermost = new SafeTreeMap<>(); 268 for (Entry<String, String> entry : entries) { 269 innermost.put(entry.getKey(), entry.getValue()); 270 } 271 TestMap<String, String> inner = new TestMap<>(innermost, mutex); 272 NavigableMap<String, String> outer = Synchronized.navigableMap(inner, mutex); 273 return outer; 274 } 275 }) 276 .named("Maps.synchronizedNavigableMap[SafeTreeMap]") 277 .withFeatures( 278 CollectionSize.ANY, 279 CollectionFeature.KNOWN_ORDER, 280 MapFeature.GENERAL_PURPOSE, 281 MapFeature.ALLOWS_NULL_VALUES, 282 CollectionFeature.SUPPORTS_ITERATOR_REMOVE) 283 .createTestSuite()); 284 285 return suite; 286 } 287 testComparator()288 public void testComparator() { 289 create().comparator(); 290 } 291 testCeilingEntry()292 public void testCeilingEntry() { 293 create().ceilingEntry("a"); 294 } 295 testCeilingKey()296 public void testCeilingKey() { 297 create().ceilingKey("a"); 298 } 299 testDescendingKeySet()300 public void testDescendingKeySet() { 301 NavigableMap<String, Integer> map = create(); 302 NavigableSet<String> descendingKeySet = map.descendingKeySet(); 303 assertTrue(descendingKeySet instanceof SynchronizedNavigableSet); 304 assertSame(mutex, ((SynchronizedNavigableSet<String>) descendingKeySet).mutex); 305 } 306 testDescendingMap()307 public void testDescendingMap() { 308 NavigableMap<String, Integer> map = create(); 309 NavigableMap<String, Integer> descendingMap = map.descendingMap(); 310 assertTrue(descendingMap instanceof SynchronizedNavigableMap); 311 assertSame(mutex, ((SynchronizedNavigableMap<String, Integer>) descendingMap).mutex); 312 } 313 testFirstEntry()314 public void testFirstEntry() { 315 create().firstEntry(); 316 } 317 testFirstKey()318 public void testFirstKey() { 319 NavigableMap<String, Integer> map = create(); 320 map.put("a", 1); 321 map.firstKey(); 322 } 323 testFloorEntry()324 public void testFloorEntry() { 325 create().floorEntry("a"); 326 } 327 testFloorKey()328 public void testFloorKey() { 329 create().floorKey("a"); 330 } 331 testHeadMap_K()332 public void testHeadMap_K() { 333 NavigableMap<String, Integer> map = create(); 334 SortedMap<String, Integer> headMap = map.headMap("a"); 335 assertTrue(headMap instanceof SynchronizedSortedMap); 336 assertSame(mutex, ((SynchronizedSortedMap<String, Integer>) headMap).mutex); 337 } 338 testHeadMap_K_B()339 public void testHeadMap_K_B() { 340 NavigableMap<String, Integer> map = create(); 341 NavigableMap<String, Integer> headMap = map.headMap("a", true); 342 assertTrue(headMap instanceof SynchronizedNavigableMap); 343 assertSame(mutex, ((SynchronizedNavigableMap<String, Integer>) headMap).mutex); 344 } 345 testHigherEntry()346 public void testHigherEntry() { 347 create().higherEntry("a"); 348 } 349 testHigherKey()350 public void testHigherKey() { 351 create().higherKey("a"); 352 } 353 testLastEntry()354 public void testLastEntry() { 355 create().lastEntry(); 356 } 357 testLastKey()358 public void testLastKey() { 359 NavigableMap<String, Integer> map = create(); 360 map.put("a", 1); 361 map.lastKey(); 362 } 363 testLowerEntry()364 public void testLowerEntry() { 365 create().lowerEntry("a"); 366 } 367 testLowerKey()368 public void testLowerKey() { 369 create().lowerKey("a"); 370 } 371 testNavigableKeySet()372 public void testNavigableKeySet() { 373 NavigableMap<String, Integer> map = create(); 374 NavigableSet<String> navigableKeySet = map.navigableKeySet(); 375 assertTrue(navigableKeySet instanceof SynchronizedNavigableSet); 376 assertSame(mutex, ((SynchronizedNavigableSet<String>) navigableKeySet).mutex); 377 } 378 testPollFirstEntry()379 public void testPollFirstEntry() { 380 create().pollFirstEntry(); 381 } 382 testPollLastEntry()383 public void testPollLastEntry() { 384 create().pollLastEntry(); 385 } 386 testSubMap_K_K()387 public void testSubMap_K_K() { 388 NavigableMap<String, Integer> map = create(); 389 SortedMap<String, Integer> subMap = map.subMap("a", "b"); 390 assertTrue(subMap instanceof SynchronizedSortedMap); 391 assertSame(mutex, ((SynchronizedSortedMap<String, Integer>) subMap).mutex); 392 } 393 testSubMap_K_B_K_B()394 public void testSubMap_K_B_K_B() { 395 NavigableMap<String, Integer> map = create(); 396 NavigableMap<String, Integer> subMap = map.subMap("a", true, "b", false); 397 assertTrue(subMap instanceof SynchronizedNavigableMap); 398 assertSame(mutex, ((SynchronizedNavigableMap<String, Integer>) subMap).mutex); 399 } 400 testTailMap_K()401 public void testTailMap_K() { 402 NavigableMap<String, Integer> map = create(); 403 SortedMap<String, Integer> subMap = map.tailMap("a"); 404 assertTrue(subMap instanceof SynchronizedSortedMap); 405 assertSame(mutex, ((SynchronizedSortedMap<String, Integer>) subMap).mutex); 406 } 407 testTailMap_K_B()408 public void testTailMap_K_B() { 409 NavigableMap<String, Integer> map = create(); 410 NavigableMap<String, Integer> subMap = map.tailMap("a", true); 411 assertTrue(subMap instanceof SynchronizedNavigableMap); 412 assertSame(mutex, ((SynchronizedNavigableMap<String, Integer>) subMap).mutex); 413 } 414 415 @Override testSerialization()416 public void testSerialization() { 417 SerializableTester.reserializeAndAssert(create()); 418 } 419 } 420