Przemyslaw Szczepaniak | e8b323c | 2016-03-11 15:59:10 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Written by Doug Lea and Martin Buchholz with assistance from |
| 3 | * members of JCP JSR-166 Expert Group and released to the public |
| 4 | * domain, as explained at |
| 5 | * http://creativecommons.org/publicdomain/zero/1.0/ |
| 6 | */ |
| 7 | |
| 8 | package jsr166; |
| 9 | |
| 10 | import static java.util.concurrent.TimeUnit.MILLISECONDS; |
| 11 | |
| 12 | import java.util.ArrayList; |
| 13 | import java.util.Collection; |
| 14 | import java.util.Collections; |
| 15 | import java.util.concurrent.CountDownLatch; |
| 16 | import java.util.concurrent.Executors; |
| 17 | import java.util.concurrent.ExecutorService; |
| 18 | import java.util.concurrent.Future; |
| 19 | import java.util.concurrent.atomic.AtomicBoolean; |
| 20 | import java.util.concurrent.atomic.AtomicLong; |
| 21 | import java.util.function.Consumer; |
| 22 | |
| 23 | import junit.framework.Test; |
| 24 | |
| 25 | /** |
| 26 | * Contains tests applicable to all jdk8+ Collection implementations. |
| 27 | * An extension of CollectionTest. |
| 28 | */ |
Nicholas Sauer | b30ea05 | 2016-05-01 21:22:28 -0700 | [diff] [blame] | 29 | // Android-changed: Made class abstract so it will be ignored by test runners. |
| 30 | public abstract class Collection8Test extends JSR166TestCase { |
Przemyslaw Szczepaniak | e8b323c | 2016-03-11 15:59:10 +0000 | [diff] [blame] | 31 | final CollectionImplementation impl; |
| 32 | |
| 33 | /** Tests are parameterized by a Collection implementation. */ |
| 34 | Collection8Test(CollectionImplementation impl, String methodName) { |
| 35 | super(methodName); |
| 36 | this.impl = impl; |
| 37 | } |
| 38 | |
| 39 | public static Test testSuite(CollectionImplementation impl) { |
| 40 | return parameterizedTestSuite(Collection8Test.class, |
| 41 | CollectionImplementation.class, |
| 42 | impl); |
| 43 | } |
| 44 | |
| 45 | /** |
| 46 | * stream().forEach returns elements in the collection |
| 47 | */ |
Igor Murashkin | ff18b5f | 2016-03-16 13:29:15 +0000 | [diff] [blame] | 48 | public void testForEach() throws Throwable { |
| 49 | final Collection c = impl.emptyCollection(); |
| 50 | final AtomicLong count = new AtomicLong(0L); |
| 51 | final Object x = impl.makeElement(1); |
| 52 | final Object y = impl.makeElement(2); |
| 53 | final ArrayList found = new ArrayList(); |
| 54 | Consumer<Object> spy = (o) -> { found.add(o); }; |
| 55 | c.stream().forEach(spy); |
| 56 | assertTrue(found.isEmpty()); |
Przemyslaw Szczepaniak | e8b323c | 2016-03-11 15:59:10 +0000 | [diff] [blame] | 57 | |
Igor Murashkin | ff18b5f | 2016-03-16 13:29:15 +0000 | [diff] [blame] | 58 | assertTrue(c.add(x)); |
| 59 | c.stream().forEach(spy); |
| 60 | assertEquals(Collections.singletonList(x), found); |
| 61 | found.clear(); |
Przemyslaw Szczepaniak | e8b323c | 2016-03-11 15:59:10 +0000 | [diff] [blame] | 62 | |
Igor Murashkin | ff18b5f | 2016-03-16 13:29:15 +0000 | [diff] [blame] | 63 | assertTrue(c.add(y)); |
| 64 | c.stream().forEach(spy); |
| 65 | assertEquals(2, found.size()); |
| 66 | assertTrue(found.contains(x)); |
| 67 | assertTrue(found.contains(y)); |
| 68 | found.clear(); |
Przemyslaw Szczepaniak | e8b323c | 2016-03-11 15:59:10 +0000 | [diff] [blame] | 69 | |
Igor Murashkin | ff18b5f | 2016-03-16 13:29:15 +0000 | [diff] [blame] | 70 | c.clear(); |
| 71 | c.stream().forEach(spy); |
| 72 | assertTrue(found.isEmpty()); |
| 73 | } |
Przemyslaw Szczepaniak | e8b323c | 2016-03-11 15:59:10 +0000 | [diff] [blame] | 74 | |
Igor Murashkin | ff18b5f | 2016-03-16 13:29:15 +0000 | [diff] [blame] | 75 | public void testForEachConcurrentStressTest() throws Throwable { |
| 76 | if (!impl.isConcurrent()) return; |
| 77 | final Collection c = impl.emptyCollection(); |
| 78 | final long testDurationMillis = timeoutMillis(); |
| 79 | final AtomicBoolean done = new AtomicBoolean(false); |
| 80 | final Object elt = impl.makeElement(1); |
| 81 | final Future<?> f1, f2; |
| 82 | final ExecutorService pool = Executors.newCachedThreadPool(); |
| 83 | try (PoolCleaner cleaner = cleaner(pool, done)) { |
| 84 | final CountDownLatch threadsStarted = new CountDownLatch(2); |
| 85 | Runnable checkElt = () -> { |
| 86 | threadsStarted.countDown(); |
| 87 | while (!done.get()) |
| 88 | c.stream().forEach((x) -> { assertSame(x, elt); }); }; |
| 89 | Runnable addRemove = () -> { |
| 90 | threadsStarted.countDown(); |
| 91 | while (!done.get()) { |
| 92 | assertTrue(c.add(elt)); |
| 93 | assertTrue(c.remove(elt)); |
| 94 | }}; |
| 95 | f1 = pool.submit(checkElt); |
| 96 | f2 = pool.submit(addRemove); |
| 97 | Thread.sleep(testDurationMillis); |
| 98 | } |
| 99 | assertNull(f1.get(0L, MILLISECONDS)); |
| 100 | assertNull(f2.get(0L, MILLISECONDS)); |
| 101 | } |
Przemyslaw Szczepaniak | e8b323c | 2016-03-11 15:59:10 +0000 | [diff] [blame] | 102 | |
| 103 | // public void testCollection8DebugFail() { fail(); } |
| 104 | } |