• 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 
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