/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8048209
* @summary Check that Collections.synchronizedNavigableSet().tailSet() is using
* the same lock object as it's source.
* @modules java.base/java.util:open
* @run testng SyncSubMutexes
*/
import java.lang.reflect.Field;
import java.util.*;
import java.util.Set;
import java.util.Arrays;
import org.testng.annotations.Test;
import org.testng.annotations.DataProvider;
import static org.testng.Assert .assertSame;
public class SyncSubMutexes {
@Test(dataProvider = "Collections" )
public void testCollections(Collection<String> instance) {
// nothing to test, no subset methods
}
@Test(dataProvider = "Lists" )
public void testLists(List<String> instance) {
assertSame(getSyncCollectionMutex(instance.subList(0, 1)), getSyncCollectionMutex(instance));
}
@Test(dataProvider = "Sets" )
public void testSets(Set<String> instance) {
// nothing to test, no subset methods
}
@Test(dataProvider = "SortedSets" )
public void testSortedSets(SortedSet<String> instance) {
assertSame(getSyncCollectionMutex(instance.headSet("Echo" )), getSyncCollectionMutex(instance));
assertSame(getSyncCollectionMutex(instance.tailSet("Charlie" )), getSyncCollectionMutex(instance));
assertSame(getSyncCollectionMutex(instance.subSet("Charlie" , "Echo" )), getSyncCollectionMutex(instance));
}
@Test(dataProvider = "NavigableSets" )
public void testNavigableSets(NavigableSet<String> instance) {
assertSame(getSyncCollectionMutex(instance.descendingSet()), getSyncCollectionMutex(instance));
assertSame(getSyncCollectionMutex(instance.headSet("Echo" )), getSyncCollectionMutex(instance));
assertSame(getSyncCollectionMutex(instance.headSet("Echo" , true )), getSyncCollectionMutex(instance));
assertSame(getSyncCollectionMutex(instance.tailSet("Charlie" )), getSyncCollectionMutex(instance));
assertSame(getSyncCollectionMutex(instance.tailSet("Charlie" , true )), getSyncCollectionMutex(instance));
assertSame(getSyncCollectionMutex(instance.subSet("Charlie" , "Echo" )), getSyncCollectionMutex(instance));
assertSame(getSyncCollectionMutex(instance.subSet("Charlie" , true , "Echo" , true )), getSyncCollectionMutex(instance));
}
@Test(dataProvider = "Maps" )
public void testMaps(Map<String, String> instance) {
assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
}
@Test(dataProvider = "SortedMaps" )
public void testSortedMaps(SortedMap<String, String> instance) {
assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
assertSame(getSyncMapMutex(instance.headMap("Echo" )), getSyncMapMutex(instance));
assertSame(getSyncMapMutex(instance.tailMap("Charlie" )), getSyncMapMutex(instance));
assertSame(getSyncMapMutex(instance.subMap("Charlie" , "Echo" )), getSyncMapMutex(instance));
}
@Test(dataProvider = "NavigableMaps" )
public void testNavigableMaps(NavigableMap<String, String> instance) {
assertSame(getSyncMapMutex(instance.descendingMap()), getSyncMapMutex(instance));
assertSame(getSyncCollectionMutex(instance.entrySet()), getSyncMapMutex(instance));
assertSame(getSyncCollectionMutex(instance.keySet()), getSyncMapMutex(instance));
assertSame(getSyncCollectionMutex(instance.descendingKeySet()), getSyncMapMutex(instance));
assertSame(getSyncCollectionMutex(instance.values()), getSyncMapMutex(instance));
assertSame(getSyncMapMutex(instance.headMap("Echo" )), getSyncMapMutex(instance));
assertSame(getSyncMapMutex(instance.headMap("Echo" , true )), getSyncMapMutex(instance));
assertSame(getSyncMapMutex(instance.tailMap("Charlie" )), getSyncMapMutex(instance));
assertSame(getSyncMapMutex(instance.tailMap("Charlie" , true )), getSyncMapMutex(instance));
assertSame(getSyncMapMutex(instance.subMap("Charlie" , true , "Echo" , true )), getSyncMapMutex(instance));
assertSame(getSyncMapMutex(instance.subMap("Charlie" , true , "Echo" , true )), getSyncMapMutex(instance));
}
@DataProvider(name = "Collections" , parallel = true )
public static Iterator<Object[]> collectionProvider() {
return makeCollections().iterator();
}
@DataProvider(name = "Lists" , parallel = true )
public static Iterator<Object[]> listProvider() {
return makeLists().iterator();
}
@DataProvider(name = "Sets" , parallel = true )
public static Iterator<Object[]> setProvider() {
return makeSets().iterator();
}
@DataProvider(name = "SortedSets" , parallel = true )
public static Iterator<Object[]> sortedsetProvider() {
return makeSortedSets().iterator();
}
@DataProvider(name = "NavigableSets" , parallel = true )
public static Iterator<Object[]> navigablesetProvider() {
return makeNavigableSets().iterator();
}
@DataProvider(name = "Maps" , parallel = true )
public static Iterator<Object[]> mapProvider() {
return makeMaps().iterator();
}
@DataProvider(name = "SortedMaps" , parallel = true )
public static Iterator<Object[]> sortedmapProvider() {
return makeSortedMaps().iterator();
}
@DataProvider(name = "NavigableMaps" , parallel = true )
public static Iterator<Object[]> navigablemapProvider() {
return makeNavigableMaps().iterator();
}
private static final Collection<String> BASE_COLLECTION = Collections.unmodifiableCollection(
Arrays.asList("Alpha" , "Bravo" , "Charlie" , "Delta" , "Echo" , "Foxtrot" , "Golf" )
);
private static final Map<String, String> BASE_MAP;
static {
Map<String, String> map = new HashMap<>();
for (String each : BASE_COLLECTION) {
map.put(each, "*" + each + "*" );
}
BASE_MAP = Collections.unmodifiableMap(map);
}
public static Collection<Object[]> makeCollections() {
Collection<Object[]> instances = new ArrayList<>();
instances.add(new Object[] {Collections.synchronizedCollection(new ArrayList<>(BASE_COLLECTION))});
instances.addAll(makeLists());
return instances;
}
public static Collection<Object[]> makeLists() {
Collection<Object[]> instances = new ArrayList<>();
instances.add(new Object[] {Collections.synchronizedList(new ArrayList<>(BASE_COLLECTION))});
instances.add(new Object[] {Collections.synchronizedList(new ArrayList<>(BASE_COLLECTION)).subList(1, 2)});
return instances;
}
public static Collection<Object[]> makeSets() {
Collection<Object[]> instances = new ArrayList<>();
instances.add(new Object[] {Collections.synchronizedSet(new TreeSet<>(BASE_COLLECTION))});
instances.addAll(makeSortedSets());
return instances;
}
public static Collection<Object[]> makeSortedSets() {
Collection<Object[]> instances = new ArrayList<>();
instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION))});
instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot" )});
instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo" )});
instances.add(new Object[] {Collections.synchronizedSortedSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo" , "Foxtrot" )});
instances.addAll(makeNavigableSets());
return instances;
}
public static Collection<Object[]> makeNavigableSets() {
Collection<Object[]> instances = new ArrayList<>();
instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION))});
instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).descendingSet().descendingSet()});
instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot" )});
instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).headSet("Foxtrot" , true )});
instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo" )});
instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).tailSet("Bravo" , true )});
instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo" , "Foxtrot" )});
instances.add(new Object[] {Collections.synchronizedNavigableSet(new TreeSet<>(BASE_COLLECTION)).subSet("Bravo" , true , "Foxtrot" , true )});
return instances;
}
public static Collection<Object[]> makeMaps() {
Collection<Object[]> instances = new ArrayList<>();
instances.add(new Object[] {Collections.synchronizedMap(new HashMap<>(BASE_MAP))});
instances.addAll(makeSortedMaps());
return instances;
}
public static Collection<Object[]> makeSortedMaps() {
Collection<Object[]> instances = new ArrayList<>();
instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP))});
instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot" )});
instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo" )});
instances.add(new Object[] {Collections.synchronizedSortedMap(new TreeMap<>(BASE_MAP)).subMap("Bravo" , "Foxtrot" )});
instances.addAll(makeNavigableMaps());
return instances;
}
public static Collection<Object[]> makeNavigableMaps() {
Collection<Object[]> instances = new ArrayList<>();
instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP))});
instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP).descendingMap().descendingMap())});
instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot" )});
instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).headMap("Foxtrot" , true )});
instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo" )});
instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).tailMap("Bravo" , true )});
instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).subMap("Bravo" , "Foxtrot" )});
instances.add(new Object[] {Collections.synchronizedNavigableMap(new TreeMap<>(BASE_MAP)).subMap("Bravo" , true , "Foxtrot" , true )});
return instances;
}
private static Object getSyncCollectionMutex(Collection<?> from) {
try {
Class <?> synchronizedCollectionClazz = Class .forName("java.util.Collections$SynchronizedCollection" );
Field f = synchronizedCollectionClazz.getDeclaredField("mutex" );
f.setAccessible(true );
return f.get(from);
} catch ( ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException("Unable to get mutex field." , e);
}
}
private static Object getSyncMapMutex(Map<?,?> from) {
try {
Class <?> synchronizedMapClazz = Class .forName("java.util.Collections$SynchronizedMap" );
Field f = synchronizedMapClazz.getDeclaredField("mutex" );
f.setAccessible(true );
return f.get(from);
} catch ( ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException("Unable to get mutex field." , e);
}
}
}
quality 97%
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland