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