8016455: Sync stream tests from lambda to tl
authorpsandoz
Thu, 20 Jun 2013 11:15:23 +0200
changeset 18529 930f51c90ea7
parent 18528 9b02581cf079
child 18530 f28682666cf7
8016455: Sync stream tests from lambda to tl Reviewed-by: mduigou Contributed-by: Brian Goetz <brian.goetz@oracle.com>, Paul Sandoz <paul.sandoz@oracle.com>
jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestDataProvider.java
jdk/test/java/util/stream/bootlib/java/util/stream/LambdaTestHelpers.java
jdk/test/java/util/stream/bootlib/java/util/stream/LoggingTestCase.java
jdk/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java
jdk/test/java/util/stream/bootlib/java/util/stream/SpliteratorTestHelper.java
jdk/test/java/util/stream/boottest/java/util/stream/DoubleNodeTest.java
jdk/test/java/util/stream/boottest/java/util/stream/IntNodeTest.java
jdk/test/java/util/stream/boottest/java/util/stream/LongNodeTest.java
jdk/test/java/util/stream/boottest/java/util/stream/NodeTest.java
jdk/test/java/util/stream/boottest/java/util/stream/UnorderedTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/DistinctOpTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ForEachOpTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/GroupByOpTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntSliceOpTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntUniqOpTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/MatchOpTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/RangeTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ReduceByOpTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SequentialOpTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamLinkTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamSpliteratorTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java
jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ToArrayOpTest.java
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestDataProvider.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/IntStreamTestDataProvider.java	Thu Jun 20 11:15:23 2013 +0200
@@ -129,7 +129,6 @@
                                             () -> IntStream.range(0, ints.length).spliterator()));
                 spliterators.add(splitDescr("IntStream.intRangeClosed(0,l):" + name,
                                             () -> IntStream.rangeClosed(0, ints.length).spliterator()));
-
                 // Need more!
             }
             spliteratorTestData = spliterators.toArray(new Object[0][]);
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/LambdaTestHelpers.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/LambdaTestHelpers.java	Thu Jun 20 11:15:23 2013 +0200
@@ -269,7 +269,7 @@
         Set<T> uniq = new HashSet<>();
         while(iter.hasNext()) {
             T each = iter.next();
-            assertTrue(!uniq.contains(each));
+            assertTrue(!uniq.contains(each), "Not unique");
             uniq.add(each);
         }
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/LoggingTestCase.java	Thu Jun 20 11:15:23 2013 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2013, 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.
+ */
+package java.util.stream;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.Assert;
+import org.testng.ITestResult;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * LoggingTestCase
+ *
+ */
+@Test
+public class LoggingTestCase extends Assert {
+    private Map<String, Object> context = new HashMap<>();
+
+    @BeforeMethod
+    public void before() {
+        context.clear();
+    }
+
+    @AfterMethod
+    public void after(ITestResult result) {
+        if (!result.isSuccess()) {
+            List<Object> list = new ArrayList<>();
+            Collections.addAll(list, result.getParameters());
+            list.add(context.toString());
+            result.setParameters(list.toArray(new Object[list.size()]));
+        }
+    }
+
+    protected void setContext(String key, Object value) {
+        context.put(key, value);
+    }
+
+    protected void clearContext(String key) {
+        context.remove(key);
+    }
+}
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/OpTestCase.java	Thu Jun 20 11:15:23 2013 +0200
@@ -50,7 +50,7 @@
  * ways and asserts that they produce equivalent results.
  */
 @Test
-public abstract class OpTestCase extends Assert {
+public abstract class OpTestCase extends LoggingTestCase {
 
     private final Map<StreamShape, Set<? extends BaseStreamTestScenario>> testScenarios;
 
@@ -67,6 +67,25 @@
         return ((AbstractPipeline) s).getStreamFlags();
     }
 
+    /**
+     * An asserter for results produced when exercising of stream or terminal
+     * tests.
+     *
+     * @param <R> the type of result to assert on
+     */
+    public interface ResultAsserter<R> {
+        /**
+         * Assert a result produced when exercising of stream or terminal
+         * test.
+         *
+         * @param actual the actual result
+         * @param excepted the expected result
+         * @param isOrdered true if the pipeline is ordered
+         * @param isParallel true if the pipeline is parallel
+         */
+        void assertResult(R actual, R excepted, boolean isOrdered, boolean isParallel);
+    }
+
     // Exercise stream operations
 
     public interface BaseStreamTestScenario {
@@ -190,14 +209,19 @@
         Set<BaseStreamTestScenario> testSet = new HashSet<>();
 
         Collection<U> refResult;
-        boolean isOrdered;
 
         Consumer<TestData<T, S_IN>> before = LambdaTestHelpers.bEmpty;
 
         Consumer<TestData<T, S_IN>> after = LambdaTestHelpers.bEmpty;
 
-        BiConsumer<Iterable<U>, Iterable<U>> sequentialEqualityAsserter = LambdaTestHelpers::assertContentsEqual;
-        BiConsumer<Iterable<U>, Iterable<U>> parallelEqualityAsserter = LambdaTestHelpers::assertContentsEqual;
+        ResultAsserter<Iterable<U>> resultAsserter = (act, exp, ord, par) -> {
+            if (par & !ord) {
+                LambdaTestHelpers.assertContentsUnordered(act, exp);
+            }
+            else {
+                LambdaTestHelpers.assertContentsEqual(act, exp);
+            }
+        };
 
         private ExerciseDataStreamBuilder(TestData<T, S_IN> data, Function<S_IN, S_OUT> m) {
             this.data = data;
@@ -211,10 +235,6 @@
             testSet.addAll(testScenarios.get(shape));
         }
 
-        public BiConsumer<Iterable<U>, Iterable<U>> getEqualityAsserter(BaseStreamTestScenario t) {
-            return t.isParallel() ? parallelEqualityAsserter : sequentialEqualityAsserter;
-        }
-
         //
 
         public <I extends Iterable<U>> ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> expectedResult(I expectedResult) {
@@ -299,29 +319,15 @@
             return this;
         }
 
-        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> sequentialEqualityAsserter(BiConsumer<Iterable<U>, Iterable<U>> equalator) {
-            this.sequentialEqualityAsserter = equalator;
-            return this;
-        }
-
-        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> parallelEqualityAsserter(BiConsumer<Iterable<U>, Iterable<U>> equalator) {
-            this.parallelEqualityAsserter = equalator;
+        public ExerciseDataStreamBuilder<T, U, S_IN, S_OUT> resultAsserter(ResultAsserter<Iterable<U>> resultAsserter) {
+            this.resultAsserter = resultAsserter;
             return this;
         }
 
         // Build method
 
-        private long count(StreamShape shape, BaseStream s) {
-            switch (shape) {
-                case REFERENCE:    return ((Stream) s).count();
-                case INT_VALUE:    return ((IntStream) s).count();
-                case LONG_VALUE:   return ((LongStream) s).count();
-                case DOUBLE_VALUE: return ((DoubleStream) s).count();
-                default: throw new IllegalStateException("Unknown shape: " + shape);
-            }
-        }
-
         public Collection<U> exercise() {
+            final boolean isOrdered;
             if (refResult == null) {
                 // Induce the reference result
                 before.accept(data);
@@ -330,9 +336,10 @@
                 Node<U> refNodeResult = ((AbstractPipeline<?, U, ?>) sOut).evaluateToArrayNode(size -> (U[]) new Object[size]);
                 refResult = LambdaTestHelpers.toBoxedList(refNodeResult.spliterator());
                 after.accept(data);
-                S_OUT anotherCopy = m.apply(data.stream());
-                long count = count(((AbstractPipeline) anotherCopy).getOutputShape(), anotherCopy);
-                assertEquals(count, refNodeResult.count());
+            }
+            else {
+                S_OUT sOut = m.apply(data.stream());
+                isOrdered = StreamOpFlag.ORDERED.isKnown(((AbstractPipeline) sOut).getStreamFlags());
             }
 
             List<Error> errors = new ArrayList<>();
@@ -343,16 +350,20 @@
                     List<U> result = new ArrayList<>();
                     test.run(data, LambdaTestHelpers.<U>toBoxingConsumer(result::add), m);
 
-                    Runnable asserter = () -> getEqualityAsserter(test).accept(result, refResult);
-                    if (test.isParallel() && !isOrdered)
-                        asserter = () -> LambdaTestHelpers.assertContentsUnordered(result, refResult);
-                    LambdaTestHelpers.launderAssertion(
-                            asserter,
-                            () -> String.format("%n%s: %s != %s", test, refResult, result));
+                    Runnable asserter = () -> resultAsserter.assertResult(result, refResult, isOrdered, test.isParallel());
+
+                    if (refResult.size() > 1000) {
+                        LambdaTestHelpers.launderAssertion(
+                                asserter,
+                                () -> String.format("%n%s: [actual size=%d] != [expected size=%d]", test, result.size(), refResult.size()));
+                    }
+                    else {
+                        LambdaTestHelpers.launderAssertion(
+                                asserter,
+                                () -> String.format("%n%s: [actual] %s != [expected] %s", test, result, refResult));
+                    }
 
                     after.accept(data);
-//                } catch (AssertionError ae) {
-//                    errors.add(ae);
                 } catch (Throwable t) {
                     errors.add(new Error(String.format("%s: %s", test, t), t));
                 }
@@ -406,8 +417,7 @@
 
         Set<TerminalTestScenario> testSet = EnumSet.allOf(TerminalTestScenario.class);
 
-        Function<S_OUT, BiConsumer<R, R>> sequentialEqualityAsserter = s -> LambdaTestHelpers::assertContentsEqual;
-        Function<S_OUT, BiConsumer<R, R>> parallelEqualityAsserter = s -> LambdaTestHelpers::assertContentsEqual;
+        ResultAsserter<R> resultAsserter = (act, exp, ord, par) -> LambdaTestHelpers.assertContentsEqual(act, exp);
 
         private ExerciseDataTerminalBuilder(TestData<T, S_IN> data, Function<S_IN, S_OUT> streamF, Function<S_OUT, R> terminalF) {
             this.data = data;
@@ -423,23 +433,12 @@
         }
 
         public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> equalator(BiConsumer<R, R> equalityAsserter) {
-            this.sequentialEqualityAsserter = s -> equalityAsserter;
-            this.parallelEqualityAsserter = s -> equalityAsserter;
+            resultAsserter = (act, exp, ord, par) -> equalityAsserter.accept(act, exp);
             return this;
         }
 
-        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> sequentialEqualityAsserter(BiConsumer<R, R> equalityAsserter) {
-            this.sequentialEqualityAsserter = s -> equalityAsserter;
-            return this;
-        }
-
-        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> parallelEqualityAsserter(BiConsumer<R, R> equalityAsserter) {
-            this.parallelEqualityAsserter = s -> equalityAsserter;
-            return this;
-        }
-
-        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> parallelEqualityAsserter(Function<S_OUT, BiConsumer<R, R>> equalatorProvider) {
-            this.parallelEqualityAsserter = equalatorProvider;
+        public ExerciseDataTerminalBuilder<T, U, R, S_IN, S_OUT> resultAsserter(ResultAsserter<R> resultAsserter) {
+            this.resultAsserter = resultAsserter;
             return this;
         }
 
@@ -467,8 +466,9 @@
         // Build method
 
         public R exercise() {
-            S_OUT out = streamF.apply(data.stream());
+            S_OUT out = streamF.apply(data.stream()).sequential();
             AbstractPipeline ap = (AbstractPipeline) out;
+            boolean isOrdered = StreamOpFlag.ORDERED.isKnown(ap.getStreamFlags());
             StreamShape shape = ap.getOutputShape();
 
             Node<U> node = ap.evaluateToArrayNode(size -> (U[]) new Object[size]);
@@ -481,9 +481,8 @@
                 S_OUT source = (S_OUT) createPipeline(shape, node.spliterator(),
                                                       StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED,
                                                       false);
-                BiConsumer<R, R> asserter = sequentialEqualityAsserter.apply(source);
                 R result = terminalF.apply(source);
-                LambdaTestHelpers.launderAssertion(() -> asserter.accept(refResult, result),
+                LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, false),
                                                    () -> String.format("Single sequential: %s != %s", refResult, result));
             }
 
@@ -491,11 +490,10 @@
                 S_OUT source = (S_OUT) createPipeline(shape, node.spliterator(),
                                                       StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED,
                                                       false);
-                // Force short-curcuit
+                // Force short-circuit
                 source = (S_OUT) chain(source, new ShortCircuitOp<U>(shape));
-                BiConsumer<R, R> asserter = sequentialEqualityAsserter.apply(source);
                 R result = terminalF.apply(source);
-                LambdaTestHelpers.launderAssertion(() -> asserter.accept(refResult, result),
+                LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, false),
                                                    () -> String.format("Single sequential pull: %s != %s", refResult, result));
             }
 
@@ -503,44 +501,39 @@
                 S_OUT source = (S_OUT) createPipeline(shape, node.spliterator(),
                                                       StreamOpFlag.IS_ORDERED | StreamOpFlag.IS_SIZED,
                                                       true);
-                BiConsumer<R, R> asserter = parallelEqualityAsserter.apply(source);
                 R result = terminalF.apply(source);
-                LambdaTestHelpers.launderAssertion(() -> asserter.accept(refResult, result),
+                LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, true),
                                                    () -> String.format("Single parallel: %s != %s", refResult, result));
             }
 
             if (testSet.contains(TerminalTestScenario.ALL_SEQUENTIAL)) {
                 // This may forEach or tryAdvance depending on the terminal op implementation
                 S_OUT source = streamF.apply(data.stream());
-                BiConsumer<R, R> asserter = sequentialEqualityAsserter.apply(source);
                 R result = terminalF.apply(source);
-                LambdaTestHelpers.launderAssertion(() -> asserter.accept(refResult, result),
+                LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, false),
                                                    () -> String.format("All sequential: %s != %s", refResult, result));
             }
 
             if (testSet.contains(TerminalTestScenario.ALL_SEQUENTIAL_SHORT_CIRCUIT)) {
                 S_OUT source = streamF.apply(data.stream());
-                // Force short-curcuit
+                // Force short-circuit
                 source = (S_OUT) chain(source, new ShortCircuitOp<U>(shape));
-                BiConsumer<R, R> asserter = sequentialEqualityAsserter.apply(source);
                 R result = terminalF.apply(source);
-                LambdaTestHelpers.launderAssertion(() -> asserter.accept(refResult, result),
+                LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, false),
                                                    () -> String.format("All sequential pull: %s != %s", refResult, result));
             }
 
             if (testSet.contains(TerminalTestScenario.ALL_PARALLEL)) {
                 S_OUT source = streamF.apply(data.parallelStream());
-                BiConsumer<R, R> asserter = parallelEqualityAsserter.apply(source);
                 R result = terminalF.apply(source);
-                LambdaTestHelpers.launderAssertion(() -> asserter.accept(refResult, result),
+                LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, true),
                                                    () -> String.format("All parallel: %s != %s", refResult, result));
             }
 
             if (testSet.contains(TerminalTestScenario.ALL_PARALLEL_SEQUENTIAL)) {
                 S_OUT source = streamF.apply(data.parallelStream());
-                BiConsumer<R, R> asserter = parallelEqualityAsserter.apply(source);
                 R result = terminalF.apply(source.sequential());
-                LambdaTestHelpers.launderAssertion(() -> asserter.accept(refResult, result),
+                LambdaTestHelpers.launderAssertion(() -> resultAsserter.assertResult(result, refResult, isOrdered, false),
                                                    () -> String.format("All parallel then sequential: %s != %s", refResult, result));
             }
 
--- a/jdk/test/java/util/stream/bootlib/java/util/stream/SpliteratorTestHelper.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/bootlib/java/util/stream/SpliteratorTestHelper.java	Thu Jun 20 11:15:23 2013 +0200
@@ -65,7 +65,7 @@
             }
         }
 
-        testSpliterator(supplier, c -> new BoxingAdapter(c));
+        testSpliterator(supplier, BoxingAdapter::new);
     }
 
     public static void testLongSpliterator(Supplier<Spliterator.OfLong> supplier) {
@@ -87,7 +87,7 @@
             }
         }
 
-        testSpliterator(supplier, c -> new BoxingAdapter(c));
+        testSpliterator(supplier, BoxingAdapter::new);
     }
 
     public static void testDoubleSpliterator(Supplier<Spliterator.OfDouble> supplier) {
@@ -109,7 +109,7 @@
             }
         }
 
-        testSpliterator(supplier, c -> new BoxingAdapter(c));
+        testSpliterator(supplier, BoxingAdapter::new);
     }
 
     static <T, S extends Spliterator<T>> void testSpliterator(Supplier<S> supplier,
--- a/jdk/test/java/util/stream/boottest/java/util/stream/DoubleNodeTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/boottest/java/util/stream/DoubleNodeTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -162,4 +162,18 @@
     public void testSpliterator(double[] array, Node.OfDouble n) {
         SpliteratorTestHelper.testDoubleSpliterator(n::spliterator);
     }
+
+    @Test(dataProvider = "nodes")
+    public void testTruncate(double[] array, Node.OfDouble n) {
+        int[] nums = new int[] { 0, 1, array.length / 2, array.length - 1, array.length };
+        for (int start : nums)
+            for (int end : nums) {
+                if (start < 0 || end < 0 || end < start || end > array.length)
+                    continue;
+                Node.OfDouble slice = n.truncate(start, end, Double[]::new);
+                double[] asArray = slice.asPrimitiveArray();
+                for (int k = start; k < end; k++)
+                    assertEquals(array[k], asArray[k - start]);
+            }
+    }
 }
--- a/jdk/test/java/util/stream/boottest/java/util/stream/IntNodeTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/boottest/java/util/stream/IntNodeTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -160,4 +160,18 @@
     public void testSpliterator(int[] array, Node.OfInt n) {
         SpliteratorTestHelper.testIntSpliterator(n::spliterator);
     }
+
+    @Test(dataProvider = "nodes")
+    public void testTruncate(int[] array, Node.OfInt n) {
+        int[] nums = new int[] { 0, 1, array.length / 2, array.length - 1, array.length };
+        for (int start : nums)
+            for (int end : nums) {
+                if (start < 0 || end < 0 || end < start || end > array.length)
+                    continue;
+                Node.OfInt slice = n.truncate(start, end, Integer[]::new);
+                int[] asArray = slice.asPrimitiveArray();
+                for (int k = start; k < end; k++)
+                    assertEquals(array[k], asArray[k - start]);
+            }
+    }
 }
--- a/jdk/test/java/util/stream/boottest/java/util/stream/LongNodeTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/boottest/java/util/stream/LongNodeTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -161,4 +161,18 @@
     public void testSpliterator(long[] array, Node.OfLong n) {
         SpliteratorTestHelper.testLongSpliterator(n::spliterator);
     }
+
+    @Test(dataProvider = "nodes")
+    public void testTruncate(long[] array, Node.OfLong n) {
+        int[] nums = new int[] { 0, 1, array.length / 2, array.length - 1, array.length };
+        for (int start : nums)
+            for (int end : nums) {
+                if (start < 0 || end < 0 || end < start || end > array.length)
+                    continue;
+                Node.OfLong slice = n.truncate(start, end, Long[]::new);
+                long[] asArray = slice.asPrimitiveArray();
+                for (int k = start; k < end; k++)
+                    assertEquals(array[k], asArray[k - start]);
+            }
+    }
 }
--- a/jdk/test/java/util/stream/boottest/java/util/stream/NodeTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/boottest/java/util/stream/NodeTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -137,4 +137,18 @@
     public void testSpliterator(Integer[] array, Node<Integer> n) {
         SpliteratorTestHelper.testSpliterator(n::spliterator);
     }
+
+    @Test(dataProvider = "nodes")
+    public void testTruncate(Integer[] array, Node<Integer> n) {
+        int[] nums = new int[] { 0, 1, array.length / 2, array.length - 1, array.length };
+        for (int start : nums)
+            for (int end : nums) {
+                if (start < 0 || end < 0 || end < start || end > array.length)
+                    continue;
+                Node<Integer> slice = n.truncate(start, end, Integer[]::new);
+                Integer[] asArray = slice.asArray(Integer[]::new);
+                for (int k = start; k < end; k++)
+                    assertEquals(array[k], asArray[k - start]);
+            }
+    }
 }
--- a/jdk/test/java/util/stream/boottest/java/util/stream/UnorderedTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/boottest/java/util/stream/UnorderedTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -184,7 +184,6 @@
             UnaryOperator<S> fi = interpose(f, (S s) -> (S) chain(s, checkClearOrderedOp));
             withData(data).
                     terminal(fi, terminalF).
-                    without(TerminalTestScenario.ALL_PARALLEL_SEQUENTIAL).
                     equalator(equalityAsserter).
                     exercise();
         }
@@ -195,7 +194,6 @@
             UnaryOperator<S> fi = interpose(f, (S s) -> (S) chain(s, checkSetOrderedOp));
             withData(data).
                     terminal(fi, s -> terminalF.apply(s.sequential())).
-                    without(TerminalTestScenario.ALL_PARALLEL_SEQUENTIAL).
                     equalator(equalityAsserter).
                     exercise();
         }
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/DistinctOpTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/DistinctOpTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -64,7 +64,6 @@
 
         node = withData(data).
                 stream(s -> s.unordered().distinct()).
-                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
                 exercise();
         assertUnique(node);
 
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ForEachOpTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ForEachOpTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -58,6 +58,17 @@
                             55);
     }
 
+    private <U> ResultAsserter<List<U>> resultAsserter() {
+        return (act, exp, ord, par) -> {
+            if (par) {
+                LambdaTestHelpers.assertContentsUnordered(act, exp);
+            }
+            else {
+                LambdaTestHelpers.assertContents(act, exp);
+            }
+        };
+    }
+
     @Test
     public void testForEachOrdered() {
         List<Integer> input = countTo(10000);
@@ -93,13 +104,13 @@
         // Test head
         withData(data).
                 terminal(terminalFunc).
-                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                resultAsserter(resultAsserter()).
                 exercise();
 
         // Test multiple stages
         withData(data).
                 terminal(s -> s.map(LambdaTestHelpers.identity()), terminalFunc).
-                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                resultAsserter(resultAsserter()).
                 exercise();
     }
 
@@ -141,13 +152,13 @@
         // Test head
         withData(data).
                 terminal(terminalFunc).
-                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                resultAsserter(resultAsserter()).
                 exercise();
 
         // Test multiple stages
         withData(data).
                 terminal(s -> s.map(i -> i), terminalFunc).
-                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                resultAsserter(resultAsserter()).
                 exercise();
     }
 
@@ -189,13 +200,13 @@
         // Test head
         withData(data).
                 terminal(terminalFunc).
-                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                resultAsserter(resultAsserter()).
                 exercise();
 
         // Test multiple stages
         withData(data).
                 terminal(s -> s.map(i -> i), terminalFunc).
-                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                resultAsserter(resultAsserter()).
                 exercise();
     }
 
@@ -237,13 +248,13 @@
         // Test head
         withData(data).
                 terminal(terminalFunc).
-                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                resultAsserter(resultAsserter()).
                 exercise();
 
         // Test multiple stages
         withData(data).
                 terminal(s -> s.map(i -> i), terminalFunc).
-                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
+                resultAsserter(resultAsserter()).
                 exercise();
     }
 
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/GroupByOpTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/GroupByOpTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -133,9 +133,16 @@
             Collector<Integer, Map<Object, List<Integer>>> tab = Collectors.groupingBy(md.m);
             Map<Object, List<Integer>> result =
                     withData(data)
