From cff661d65e3e6e2ac731ebbf938251656deb4be4 Mon Sep 17 00:00:00 2001 From: Tobias Thierer Date: Sun, 19 Feb 2017 15:01:51 +0000 Subject: Port JSR166 LinkedTransferQueueTest flakiness fix This CL cherry-picks the following upstream (*) test changes ("upstream" here is JSR166's CVS repository cvs -d ':pserver:anonymous@gee.cs.oswego.edu/home/jsr166/jsr166' This is in contrast to the code under test, whose upstream is OpenJDK). ===== src/test/tck/LinkedTransferQueueTest.java revision 1.70 date: 2017/02/18 16:37:49; author: jsr166; state: Exp; lines: +11 -5 waitForThreadToEnterWaitState should fail on timeout; tests should tolerate transient blocking Thread.State at any time (e.g. due to classloading) src/test/tck/JSR166TestCase.java revision 1.219 date: 2017/02/18 16:37:49; author: jsr166; state: Exp; lines: +43 -3 waitForThreadToEnterWaitState should fail on timeout; tests should tolerate transient blocking Thread.State at any time (e.g. due to classloading) src/test/tck/PhaserTest.java revision 1.45 date: 2017/02/18 15:05:55; author: jsr166; state: Exp; lines: +10 -10 use default timeout of LONG_DELAY_MS with waitForThreadToEnterWaitState ====== The effect of this CL is to fix flakiness in LinkedTransferQueueTest's testTransfer2() and testWaitingConsumer(). These test methods need to wait until a background thread was blocked waiting on a LinkedTransferQueue; before this CL, they did so by calling a helper method that waited for the background thread's state to become WAITING, TIMED_WAITING, or BLOCKED. After this CL, they also check that the LinkedTransferQueue is in the expected state before they stop waiting. The additional check is necessary because LinkedTransferQueue uses LockSupport.park(), which on Android involves a synchronized lock and therefore BLOCKED state. This caused the test methods to prematurely stop waiting, which caused the test to fail. The concrete failure could also have been prevented by waiting for the thread to enter WAITING or TIMED_WAITING state rather than BLOCKED. This was considered but not chosen by upstream since it would still have made assumptions about those states not being entered elsewhere. This CL also changes the waiting logic to fail() the test upon timeout. PhaserTest was changed to use longer timeouts (10sec rather than 250msec) to avoid flaky timeout failures. Bug: 34814528 Test: LinkedTransferQueueTest Test: PhaserTest Test: Checked that testTransfer2() and testWaitingConsumer() are non-flaky by running their body 10,000 times each in a loop. Change-Id: I112ee1fba8aea6ca97ca0f99bba0fc9f00e5c0c2 --- .../src/test/java/jsr166/LinkedTransferQueueTest.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java') diff --git a/jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java b/jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java index 05fc689119..efe5a58280 100644 --- a/jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java +++ b/jsr166-tests/src/test/java/jsr166/LinkedTransferQueueTest.java @@ -17,6 +17,7 @@ import java.util.List; import java.util.NoSuchElementException; import java.util.Queue; import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; @@ -750,9 +751,11 @@ public class LinkedTransferQueueTest extends JSR166TestCase { }}); threadStarted.await(); - waitForThreadToEnterWaitState(t); - assertEquals(1, q.getWaitingConsumerCount()); - assertTrue(q.hasWaitingConsumer()); + Callable oneConsumer + = new Callable() { public Boolean call() { + return q.hasWaitingConsumer() + && q.getWaitingConsumerCount() == 1; }}; + waitForThreadToEnterWaitState(t, oneConsumer); assertTrue(q.offer(one)); assertEquals(0, q.getWaitingConsumerCount()); @@ -789,8 +792,11 @@ public class LinkedTransferQueueTest extends JSR166TestCase { }}); threadStarted.await(); - waitForThreadToEnterWaitState(t); - assertEquals(1, q.size()); + Callable oneElement + = new Callable() { public Boolean call() { + return !q.isEmpty() && q.size() == 1; }}; + waitForThreadToEnterWaitState(t, oneElement); + assertSame(five, q.poll()); checkEmpty(q); awaitTermination(t); -- cgit v1.2.3