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