-                            .terminal(s -> s, s -> s.collect(tab))
-                            .parallelEqualityAsserter(s -> StreamOpFlagTestHelper.isStreamOrdered(s) ? GroupByOpTest::assertObjectEquals : GroupByOpTest::assertMultiMapEquals)
-                            .exercise();
+                    .terminal(s -> s, s -> s.collect(tab))
+                    .resultAsserter((act, exp, ord, par) -> {
+                        if (par & !ord) {
+                            GroupByOpTest.assertMultiMapEquals(act, exp);
+                        }
+                        else {
+                            GroupByOpTest.assertObjectEquals(act, exp);
+                        }
+                    })
+                    .exercise();
             assertEquals(result.keySet().size(), md.expectedSize);
         }
     }
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntSliceOpTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntSliceOpTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -145,6 +145,7 @@
         List<Integer> skips = sizes(data.size());
 
         for (int s : skips) {
+            setContext("skip", s);
             Collection<Integer> sr = exerciseOps(data, st -> st.substream(s));
             assertEquals(sr.size(), sliceSize(data.size(), s));
 
@@ -159,7 +160,9 @@
         List<Integer> limits = skips;
 
         for (int s : skips) {
+            setContext("skip", s);
             for (int limit : limits) {
+                setContext("limit", limit);
                 Collection<Integer> sr = exerciseOps(data, st -> st.substream(s).limit(limit));
                 assertEquals(sr.size(), sliceSize(sliceSize(data.size(), s), 0, limit));
 
@@ -174,6 +177,7 @@
         List<Integer> limits = sizes(data.size());
 
         for (int limit : limits) {
+            setContext("limit", limit);
             Collection<Integer> sr = exerciseOps(data, st -> st.limit(limit));
             assertEquals(sr.size(), sliceSize(data.size(), 0, limit));
 
@@ -189,6 +193,7 @@
     @Test(groups = { "serialization-hostile" })
     public void testLimitShortCircuit() {
         for (int l : Arrays.asList(0, 10)) {
+            setContext("limit", l);
             AtomicInteger ai = new AtomicInteger();
             IntStream.range(1, 101)
                     .peek(i -> ai.getAndIncrement())
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntUniqOpTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/IntUniqOpTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -60,7 +60,6 @@
     public void testOpSorted(String name, TestData.OfInt data) {
         Collection<Integer> result = withData(data).
                 stream(s -> s.sorted().distinct().boxed()).
-                parallelEqualityAsserter(LambdaTestHelpers::assertContentsUnordered).
                 exercise();
 
         assertUnique(result);
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/MatchOpTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/MatchOpTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -23,19 +23,16 @@
 package org.openjdk.tests.java.util.stream;
 
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.PrimitiveIterator;
+import java.util.Spliterators;
 import java.util.function.DoublePredicate;
-import java.util.function.DoubleSupplier;
 import java.util.function.Function;
 import java.util.function.IntPredicate;
-import java.util.function.IntSupplier;
 import java.util.function.LongPredicate;
-import java.util.function.LongSupplier;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
 import java.util.stream.DoubleStream;
@@ -46,6 +43,7 @@
 import java.util.stream.LongStreamTestDataProvider;
 import java.util.stream.OpTestCase;
 import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
 import java.util.stream.StreamTestDataProvider;
 import java.util.stream.TestData;
 
@@ -97,6 +95,7 @@
 
     private <T> void assertPredicates(List<T> source, Kind kind, Predicate<T>[] predicates, boolean... answers) {
         for (int i = 0; i < predicates.length; i++) {
+            setContext("i", i);
             boolean match = this.<T>kinds().get(kind).apply(predicates[i]).apply(source.stream());
             assertEquals(answers[i], match, kind.toString() + predicates[i].toString());
         }
@@ -119,7 +118,9 @@
     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
     public void testStream(String name, TestData.OfRef<Integer> data) {
         for (Predicate<Integer> p : INTEGER_PREDICATES) {
+            setContext("p", p);
             for (Kind kind : Kind.values()) {
+                setContext("kind", kind);
                 exerciseTerminalOps(data, this.<Integer>kinds().get(kind).apply(p));
                 exerciseTerminalOps(data, s -> s.filter(pFalse), this.<Integer>kinds().get(kind).apply(p));
                 exerciseTerminalOps(data, s -> s.filter(pEven), this.<Integer>kinds().get(kind).apply(p));
@@ -128,29 +129,40 @@
     }
 
     public void testInfinite() {
-        class CycleSupplier<T> implements Supplier<T> {
-            final Iterable<T> source;
-            Iterator<T> i = Collections.emptyIterator();
+        class CycleIterator implements Iterator<Integer> {
+            final Supplier<Iterator<Integer>> source;
+            Iterator<Integer> i = null;
 
-            CycleSupplier(Iterable<T> source) {
+            CycleIterator(Supplier<Iterator<Integer>> source) {
                 this.source = source;
             }
 
             @Override
-            public T get() {
-                if (!i.hasNext()) {
-                    i = source.iterator();
+            public Integer next() {
+                if (i == null || !i.hasNext()) {
+                    i = source.get();
                 }
                 return i.next();
             }
+
+            @Override
+            public boolean hasNext() {
+                if (i == null || !i.hasNext()) {
+                    i = source.get();
+                }
+                return i.hasNext();
+            }
         }
 
-        assertFalse(Stream.generate(new CycleSupplier<>(Arrays.asList(1, 2, 3, 4))).allMatch(i -> i > 3));
-        assertTrue(Stream.generate(new CycleSupplier<>(Arrays.asList(1, 2, 3, 4))).anyMatch(i -> i > 3));
-        assertFalse(Stream.generate(new CycleSupplier<>(Arrays.asList(1, 2, 3, 4))).noneMatch(i -> i > 3));
-        assertFalse(Stream.generate(new CycleSupplier<>(Arrays.asList(1, 2, 3, 4))).parallel().allMatch(i -> i > 3));
-        assertTrue(Stream.generate(new CycleSupplier<>(Arrays.asList(1, 2, 3, 4))).parallel().anyMatch(i -> i > 3));
-        assertFalse(Stream.generate(new CycleSupplier<>(Arrays.asList(1, 2, 3, 4))).parallel().noneMatch(i -> i > 3));
+        Supplier<Iterator<Integer>> source = () -> Arrays.asList(1, 2, 3, 4).iterator();
+        Supplier<Stream<Integer>> s = () -> StreamSupport.stream(Spliterators.spliteratorUnknownSize(new CycleIterator(source), 0));
+
+        assertFalse(s.get().allMatch(i -> i > 3));
+        assertTrue(s.get().anyMatch(i -> i > 3));
+        assertFalse(s.get().noneMatch(i -> i > 3));
+        assertFalse(s.get().parallel().allMatch(i -> i > 3));
+        assertTrue(s.get().parallel().anyMatch(i -> i > 3));
+        assertFalse(s.get().parallel().noneMatch(i -> i > 3));
     }
 
     //
@@ -168,6 +180,7 @@
 
     private void assertIntPredicates(Supplier<IntStream> source, Kind kind, IntPredicate[] predicates, boolean... answers) {
         for (int i = 0; i < predicates.length; i++) {
+            setContext("i", i);
             boolean match = intKinds.get(kind).apply(predicates[i]).apply(source.get());
             assertEquals(answers[i], match, kind.toString() + predicates[i].toString());
         }
@@ -189,40 +202,52 @@
 
     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
     public void testIntStream(String name, TestData.OfInt data) {
-        for (IntPredicate p : INT_PREDICATES)
+        for (IntPredicate p : INT_PREDICATES) {
+            setContext("p", p);
             for (Kind kind : Kind.values()) {
+                setContext("kind", kind);
                 exerciseTerminalOps(data, intKinds.get(kind).apply(p));
                 exerciseTerminalOps(data, s -> s.filter(ipFalse), intKinds.get(kind).apply(p));
                 exerciseTerminalOps(data, s -> s.filter(ipEven), intKinds.get(kind).apply(p));
             }
+        }
     }
 
     public void testIntInfinite() {
-        class CycleSupplier implements IntSupplier {
+        class CycleIterator implements PrimitiveIterator.OfInt {
             final Supplier<PrimitiveIterator.OfInt> source;
             PrimitiveIterator.OfInt i = null;
 
-            CycleSupplier(Supplier<PrimitiveIterator.OfInt> source) {
+            CycleIterator(Supplier<PrimitiveIterator.OfInt> source) {
                 this.source = source;
             }
 
             @Override
-            public int getAsInt() {
+            public int nextInt() {
                 if (i == null || !i.hasNext()) {
                     i = source.get();
                 }
                 return i.nextInt();
             }
+
+            @Override
+            public boolean hasNext() {
+                if (i == null || !i.hasNext()) {
+                    i = source.get();
+                }
+                return i.hasNext();
+            }
         }
 
         Supplier<PrimitiveIterator.OfInt> source = () -> Arrays.stream(new int[]{1, 2, 3, 4}).iterator();
+        Supplier<IntStream> s = () -> StreamSupport.intStream(Spliterators.spliteratorUnknownSize(new CycleIterator(source), 0));
 
-        assertFalse(IntStream.generate(new CycleSupplier(source)).allMatch(i -> i > 3));
-        assertTrue(IntStream.generate(new CycleSupplier(source)).anyMatch(i -> i > 3));
-        assertFalse(IntStream.generate(new CycleSupplier(source)).noneMatch(i -> i > 3));
-        assertFalse(IntStream.generate(new CycleSupplier(source)).parallel().allMatch(i -> i > 3));
-        assertTrue(IntStream.generate(new CycleSupplier(source)).parallel().anyMatch(i -> i > 3));
-        assertFalse(IntStream.generate(new CycleSupplier(source)).parallel().noneMatch(i -> i > 3));
+        assertFalse(s.get().allMatch(i -> i > 3));
+        assertTrue(s.get().anyMatch(i -> i > 3));
+        assertFalse(s.get().noneMatch(i -> i > 3));
+        assertFalse(s.get().parallel().allMatch(i -> i > 3));
+        assertTrue(s.get().parallel().anyMatch(i -> i > 3));
+        assertFalse(s.get().parallel().noneMatch(i -> i > 3));
     }
 
     //
@@ -240,6 +265,7 @@
 
     private void assertLongPredicates(Supplier<LongStream> source, Kind kind, LongPredicate[] predicates, boolean... answers) {
         for (int i = 0; i < predicates.length; i++) {
+            setContext("i", i);
             boolean match = longKinds.get(kind).apply(predicates[i]).apply(source.get());
             assertEquals(answers[i], match, kind.toString() + predicates[i].toString());
         }
@@ -261,40 +287,52 @@
 
     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
     public void testLongStream(String name, TestData.OfLong data) {
-        for (LongPredicate p : LONG_PREDICATES)
+        for (LongPredicate p : LONG_PREDICATES) {
+            setContext("p", p);
             for (Kind kind : Kind.values()) {
+                setContext("kind", kind);
                 exerciseTerminalOps(data, longKinds.get(kind).apply(p));
                 exerciseTerminalOps(data, s -> s.filter(lpFalse), longKinds.get(kind).apply(p));
                 exerciseTerminalOps(data, s -> s.filter(lpEven), longKinds.get(kind).apply(p));
             }
+        }
     }
 
     public void testLongInfinite() {
-        class CycleSupplier implements LongSupplier {
+        class CycleIterator implements PrimitiveIterator.OfLong {
             final Supplier<PrimitiveIterator.OfLong> source;
             PrimitiveIterator.OfLong i = null;
 
-            CycleSupplier(Supplier<PrimitiveIterator.OfLong> source) {
+            CycleIterator(Supplier<PrimitiveIterator.OfLong> source) {
                 this.source = source;
             }
 
             @Override
-            public long getAsLong() {
+            public long nextLong() {
                 if (i == null || !i.hasNext()) {
                     i = source.get();
                 }
                 return i.nextLong();
             }
+
+            @Override
+            public boolean hasNext() {
+                if (i == null || !i.hasNext()) {
+                    i = source.get();
+                }
+                return i.hasNext();
+            }
         }
 
         Supplier<PrimitiveIterator.OfLong> source = () -> Arrays.stream(new long[]{1, 2, 3, 4}).iterator();
+        Supplier<LongStream> s = () -> StreamSupport.longStream(Spliterators.spliteratorUnknownSize(new CycleIterator(source), 0));
 
-        assertFalse(LongStream.generate(new CycleSupplier(source)).allMatch(i -> i > 3));
-        assertTrue(LongStream.generate(new CycleSupplier(source)).anyMatch(i -> i > 3));
-        assertFalse(LongStream.generate(new CycleSupplier(source)).noneMatch(i -> i > 3));
-        assertFalse(LongStream.generate(new CycleSupplier(source)).parallel().allMatch(i -> i > 3));
-        assertTrue(LongStream.generate(new CycleSupplier(source)).parallel().anyMatch(i -> i > 3));
-        assertFalse(LongStream.generate(new CycleSupplier(source)).parallel().noneMatch(i -> i > 3));
+        assertFalse(s.get().allMatch(i -> i > 3));
+        assertTrue(s.get().anyMatch(i -> i > 3));
+        assertFalse(s.get().noneMatch(i -> i > 3));
+        assertFalse(s.get().parallel().allMatch(i -> i > 3));
+        assertTrue(s.get().parallel().anyMatch(i -> i > 3));
+        assertFalse(s.get().parallel().noneMatch(i -> i > 3));
     }
 
     //
@@ -312,6 +350,7 @@
 
     private void assertDoublePredicates(Supplier<DoubleStream> source, Kind kind, DoublePredicate[] predicates, boolean... answers) {
         for (int i = 0; i < predicates.length; i++) {
+            setContext("i", i);
             boolean match = doubleKinds.get(kind).apply(predicates[i]).apply(source.get());
             assertEquals(answers[i], match, kind.toString() + predicates[i].toString());
         }
@@ -333,39 +372,51 @@
 
     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
     public void testDoubleStream(String name, TestData.OfDouble data) {
-        for (DoublePredicate p : DOUBLE_PREDICATES)
+        for (DoublePredicate p : DOUBLE_PREDICATES) {
+            setContext("p", p);
             for (Kind kind : Kind.values()) {
+                setContext("kind", kind);
                 exerciseTerminalOps(data, doubleKinds.get(kind).apply(p));
                 exerciseTerminalOps(data, s -> s.filter(dpFalse), doubleKinds.get(kind).apply(p));
                 exerciseTerminalOps(data, s -> s.filter(dpEven), doubleKinds.get(kind).apply(p));
             }
+        }
     }
 
     public void testDoubleInfinite() {
-        class CycleSupplier implements DoubleSupplier {
+        class CycleIterator implements PrimitiveIterator.OfDouble {
             final Supplier<PrimitiveIterator.OfDouble> source;
             PrimitiveIterator.OfDouble i = null;
 
-            CycleSupplier(Supplier<PrimitiveIterator.OfDouble> source) {
+            CycleIterator(Supplier<PrimitiveIterator.OfDouble> source) {
                 this.source = source;
             }
 
             @Override
-            public double getAsDouble() {
+            public double nextDouble() {
                 if (i == null || !i.hasNext()) {
                     i = source.get();
                 }
                 return i.nextDouble();
             }
+
+            @Override
+            public boolean hasNext() {
+                if (i == null || !i.hasNext()) {
+                    i = source.get();
+                }
+                return i.hasNext();
+            }
         }
 
         Supplier<PrimitiveIterator.OfDouble> source = () -> Arrays.stream(new double[]{1, 2, 3, 4}).iterator();
+        Supplier<DoubleStream> s = () -> StreamSupport.doubleStream(Spliterators.spliteratorUnknownSize(new CycleIterator(source), 0));
 
-        assertFalse(DoubleStream.generate(new CycleSupplier(source)).allMatch(i -> i > 3));
-        assertTrue(DoubleStream.generate(new CycleSupplier(source)).anyMatch(i -> i > 3));
-        assertFalse(DoubleStream.generate(new CycleSupplier(source)).noneMatch(i -> i > 3));
-        assertFalse(DoubleStream.generate(new CycleSupplier(source)).parallel().allMatch(i -> i > 3));
-        assertTrue(DoubleStream.generate(new CycleSupplier(source)).parallel().anyMatch(i -> i > 3));
-        assertFalse(DoubleStream.generate(new CycleSupplier(source)).parallel().noneMatch(i -> i > 3));
+        assertFalse(s.get().allMatch(i -> i > 3));
+        assertTrue(s.get().anyMatch(i -> i > 3));
+        assertFalse(s.get().noneMatch(i -> i > 3));
+        assertFalse(s.get().parallel().allMatch(i -> i > 3));
+        assertTrue(s.get().parallel().anyMatch(i -> i > 3));
+        assertFalse(s.get().parallel().noneMatch(i -> i > 3));
     }
 }
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/RangeTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/RangeTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -58,7 +58,9 @@
     public void testIntRange() {
         // Half-open
         for (int start : Arrays.asList(1, 10, -1, -10)) {
+            setContext("start", start);
             for (int end : Arrays.asList(1, 10, -1, -10)) {
+                setContext("end", end);
                 int size = (start < end) ? end - start : 0;
                 int[] exp = new int[size];
                 for (int i = start, p = 0; i < end; i++, p++) {
@@ -76,7 +78,9 @@
 
         // Closed
         for (int start : Arrays.asList(1, 10, -1, -10)) {
+            setContext("start", start);
             for (int end : Arrays.asList(1, 10, -1, -10)) {
+                setContext("end", end);
                 int size = (start <= end) ? end - start + 1 : 0;
                 int[] exp = new int[size];
                 for (int i = start, p = 0; i <= end; i++, p++) {
@@ -144,7 +148,9 @@
     public void testLongRange() {
         // Half-open
         for (long start : Arrays.asList(1, 1000, -1, -1000)) {
+            setContext("start", start);
             for (long end : Arrays.asList(1, 1000, -1, -1000)) {
+                setContext("end", end);
                 long size = start < end ? end - start : 0;
                 long[] exp = new long[(int) size];
                 for (long i = start, p = 0; i < end; i++, p++) {
@@ -162,7 +168,9 @@
 
         // Closed
         for (long start : Arrays.asList(1, 1000, -1, -1000)) {
+            setContext("start", start);
             for (long end : Arrays.asList(1, 1000, -1, -1000)) {
+                setContext("end", end);
                 long size = start <= end ? end - start + 1: 0;
                 long[] exp = new long[(int) size];
                 for (long i = start, p = 0; i <= end; i++, p++) {
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ReduceByOpTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ReduceByOpTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -51,6 +51,7 @@
         Map<Boolean, Integer> result = data.stream().collect(groupingBy(LambdaTestHelpers.forPredicate(pEven, true, false), reducing(0, rPlus)));
         assertEquals(result.size(), gbResult.size());
         for (Map.Entry<Boolean, Integer> entry : result.entrySet()) {
+            setContext("entry", entry);
             Boolean key = entry.getKey();
             assertEquals(entry.getValue(), data.stream().filter(e -> pEven.test(e) == key).reduce(0, rPlus));
         }
@@ -59,7 +60,9 @@
         Map<Integer, List<Integer>> mgResult = exerciseTerminalOps(data, s -> s.collect(groupingBy(mId)));
         Map<Integer, Integer> miResult = exerciseTerminalOps(data, s -> s.collect(groupingBy(mId, reducing(0, e -> 1, Integer::sum))));
         assertEquals(miResult.keySet().size(), uniqueSize);
-        for (Map.Entry<Integer, Integer> entry : miResult.entrySet())
+        for (Map.Entry<Integer, Integer> entry : miResult.entrySet()) {
+            setContext("entry", entry);
             assertEquals((int) entry.getValue(), mgResult.get(entry.getKey()).size());
+        }
     }
 }
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SequentialOpTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SequentialOpTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -22,13 +22,14 @@
  */
 package org.openjdk.tests.java.util.stream;
 
+import java.util.Comparators;
 import java.util.stream.LambdaTestHelpers;
 import java.util.stream.OpTestCase;
 import java.util.stream.StreamTestDataProvider;
 import org.testng.annotations.Test;
 
-import java.util.Comparators;
 import java.util.Iterator;
+import java.util.Comparator;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Function;
 import java.util.function.Supplier;
@@ -64,8 +65,12 @@
                     (UnaryOperator<Stream<Integer>>) s -> s.parallel().map(id).peek(e -> { counter.incrementAndGet(); }).map(id)
         };
 
-        for (Supplier<Stream<Integer>> supp : suppliers)
-            for (UnaryOperator<Stream<Integer>> config : configs) {
+        for (int i = 0; i < suppliers.length; i++) {
+            setContext("supplierIndex", i);
+            Supplier<Stream<Integer>> supp = suppliers[i];
+            for (int j = 0; j < configs.length; j++) {
+                setContext("configIndex", j);
+                UnaryOperator<Stream<Integer>> config = configs[j];
                 counter.set(0);
                 Stream<Integer> stream = config.apply(supp.get());
                 assertEquals(0, counter.get());
@@ -86,6 +91,7 @@
                 });
                 assertTrue(data.size() == 0 || counter.get() > 0);
             }
+        }
     }
 
     @SuppressWarnings({"rawtypes", "unchecked"})
@@ -96,7 +102,8 @@
                 = new UnaryOperator[] {
                 (UnaryOperator<Stream<Integer>>) s -> s,
                 (UnaryOperator<Stream<Integer>>) s -> s.sequential(),
-                (UnaryOperator<Stream<Integer>>) s -> s.parallel()
+                (UnaryOperator<Stream<Integer>>) s -> s.parallel(),
+                (UnaryOperator<Stream<Integer>>) s -> s.unordered()
         };
         UnaryOperator<Stream<Integer>>[] stuff
                 = new UnaryOperator[] {
@@ -107,12 +114,23 @@
                 (UnaryOperator<Stream<Integer>>) s -> s.filter(LambdaTestHelpers.pEven).sorted(Comparators.naturalOrder()).map(id),
         };
 
-        for (UnaryOperator<Stream<Integer>> c1 : changers)
-            for (UnaryOperator<Stream<Integer>> s1 : stuff)
-                for (UnaryOperator<Stream<Integer>> c2 : changers)
-                    for (UnaryOperator<Stream<Integer>> s2 : stuff) {
+        for (int c1Index = 0; c1Index < changers.length; c1Index++) {
+            setContext("c1Index", c1Index);
+            UnaryOperator<Stream<Integer>> c1 = changers[c1Index];
+            for (int s1Index = 0; s1Index < stuff.length; s1Index++) {
+                setContext("s1Index", s1Index);
+                UnaryOperator<Stream<Integer>> s1 = stuff[s1Index];
+                for (int c2Index = 0; c2Index < changers.length; c2Index++) {
+                    setContext("c2Index", c2Index);
+                    UnaryOperator<Stream<Integer>> c2 = changers[c2Index];
+                    for (int s2Index = 0; s2Index < stuff.length; s2Index++) {
+                        setContext("s2Index", s2Index);
+                        UnaryOperator<Stream<Integer>> s2 = stuff[s2Index];
                         UnaryOperator<Stream<Integer>> composed = s -> s2.apply(c2.apply(s1.apply(c1.apply(s))));
                         exerciseOps(data, composed);
                     }
+                }
+            }
+        }
     }
 }
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/SliceOpTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -26,7 +26,11 @@
 
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
+import java.util.function.Function;
+import java.util.stream.DoubleStream;
+import java.util.stream.IntStream;
+import java.util.stream.LambdaTestHelpers;
+import java.util.stream.LongStream;
 import java.util.stream.OpTestCase;
 import java.util.stream.Stream;
 import java.util.stream.StreamTestDataProvider;
@@ -145,19 +149,20 @@
         List<Integer> skips = sizes(data.size());
 
         for (int s : skips) {
-            Collection<Integer> sr = exerciseOpsInt(data,
-                                                      st -> st.substream(s),
-                                                      st -> st.substream(s),
-                                                      st -> st.substream(s),
-                                                      st -> st.substream(s));
-            assertEquals(sr.size(), sliceSize(data.size(), s));
+            setContext("skip", s);
+            testSliceMulti(data,
+                           sliceSize(data.size(), s),
+                           st -> st.substream(s),
+                           st -> st.substream(s),
+                           st -> st.substream(s),
+                           st -> st.substream(s));
 
-            sr = exerciseOpsInt(data,
-                                  st -> st.substream(s).substream(s / 2),
-                                  st -> st.substream(s).substream(s / 2),
-                                  st -> st.substream(s).substream(s / 2),
-                                  st -> st.substream(s).substream(s / 2));
-            assertEquals(sr.size(), sliceSize(sliceSize(data.size(), s), s/2));
+            testSliceMulti(data,
+                           sliceSize(sliceSize(data.size(), s), s/2),
+                           st -> st.substream(s).substream(s / 2),
+                           st -> st.substream(s).substream(s / 2),
+                           st -> st.substream(s).substream(s / 2),
+                           st -> st.substream(s).substream(s / 2));
         }
     }
 
@@ -167,20 +172,22 @@
         List<Integer> limits = skips;
 
         for (int s : skips) {
-            for (int limit : limits) {
-                Collection<Integer> sr = exerciseOpsInt(data,
-                                                        st -> st.substream(s).limit(limit),
-                                                        st -> st.substream(s).limit(limit),
-                                                        st -> st.substream(s).limit(limit),
-                                                        st -> st.substream(s).limit(limit));
-                assertEquals(sr.size(), sliceSize(sliceSize(data.size(), s), 0, limit));
+            setContext("skip", s);
+            for (int l : limits) {
+                setContext("limit", l);
+                testSliceMulti(data,
+                               sliceSize(sliceSize(data.size(), s), 0, l),
+                               st -> st.substream(s).limit(l),
+                               st -> st.substream(s).limit(l),
+                               st -> st.substream(s).limit(l),
+                               st -> st.substream(s).limit(l));
 
-                sr = exerciseOpsInt(data,
-                                    st -> st.substream(s, limit+s),
-                                    st -> st.substream(s, limit+s),
-                                    st -> st.substream(s, limit+s),
-                                    st -> st.substream(s, limit+s));
-                assertEquals(sr.size(), sliceSize(data.size(), s, limit));
+                testSliceMulti(data,
+                               sliceSize(data.size(), s, l),
+                                st -> st.substream(s, l+s),
+                                st -> st.substream(s, l+s),
+                                st -> st.substream(s, l+s),
+                                st -> st.substream(s, l+s));
             }
         }
     }
@@ -189,20 +196,74 @@
     public void testLimitOps(String name, TestData.OfRef<Integer> data) {
         List<Integer> limits = sizes(data.size());
 
-        for (int limit : limits) {
-            Collection<Integer> sr = exerciseOpsInt(data,
-                                                    st -> st.limit(limit),
-                                                    st -> st.limit(limit),
-                                                    st -> st.limit(limit),
-                                                    st -> st.limit(limit));
-            assertEquals(sr.size(), sliceSize(data.size(), 0, limit));
+        for (int l : limits) {
+            setContext("limit", l);
+            testSliceMulti(data,
+                           sliceSize(data.size(), 0, l),
+                           st -> st.limit(l),
+                           st -> st.limit(l),
+                           st -> st.limit(l),
+                           st -> st.limit(l));
+        }
+
+        for (int l : limits) {
+            setContext("limit", l);
+            testSliceMulti(data,
+                           sliceSize(sliceSize(data.size(), 0, l), 0, l / 2),
+                           st -> st.limit(l).limit(l / 2),
+                           st -> st.limit(l).limit(l / 2),
+                           st -> st.limit(l).limit(l / 2),
+                           st -> st.limit(l).limit(l / 2));
+        }
+    }
+
+    private ResultAsserter<Iterable<Integer>> sliceResultAsserter(Iterable<Integer> data,
+                                                                  int expectedSize) {
+        return (act, exp, ord, par) -> {
+            if (par & !ord) {
+                List<Integer> expected = new ArrayList<>();
+                data.forEach(expected::add);
+
+                List<Integer> actual = new ArrayList<>();
+                act.forEach(actual::add);
 
-            sr = exerciseOpsInt(data,
-                                st -> st.limit(limit).limit(limit / 2),
-                                st -> st.limit(limit).limit(limit / 2),
-                                st -> st.limit(limit).limit(limit / 2),
-                                st -> st.limit(limit).limit(limit / 2));
-            assertEquals(sr.size(), sliceSize(sliceSize(data.size(), 0, limit), 0, limit/2));
+                assertEquals(actual.size(), expectedSize);
+                assertTrue(expected.containsAll(actual));
+            }
+            else {
+                LambdaTestHelpers.assertContents(act, exp);
+            }
+        };
+    }
+
+    private void testSliceMulti(TestData.OfRef<Integer> data,
+                                int expectedSize,
+                                Function<Stream<Integer>, Stream<Integer>> mRef,
+                                Function<IntStream, IntStream> mInt,
+                                Function<LongStream, LongStream> mLong,
+                                Function<DoubleStream, DoubleStream> mDouble) {
+
+        @SuppressWarnings({ "rawtypes", "unchecked" })
+        Function<Stream<Integer>, Stream<Integer>>[] ms = new Function[4];
+        ms[0] = mRef;
+        ms[1] = s -> mInt.apply(s.mapToInt(e -> e)).mapToObj(e -> e);
+        ms[2] = s -> mLong.apply(s.mapToLong(e -> e)).mapToObj(e -> (int) e);
+        ms[3] = s -> mDouble.apply(s.mapToDouble(e -> e)).mapToObj(e -> (int) e);
+        testSliceMulti(data, expectedSize, ms);
+    }
+
+    @SafeVarargs
+    private final void testSliceMulti(TestData.OfRef<Integer> data,
+                                      int expectedSize,
+                                      Function<Stream<Integer>, Stream<Integer>>... ms) {
+        for (int i = 0; i < ms.length; i++) {
+            setContext("mIndex", i);
+            Function<Stream<Integer>, Stream<Integer>> m = ms[i];
+            Collection<Integer> sr = withData(data)
+                    .stream(m)
+                    .resultAsserter(sliceResultAsserter(data, expectedSize))
+                    .exercise();
+            assertEquals(sr.size(), expectedSize);
         }
     }
 
@@ -215,6 +276,7 @@
     @Test(groups = { "serialization-hostile" })
     public void testLimitShortCircuit() {
         for (int l : Arrays.asList(0, 10)) {
+            setContext("l", l);
             AtomicInteger ai = new AtomicInteger();
             countTo(100).stream()
                     .peek(i -> ai.getAndIncrement())
@@ -224,18 +286,6 @@
         }
     }
 
-    public void testSkipParallel() {
-        List<Integer> l = countTo(1000).parallelStream().substream(200).limit(200).sequential().collect(Collectors.toList());
-        assertEquals(l.size(), 200);
-        assertEquals(l.get(l.size() -1).intValue(), 400);
-    }
-
-    public void testLimitParallel() {
-        List<Integer> l = countTo(1000).parallelStream().limit(500).sequential().collect(Collectors.toList());
-        assertEquals(l.size(), 500);
-        assertEquals(l.get(l.size() -1).intValue(), 500);
-    }
-
     private List<Integer> sizes(int size) {
         if (size < 4) {
             return Arrays.asList(0, 1, 2, 3, 4, 6);
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamLinkTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamLinkTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -47,6 +47,7 @@
     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
     public void testManyStreams(String name, TestData.OfRef<Integer> data) {
         for (int n : sizes) {
+            setContext("n", n);
             List<Integer> expected = data.stream().map(e -> (Integer) (e + n)).collect(Collectors.toList());
 
             withData(data).
@@ -59,6 +60,7 @@
     @Test(dataProvider = "IntStreamTestData", dataProviderClass = IntStreamTestDataProvider.class)
     public void testIntManyStreams(String name, TestData.OfInt data) {
         for (int n : sizes) {
+            setContext("n", n);
             int[] expected = data.stream().map(e -> e + n).toArray();
 
             withData(data).
@@ -71,6 +73,7 @@
     @Test(dataProvider = "LongStreamTestData", dataProviderClass = LongStreamTestDataProvider.class)
     public void testLongManyStreams(String name, TestData.OfLong data) {
         for (int n : sizes) {
+            setContext("n", n);
             long[] expected = data.stream().map(e -> e + n).toArray();
 
             withData(data).
@@ -83,6 +86,7 @@
     @Test(dataProvider = "DoubleStreamTestData", dataProviderClass = DoubleStreamTestDataProvider.class)
     public void testDoubleManyStreams(String name, TestData.OfDouble data) {
         for (int n : sizes) {
+            setContext("n", n);
             double[] expected = data.stream().map(e -> accumulate(e, n)).toArray();
 
             withData(data).
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamSpliteratorTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/StreamSpliteratorTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -256,9 +256,14 @@
                 s -> s.map(LambdaTestHelpers.identity()).parallel()
         );
 
-        for (Consumer<Stream<Integer>> terminalOp : terminalOps) {
-            for (UnaryOperator<Stream<Integer>> intermediateOp : intermediateOps) {
-                for (boolean proxyEstimateSize : new boolean[]{false, true}) {
+        for (int i = 0; i < terminalOps.size(); i++) {
+            setContext("termOpIndex", i);
+            Consumer<Stream<Integer>> terminalOp = terminalOps.get(i);
+            for (int j = 0; j < intermediateOps.size(); j++) {
+                setContext("intOpIndex", j);
+                UnaryOperator<Stream<Integer>> intermediateOp = intermediateOps.get(j);
+                for (boolean proxyEstimateSize : new boolean[] {false, true}) {
+                    setContext("proxyEstimateSize", proxyEstimateSize);
                     Spliterator<Integer> sp = intermediateOp.apply(l.stream()).spliterator();
                     ProxyNoExactSizeSpliterator<Integer> psp = new ProxyNoExactSizeSpliterator<>(sp, proxyEstimateSize);
                     Stream<Integer> s = StreamSupport.parallelStream(psp);
@@ -345,9 +350,14 @@
                 s -> s.map(i -> i).parallel()
         );
 
-        for (Consumer<IntStream> terminalOp : terminalOps) {
-            for (UnaryOperator<IntStream> intermediateOp : intermediateOps) {
-                for (boolean proxyEstimateSize : new boolean[]{false, true}) {
+        for (int i = 0; i < terminalOps.size(); i++) {
+            setContext("termOpIndex", i);
+            Consumer<IntStream> terminalOp = terminalOps.get(i);
+            for (int j = 0; j < intermediateOps.size(); j++) {
+                setContext("intOpIndex", j);
+                UnaryOperator<IntStream> intermediateOp = intermediateOps.get(j);
+                for (boolean proxyEstimateSize : new boolean[] {false, true}) {
+                    setContext("proxyEstimateSize", proxyEstimateSize);
                     // Size is assumed to be larger than the target size for no splitting
                     // @@@ Need way to obtain the target size
                     Spliterator.OfInt sp = intermediateOp.apply(IntStream.range(0, 1000)).spliterator();
@@ -433,9 +443,14 @@
                 s -> s.map(i -> i).parallel()
         );
 
-        for (Consumer<LongStream> terminalOp : terminalOps) {
-            for (UnaryOperator<LongStream> intermediateOp : intermediateOps) {
-                for (boolean proxyEstimateSize : new boolean[]{false, true}) {
+        for (int i = 0; i < terminalOps.size(); i++) {
+            Consumer<LongStream> terminalOp = terminalOps.get(i);
+            setContext("termOpIndex", i);
+            for (int j = 0; j < intermediateOps.size(); j++) {
+                setContext("intOpIndex", j);
+                UnaryOperator<LongStream> intermediateOp = intermediateOps.get(j);
+                for (boolean proxyEstimateSize : new boolean[] {false, true}) {
+                    setContext("proxyEstimateSize", proxyEstimateSize);
                     // Size is assumed to be larger than the target size for no splitting
                     // @@@ Need way to obtain the target size
                     Spliterator.OfLong sp = intermediateOp.apply(LongStream.range(0, 1000)).spliterator();
@@ -521,9 +536,14 @@
                 s -> s.map(i -> i).parallel()
         );
 
-        for (Consumer<DoubleStream> terminalOp : terminalOps) {
-            for (UnaryOperator<DoubleStream> intermediateOp : intermediateOps) {
-                for (boolean proxyEstimateSize : new boolean[]{false, true}) {
+        for (int i = 0; i < terminalOps.size(); i++) {
+            Consumer<DoubleStream> terminalOp = terminalOps.get(i);
+            setContext("termOpIndex", i);
+            for (int j = 0; j < intermediateOps.size(); j++) {
+                UnaryOperator<DoubleStream> intermediateOp = intermediateOps.get(j);
+                setContext("intOpIndex", j);
+                for (boolean proxyEstimateSize : new boolean[] {false, true}) {
+                    setContext("proxyEstimateSize", proxyEstimateSize);
                     // Size is assumed to be larger than the target size for no splitting
                     // @@@ Need way to obtain the target size
                     Spliterator.OfDouble sp = intermediateOp.apply(IntStream.range(0, 1000).asDoubleStream()).spliterator();
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/TabulatorsTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -202,26 +202,38 @@
         }
     }
 
+    private <T> ResultAsserter<T> mapTabulationAsserter(boolean ordered) {
+        return (act, exp, ord, par) -> {
+            if (par & (!ordered || !ord)) {
+                TabulatorsTest.nestedMapEqualityAssertion(act, exp);
+            }
+            else {
+                LambdaTestHelpers.assertContentsEqual(act, exp);
+            }
+        };
+    }
+
     private<T, M extends Map>
     void exerciseMapTabulation(TestData<T, Stream<T>> data,
                                Collector<T, ? extends M> collector,
                                TabulationAssertion<T, M> assertion)
             throws ReflectiveOperationException {
-        boolean ordered = data.isOrdered()
-                          && !collector.characteristics().contains(Collector.Characteristics.UNORDERED);
+        boolean ordered = !collector.characteristics().contains(Collector.Characteristics.UNORDERED);
+
         M m = withData(data)
                 .terminal(s -> s.collect(collector))
-                .parallelEqualityAsserter(ordered ? LambdaTestHelpers::assertContentsEqual : this::nestedMapEqualityAssertion)
+                .resultAsserter(mapTabulationAsserter(ordered))
                 .exercise();
         assertion.assertValue(m, () -> data.stream(), ordered);
+
         m = withData(data)
                 .terminal(s -> s.unordered().collect(collector))
-                .parallelEqualityAsserter(this::nestedMapEqualityAssertion)
+                .resultAsserter(mapTabulationAsserter(ordered))
                 .exercise();
         assertion.assertValue(m, () -> data.stream(), false);
     }
 
-    private void nestedMapEqualityAssertion(Object o1, Object o2) {
+    private static void nestedMapEqualityAssertion(Object o1, Object o2) {
         if (o1 instanceof Map) {
             Map m1 = (Map) o1;
             Map m2 = (Map) o2;
--- a/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ToArrayOpTest.java	Thu Jun 20 11:02:28 2013 +0200
+++ b/jdk/test/java/util/stream/test/org/openjdk/tests/java/util/stream/ToArrayOpTest.java	Thu Jun 20 11:15:23 2013 +0200
@@ -29,6 +29,7 @@
 import java.util.stream.*;
 
 import static java.util.stream.LambdaTestHelpers.*;
+import static org.testng.Assert.assertEquals;
 
 
 /**
@@ -134,15 +135,51 @@
                     s -> s.sorted()
             ));
 
+    private <T extends Object> ResultAsserter<T[]> statefulOpResultAsserter(TestData.OfRef<Integer> data) {
+        return (act, exp, ord, par) -> {
+            if (par) {
+                if (!data.isOrdered()) {
+                    // Relax the checking if the data source is unordered
+                    // It is not exactly possible to determine if the limit
+                    // operation is present and if it is before or after
+                    // the sorted operation
+                    // If the limit operation is present and before the sorted
+                    // operation then the sub-set output after limit is a
+                    // non-deterministic sub-set of the source
+                    List<Integer> expected = new ArrayList<>();
+                    data.forEach(expected::add);
+
+                    List<T> actual = Arrays.asList(act);
+
+                    assertEquals(actual.size(), exp.length);
+                    assertTrue(expected.containsAll(actual));
+                    return;
+                }
+                else if (!ord) {
+                    LambdaTestHelpers.assertContentsUnordered(Arrays.asList(act),
+                                                              Arrays.asList(exp));
+                    return;
+                }
+            }
+            assertEquals(act, exp);
+        };
+    }
+
     @Test(dataProvider = "StreamTestData<Integer>", dataProviderClass = StreamTestDataProvider.class)
     public void testStatefulOpPermutations(String name, TestData.OfRef<Integer> data) {
         for (Function<Stream<Integer>, Stream<Integer>> f : statefulOpPermutations) {
-            exerciseTerminalOps(data, f, s -> s.toArray());
+            withData(data).terminal(f, s -> s.toArray())
+                    .resultAsserter(statefulOpResultAsserter(data))
+                    .exercise();
 
-            Integer[] is = exerciseTerminalOps(data, f, s -> s.toArray(Integer[]::new));
+            Integer[] is = withData(data).terminal(f, s -> s.toArray(Integer[]::new))
+                    .resultAsserter(statefulOpResultAsserter(data))
+                    .exercise();
             assertEquals(is.getClass(), Integer[].class);
 
-            Number[] ns = exerciseTerminalOps(data, f, s -> s.toArray(Number[]::new));
+            Number[] ns = withData(data).terminal(f, s -> s.toArray(Number[]::new))
+                    .resultAsserter(statefulOpResultAsserter(data))
+                    .exercise();
             assertEquals(ns.getClass(), Number[].class);
 
             if (data.size() > 0) {