ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ConcurrentLinkedDequeTest.java
(Generate patch)

Comparing jsr166/src/test/tck/ConcurrentLinkedDequeTest.java (file contents):
Revision 1.24 by jsr166, Sun Oct 16 20:44:18 2016 UTC vs.
Revision 1.34 by jsr166, Tue Aug 13 00:54:51 2019 UTC

# Line 13 | Line 13 | import java.util.Iterator;
13   import java.util.NoSuchElementException;
14   import java.util.Queue;
15   import java.util.Random;
16 + import java.util.concurrent.CompletableFuture;
17   import java.util.concurrent.ConcurrentLinkedDeque;
18 + import java.util.concurrent.ThreadLocalRandom;
19 + import java.util.concurrent.atomic.LongAdder;
20  
21   import junit.framework.Test;
19 import junit.framework.TestSuite;
22  
23   public class ConcurrentLinkedDequeTest extends JSR166TestCase {
24  
# Line 40 | Line 42 | public class ConcurrentLinkedDequeTest e
42       * Returns a new deque of given size containing consecutive
43       * Integers 0 ... n - 1.
44       */
45 <    private ConcurrentLinkedDeque<Integer> populatedDeque(int n) {
46 <        ConcurrentLinkedDeque<Integer> q = new ConcurrentLinkedDeque<Integer>();
45 >    private static ConcurrentLinkedDeque<Integer> populatedDeque(int n) {
46 >        ConcurrentLinkedDeque<Integer> q = new ConcurrentLinkedDeque<>();
47          assertTrue(q.isEmpty());
48          for (int i = 0; i < n; ++i)
49              assertTrue(q.offer(new Integer(i)));
# Line 313 | Line 315 | public class ConcurrentLinkedDequeTest e
315      }
316  
317      /**
318 <     * addAll(this) throws IAE
318 >     * addAll(this) throws IllegalArgumentException
319       */
320      public void testAddAllSelf() {
321          ConcurrentLinkedDeque q = populatedDeque(SIZE);
# Line 660 | Line 662 | public class ConcurrentLinkedDequeTest e
662       */
663      public void testToArray() {
664          ConcurrentLinkedDeque q = populatedDeque(SIZE);
665 <        Object[] o = q.toArray();
666 <        for (int i = 0; i < o.length; i++)
667 <            assertSame(o[i], q.poll());
665 >        Object[] a = q.toArray();
666 >        assertSame(Object[].class, a.getClass());
667 >        for (Object o : a)
668 >            assertSame(o, q.poll());
669 >        assertTrue(q.isEmpty());
670      }
671  
672      /**
# Line 673 | Line 677 | public class ConcurrentLinkedDequeTest e
677          Integer[] ints = new Integer[SIZE];
678          Integer[] array = q.toArray(ints);
679          assertSame(ints, array);
680 <        for (int i = 0; i < ints.length; i++)
681 <            assertSame(ints[i], q.poll());
680 >        for (Integer o : ints)
681 >            assertSame(o, q.poll());
682 >        assertTrue(q.isEmpty());
683      }
684  
685      /**
# Line 683 | Line 688 | public class ConcurrentLinkedDequeTest e
688      public void testToArray_NullArg() {
689          ConcurrentLinkedDeque q = populatedDeque(SIZE);
690          try {
691 <            q.toArray(null);
691 >            q.toArray((Object[])null);
692              shouldThrow();
693          } catch (NullPointerException success) {}
694      }
# Line 863 | Line 868 | public class ConcurrentLinkedDequeTest e
868      }
869  
870      /**
871 <     * A deserialized serialized deque has same elements in same order
871 >     * A deserialized/reserialized deque has same elements in same order
872       */
873      public void testSerialization() throws Exception {
874          Queue x = populatedDeque(SIZE);
# Line 906 | Line 911 | public class ConcurrentLinkedDequeTest e
911              } catch (NullPointerException success) {}
912          }
913      }
914 +
915 +    void runAsync(Runnable r1, Runnable r2) {
916 +        boolean b = randomBoolean();
917 +        CompletableFuture<Void> f1 = CompletableFuture.runAsync(b ? r1 : r2);
918 +        CompletableFuture<Void> f2 = CompletableFuture.runAsync(b ? r2 : r1);
919 +        f1.join();
920 +        f2.join();
921 +    }
922 +
923 +    /**
924 +     * Non-traversing Deque operations are linearizable.
925 +     * https://bugs.openjdk.java.net/browse/JDK-8188900
926 +     * ant -Djsr166.expensiveTests=true -Djsr166.tckTestClass=ConcurrentLinkedDequeTest -Djsr166.methodFilter=testBug8188900 tck
927 +     */
928 +    public void testBug8188900() {
929 +        final ThreadLocalRandom rnd = ThreadLocalRandom.current();
930 +        final LongAdder nulls = new LongAdder(), zeros = new LongAdder();
931 +        for (int n = expensiveTests ? 100_000 : 10; n--> 0; ) {
932 +            ConcurrentLinkedDeque<Integer> d = new ConcurrentLinkedDeque<>();
933 +
934 +            boolean peek = rnd.nextBoolean();
935 +            Runnable getter = () -> {
936 +                Integer x = peek ? d.peekFirst() : d.pollFirst();
937 +                if (x == null) nulls.increment();
938 +                else if (x == 0) zeros.increment();
939 +                else
940 +                    throw new AssertionError(
941 +                        String.format(
942 +                            "unexpected value %d after %d nulls and %d zeros",
943 +                            x, nulls.sum(), zeros.sum()));
944 +            };
945 +
946 +            Runnable adder = () -> { d.addFirst(0); d.addLast(42); };
947 +
948 +            runAsync(getter, adder);
949 +        }
950 +    }
951 +
952 +    /**
953 +     * Reverse direction variant of testBug8188900
954 +     */
955 +    public void testBug8188900_reverse() {
956 +        final ThreadLocalRandom rnd = ThreadLocalRandom.current();
957 +        final LongAdder nulls = new LongAdder(), zeros = new LongAdder();
958 +        for (int n = expensiveTests ? 100_000 : 10; n--> 0; ) {
959 +            ConcurrentLinkedDeque<Integer> d = new ConcurrentLinkedDeque<>();
960 +
961 +            boolean peek = rnd.nextBoolean();
962 +            Runnable getter = () -> {
963 +                Integer x = peek ? d.peekLast() : d.pollLast();
964 +                if (x == null) nulls.increment();
965 +                else if (x == 0) zeros.increment();
966 +                else
967 +                    throw new AssertionError(
968 +                        String.format(
969 +                            "unexpected value %d after %d nulls and %d zeros",
970 +                            x, nulls.sum(), zeros.sum()));
971 +            };
972 +
973 +            Runnable adder = () -> { d.addLast(0); d.addFirst(42); };
974 +
975 +            runAsync(getter, adder);
976 +        }
977 +    }
978 +
979 +    <T> T chooseRandomly(T... choices) {
980 +        return choices[ThreadLocalRandom.current().nextInt(choices.length)];
981 +    }
982 +
983 +    /**
984 +     * Non-traversing Deque operations (that return null) are linearizable.
985 +     * Don't return null when the deque is observably never empty.
986 +     * https://bugs.openjdk.java.net/browse/JDK-8189387
987 +     * ant -Djsr166.expensiveTests=true -Djsr166.tckTestClass=ConcurrentLinkedDequeTest -Djsr166.methodFilter=testBug8189387 tck
988 +     */
989 +    public void testBug8189387() {
990 +        final ThreadLocalRandom rnd = ThreadLocalRandom.current();
991 +        Object x = new Object();
992 +        for (int n = expensiveTests ? 100_000 : 10; n--> 0; ) {
993 +            ConcurrentLinkedDeque<Object> d = new ConcurrentLinkedDeque<>();
994 +            Runnable add = chooseRandomly(
995 +                () -> d.addFirst(x),
996 +                () -> d.offerFirst(x),
997 +                () -> d.addLast(x),
998 +                () -> d.offerLast(x));
999 +
1000 +            Runnable get = chooseRandomly(
1001 +                () -> assertFalse(d.isEmpty()),
1002 +                () -> assertSame(x, d.peekFirst()),
1003 +                () -> assertSame(x, d.peekLast()),
1004 +                () -> assertSame(x, d.pollFirst()),
1005 +                () -> assertSame(x, d.pollLast()));
1006 +
1007 +            Runnable addRemove = chooseRandomly(
1008 +                () -> { d.addFirst(x); d.pollLast(); },
1009 +                () -> { d.offerFirst(x); d.removeFirst(); },
1010 +                () -> { d.offerLast(x); d.removeLast(); },
1011 +                () -> { d.addLast(x); d.pollFirst(); });
1012 +
1013 +            add.run();
1014 +            runAsync(get, addRemove);
1015 +        }
1016 +    }
1017   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines