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