Author: markt
Date: Wed Sep 23 11:07:58 2015
New Revision: 1704817
URL: http://svn.apache.org/viewvc?rev=1704817&view=rev
Log:
Refactor to remove timing dependencies which were causing unit test failures.
Modified:
tomcat/tc8.0.x/trunk/test/org/apache/tomcat/util/threads/TestLimitLatch.java
Modified:
tomcat/tc8.0.x/trunk/test/org/apache/tomcat/util/threads/TestLimitLatch.java
URL:
http://svn.apache.org/viewvc/tomcat/tc8.0.x/trunk/test/org/apache/tomcat/util/threads/TestLimitLatch.java?rev=1704817&r1=1704816&r2=1704817&view=diff
==============================================================================
---
tomcat/tc8.0.x/trunk/test/org/apache/tomcat/util/threads/TestLimitLatch.java
(original)
+++
tomcat/tc8.0.x/trunk/test/org/apache/tomcat/util/threads/TestLimitLatch.java
Wed Sep 23 11:07:58 2015
@@ -16,102 +16,216 @@
*/
package org.apache.tomcat.util.threads;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
+import org.junit.Assert;
import org.junit.Test;
public class TestLimitLatch {
+ // This should be plenty of time, even on slow systems.
+ private static final long THREAD_WAIT_TIME = 60000;
+
@Test
public void testNoThreads() throws Exception {
LimitLatch latch = new LimitLatch(0);
- assertFalse("No threads should be waiting", latch.hasQueuedThreads());
+ Assert.assertFalse("No threads should be waiting",
latch.hasQueuedThreads());
}
@Test
public void testOneThreadNoWait() throws Exception {
LimitLatch latch = new LimitLatch(1);
- assertFalse("No threads should be waiting", latch.hasQueuedThreads());
- Thread testThread = new TestThread(latch);
+ Object lock = new Object();
+ checkWaitingThreadCount(latch, 0);
+ TestThread testThread = new TestThread(latch, lock);
testThread.start();
- Thread.sleep(50);
- assertEquals("0 threads should be waiting", 0,
- latch.getQueuedThreads().size());
- latch.countUpOrAwait();
- Thread.sleep(50);
- assertFalse("No threads should be waiting", latch.hasQueuedThreads());
+ if (!waitForThreadToStart(testThread)) {
+ Assert.fail("Test thread did not start");
+ }
+ checkWaitingThreadCount(latch, 0);
+ if (!waitForThreadToStop(testThread, lock)) {
+ Assert.fail("Test thread did not stop");
+ }
+ checkWaitingThreadCount(latch, 0);
}
@Test
- public void testOneThreadWaitCountUp() throws Exception {
+ public void testOneThreadWaitCountDown() throws Exception {
LimitLatch latch = new LimitLatch(1);
- assertFalse("No threads should be waiting", latch.hasQueuedThreads());
- Thread testThread = new TestThread(latch);
+ Object lock = new Object();
+ checkWaitingThreadCount(latch, 0);
+ TestThread testThread = new TestThread(latch, lock);
latch.countUpOrAwait();
testThread.start();
- Thread.sleep(50);
- assertEquals("1 threads should be waiting", 1,
- latch.getQueuedThreads().size());
+ if (!waitForThreadToStart(testThread)) {
+ Assert.fail("Test thread did not start");
+ }
+ checkWaitingThreadCount(latch, 1);
latch.countDown();
- Thread.sleep(50);
- assertFalse("No threads should be waiting", latch.hasQueuedThreads());
+ if (!waitForThreadToStop(testThread, lock)) {
+ Assert.fail("Test thread did not stop");
+ }
+ checkWaitingThreadCount(latch, 0);
}
@Test
public void testOneRelease() throws Exception {
LimitLatch latch = new LimitLatch(1);
- assertFalse("No threads should be waiting", latch.hasQueuedThreads());
- Thread testThread = new TestThread(latch);
+ Object lock = new Object();
+ checkWaitingThreadCount(latch, 0);
+ TestThread testThread = new TestThread(latch, lock);
latch.countUpOrAwait();
testThread.start();
- Thread.sleep(50);
- assertEquals("1 threads should be waiting", 1,
- latch.getQueuedThreads().size());
+ if (!waitForThreadToStart(testThread)) {
+ Assert.fail("Test thread did not start");
+ }
+ checkWaitingThreadCount(latch, 1);
latch.releaseAll();
- Thread.sleep(50);
- assertFalse("No threads should be waiting", latch.hasQueuedThreads());
+ if (!waitForThreadToStop(testThread, lock)) {
+ Assert.fail("Test thread did not stop");
+ }
+ checkWaitingThreadCount(latch, 0);
}
@Test
public void testTenWait() throws Exception {
LimitLatch latch = new LimitLatch(10);
- assertFalse("No threads should be waiting", latch.hasQueuedThreads());
- Thread[] testThread = new TestThread[30];
+ Object lock = new Object();
+ checkWaitingThreadCount(latch, 0);
+
+ TestThread[] testThreads = new TestThread[30];
for (int i = 0; i < 30; i++) {
- testThread[i] = new TestThread(latch, 1000);
- testThread[i].start();
+ testThreads[i] = new TestThread(latch, lock);
+ testThreads[i].start();
+ }
+
+ for (int i = 0; i < 30; i++) {
+ if (!waitForThreadToStart(testThreads[i])) {
+ Assert.fail("Test thread [" + i + "] did not start");
+ }
+ }
+
+ if (!waitForThreadsToReachStage(testThreads, 20, 10, 0)) {
+ Assert.fail("Failed at 20-10-00");
+ }
+ checkWaitingThreadCount(latch, 20);
+
+ synchronized (lock) {
+ lock.notifyAll();
+ }
+
+ if (!waitForThreadsToReachStage(testThreads, 10, 10, 10)) {
+ Assert.fail("Failed at 10-10-10");
+ }
+ checkWaitingThreadCount(latch, 10);
+
+ synchronized (lock) {
+ lock.notifyAll();
+ }
+
+ if (!waitForThreadsToReachStage(testThreads, 0, 10, 20)) {
+ Assert.fail("Failed at 00-10-20");
+ }
+ checkWaitingThreadCount(latch, 0);
+
+ synchronized (lock) {
+ lock.notifyAll();
+ }
+
+ if (!waitForThreadsToReachStage(testThreads, 0, 0, 30)) {
+ Assert.fail("Failed at 00-00-30");
}
- Thread.sleep(50);
- assertEquals("20 threads should be waiting", 20,
- latch.getQueuedThreads().size());
- Thread.sleep(1000);
- assertEquals("10 threads should be waiting", 10,
- latch.getQueuedThreads().size());
- Thread.sleep(1000);
- assertFalse("No threads should be waiting", latch.hasQueuedThreads());
}
- private static class TestThread extends Thread {
+ private boolean waitForThreadToStart(TestThread t) throws
InterruptedException {
+ long wait = 0;
+ while (t.getStage() == 0 && wait < THREAD_WAIT_TIME) {
+ Thread.sleep(100);
+ wait += 100;
+ }
+ return t.getStage() > 0;
+ }
- private int holdTime;
- private LimitLatch latch;
+ private boolean waitForThreadToStop(TestThread t, Object lock) throws
InterruptedException {
+ long wait = 0;
+ while (t.getStage() < 3 && wait < THREAD_WAIT_TIME) {
+ Thread.sleep(100);
+ wait += 100;
+ synchronized (lock) {
+ lock.notifyAll();
+ }
+ }
+ return t.getStage() == 3;
+ }
- public TestThread(LimitLatch latch) {
- this(latch, 100);
+ private void checkWaitingThreadCount(LimitLatch latch, int target) throws
InterruptedException {
+ long wait = 0;
+ while (latch.getQueuedThreads().size() != target && wait <
THREAD_WAIT_TIME) {
+ Thread.sleep(100);
+ wait += 100;
}
+ Assert.assertEquals(target, latch.getQueuedThreads().size());
+ }
- public TestThread(LimitLatch latch, int holdTime) {
+ private boolean waitForThreadsToReachStage(TestThread[] testThreads,
+ int stage1Target, int stage2Target, int stage3Target) throws
InterruptedException {
+
+ long wait = 0;
+
+ int stage1 = 0;
+ int stage2 = 0;
+ int stage3 = 0;
+
+ while((stage1 != stage1Target || stage2 != stage2Target || stage3 !=
stage3Target) &&
+ wait < THREAD_WAIT_TIME) {
+ stage1 = 0;
+ stage2 = 0;
+ stage3 = 0;
+ for (TestThread testThread : testThreads) {
+ switch(testThread.getStage()){
+ case 1:
+ stage1++;
+ break;
+ case 2:
+ stage2++;
+ break;
+ case 3:
+ stage3++;
+ break;
+ }
+ }
+ Thread.sleep(100);
+ wait += 100;
+ }
+ return stage1 == stage1Target && stage2 == stage2Target && stage3 ==
stage3Target;
+ }
+
+ private static class TestThread extends Thread {
+
+ private final Object lock;
+ private final LimitLatch latch;
+ private volatile int stage = 0;
+
+ public TestThread(LimitLatch latch, Object lock) {
this.latch = latch;
- this.holdTime = holdTime;
+ this.lock = lock;
+ }
+
+ public int getStage() {
+ return stage;
}
@Override
public void run() {
try {
+ stage = 1;
latch.countUpOrAwait();
- Thread.sleep(holdTime);
+ stage = 2;
+ if (lock != null) {
+ synchronized (lock) {
+ lock.wait();
+ }
+ }
latch.countDown();
+ stage = 3;
} catch (InterruptedException x) {
x.printStackTrace();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]