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: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to