Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/util/Spliterator/SpliteratorLateBindingFailFastTest.java
38811 views
/*1* Copyright (c) 2013, 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*/2223import org.testng.annotations.DataProvider;24import org.testng.annotations.Test;2526import java.util.ArrayList;27import java.util.Arrays;28import java.util.Collection;29import java.util.Collections;30import java.util.ConcurrentModificationException;31import java.util.HashMap;32import java.util.HashSet;33import java.util.LinkedHashMap;34import java.util.LinkedHashSet;35import java.util.LinkedList;36import java.util.List;37import java.util.Map;38import java.util.PriorityQueue;39import java.util.Set;40import java.util.Spliterator;41import java.util.Stack;42import java.util.TreeMap;43import java.util.TreeSet;44import java.util.Vector;45import java.util.WeakHashMap;46import java.util.function.Consumer;47import java.util.function.Function;48import java.util.function.Supplier;4950import static org.testng.Assert.*;5152/**53* @test54* @summary Spliterator last-binding and fail-fast tests55* @run testng SpliteratorLateBindingFailFastTest56*/5758@Test59public class SpliteratorLateBindingFailFastTest {6061private interface Source<T> {62Collection<T> asCollection();63void update();64}6566private static class SpliteratorDataBuilder<T> {67final List<Object[]> data;6869final T newValue;7071final List<T> exp;7273final Map<T, T> mExp;7475SpliteratorDataBuilder(List<Object[]> data, T newValue, List<T> exp) {76this.data = data;77this.newValue = newValue;78this.exp = exp;79this.mExp = createMap(exp);80}8182Map<T, T> createMap(List<T> l) {83Map<T, T> m = new LinkedHashMap<>();84for (T t : l) {85m.put(t, t);86}87return m;88}8990void add(String description, Supplier<Source<?>> s) {91description = joiner(description).toString();92data.add(new Object[]{description, s});93}9495void addCollection(Function<Collection<T>, ? extends Collection<T>> f) {96class CollectionSource implements Source<T> {97final Collection<T> c = f.apply(exp);9899final Consumer<Collection<T>> updater;100101CollectionSource(Consumer<Collection<T>> updater) {102this.updater = updater;103}104105@Override106public Collection<T> asCollection() {107return c;108}109110@Override111public void update() {112updater.accept(c);113}114}115116String description = "new " + f.apply(Collections.<T>emptyList()).getClass().getName() + ".spliterator() ";117add(description + "ADD", () -> new CollectionSource(c -> c.add(newValue)));118add(description + "REMOVE", () -> new CollectionSource(c -> c.remove(c.iterator().next())));119}120121void addList(Function<Collection<T>, ? extends List<T>> l) {122// @@@ If collection is instance of List then add sub-list tests123addCollection(l);124}125126void addMap(Function<Map<T, T>, ? extends Map<T, T>> mapConstructor) {127class MapSource<U> implements Source<U> {128final Map<T, T> m = mapConstructor.apply(mExp);129130final Collection<U> c;131132final Consumer<Map<T, T>> updater;133134MapSource(Function<Map<T, T>, Collection<U>> f, Consumer<Map<T, T>> updater) {135this.c = f.apply(m);136this.updater = updater;137}138139@Override140public Collection<U> asCollection() {141return c;142}143144@Override145public void update() {146updater.accept(m);147}148}149150Map<String, Consumer<Map<T, T>>> actions = new HashMap<>();151actions.put("ADD", m -> m.put(newValue, newValue));152actions.put("REMOVE", m -> m.remove(m.keySet().iterator().next()));153154String description = "new " + mapConstructor.apply(Collections.<T, T>emptyMap()).getClass().getName();155for (Map.Entry<String, Consumer<Map<T, T>>> e : actions.entrySet()) {156add(description + ".keySet().spliterator() " + e.getKey(),157() -> new MapSource<T>(m -> m.keySet(), e.getValue()));158add(description + ".values().spliterator() " + e.getKey(),159() -> new MapSource<T>(m -> m.values(), e.getValue()));160add(description + ".entrySet().spliterator() " + e.getKey(),161() -> new MapSource<Map.Entry<T, T>>(m -> m.entrySet(), e.getValue()));162}163}164165StringBuilder joiner(String description) {166return new StringBuilder(description).167append(" {").168append("size=").append(exp.size()).169append("}");170}171}172173static Object[][] spliteratorDataProvider;174175@DataProvider(name = "Source")176public static Object[][] spliteratorDataProvider() {177if (spliteratorDataProvider != null) {178return spliteratorDataProvider;179}180181List<Object[]> data = new ArrayList<>();182SpliteratorDataBuilder<Integer> db = new SpliteratorDataBuilder<>(data, 5, Arrays.asList(1, 2, 3, 4));183184// Collections185186db.addList(ArrayList::new);187188db.addList(LinkedList::new);189190db.addList(Vector::new);191192193db.addCollection(HashSet::new);194195db.addCollection(LinkedHashSet::new);196197db.addCollection(TreeSet::new);198199200db.addCollection(c -> { Stack<Integer> s = new Stack<>(); s.addAll(c); return s;});201202db.addCollection(PriorityQueue::new);203204// ArrayDeque fails some tests since it's fail-fast support is weaker205// than other collections and limited to detecting most, but not all,206// removals. It probably requires it's own test since it is difficult207// to abstract out the conditions under which it fails-fast.208// db.addCollection(ArrayDeque::new);209210// Maps211212db.addMap(HashMap::new);213214db.addMap(LinkedHashMap::new);215216// This fails when run through jrteg but passes when run though217// ant218// db.addMap(IdentityHashMap::new);219220db.addMap(WeakHashMap::new);221222// @@@ Descending maps etc223db.addMap(TreeMap::new);224225return spliteratorDataProvider = data.toArray(new Object[0][]);226}227228@Test(dataProvider = "Source")229public <T> void lateBindingTestWithForEach(String description, Supplier<Source<T>> ss) {230Source<T> source = ss.get();231Collection<T> c = source.asCollection();232Spliterator<T> s = c.spliterator();233234source.update();235236Set<T> r = new HashSet<>();237s.forEachRemaining(r::add);238239assertEquals(r, new HashSet<>(c));240}241242@Test(dataProvider = "Source")243public <T> void lateBindingTestWithTryAdvance(String description, Supplier<Source<T>> ss) {244Source<T> source = ss.get();245Collection<T> c = source.asCollection();246Spliterator<T> s = c.spliterator();247248source.update();249250Set<T> r = new HashSet<>();251while (s.tryAdvance(r::add)) { }252253assertEquals(r, new HashSet<>(c));254}255256@Test(dataProvider = "Source")257public <T> void lateBindingTestWithCharacteritics(String description, Supplier<Source<T>> ss) {258Source<T> source = ss.get();259Collection<T> c = source.asCollection();260Spliterator<T> s = c.spliterator();261s.characteristics();262263Set<T> r = new HashSet<>();264s.forEachRemaining(r::add);265266assertEquals(r, new HashSet<>(c));267}268269270@Test(dataProvider = "Source")271public <T> void testFailFastTestWithTryAdvance(String description, Supplier<Source<T>> ss) {272{273Source<T> source = ss.get();274Collection<T> c = source.asCollection();275Spliterator<T> s = c.spliterator();276277s.tryAdvance(e -> {278});279source.update();280281executeAndCatch(() -> s.tryAdvance(e -> { }));282}283284{285Source<T> source = ss.get();286Collection<T> c = source.asCollection();287Spliterator<T> s = c.spliterator();288289s.tryAdvance(e -> {290});291source.update();292293executeAndCatch(() -> s.forEachRemaining(e -> {294}));295}296}297298@Test(dataProvider = "Source")299public <T> void testFailFastTestWithForEach(String description, Supplier<Source<T>> ss) {300Source<T> source = ss.get();301Collection<T> c = source.asCollection();302Spliterator<T> s = c.spliterator();303304executeAndCatch(() -> s.forEachRemaining(e -> {305source.update();306}));307}308309@Test(dataProvider = "Source")310public <T> void testFailFastTestWithEstimateSize(String description, Supplier<Source<T>> ss) {311{312Source<T> source = ss.get();313Collection<T> c = source.asCollection();314Spliterator<T> s = c.spliterator();315316s.estimateSize();317source.update();318319executeAndCatch(() -> s.tryAdvance(e -> { }));320}321322{323Source<T> source = ss.get();324Collection<T> c = source.asCollection();325Spliterator<T> s = c.spliterator();326327s.estimateSize();328source.update();329330executeAndCatch(() -> s.forEachRemaining(e -> {331}));332}333}334335private void executeAndCatch(Runnable r) {336executeAndCatch(ConcurrentModificationException.class, r);337}338339private void executeAndCatch(Class<? extends Exception> expected, Runnable r) {340Exception caught = null;341try {342r.run();343}344catch (Exception e) {345caught = e;346}347348assertNotNull(caught,349String.format("No Exception was thrown, expected an Exception of %s to be thrown",350expected.getName()));351assertTrue(expected.isInstance(caught),352String.format("Exception thrown %s not an instance of %s",353caught.getClass().getName(), expected.getName()));354}355356}357358359