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