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 import android.platform.test.annotations.LargeTest;
54 
55 
56 @LargeTest
57 @Test
58 public class InfiniteStreamWithLimitOpTest extends OpTestCase {
59 
60     private static final long SKIP_LIMIT_SIZE = 1 << 16;
61 
62     @DataProvider(name = "Stream.limit")
63     @SuppressWarnings("rawtypes")
sliceFunctionsDataProvider()64     public static Object[][] sliceFunctionsDataProvider() {
65         Function<String, String> f = s -> String.format(s, SKIP_LIMIT_SIZE);
66 
67         List<Object[]> data = new ArrayList<>();
68 
69         data.add(new Object[]{f.apply("Stream.limit(%d)"),
70                 (UnaryOperator<Stream>) s -> s.limit(SKIP_LIMIT_SIZE)});
71         data.add(new Object[]{f.apply("Stream.skip(%1$d).limit(%1$d)"),
72                 (UnaryOperator<Stream>) s -> s.skip(SKIP_LIMIT_SIZE).limit(SKIP_LIMIT_SIZE)});
73 
74         return data.toArray(new Object[0][]);
75     }
76 
77     @DataProvider(name = "IntStream.limit")
intSliceFunctionsDataProvider()78     public static Object[][] intSliceFunctionsDataProvider() {
79         Function<String, String> f = s -> String.format(s, SKIP_LIMIT_SIZE);
80 
81         List<Object[]> data = new ArrayList<>();
82 
83         data.add(new Object[]{f.apply("IntStream.limit(%d)"),
84                 (UnaryOperator<IntStream>) s -> s.limit(SKIP_LIMIT_SIZE)});
85         data.add(new Object[]{f.apply("IntStream.skip(%1$d).limit(%1$d)"),
86                 (UnaryOperator<IntStream>) s -> s.skip(SKIP_LIMIT_SIZE).limit(SKIP_LIMIT_SIZE)});
87 
88         return data.toArray(new Object[0][]);
89     }
90 
91     @DataProvider(name = "LongStream.limit")
longSliceFunctionsDataProvider()92     public static Object[][] longSliceFunctionsDataProvider() {
93         Function<String, String> f = s -> String.format(s, SKIP_LIMIT_SIZE);
94 
95         List<Object[]> data = new ArrayList<>();
96 
97         data.add(new Object[]{f.apply("LongStream.limit(%d)"),
98                 (UnaryOperator<LongStream>) s -> s.limit(SKIP_LIMIT_SIZE)});
99         data.add(new Object[]{f.apply("LongStream.skip(%1$d).limit(%1$d)"),
100                 (UnaryOperator<LongStream>) s -> s.skip(SKIP_LIMIT_SIZE).limit(SKIP_LIMIT_SIZE)});
101 
102         return data.toArray(new Object[0][]);
103     }
104 
105     @DataProvider(name = "DoubleStream.limit")
doubleSliceFunctionsDataProvider()106     public static Object[][] doubleSliceFunctionsDataProvider() {
107         Function<String, String> f = s -> String.format(s, SKIP_LIMIT_SIZE);
108 
109         List<Object[]> data = new ArrayList<>();
110 
111         data.add(new Object[]{f.apply("DoubleStream.limit(%d)"),
112                 (UnaryOperator<DoubleStream>) s -> s.limit(SKIP_LIMIT_SIZE)});
113         data.add(new Object[]{f.apply("DoubleStream.skip(%1$d).limit(%1$d)"),
114                 (UnaryOperator<DoubleStream>) s -> s.skip(SKIP_LIMIT_SIZE).limit(SKIP_LIMIT_SIZE)});
115 
116         return data.toArray(new Object[0][]);
117     }
118 
unorderedAsserter()119     private <T> ResultAsserter<Iterable<T>> unorderedAsserter() {
120         return (act, exp, ord, par) -> {
121             if (par & !ord) {
122                 // Can only assert that all elements of the actual result
123                 // are distinct and that the count is the limit size
124                 // any element within the range [0, Long.MAX_VALUE) may be
125                 // present
126                 assertUnique(act);
127                 long count = 0;
128                 for (T l : act) {
129                     count++;
130                 }
131                 assertEquals(count, SKIP_LIMIT_SIZE, "size not equal");
132             }
133             else {
134                 LambdaTestHelpers.assertContents(act, exp);
135             }
136         };
137     }
138 
139     private TestData.OfRef<Long> refLongs() {
140         return refLongRange(0, Long.MAX_VALUE);
141     }
142 
143     private TestData.OfRef<Long> refLongRange(long l, long u) {
144         return TestData.Factory.ofSupplier(
145                 String.format("[%d, %d)", l, u),
146                 () -> LongStream.range(l, u).boxed());
147     }
148 
149     private TestData.OfInt ints() {
150         return intRange(0, Integer.MAX_VALUE);
151     }
152 
153     private TestData.OfInt intRange(int l, int u) {
154         return TestData.Factory.ofIntSupplier(
155                 String.format("[%d, %d)", l, u),
156                 () -> IntStream.range(l, u));
157     }
158 
159     private TestData.OfLong longs() {
160         return longRange(0, Long.MAX_VALUE);
161     }
162 
163     private TestData.OfLong longRange(long l, long u) {
164         return TestData.Factory.ofLongSupplier(
165                 String.format("[%d, %d)", l, u),
166                 () -> LongStream.range(l, u));
167     }
168 
169     private TestData.OfDouble doubles() {
170         return doubleRange(0, 1L << 53);
171     }
172 
173     private TestData.OfDouble doubleRange(long l, long u) {
174         return TestData.Factory.ofDoubleSupplier(
175                 String.format("[%d, %d)", l, u),
176                 () -> LongStream.range(l, u).mapToDouble(i -> (double) i));
177     }
178 
179 
180     // Sized/subsized range
181 
182     @Test(dataProvider = "Stream.limit")
183     public void testSubsizedWithRange(String description, UnaryOperator<Stream<Long>> fs) {
184         // Range is [0, Long.MAX_VALUE), splits are SUBSIZED
185         // Such a size will induce out of memory errors for incorrect
186         // slice implementations
187         withData(refLongs()).
188                 stream(s -> fs.apply(s)).
189                 without(StreamTestScenario.CLEAR_SIZED_SCENARIOS).
190                 exercise();
191     }
192 
193     @Test(dataProvider = "IntStream.limit")
194     public void testIntSubsizedWithRange(String description, UnaryOperator<IntStream> fs) {
195         // Range is [0, Integer.MAX_VALUE), splits are SUBSIZED
196         // Such a size will induce out of memory errors for incorrect
197         // slice implementations
198         withData(ints()).
199                 stream(s -> fs.apply(s)).
200                 without(IntStreamTestScenario.CLEAR_SIZED_SCENARIOS).
201                 exercise();
202     }
203 
204     @Test(dataProvider = "LongStream.limit")
205     public void testLongSubsizedWithRange(String description, UnaryOperator<LongStream> fs) {
206         // Range is [0, Long.MAX_VALUE), splits are SUBSIZED
207         // Such a size will induce out of memory errors for incorrect
208         // slice implementations
209         withData(longs()).
210                 stream(s -> fs.apply(s)).
211                 without(LongStreamTestScenario.CLEAR_SIZED_SCENARIOS).
212                 exercise();
213     }
214 
215     @Test(dataProvider = "DoubleStream.limit")
216     public void testDoubleSubsizedWithRange(String description, UnaryOperator<DoubleStream> fs) {
217         // Range is [0, 2^53), splits are SUBSIZED
218         // Such a size will induce out of memory errors for incorrect
219         // slice implementations
220         withData(doubles()).
221                 stream(s -> fs.apply(s)).
222                 without(DoubleStreamTestScenario.CLEAR_SIZED_SCENARIOS).
223                 exercise();
224     }
225 
226 
227     // Unordered finite not SIZED/SUBSIZED
228 
229     @Test(dataProvider = "Stream.limit")
230     public void testUnorderedFinite(String description, UnaryOperator<Stream<Long>> fs) {
231         // Range is [0, Long.MAX_VALUE), splits are SUBSIZED
232         // Such a size will induce out of memory errors for incorrect
233         // slice implementations
234         withData(longs()).
235                 stream(s -> fs.apply(s.filter(i -> true).unordered().boxed())).
236                 resultAsserter(unorderedAsserter()).
237                 exercise();
238     }
239 
240     @Test(dataProvider = "IntStream.limit")
241     public void testIntUnorderedFinite(String description, UnaryOperator<IntStream> fs) {
242         // Range is [0, Integer.MAX_VALUE), splits are SUBSIZED
243         // Such a size will induce out of memory errors for incorrect
244         // slice implementations
245         withData(ints()).
246                 stream(s -> fs.apply(s.filter(i -> true).unordered())).
247                 resultAsserter(unorderedAsserter()).
248                 exercise();
249     }
250 
251     @Test(dataProvider = "LongStream.limit")
252     public void testLongUnorderedFinite(String description, UnaryOperator<LongStream> fs) {
253         // Range is [0, Long.MAX_VALUE), splits are SUBSIZED
254         // Such a size will induce out of memory errors for incorrect
255         // slice implementations
256         withData(longs()).
257                 stream(s -> fs.apply(s.filter(i -> true).unordered())).
258                 resultAsserter(unorderedAsserter()).
259                 exercise();
260     }
261 
262     @Test(dataProvider = "DoubleStream.limit")
263     public void testDoubleUnorderedFinite(String description, UnaryOperator<DoubleStream> fs) {
264         // Range is [0, 1L << 53), splits are SUBSIZED
265         // Such a size will induce out of memory errors for incorrect
266         // slice implementations
267         // Upper bound ensures values mapped to doubles will be unique
268         withData(doubles()).
269                 stream(s -> fs.apply(s.filter(i -> true).unordered())).
270                 resultAsserter(unorderedAsserter()).
271                 exercise();
272     }
273 
274 
275     // Unordered finite not SUBSIZED
276 
277     @SuppressWarnings({"rawtypes", "unchecked"})
278     private Spliterator.OfLong proxyNotSubsized(Spliterator.OfLong s) {
279         InvocationHandler ih = new InvocationHandler() {
280             @Override
281             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
282                 switch (method.getName()) {
283                     case "characteristics": {
284                         int c = (Integer) method.invoke(s, args);
285                         return c & ~Spliterator.SUBSIZED;
286                     }
287                     case "hasCharacteristics": {
288                         int c = (Integer) args[0];
289                         boolean b = (Boolean) method.invoke(s, args);
290                         return b & ((c & Spliterator.SUBSIZED) == 0);
291                     }
292                     default:
293                         return method.invoke(s, args);
294                 }
295             }
296         };
297 
298         return (Spliterator.OfLong) Proxy.newProxyInstance(this.getClass().getClassLoader(),
299                                                            new Class[]{Spliterator.OfLong.class},
300                                                            ih);
301     }
302 
303     private TestData.OfLong proxiedLongRange(long l, long u) {
304         return TestData.Factory.ofLongSupplier(
305                 String.format("[%d, %d)", l, u),
306                 () -> StreamSupport.longStream(proxyNotSubsized(LongStream.range(l, u).spliterator()), false));
307     }
308 
309     @Test(dataProvider = "Stream.limit")
310     public void testUnorderedSizedNotSubsizedFinite(String description, UnaryOperator<Stream<Long>> fs) {
311         // Range is [0, Long.MAX_VALUE), splits are not SUBSIZED (proxy clears
312         // the SUBSIZED characteristic)
313         // Such a size will induce out of memory errors for incorrect
314         // slice implementations
315         withData(proxiedLongRange(0, Long.MAX_VALUE)).
316                 stream(s -> fs.apply(s.unordered().boxed())).
317                 resultAsserter(unorderedAsserter()).
318                 exercise();
319     }
320 
321     @Test(dataProvider = "IntStream.limit")
322     public void testIntUnorderedSizedNotSubsizedFinite(String description, UnaryOperator<IntStream> fs) {
323         // Range is [0, Integer.MAX_VALUE), splits are not SUBSIZED (proxy clears
324         // the SUBSIZED characteristic)
325         // Such a size will induce out of memory errors for incorrect
326         // slice implementations
327         withData(proxiedLongRange(0, Integer.MAX_VALUE)).
328                 stream(s -> fs.apply(s.unordered().mapToInt(i -> (int) i))).
329                 resultAsserter(unorderedAsserter()).
330                 exercise();
331     }
332 
333     @Test(dataProvider = "LongStream.limit")
334     public void testLongUnorderedSizedNotSubsizedFinite(String description, UnaryOperator<LongStream> fs) {
335         // Range is [0, Long.MAX_VALUE), splits are not SUBSIZED (proxy clears
336         // the SUBSIZED characteristic)
337         // Such a size will induce out of memory errors for incorrect
338         // slice implementations
339         withData(proxiedLongRange(0, Long.MAX_VALUE)).
340                 stream(s -> fs.apply(s.unordered())).
341                 resultAsserter(unorderedAsserter()).
342                 exercise();
343     }
344 
345     @Test(dataProvider = "DoubleStream.limit")
346     public void testDoubleUnorderedSizedNotSubsizedFinite(String description, UnaryOperator<DoubleStream> fs) {
347         // Range is [0, Double.MAX_VALUE), splits are not SUBSIZED (proxy clears
348         // the SUBSIZED characteristic)
349         // Such a size will induce out of memory errors for incorrect
350         // slice implementations
351         withData(proxiedLongRange(0, 1L << 53)).
352                 stream(s -> fs.apply(s.unordered().mapToDouble(i -> (double) i))).
353                 resultAsserter(unorderedAsserter()).
354                 exercise();
355     }
356 
357 
358     // Unordered generation
359 
360     @Test(dataProvider = "Stream.limit")
361     public void testUnorderedGenerator(String description, UnaryOperator<Stream<Long>> fs) {
362         // Source is spliterator of infinite size
363         TestData.OfRef<Long> generator = TestData.Factory.ofSupplier(
364                 "[1L, 1L, ...]", () -> Stream.generate(() -> 1L));
365 
366         withData(generator).
367                 stream(s -> fs.apply(s.filter(i -> true).unordered())).
368                 exercise();
369     }
370 
371     @Test(dataProvider = "IntStream.limit")
372     public void testIntUnorderedGenerator(String description, UnaryOperator<IntStream> fs) {
373         // Source is spliterator of infinite size
374         TestData.OfInt generator = TestData.Factory.ofIntSupplier(
375                 "[1, 1, ...]", () -> IntStream.generate(() -> 1));
376 
377         withData(generator).
378                 stream(s -> fs.apply(s.filter(i -> true).unordered())).
379                 exercise();
380     }
381 
382     @Test(dataProvider = "LongStream.limit")
383     public void testLongUnorderedGenerator(String description, UnaryOperator<LongStream> fs) {
384         // Source is spliterator of infinite size
385         TestData.OfLong generator = TestData.Factory.ofLongSupplier(
386                 "[1L, 1L, ...]", () -> LongStream.generate(() -> 1));
387 
388         withData(generator).
389                 stream(s -> fs.apply(s.filter(i -> true).unordered())).
390                 exercise();
391     }
392 
393     @Test(dataProvider = "DoubleStream.limit")
394     public void testDoubleUnorderedGenerator(String description, UnaryOperator<DoubleStream> fs) {
395         // Source is spliterator of infinite size
396         TestData.OfDouble generator = TestData.Factory.ofDoubleSupplier(
397                 "[1.0, 1.0, ...]", () -> DoubleStream.generate(() -> 1.0));
398 
399         withData(generator).
400                 stream(s -> fs.apply(s.filter(i -> true).unordered())).
401                 exercise();
402     }
403 
404 
405     // Unordered iteration
406 
407     @Test(dataProvider = "Stream.limit")
408     public void testUnorderedIteration(String description, UnaryOperator<Stream<Long>> fs) {
409         // Source is a right-balanced tree of infinite size
410         TestData.OfRef<Long> iterator = TestData.Factory.ofSupplier(
411                 "[1L, 2L, 3L, ...]", () -> Stream.iterate(1L, i -> i + 1L));
412 
413         // Ref
414         withData(iterator).
415                 stream(s -> fs.apply(s.unordered())).
416                 resultAsserter(unorderedAsserter()).
417                 exercise();
418     }
419 
420     @Test(dataProvider = "IntStream.limit")
421     public void testIntUnorderedIteration(String description, UnaryOperator<IntStream> fs) {
422         // Source is a right-balanced tree of infinite size
423         TestData.OfInt iterator = TestData.Factory.ofIntSupplier(
424                 "[1, 2, 3, ...]", () -> IntStream.iterate(1, i -> i + 1));
425 
426         // Ref
427         withData(iterator).
428                 stream(s -> fs.apply(s.unordered())).
429                 resultAsserter(unorderedAsserter()).
430                 exercise();
431     }
432 
433     @Test(dataProvider = "LongStream.limit")
434     public void testLongUnorderedIteration(String description, UnaryOperator<LongStream> fs) {
435         // Source is a right-balanced tree of infinite size
436         TestData.OfLong iterator = TestData.Factory.ofLongSupplier(
437                 "[1L, 2L, 3L, ...]", () -> LongStream.iterate(1, i -> i + 1));
438 
439         // Ref
440         withData(iterator).
441                 stream(s -> fs.apply(s.unordered())).
442                 resultAsserter(unorderedAsserter()).
443                 exercise();
444     }
445 
446     @Test(dataProvider = "DoubleStream.limit")
447     public void testDoubleUnorderedIteration(String description, UnaryOperator<DoubleStream> fs) {
448         // Source is a right-balanced tree of infinite size
449         TestData.OfDouble iterator = TestData.Factory.ofDoubleSupplier(
450                 "[1.0, 2.0, 3.0, ...]", () -> DoubleStream.iterate(1, i -> i + 1));
451 
452         // Ref
453         withData(iterator).
454                 stream(s -> fs.apply(s.unordered())).
455                 resultAsserter(unorderedAsserter()).
456                 exercise();
457     }
458 }
459