Add timeout exception when waiting for jobs
authorMarc-Andre Laperle <marc-andre.laperle@ericsson.com>
Sat, 19 Mar 2016 22:02:02 +0000 (18:02 -0400)
committerMarc-Andre Laperle <marc-andre.laperle@ericsson.com>
Thu, 31 Mar 2016 17:53:25 +0000 (13:53 -0400)
It can happen that jobs never finish and tests calling waitForJobs
will run forever (or time out if a Jenkins/Hudson job is set to
timeout). Normally it would be possible to set a timeout on individual
JUnit tests but this doesn't seem to play well with SWTBot (to be
investigated).

To reproduce the issue before this patch, add this line to the
beginning of SWTBotUtils.waitForJobs method:
new Job("Foo") {@Override protected IStatus run(IProgressMonitor monitor) {while(true){}}}.schedule();

This simulates a never finishing job. Then run OpenTraceStressTest.
The test should never time out.

With this patch, waitForJobs will timeout after 5 mins (300000ms) by
default. When it does timeout, it will print each job, its state and
stack trace.

To reproduce the timeout added with this patch, apply the line as
mentioned above, reduce MAX_JOBS_WAIT_TIME to a smaller value (5000ms)
then run OpenTraceStressTest.

Change-Id: I0cdbaa10c87b93aa2ac6c7f146f7a6e008983fbd
Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/68850
Reviewed-by: Hudson CI
tmf/org.eclipse.tracecompass.tmf.ui.swtbot.tests/shared/org/eclipse/tracecompass/tmf/ui/swtbot/tests/shared/SWTBotUtils.java

index 3e0638adeccb254ed24315291d4048191106aebe..f8edc19304a22d0bffedbf67a4b0dc3cad5bd3e0 100644 (file)
@@ -88,6 +88,7 @@ import org.hamcrest.Matcher;
 @SuppressWarnings("restriction")
 public final class SWTBotUtils {
 
+    private static final long MAX_JOBS_WAIT_TIME = 300000;
     private static final String WINDOW_MENU = "Window";
     private static final String PREFERENCES_MENU_ITEM = "Preferences";
     private static boolean fPrintedEnvironment = false;
@@ -98,14 +99,66 @@ public final class SWTBotUtils {
     private static final String TRACING_PERSPECTIVE_ID = TracingPerspectiveFactory.ID;
 
     /**
-     * Waits for all Eclipse jobs to finish
+     * Waits for all Eclipse jobs to finish. Times out after
+     * SWTBotUtils#MAX_JOBS_WAIT_TIME by default.
+     *
+     * @throws TimeoutException
+     *             once the waiting time passes the default maximum value
      */
     public static void waitForJobs() {
+        waitForJobs(MAX_JOBS_WAIT_TIME);
+    }
+
+    /**
+     * Waits for all Eclipse jobs to finish
+     *
+     * @param maxWait
+     *            the maximum time to wait, in milliseconds. Once the waiting
+     *            time passes the maximum value, a TimeoutException is thrown
+     * @throws TimeoutException
+     *             once the waiting time passes the maximum value
+     */
+    public static void waitForJobs(long maxWait) {
+        long waitStart = System.currentTimeMillis();
         while (!Job.getJobManager().isIdle()) {
+            if (System.currentTimeMillis() - waitStart > maxWait) {
+                printJobs();
+                throw new TimeoutException("Timed out waiting for jobs to finish.");
+            }
+
             delay(100);
         }
     }
 
+    private static void printJobs() {
+        Job[] jobs = Job.getJobManager().find(null);
+        for (Job job : jobs) {
+            System.err.println(job.toString() + " state: " + jobStateToString(job.getState()));
+            Thread thread = job.getThread();
+            if (thread != null) {
+                for (StackTraceElement stractTraceElement : thread.getStackTrace()) {
+                    System.err.println("  " + stractTraceElement);
+                }
+            }
+            System.err.println();
+        }
+    }
+
+    private static String jobStateToString(int jobState) {
+        switch (jobState) {
+        case Job.RUNNING:
+            return "RUNNING";
+        case Job.WAITING:
+            return "WAITING";
+        case Job.SLEEPING:
+            return "SLEEPING";
+        case Job.NONE:
+            return "NONE";
+        default:
+            return "UNKNOWN";
+        }
+    }
+
     /**
      * Sleeps current thread for a given time.
      *
This page took 0.027128 seconds and 5 git commands to generate.