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
8package jsr166;
9
10import static java.util.concurrent.TimeUnit.MILLISECONDS;
11
12import java.util.ArrayList;
13import java.util.Collection;
14import java.util.Collections;
15import java.util.concurrent.CountDownLatch;
16import java.util.concurrent.Executors;
17import java.util.concurrent.ExecutorService;
18import java.util.concurrent.Future;
19import java.util.concurrent.atomic.AtomicBoolean;
20import java.util.concurrent.atomic.AtomicLong;
21import java.util.function.Consumer;
22
23import junit.framework.Test;
24
25/**
26 * Contains tests applicable to all jdk8+ Collection implementations.
27 * An extension of CollectionTest.
28 */
29// Android-changed: Made class abstract so it will be ignored by test runners.
30public abstract class Collection8Test extends JSR166TestCase {
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     */
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());
57
58        assertTrue(c.add(x));
59        c.stream().forEach(spy);
60        assertEquals(Collections.singletonList(x), found);
61        found.clear();
62
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();
69
70        c.clear();
71        c.stream().forEach(spy);
72        assertTrue(found.isEmpty());
73    }
74
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    }
102
103    // public void testCollection8DebugFail() { fail(); }
104}
105