jdk/test/java/util/Collections/SyncSubMutexes.java
changeset 25748 8914cd976d19
child 42338 a60f280f803c
equal deleted inserted replaced
25669:daa21271c03b 25748:8914cd976d19
       
     1 /*
       
     2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /**
       
    25  * @test
       
    26  * @bug 8048209
       
    27  * @summary Check that Collections.synchronizedNavigableSet().tailSet() is using
       
    28  * the same lock object as it's source.
       
    29  * @run testng SyncSubMutexes
       
    30  */
       
    31 import java.lang.reflect.Field;
       
    32 import java.util.*;
       
    33 import java.util.Set;
       
    34 import java.util.Arrays;
       
    35 
       
    36 import org.testng.annotations.Test;
       
    37 import org.testng.annotations.DataProvider;
       
    38 import static org.testng.Assert.assertSame;
       
    39 
       
    40 public class SyncSubMutexes {
       
    41 
       
    42     @Test(dataProvider = "Collections")
       
    43     public void testCollections(Collection<String> instance) {
       
    44         // nothing to test, no subset methods
       
    45     }
       
    46 
       
    47     @Test(dataProvider = "Lists")
       
    48     public void testLists(List<String> instance) {
       
    49          assertSame(getSyncCollectionMutex(instance.subList(0, 1)), getSyncCollectionMutex(instance));
       
    50     }
       
    51 
       
    52     @Test(dataProvider = "Sets")
       
    53     public void testSets(Set<String> instance) {
       
    54         // nothing to test, no subset methods
       
    55 
       
    56     }
       
    57 
       
    58     @Test(dataProvider = "SortedSets")
       
    59     public void testSortedSets(SortedSet<String> instance) {
       
    60          assertSame(getSyncCollectionMutex(instance.headSet("Echo")), getSyncCollectionMutex(instance));
       
    61          assertSame(getSyncCollectionMutex(instance.tailSet("Charlie")), getSyncCollectionMutex(instance));
       
    62          assertSame(getSyncCollectionMutex(instance.subSet("Charlie", "Echo")), getSyncCollectionMutex(instance));
       
    63 
       
    64     }
       
    65 
       
    66     @Test(dataProvider = "NavigableSets")
       
    67     public void testNavigableSets(NavigableSet<String> instance) {
       
    68          assertSame(getSyncCollectionMutex(instance.descendingSet()), getSyncCollectionMutex(instance));
       
    69          assertSame(getSyncCollectionMutex(instance.headSet("Echo")), getSyncCollectionMutex(instance));
       
    70          assertSame(getSyncCollectionMutex(instance.headSet("Echo", true)), getSyncCollectionMutex(instance));
       
    71          assertSame(getSyncCollectionMutex(instance.tailSet("Charlie")), getSyncCollectionMutex(instance));
       
    72          assertSame(getSyncCollectionMutex(instance.tailSet("Charlie", true)), getSyncCollectionMutex(instance));
       
    73          assertSame(getSyncCollectionMutex(instance.subSet("Charlie", "Echo")), getSyncCollectionMutex(instance));
       
    74          assertSame(getSyncCollectionMutex(instance.subSet("Charlie", true, "Echo", true)), getSyncCollectionMutex(instance));
       
    75     }
       
    76 
       
    77     @Test(dataProvider = "Maps")
       
    78     public void testMaps(Map<String, String> instance) {
       
    79          assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
       
    80          assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
       
    81          assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
       
    82     }
       
    83 
       
    84     @Test(dataProvider = "SortedMaps")
       
    85     public void testSortedMaps(SortedMap<String, String> instance) {
       
    86          assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
       
    87          assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
       
    88          assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
       
    89          assertSame(getSyncMapMutex(instance.headMap("Echo")), getSyncMapMutex(instance));
       
    90          assertSame(getSyncMapMutex(instance.tailMap("Charlie")), getSyncMapMutex(instance));
       
    91          assertSame(getSyncMapMutex(instance.subMap("Charlie", "Echo")), getSyncMapMutex(instance));
       
    92     }
       
    93 
       
    94     @Test(dataProvider = "NavigableMaps")
       
    95     public void testNavigableMaps(NavigableMap<String, String> instance) {
       
    96          assertSame(getSyncMapMutex(instance.descendingMap()), getSyncMapMutex(instance));
       
    97          assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
       
    98          assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
       
    99          assertSame(getSyncCollectionMutex(instance.descendingKeySet()), getSyncMapMutex(instance));
       
   100          assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
       
   101          assertSame(getSyncMapMutex(instance.headMap("Echo")), getSyncMapMutex(instance));
       
   102          assertSame(getSyncMapMutex(instance.headMap("Echo", true)), getSyncMapMutex(instance));
       
   103          assertSame(getSyncMapMutex(instance.tailMap("Charlie")), getSyncMapMutex(instance));
       
   104          assertSame(getSyncMapMutex(instance.tailMap("Charlie", true)), getSyncMapMutex(instance));
       
   105          assertSame(getSyncMapMutex(instance.subMap("Charlie", true, "Echo", true)), getSyncMapMutex(instance));
       
   106          assertSame(getSyncMapMutex(instance.subMap("Charlie", true, "Echo", true)), getSyncMapMutex(instance));
       
   107     }
       
   108 
       
   109     @DataProvider(name = "Collections", parallel = true)
       
   110     public static Iterator<Object[]> collectionProvider() {
       
   111         return makeCollections().iterator();
       
   112     }
       
   113 
       
   114     @DataProvider(name = "Lists", parallel = true)
       
   115     public static Iterator<Object[]> listProvider() {
       
   116         return makeLists().iterator();
       
   117     }
       
   118 
       
   119     @DataProvider(name = "Sets", parallel = true)
       
   120     public static Iterator<Object[]> setProvider() {
       
   121         return makeSets().iterator();
       
   122     }
       
   123 
       
   124     @DataProvider(name = "SortedSets", parallel = true)
       
   125     public static Iterator<Object[]> sortedsetProvider() {
       
   126         return makeSortedSets().iterator();
       
   127     }
       
   128 
       
   129     @DataProvider(name = "NavigableSets", parallel = true)
       
   130     public static Iterator<Object[]> navigablesetProvider() {
       
   131         return makeNavigableSets().iterator();
       
   132     }
       
   133 
       
   134     @DataProvider(name = "Maps", parallel = true)
       
   135     public static Iterator<Object[]> mapProvider() {
       
   136         return makeMaps().iterator();
       
   137     }
       
   138 
       
   139     @DataProvider(name = "SortedMaps", parallel = true)
       
   140     public static Iterator<Object[]> sortedmapProvider() {
       
   141         return makeSortedMaps().iterator();
       
   142     }
       
   143 
       
   144     @DataProvider(name = "NavigableMaps", parallel = true)
       
   145     public static Iterator<Object[]> navigablemapProvider() {
       
   146         return makeNavigableMaps().iterator();
       
   147     }
       
   148 
       
   149     private static final Collection<String> BASE_COLLECTION = Collections.unmodifiableCollection(
       
   150             Arrays.asList("Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf")
       
   151     );
       
   152     private static final Map<String, String> BASE_MAP;
       
   153 
       
   154     static {
       
   155         Map<String, String> map = new HashMap<>();
       
   156         for(String each : BASE_COLLECTION) {
       
   157             map.put(each, "*" + each + "*");
       
   158         }
       
   159         BASE_MAP = Collections.unmodifiableMap(map);
       
   160     }
       
   161 
       
   162     public static Collection<Object[]> makeCollections() {
       
   163         Collection<Object[]> instances = new ArrayList<>();
       
   164         instances.add(new Object[] {Collections.synchronizedCollection(new ArrayList<>(BASE_COLLECTION))});
       
   165         instances.addAll(makeLists());
       
   166 
       
   167         return instances;
       
   168     }
       
   169 
       
   170     public static Collection<Object[]> makeLists() {
       
   171         Collection<Object[]> instances = new ArrayList<>();
       
   172         instances.add(new Object[] {Collections.synchronizedList(new ArrayList<>(BASE_COLLECTION))});
       
   173         instances.add(new Object[] {Collections.synchronizedList(new ArrayList<>(BASE_COLLECTION)).subList(1, 2)});
       
   174 
       
   175         return instances;
       
   176     }
       
   177 
       
   178      public static Collection<Object[]> makeSets() {
       
   179         Collection<Object[]> instances = new ArrayList<>();
       
   180 
       
   181         instances.add(new Object[] {Collections.synchronizedSet(new TreeSet<>(BASE_COLLECTION))});
       
   182         instances.addAll(makeSortedSets());
       
   183         return instances;
       
   184      }
       
   185 
       
   186     public static Collection<Object[]> makeSortedSets() {
       
   187         Collection<Object[]> instances = new ArrayList<>();
       
   188         instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION))});
       
   189         instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot")});
       
   190         instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo")});
       
   191         instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo", "Foxtrot")});
       
   192         instances.addAll(makeNavigableSets());
       
   193 
       
   194         return instances;
       
   195      }
       
   196 
       
   197     public static Collection<Object[]> makeNavigableSets() {
       
   198         Collection<Object[]> instances = new ArrayList<>();
       
   199 
       
   200         instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION))});
       
   201         instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).descendingSet().descendingSet()});
       
   202         instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot")});
       
   203         instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot", true)});
       
   204         instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo")});
       
   205         instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo", true)});
       
   206         instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo", "Foxtrot")});
       
   207         instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo", true, "Foxtrot", true)});
       
   208 
       
   209         return instances;
       
   210     }
       
   211 
       
   212     public static Collection<Object[]> makeMaps() {
       
   213         Collection<Object[]> instances = new ArrayList<>();
       
   214 
       
   215         instances.add(new Object[] {Collections.synchronizedMap(new HashMap<>(BASE_MAP))});
       
   216         instances.addAll(makeSortedMaps());
       
   217 
       
   218         return instances;
       
   219     }
       
   220 
       
   221     public static Collection<Object[]> makeSortedMaps() {
       
   222         Collection<Object[]> instances = new ArrayList<>();
       
   223 
       
   224         instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP))});
       
   225         instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot")});
       
   226         instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo")});
       
   227         instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).subMap("Bravo", "Foxtrot")});
       
   228         instances.addAll(makeNavigableMaps());
       
   229 
       
   230         return instances;
       
   231     }
       
   232 
       
   233     public static Collection<Object[]> makeNavigableMaps() {
       
   234         Collection<Object[]> instances = new ArrayList<>();
       
   235 
       
   236         instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP))});
       
   237         instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP).descendingMap().descendingMap())});
       
   238         instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot")});
       
   239         instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot", true)});
       
   240         instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo")});
       
   241         instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo", true)});
       
   242         instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).subMap("Bravo", "Foxtrot")});
       
   243         instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).subMap("Bravo", true, "Foxtrot", true)});
       
   244 
       
   245         return instances;
       
   246     }
       
   247 
       
   248     private static Object getSyncCollectionMutex(Collection<?> from) {
       
   249         try {
       
   250             Class<?> synchronizedCollectionClazz = Class.forName("java.util.Collections$SynchronizedCollection");
       
   251             Field f = synchronizedCollectionClazz.getDeclaredField("mutex");
       
   252             f.setAccessible(true);
       
   253             return f.get(from);
       
   254         } catch ( ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
       
   255             throw new RuntimeException("Unable to get mutex field.", e);
       
   256         }
       
   257     }
       
   258 
       
   259     private static Object getSyncMapMutex(Map<?,?> from) {
       
   260         try {
       
   261             Class<?> synchronizedMapClazz = Class.forName("java.util.Collections$SynchronizedMap");
       
   262             Field f = synchronizedMapClazz.getDeclaredField("mutex");
       
   263             f.setAccessible(true);
       
   264             return f.get(from);
       
   265         } catch ( ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
       
   266             throw new RuntimeException("Unable to get mutex field.", e);
       
   267         }
       
   268     }
       
   269 
       
   270 }