1 /* 2 * Copyright (c) 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.openjdk.testlib.java.util.stream.DefaultMethodStreams; 26 import org.openjdk.testlib.java.util.stream.OpTestCase; 27 import org.testng.annotations.Test; 28 29 import java.util.HashMap; 30 import java.util.LinkedList; 31 import java.util.Map; 32 import java.util.concurrent.TimeUnit; 33 import java.util.concurrent.atomic.AtomicLong; 34 import java.util.function.BooleanSupplier; 35 import java.util.function.Consumer; 36 import java.util.function.Function; 37 import java.util.function.Supplier; 38 import java.util.stream.DoubleStream; 39 import java.util.stream.IntStream; 40 import java.util.stream.LongStream; 41 import java.util.stream.Stream; 42 43 import static java.util.stream.Collectors.toCollection; 44 45 /* 46 * @test 47 * @bug 8071597 48 */ 49 @Test 50 // Android-changed: this test checks while/drop ops on reference and primitive streams. 51 // But in Android U only reference streams have those APIs, hence primitive streams part 52 // are commented out. 53 public class WhileOpStatefulTest extends OpTestCase { 54 static final long COUNT_PERIOD = 100; 55 56 static final long EXECUTION_TIME_LIMIT = TimeUnit.SECONDS.toMillis(10); 57 58 static final long TAKE_WHILE_COUNT_LIMIT = 100_000; 59 60 static final int DROP_SOURCE_SIZE = 10_000; 61 62 static final long DROP_WHILE_COUNT_LIMIT = 5000; 63 64 @Test testTimedTakeWithCount()65 public void testTimedTakeWithCount() { 66 testTakeWhileMulti( 67 s -> { 68 BooleanSupplier isWithinTakePeriod = 69 within(System.currentTimeMillis(), COUNT_PERIOD); 70 s.takeWhile(e -> isWithinTakePeriod.getAsBoolean()) 71 .mapToLong(e -> 1).reduce(0, Long::sum); 72 }); 73 // BEGIN Android-removed: Drop primitive stream test. 74 /* 75 s -> { 76 BooleanSupplier isWithinTakePeriod = 77 within(System.currentTimeMillis(), COUNT_PERIOD); 78 s.takeWhile(e -> isWithinTakePeriod.getAsBoolean()) 79 .mapToLong(e -> 1).reduce(0, Long::sum); 80 }, 81 s -> { 82 BooleanSupplier isWithinTakePeriod = 83 within(System.currentTimeMillis(), COUNT_PERIOD); 84 s.takeWhile(e -> isWithinTakePeriod.getAsBoolean()) 85 .map(e -> 1).reduce(0, Long::sum); 86 }, 87 s -> { 88 BooleanSupplier isWithinTakePeriod = 89 within(System.currentTimeMillis(), COUNT_PERIOD); 90 s.takeWhile(e -> isWithinTakePeriod.getAsBoolean()) 91 .mapToLong(e -> 1).reduce(0, Long::sum); 92 }); 93 */ 94 // END Android-removed: Drop primitive stream test. 95 } 96 97 @Test(groups = { "serialization-hostile" }) testCountTakeWithCount()98 public void testCountTakeWithCount() { 99 testTakeWhileMulti( 100 s -> { 101 AtomicLong c = new AtomicLong(); 102 long rc = s.takeWhile(e -> c.getAndIncrement() < TAKE_WHILE_COUNT_LIMIT) 103 .mapToLong(e -> 1).reduce(0, Long::sum); 104 assertTrue(rc <= c.get()); 105 }); 106 // BEGIN Android-removed: Drop primitive stream test. 107 /* 108 s -> { 109 AtomicLong c = new AtomicLong(); 110 long rc = s.takeWhile(e -> c.getAndIncrement() < TAKE_WHILE_COUNT_LIMIT) 111 .mapToLong(e -> 1).reduce(0, Long::sum); 112 assertTrue(rc <= c.get()); 113 }, 114 s -> { 115 AtomicLong c = new AtomicLong(); 116 long rc = s.takeWhile(e -> c.getAndIncrement() < TAKE_WHILE_COUNT_LIMIT) 117 .map(e -> 1).reduce(0, Long::sum); 118 assertTrue(rc <= c.get()); 119 }, 120 s -> { 121 AtomicLong c = new AtomicLong(); 122 long rc = s.takeWhile(e -> c.getAndIncrement() < TAKE_WHILE_COUNT_LIMIT) 123 .mapToLong(e -> 1).reduce(0, Long::sum); 124 assertTrue(rc <= c.get()); 125 }); 126 */ 127 // END Android-removed: Drop primitive stream test. 128 } 129 130 @Test(groups = { "serialization-hostile" }) testCountTakeWithToArray()131 public void testCountTakeWithToArray() { 132 testTakeWhileMulti( 133 s -> { 134 AtomicLong c = new AtomicLong(); 135 Object[] ra = s.takeWhile(e -> c.getAndIncrement() < TAKE_WHILE_COUNT_LIMIT) 136 .toArray(); 137 assertTrue(ra.length <= c.get()); 138 }); 139 // BEGIN Android-removed: Drop primitive stream test. 140 /* 141 s -> { 142 AtomicLong c = new AtomicLong(); 143 int[] ra = s.takeWhile(e -> c.getAndIncrement() < TAKE_WHILE_COUNT_LIMIT) 144 .toArray(); 145 assertTrue(ra.length <= c.get()); 146 }, 147 s -> { 148 AtomicLong c = new AtomicLong(); 149 long[] ra = s.takeWhile(e -> c.getAndIncrement() < TAKE_WHILE_COUNT_LIMIT) 150 .toArray(); 151 assertTrue(ra.length <= c.get()); 152 }, 153 s -> { 154 AtomicLong c = new AtomicLong(); 155 double[] ra = s.takeWhile(e -> c.getAndIncrement() < TAKE_WHILE_COUNT_LIMIT) 156 .toArray(); 157 assertTrue(ra.length <= c.get()); 158 }); 159 */ 160 // END Android-removed: Drop primitive stream test. 161 } 162 163 164 @Test(groups = { "serialization-hostile" }) testCountDropWithCount()165 public void testCountDropWithCount() { 166 testDropWhileMulti( 167 s -> { 168 AtomicLong c = new AtomicLong(); 169 long rc = s.dropWhile(e -> c.getAndIncrement() < DROP_WHILE_COUNT_LIMIT) 170 .mapToLong(e -> 1).reduce(0, Long::sum); 171 assertTrue(c.get() >= DROP_WHILE_COUNT_LIMIT); 172 assertTrue(rc <= DROP_SOURCE_SIZE); 173 }); 174 // BEGIN Android-removed: Drop primitive stream test. 175 /* 176 s -> { 177 AtomicLong c = new AtomicLong(); 178 long rc = s.dropWhile(e -> c.getAndIncrement() < DROP_WHILE_COUNT_LIMIT) 179 .mapToLong(e -> 1).reduce(0, Long::sum); 180 assertTrue(c.get() >= DROP_WHILE_COUNT_LIMIT); 181 assertTrue(rc <= DROP_SOURCE_SIZE); 182 }, 183 s -> { 184 AtomicLong c = new AtomicLong(); 185 long rc = s.dropWhile(e -> c.getAndIncrement() < DROP_WHILE_COUNT_LIMIT) 186 .map(e -> 1).reduce(0, Long::sum); 187 assertTrue(c.get() >= DROP_WHILE_COUNT_LIMIT); 188 assertTrue(rc <= DROP_SOURCE_SIZE); 189 }, 190 s -> { 191 AtomicLong c = new AtomicLong(); 192 long rc = s.dropWhile(e -> c.getAndIncrement() < DROP_WHILE_COUNT_LIMIT) 193 .mapToLong(e -> 1).reduce(0, Long::sum); 194 assertTrue(c.get() >= DROP_WHILE_COUNT_LIMIT); 195 assertTrue(rc <= DROP_SOURCE_SIZE); 196 }); 197 */ 198 // END Android-removed: Drop primitive stream test. 199 } 200 201 @Test(groups = { "serialization-hostile" }) testCountDropWithToArray()202 public void testCountDropWithToArray() { 203 testDropWhileMulti( 204 s -> { 205 AtomicLong c = new AtomicLong(); 206 Object[] ra = s.dropWhile(e -> c.getAndIncrement() < DROP_WHILE_COUNT_LIMIT) 207 .toArray(); 208 assertTrue(c.get() >= DROP_WHILE_COUNT_LIMIT); 209 assertTrue(ra.length <= DROP_SOURCE_SIZE); 210 }); 211 // BEGIN Android-removed: Drop primitive stream test. 212 /* 213 s -> { 214 AtomicLong c = new AtomicLong(); 215 int[] ra = s.dropWhile(e -> c.getAndIncrement() < DROP_WHILE_COUNT_LIMIT) 216 .toArray(); 217 assertTrue(c.get() >= DROP_WHILE_COUNT_LIMIT); 218 assertTrue(ra.length <= DROP_SOURCE_SIZE); 219 }, 220 s -> { 221 AtomicLong c = new AtomicLong(); 222 long[] ra = s.dropWhile(e -> c.getAndIncrement() < DROP_WHILE_COUNT_LIMIT) 223 .toArray(); 224 assertTrue(c.get() >= DROP_WHILE_COUNT_LIMIT); 225 assertTrue(ra.length <= DROP_SOURCE_SIZE); 226 }, 227 s -> { 228 AtomicLong c = new AtomicLong(); 229 double[] ra = s.dropWhile(e -> c.getAndIncrement() < DROP_WHILE_COUNT_LIMIT) 230 .toArray(); 231 assertTrue(c.get() >= DROP_WHILE_COUNT_LIMIT); 232 assertTrue(ra.length <= DROP_SOURCE_SIZE); 233 }); 234 */ 235 // END Android-removed: Drop primitive stream test. 236 } 237 238 testTakeWhileMulti(Consumer<Stream<Integer>> mRef)239 private void testTakeWhileMulti(Consumer<Stream<Integer>> mRef) { 240 // Consumer<IntStream> mInt) { 241 // Consumer<LongStream> mLong, 242 // Consumer<DoubleStream> mDouble) { 243 Map<String, Supplier<Stream<Integer>>> sources = new HashMap<>(); 244 sources.put("Stream.generate()", () -> Stream.generate(() -> 1)); 245 sources.put("Stream.iterate()", () -> Stream.iterate(1, x -> 1)); 246 sources.put("Stream.iterate().unordered()", () -> Stream.iterate(1, x -> 1)); 247 248 // Android-changed: Drop primitive stream test. 249 // testWhileMulti(sources, mRef, mInt, mLong, mDouble); 250 testWhileMulti(sources, mRef); 251 } 252 253 // Android-changed: Drop primitive stream test. 254 /* 255 private void testDropWhileMulti(Consumer<Stream<Integer>> mRef, 256 Consumer<IntStream> mInt, 257 Consumer<LongStream> mLong, 258 Consumer<DoubleStream> mDouble) { 259 */ testDropWhileMulti(Consumer<Stream<Integer>> mRef)260 private void testDropWhileMulti(Consumer<Stream<Integer>> mRef) { 261 Map<String, Supplier<Stream<Integer>>> sources = new HashMap<>(); 262 sources.put("IntStream.range().boxed()", 263 () -> IntStream.range(0, DROP_SOURCE_SIZE).boxed()); 264 sources.put("IntStream.range().boxed().unordered()", 265 () -> IntStream.range(0, DROP_SOURCE_SIZE).boxed().unordered()); 266 sources.put("LinkedList.stream()", 267 () -> IntStream.range(0, DROP_SOURCE_SIZE).boxed() 268 .collect(toCollection(LinkedList::new)) 269 .stream()); 270 sources.put("LinkedList.stream().unordered()", 271 () -> IntStream.range(0, DROP_SOURCE_SIZE).boxed() 272 .collect(toCollection(LinkedList::new)) 273 .stream() 274 .unordered()); 275 // Android-changed: Drop primitive stream test. 276 // testWhileMulti(sources, mRef, mInt, mLong, mDouble); 277 testWhileMulti(sources, mRef); 278 } 279 testWhileMulti(Map<String, Supplier<Stream<Integer>>> sources, Consumer<Stream<Integer>> mRef)280 private void testWhileMulti(Map<String, Supplier<Stream<Integer>>> sources, 281 Consumer<Stream<Integer>> mRef) { 282 // Android-removed: Drop primitive stream test. 283 // Consumer<IntStream> mInt, 284 // Consumer<LongStream> mLong, 285 // Consumer<DoubleStream> mDouble) { 286 Map<String, Function<Stream<Integer>, Stream<Integer>>> transforms = new HashMap<>(); 287 transforms.put("Stream.sequential()", s -> { 288 BooleanSupplier isWithinExecutionPeriod = within(System.currentTimeMillis(), 289 EXECUTION_TIME_LIMIT); 290 return s.peek(e -> { 291 if (!isWithinExecutionPeriod.getAsBoolean()) { 292 throw new RuntimeException(); 293 } 294 }); 295 }); 296 transforms.put("Stream.parallel()", s -> { 297 BooleanSupplier isWithinExecutionPeriod = within(System.currentTimeMillis(), 298 EXECUTION_TIME_LIMIT); 299 return s.parallel() 300 .peek(e -> { 301 if (!isWithinExecutionPeriod.getAsBoolean()) { 302 throw new RuntimeException(); 303 } 304 }); 305 }); 306 307 Map<String, Consumer<Stream<Integer>>> actions = new HashMap<>(); 308 actions.put("Ref", mRef); 309 // Android-removed: Drop primitive stream test. 310 // actions.put("Int", s -> mInt.accept(s.mapToInt(e -> e))); 311 // actions.put("Long", s -> mLong.accept(s.mapToLong(e -> e))); 312 // actions.put("Double", s -> mDouble.accept(s.mapToDouble(e -> e))); 313 actions.put("Ref using defaults", s -> mRef.accept(DefaultMethodStreams.delegateTo(s))); 314 // Android-removed: Drop primitive stream test. 315 // actions.put("Int using defaults", s -> mInt.accept(DefaultMethodStreams.delegateTo(s.mapToInt(e -> e)))); 316 // actions.put("Long using defaults", s -> mLong.accept(DefaultMethodStreams.delegateTo(s.mapToLong(e -> e)))); 317 // actions.put("Double using defaults", s -> mDouble.accept(DefaultMethodStreams.delegateTo(s.mapToDouble(e -> e)))); 318 319 for (Map.Entry<String, Supplier<Stream<Integer>>> s : sources.entrySet()) { 320 setContext("source", s.getKey()); 321 322 for (Map.Entry<String, Function<Stream<Integer>, Stream<Integer>>> t : transforms.entrySet()) { 323 setContext("transform", t.getKey()); 324 325 for (Map.Entry<String, Consumer<Stream<Integer>>> a : actions.entrySet()) { 326 setContext("shape", a.getKey()); 327 328 Stream<Integer> stream = s.getValue().get(); 329 stream = t.getValue().apply(stream); 330 a.getValue().accept(stream); 331 } 332 } 333 } 334 } 335 within(long start, long durationInMillis)336 static BooleanSupplier within(long start, long durationInMillis) { 337 return () -> (System.currentTimeMillis() - start) < durationInMillis; 338 } 339 } 340