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