Path: blob/master/test/jdk/java/util/Spliterator/SpliteratorCollisions.java
41149 views
/*1* Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/**24* @test25* @bug 800569826* @library /lib/testlibrary/bootlib27* @build java.base/java.util.SpliteratorTestHelper28* @run testng SpliteratorCollisions29* @summary Spliterator traversing and splitting hash maps containing colliding hashes30*/3132import org.testng.annotations.DataProvider;33import org.testng.annotations.Test;3435import java.util.ArrayList;36import java.util.Arrays;37import java.util.Collection;38import java.util.Collections;39import java.util.HashMap;40import java.util.HashSet;41import java.util.LinkedHashMap;42import java.util.LinkedHashSet;43import java.util.List;44import java.util.Map;45import java.util.Spliterator;46import java.util.SpliteratorTestHelper;47import java.util.TreeSet;48import java.util.function.Function;49import java.util.function.Supplier;50import java.util.function.UnaryOperator;5152public class SpliteratorCollisions extends SpliteratorTestHelper {5354private static final List<Integer> SIZES = Arrays.asList(0, 1, 10, 100, 1000);5556private static class SpliteratorDataBuilder<T> {57List<Object[]> data;58List<T> exp;59Map<T, T> mExp;6061SpliteratorDataBuilder(List<Object[]> data, List<T> exp) {62this.data = data;63this.exp = exp;64this.mExp = createMap(exp);65}6667Map<T, T> createMap(List<T> l) {68Map<T, T> m = new LinkedHashMap<>();69for (T t : l) {70m.put(t, t);71}72return m;73}7475void add(String description, Collection<?> expected, Supplier<Spliterator<?>> s) {76description = joiner(description).toString();77data.add(new Object[]{description, expected, s});78}7980void add(String description, Supplier<Spliterator<?>> s) {81add(description, exp, s);82}8384void addCollection(Function<Collection<T>, ? extends Collection<T>> c) {85add("new " + c.apply(Collections.<T>emptyList()).getClass().getName() + ".spliterator()",86() -> c.apply(exp).spliterator());87}8889void addList(Function<Collection<T>, ? extends List<T>> l) {90// @@@ If collection is instance of List then add sub-list tests91addCollection(l);92}9394void addMap(Function<Map<T, T>, ? extends Map<T, T>> m) {95String description = "new " + m.apply(Collections.<T, T>emptyMap()).getClass().getName();96add(description + ".keySet().spliterator()", () -> m.apply(mExp).keySet().spliterator());97add(description + ".values().spliterator()", () -> m.apply(mExp).values().spliterator());98add(description + ".entrySet().spliterator()", mExp.entrySet(), () -> m.apply(mExp).entrySet().spliterator());99}100101StringBuilder joiner(String description) {102return new StringBuilder(description).103append(" {").104append("size=").append(exp.size()).105append("}");106}107}108109static Object[][] spliteratorDataProvider;110111@DataProvider(name = "HashableIntSpliterator")112public static Object[][] spliteratorDataProvider() {113if (spliteratorDataProvider != null) {114return spliteratorDataProvider;115}116117List<Object[]> data = new ArrayList<>();118for (int size : SIZES) {119List<HashableInteger> exp = listIntRange(size, false);120SpliteratorDataBuilder<HashableInteger> db = new SpliteratorDataBuilder<>(data, exp);121122// Maps123db.addMap(HashMap::new);124db.addMap(LinkedHashMap::new);125126// Collections that use HashMap127db.addCollection(HashSet::new);128db.addCollection(LinkedHashSet::new);129db.addCollection(TreeSet::new);130}131return spliteratorDataProvider = data.toArray(new Object[0][]);132}133134static Object[][] spliteratorDataProviderWithNull;135136@DataProvider(name = "HashableIntSpliteratorWithNull")137public static Object[][] spliteratorNullDataProvider() {138if (spliteratorDataProviderWithNull != null) {139return spliteratorDataProviderWithNull;140}141142List<Object[]> data = new ArrayList<>();143for (int size : SIZES) {144List<HashableInteger> exp = listIntRange(size, true);145SpliteratorDataBuilder<HashableInteger> db = new SpliteratorDataBuilder<>(data, exp);146147// Maps148db.addMap(HashMap::new);149db.addMap(LinkedHashMap::new);150// TODO: add this back in if we decide to keep TreeBin in WeakHashMap151//db.addMap(WeakHashMap::new);152153// Collections that use HashMap154db.addCollection(HashSet::new);155db.addCollection(LinkedHashSet::new);156// db.addCollection(TreeSet::new);157158}159return spliteratorDataProviderWithNull = data.toArray(new Object[0][]);160}161162static final class HashableInteger implements Comparable<HashableInteger> {163164final int value;165final int hashmask; //yes duplication166167HashableInteger(int value, int hashmask) {168this.value = value;169this.hashmask = hashmask;170}171172@Override173public boolean equals(Object obj) {174if (obj instanceof HashableInteger) {175HashableInteger other = (HashableInteger) obj;176177return other.value == value;178}179180return false;181}182183@Override184public int hashCode() {185return value % hashmask;186}187188@Override189public int compareTo(HashableInteger o) {190return value - o.value;191}192193@Override194public String toString() {195return Integer.toString(value);196}197}198199private static List<HashableInteger> listIntRange(int upTo, boolean withNull) {200List<HashableInteger> exp = new ArrayList<>();201if (withNull) {202exp.add(null);203}204for (int i = 0; i < upTo; i++) {205exp.add(new HashableInteger(i, 10));206}207return Collections.unmodifiableList(exp);208}209210@Test(dataProvider = "HashableIntSpliterator")211void testNullPointerException(String description,212Collection<HashableInteger> exp,213Supplier<Spliterator<HashableInteger>> s) {214assertThrowsNPE(() -> s.get().forEachRemaining(null));215assertThrowsNPE(() -> s.get().tryAdvance(null));216}217218@Test(dataProvider = "HashableIntSpliteratorWithNull")219void testNullPointerExceptionWithNull(String description,220Collection<HashableInteger> exp,221Supplier<Spliterator<HashableInteger>> s) {222assertThrowsNPE(() -> s.get().forEachRemaining(null));223assertThrowsNPE(() -> s.get().tryAdvance(null));224}225226227@Test(dataProvider = "HashableIntSpliterator")228void testForEach(String description,229Collection<HashableInteger> exp,230Supplier<Spliterator<HashableInteger>> s) {231testForEach(exp, s, UnaryOperator.identity());232}233234@Test(dataProvider = "HashableIntSpliteratorWithNull")235void testForEachWithNull(String description,236Collection<HashableInteger> exp,237Supplier<Spliterator<HashableInteger>> s) {238testForEach(exp, s, UnaryOperator.identity());239}240241242@Test(dataProvider = "HashableIntSpliterator")243void testTryAdvance(String description,244Collection<HashableInteger> exp,245Supplier<Spliterator<HashableInteger>> s) {246testTryAdvance(exp, s, UnaryOperator.identity());247}248249@Test(dataProvider = "HashableIntSpliteratorWithNull")250void testTryAdvanceWithNull(String description,251Collection<HashableInteger> exp,252Supplier<Spliterator<HashableInteger>> s) {253testTryAdvance(exp, s, UnaryOperator.identity());254}255256@Test(dataProvider = "HashableIntSpliterator")257void testMixedTryAdvanceForEach(String description,258Collection<HashableInteger> exp,259Supplier<Spliterator<HashableInteger>> s) {260testMixedTryAdvanceForEach(exp, s, UnaryOperator.identity());261}262263@Test(dataProvider = "HashableIntSpliteratorWithNull")264void testMixedTryAdvanceForEachWithNull(String description,265Collection<HashableInteger> exp,266Supplier<Spliterator<HashableInteger>> s) {267testMixedTryAdvanceForEach(exp, s, UnaryOperator.identity());268}269270@Test(dataProvider = "HashableIntSpliterator")271void testMixedTraverseAndSplit(String description,272Collection<HashableInteger> exp,273Supplier<Spliterator<HashableInteger>> s) {274testMixedTraverseAndSplit(exp, s, UnaryOperator.identity());275}276277@Test(dataProvider = "HashableIntSpliteratorWithNull")278void testMixedTraverseAndSplitWithNull(String description,279Collection<HashableInteger> exp,280Supplier<Spliterator<HashableInteger>> s) {281testMixedTraverseAndSplit(exp, s, UnaryOperator.identity());282}283284@Test(dataProvider = "HashableIntSpliterator")285void testSplitAfterFullTraversal(String description,286Collection<HashableInteger> exp,287Supplier<Spliterator<HashableInteger>> s) {288testSplitAfterFullTraversal(s, UnaryOperator.identity());289}290291@Test(dataProvider = "HashableIntSpliteratorWithNull")292void testSplitAfterFullTraversalWithNull(String description,293Collection<HashableInteger> exp,294Supplier<Spliterator<HashableInteger>> s) {295testSplitAfterFullTraversal(s, UnaryOperator.identity());296}297298299@Test(dataProvider = "HashableIntSpliterator")300void testSplitOnce(String description,301Collection<HashableInteger> exp,302Supplier<Spliterator<HashableInteger>> s) {303testSplitOnce(exp, s, UnaryOperator.identity());304}305306@Test(dataProvider = "HashableIntSpliteratorWithNull")307void testSplitOnceWithNull(String description,308Collection<HashableInteger> exp,309Supplier<Spliterator<HashableInteger>> s) {310testSplitOnce(exp, s, UnaryOperator.identity());311}312313@Test(dataProvider = "HashableIntSpliterator")314void testSplitSixDeep(String description,315Collection<HashableInteger> exp,316Supplier<Spliterator<HashableInteger>> s) {317testSplitSixDeep(exp, s, UnaryOperator.identity());318}319320@Test(dataProvider = "HashableIntSpliteratorWithNull")321void testSplitSixDeepWithNull(String description,322Collection<HashableInteger> exp,323Supplier<Spliterator<HashableInteger>> s) {324testSplitSixDeep(exp, s, UnaryOperator.identity());325}326327@Test(dataProvider = "HashableIntSpliterator")328void testSplitUntilNull(String description,329Collection<HashableInteger> exp,330Supplier<Spliterator<HashableInteger>> s) {331testSplitUntilNull(exp, s, UnaryOperator.identity());332}333334@Test(dataProvider = "HashableIntSpliteratorWithNull")335void testSplitUntilNullWithNull(String description,336Collection<HashableInteger> exp,337Supplier<Spliterator<HashableInteger>> s) {338testSplitUntilNull(exp, s, UnaryOperator.identity());339}340341}342343344