• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 package org.openjdk.tests.java.util.stream;
24 
25 import org.testng.annotations.DataProvider;
26 import org.testng.annotations.Test;
27 
28 import org.openjdk.testlib.java.util.stream.OpTestCase;
29 import org.openjdk.testlib.java.util.stream.StreamTestDataProvider;
30 import org.openjdk.testlib.java.util.stream.TestData;
31 import org.openjdk.testlib.java.util.stream.DoubleStreamTestScenario;
32 import org.openjdk.testlib.java.util.stream.IntStreamTestScenario;
33 import org.openjdk.testlib.java.util.stream.LongStreamTestScenario;
34 import org.openjdk.testlib.java.util.stream.LambdaTestHelpers;
35 import org.openjdk.testlib.java.util.stream.StreamTestScenario;
36 
37 import java.lang.reflect.InvocationHandler;
38 import java.lang.reflect.Method;
39 import java.lang.reflect.Proxy;
40 import java.util.ArrayList;
41 import java.util.List;
42 import java.util.Spliterator;
43 import java.util.function.Function;
44 import java.util.function.UnaryOperator;
45 import java.util.stream.DoubleStream;
46 import java.util.stream.IntStream;
47 import java.util.stream.LongStream;
48 import java.util.stream.Stream;
49 import java.util.stream.StreamSupport;
50 
51 import static org.openjdk.testlib.java.util.stream.LambdaTestHelpers.assertUnique;
52 
53 
54 @Test
55 public class InfiniteStreamWithLimitOpTest extends OpTestCase {
56 
57     private static final long SKIP_LIMIT_SIZE = 1 << 16;
58 
59     @DataProvider(name = "Stream.limit")
60     @SuppressWarnings("rawtypes")
sliceFunctionsDataProvider()61     public static Object[][] sliceFunctionsDataProvider() {
62         Function<String, String> f = s -> String.format(s, SKIP_LIMIT_SIZE);
63 
64         List<Object[]> data = new ArrayList<>();
65 
66         data.add(new Object[]{f.apply("Stream.limit(%d)"),
67                 (UnaryOperator<Stream>) s -> s.limit(SKIP_LIMIT_SIZE)});
68         data.add(new Object[]{f.apply("Stream.skip(%1$d).limit(%1$d)"),
69                 (UnaryOperator<Stream>) s -> s.skip(SKIP_LIMIT_SIZE).limit(SKIP_LIMIT_SIZE)});
70 
71         return data.toArray(new Object[0][]);
72     }
73 
74     @DataProvider(name = "IntStream.limit")
intSliceFunctionsDataProvider()75     public static Object[][] intSliceFunctionsDataProvider() {
76         Function<String, String> f = s -> String.format(s, SKIP_LIMIT_SIZE);
77 
78         List<Object[]> data = new ArrayList<>();
79 
80         data.add(new Object[]{f.apply("IntStream.limit(%d)"),
81                 (UnaryOperator<IntStream>) s -> s.limit(SKIP_LIMIT_SIZE)});
82         data.add(new Object[]{f.apply("IntStream.skip(%1$d).limit(%1$d)"),
83                 (UnaryOperator<IntStream>) s -> s.skip(SKIP_LIMIT_SIZE).limit(SKIP_LIMIT_SIZE)});
84 
85         return data.toArray(new Object[0][]);
86     }
87 
88     @DataProvider(name = "LongStream.limit")
longSliceFunctionsDataProvider()89     public static Object[][] longSliceFunctionsDataProvider() {
90         Function<String, String> f = s -> String.format(s, SKIP_LIMIT_SIZE);
91 
92         List<Object[]> data = new ArrayList<>();
93 
94         data.add(new Object[]{f.apply("LongStream.limit(%d)"),
95                 (UnaryOperator<LongStream>) s -> s.limit(SKIP_LIMIT_SIZE)});
96         data.add(new Object[]{f.apply("LongStream.skip(%1$d).limit(%1$d)"),
97                 (UnaryOperator<LongStream>) s -> s.skip(SKIP_LIMIT_SIZE).limit(SKIP_LIMIT_SIZE)});
98 
99         return data.toArray(new Object[0][]);
100     }
101 
102     @DataProvider(name = "DoubleStream.limit")
doubleSliceFunctionsDataProvider()103     public static Object[][] doubleSliceFunctionsDataProvider() {
104         Function<String, String> f = s -> String.format(s, SKIP_LIMIT_SIZE);
105 
106         List<Object[]> data = new ArrayList<>();
107 
108         data.add(new Object[]{f.apply("DoubleStream.limit(%d)"),
109                 (UnaryOperator<DoubleStream>) s -> s.limit(SKIP_LIMIT_SIZE)});
110         data.add(new Object[]{f.apply("DoubleStream.skip(%1$d).limit(%1$d)"),
111                 (UnaryOperator<DoubleStream>) s -> s.skip(SKIP_LIMIT_SIZE).limit(SKIP_LIMIT_SIZE)});
112 
113         return data.toArray(new Object[0][]);
114     }
115 
unorderedAsserter()116     private <T> ResultAsserter<Iterable<T>> unorderedAsserter() {
117         return (act, exp, ord, par) -> {
118             if (par & !ord) {
119                 // Can only assert that all elements of the actual result
120                 // are distinct and that the count is the limit size
121                 // any element within the range [0, Long.MAX_VALUE) may be
122                 // present
123                 assertUnique(act);
124                 long count = 0;
125                 for (T l : act) {
126                     count++;
127                 }
128                 assertEquals(count, SKIP_LIMIT_SIZE, "size not equal");
129             }
130             else {
131                 LambdaTestHelpers.assertContents(act, exp);
132             }
133         };
134     }
135 
136     private TestData.OfRef<Long> refLongs() {
137         return refLongRange(0, Long.MAX_VALUE);
138     }
139 
140     private TestData.OfRef<Long> refLongRange(long l, long u) {
141         return TestData.Factory.ofSupplier(
142                 String.format("[%d, %d)", l, u),
143                 () -> LongStream.range(l, u).boxed());
144     }
145 
146     private TestData.OfInt ints() {
147         return intRange(0, Integer.MAX_VALUE);
148     }
149 
150     private TestData.OfInt intRange(int l, int u) {
151         return TestData.Factory.ofIntSupplier(
152                 String.format("[%d, %d)", l, u),
153                 () -> IntStream.range(l, u));
154     }
155 
156     private TestData.OfLong longs() {
157         return longRange(0, Long.MAX_VALUE);
158     }
159 
160     private TestData.OfLong longRange(long l, long u) {
161         return TestData.Factory.ofLongSupplier(
162                 String.format("[%d, %d)", l, u),
163                 () -> LongStream.range(l, u));
164     }
165 
166     private TestData.OfDouble doubles() {
167         return doubleRange(0, 1L << 53);
168     }
169 
170     private TestData.OfDouble doubleRange(long l, long u) {
171         return TestData.Factory.ofDoubleSupplier(
172                 String.format("[%d, %d)", l, u),
173                 () -> LongStream.range(l, u).mapToDouble(i -> (double) i));
174     }
175 
176 
177     // Sized/subsized range
178 
179     @Test(dataProvider = "Stream.limit")
180     public void testSubsizedWithRange(String description, UnaryOperator<Stream<Long>> fs) {
181         // Range is [0, Long.MAX_VALUE), splits are SUBSIZED
182         // Such a size will induce out of memory errors for incorrect
183         // slice implementations
184         withData(refLongs()).
185                 stream(s -> fs.apply(s)).
186                 without(StreamTestScenario.CLEAR_SIZED_SCENARIOS).
187                 exercise();
188     }
189 
190     @Test(dataProvider = "IntStream.limit")
191     public void testIntSubsizedWithRange(String description, UnaryOperator<IntStream> fs) {
192         // Range is [0, Integer.MAX_VALUE), splits are SUBSIZED
193         // Such a size will induce out of memory errors for incorrect
194         // slice implementations
195         withData(ints()).
196                 stream(s -> fs.apply(s)).
197                 without(IntStreamTestScenario.CLEAR_SIZED_SCENARIOS).
198                 exercise();
199     }
200 
201     @Test(dataProvider = "LongStream.limit")
202     public void testLongSubsizedWithRange(String description, UnaryOperator<LongStream> fs) {
203         // Range is [0, Long.MAX_VALUE), splits are SUBSIZED
204         // Such a size will induce out of memory errors for incorrect
205         // slice implementations
206         withData(longs()).
207                 stream(s -> fs.apply(s)).
208                 without(LongStreamTestScenario.CLEAR_SIZED_SCENARIOS).
209                 exercise();
210     }
211 
212     @Test(dataProvider = "DoubleStream.limit")
213     public void testDoubleSubsizedWithRange(String description, UnaryOperator<DoubleStream> fs) {
214         // Range is [0, 2^53), splits are SUBSIZED
215         // Such a size will induce out of memory errors for incorrect
216         // slice implementations
217         withData(doubles()).
218                 stream(s -> fs.apply(s)).
219                 without(DoubleStreamTestScenario.CLEAR_SIZED_SCENARIOS).
220                 exercise();
221     }
222 
223 
224     // Unordered finite not SIZED/SUBSIZED
225 
226     @Test(dataProvider = "Stream.limit")
227     public void testUnorderedFinite(String description, UnaryOperator<Stream<Long>> fs) {
228         // Range is [0, Long.MAX_VALUE), splits are SUBSIZED
229         // Such a size will induce out of memory errors for incorrect
230         // slice implementations
231         withData(longs()).
232                 stream(s -> fs.apply(s.filter(i -> true).unordered().boxed())).
233                 resultAsserter(unorderedAsserter()).
234                 exercise();
235     }
236 
237     @Test(dataProvider = "IntStream.limit")
238     public void testIntUnorderedFinite(String description, UnaryOperator<IntStream> fs) {
239         // Range is [0, Integer.MAX_VALUE), splits are SUBSIZED
240         // Such a size will induce out of memory errors for incorrect
241         // slice implementations
242         withData(ints()).
243                 stream(s -> fs.apply(s.filter(i -> true).unordered())).
244                 resultAsserter(unorderedAsserter()).
245                 exercise();
246     }
247 
248     @Test(dataProvider = "LongStream.limit")
249     public void testLongUnorderedFinite(String description, UnaryOperator<LongStream> fs) {
250         // Range is [0, Long.MAX_VALUE), splits are SUBSIZED
251         // Such a size will induce out of memory errors for incorrect
252         // slice implementations
253         withData(longs()).
254                 stream(s -> fs.apply(s.filter(i -> true).unordered())).
255                 resultAsserter(unorderedAsserter()).
256                 exercise();
257     }
258 
259     @Test(dataProvider = "DoubleStream.limit")
260     public void testDoubleUnorderedFinite(String description, UnaryOperator<DoubleStream> fs) {
261         // Range is [0, 1L << 53), splits are SUBSIZED
262         // Such a size will induce out of memory errors for incorrect
263         // slice implementations
264         // Upper bound ensures values mapped to doubles will be unique
265         withData(doubles()).
266                 stream(s -> fs.apply(s.filter(i -> true).unordered())).
267                 resultAsserter(unorderedAsserter()).
268                 exercise();
269     }
270 
271 
272     // Unordered finite not SUBSIZED
273 
274     @SuppressWarnings({"rawtypes", "unchecked"})
275     private Spliterator.OfLong proxyNotSubsized(Spliterator.OfLong s) {
276         InvocationHandler ih = new InvocationHandler() {
277             @Override
278             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
279                 switch (method.getName()) {
280                     case "characteristics": {
281                         int c = (Integer) method.invoke(s, args);
282                         return c & ~Spliterator.SUBSIZED;
283                     }
284                     case "hasCharacteristics": {
285                         int c = (Integer) args[0];
286                         boolean b = (Boolean) method.invoke(s, args);
287                         return b & ((c & Spliterator.SUBSIZED) == 0);
288                     }
289                     default:
290                         return method.invoke(s, args);
291                 }
292             }
293         };
294 
295         return (Spliterator.OfLong) Proxy.newProxyInstance(this.getClass().getClassLoader(),
296                                                            new Class[]{Spliterator.OfLong.class},
297                                                            ih);
298     }
299 
300     private TestData.OfLong proxiedLongRange(long l, long u) {
301         return TestData.Factory.ofLongSupplier(
302                 String.format("[%d, %d)", l, u),
303                 () -> StreamSupport.longStream(proxyNotSubsized(LongStream.range(l, u).spliterator()), false));
304     }
305 
306     @Test(dataProvider = "Stream.limit")
307     public void testUnorderedSizedNotSubsizedFinite(String description, UnaryOperator<Stream<Long>> fs) {
308         // Range is [0, Long.MAX_VALUE), splits are not SUBSIZED (proxy clears
309         // the SUBSIZED characteristic)
310         // Such a size will induce out of memory errors for incorrect
311         // slice implementations
312         withData(proxiedLongRange(0, Long.MAX_VALUE)).
313                 stream(s -> fs.apply(s.unordered().boxed())).
314                 resultAsserter(unorderedAsserter()).
315                 exercise();
316     }
317 
318     @Test(dataProvider = "IntStream.limit")
319     public void testIntUnorderedSizedNotSubsizedFinite(String description, UnaryOperator<IntStream> fs) {
320         // Range is [0, Integer.MAX_VALUE), splits are not SUBSIZED (proxy clears
321         // the SUBSIZED characteristic)
322         // Such a size will induce out of memory errors for incorrect
323         // slice implementations
324         withData(proxiedLongRange(0, Integer.MAX_VALUE)).
325                 stream(s -> fs.apply(s.unordered().mapToInt(i -> (int) i))).
326                 resultAsserter(unorderedAsserter()).
327                 exercise();
328     }
329 
330     @Test(dataProvider = "LongStream.limit")
331     public void testLongUnorderedSizedNotSubsizedFinite(String description, UnaryOperator<LongStream> fs) {
332         // Range is [0, Long.MAX_VALUE), splits are not SUBSIZED (proxy clears
333         // the SUBSIZED characteristic)
334         // Such a size will induce out of memory errors for incorrect
335         // slice implementations
336         withData(proxiedLongRange(0, Long.MAX_VALUE)).
337                 stream(s -> fs.apply(s.unordered())).
338                 resultAsserter(unorderedAsserter()).
339                 exercise();
340     }
341 
342     @Test(dataProvider = "DoubleStream.limit")
343     public void testDoubleUnorderedSizedNotSubsizedFinite(String description, UnaryOperator<DoubleStream> fs) {
344         // Range is [0, Double.MAX_VALUE), splits are not SUBSIZED (proxy clears
345         // the SUBSIZED characteristic)
346         // Such a size will induce out of memory errors for incorrect
347         // slice implementations
348         withData(proxiedLongRange(0, 1L << 53)).
349                 stream(s -> fs.apply(s.unordered().mapToDouble(i -> (double) i))).
350                 resultAsserter(unorderedAsserter()).
351                 exercise();
352     }
353 
354 
355     // Unordered generation
356 
357     @Test(dataProvider = "Stream.limit")
358     public void testUnorderedGenerator(String description, UnaryOperator<Stream<Long>> fs) {
359         // Source is spliterator of infinite size
360         TestData.OfRef<Long> generator = TestData.Factory.ofSupplier(
361                 "[1L, 1L, ...]", () -> Stream.generate(() -> 1L));
362 
363         withData(generator).
364                 stream(s -> fs.apply(s.filter(i -> true).unordered())).
365                 exercise();
366     }
367 
368     @Test(dataProvider = "IntStream.limit")
369     public void testIntUnorderedGenerator(String description, UnaryOperator<IntStream> fs) {
370         // Source is spliterator of infinite size
371         TestData.OfInt generator = TestData.Factory.ofIntSupplier(
372                 "[1, 1, ...]", () -> IntStream.generate(() -> 1));
373 
374         withData(generator).
375                 stream(s -> fs.apply(s.filter(i -> true).unordered())).
376                 exercise();
377     }
378 
379     @Test(dataProvider = "LongStream.limit")
380     public void testLongUnorderedGenerator(String description, UnaryOperator<LongStream> fs) {
381         // Source is spliterator of infinite size
382         TestData.OfLong generator = TestData.Factory.ofLongSupplier(
383                 "[1L, 1L, ...]", () -> LongStream.generate(() -> 1));
384 
385         withData(generator).
386                 stream(s -> fs.apply(s.filter(i -> true).unordered())).
387                 exercise();
388     }
389 
390     @Test(dataProvider = "DoubleStream.limit")
391     public void testDoubleUnorderedGenerator(String description, UnaryOperator<DoubleStream> fs) {
392         // Source is spliterator of infinite size
393         TestData.OfDouble generator = TestData.Factory.ofDoubleSupplier(
394                 "[1.0, 1.0, ...]", () -> DoubleStream.generate(() -> 1.0));
395 
396         withData(generator).
397                 stream(s -> fs.apply(s.filter(i -> true).unordered())).
398                 exercise();
399     }
400 
401 
402     // Unordered iteration
403 
404     @Test(dataProvider = "Stream.limit")
405     public void testUnorderedIteration(String description, UnaryOperator<Stream<Long>> fs) {
406         // Source is a right-balanced tree of infinite size
407         TestData.OfRef<Long> iterator = TestData.Factory.ofSupplier(
408                 "[1L, 2L, 3L, ...]", () -> Stream.iterate(1L, i -> i + 1L));
409 
410         // Ref
411         withData(iterator).
412                 stream(s -> fs.apply(s.unordered())).
413                 resultAsserter(unorderedAsserter()).
414                 exercise();
415     }
416 
417     @Test(dataProvider = "IntStream.limit")
418     public void testIntUnorderedIteration(String description, UnaryOperator<IntStream> fs) {
419         // Source is a right-balanced tree of infinite size
420         TestData.OfInt iterator = TestData.Factory.ofIntSupplier(
421                 "[1, 2, 3, ...]", () -> IntStream.iterate(1, i -> i + 1));
422 
423         // Ref
424         withData(iterator).
425                 stream(s -> fs.apply(s.unordered())).
426                 resultAsserter(unorderedAsserter()).
427                 exercise();
428     }
429 
430     @Test(dataProvider = "LongStream.limit")
431     public void testLongUnorderedIteration(String description, UnaryOperator<LongStream> fs) {
432         // Source is a right-balanced tree of infinite size
433         TestData.OfLong iterator = TestData.Factory.ofLongSupplier(
434                 "[1L, 2L, 3L, ...]", () -> LongStream.iterate(1, i -> i + 1));
435 
436         // Ref
437         withData(iterator).
438                 stream(s -> fs.apply(s.unordered())).
439                 resultAsserter(unorderedAsserter()).
440                 exercise();
441     }
442 
443     @Test(dataProvider = "DoubleStream.limit")
444     public void testDoubleUnorderedIteration(String description, UnaryOperator<DoubleStream> fs) {
445         // Source is a right-balanced tree of infinite size
446         TestData.OfDouble iterator = TestData.Factory.ofDoubleSupplier(
447                 "[1.0, 2.0, 3.0, ...]", () -> DoubleStream.iterate(1, i -> i + 1));
448 
449         // Ref
450         withData(iterator).
451                 stream(s -> fs.apply(s.unordered())).
452                 resultAsserter(unorderedAsserter()).
453                 exercise();
454     }
455 }
456