• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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