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