1 /******************************************************************************* 2 * Copyright (c) 2016 Google, Inc and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * Stefan Xenos (Google) - Initial implementation 13 *******************************************************************************/ 14 package org.eclipse.ui.editors.tests; 15 16 import java.util.concurrent.TimeUnit; 17 18 import org.junit.Assert; 19 20 import org.eclipse.swt.widgets.Display; 21 22 import org.eclipse.core.runtime.jobs.Job; 23 24 public class TestUtil { 25 /** 26 * Call this in the tearDown method of every test to clean up state that can 27 * otherwise leak through SWT between tests. 28 */ cleanUp()29 public static void cleanUp() { 30 // Ensure that the Thread.interrupted() flag didn't leak. 31 Assert.assertFalse("The main thread should not be interrupted at the end of a test", Thread.interrupted()); 32 // Wait for any outstanding jobs to finish. Protect against deadlock by 33 // terminating the wait after a timeout. 34 boolean timedOut = waitForJobs(0, TimeUnit.MINUTES.toMillis(3)); 35 Assert.assertFalse("Some Job did not terminate at the end of the test", timedOut); 36 // Wait for any pending *syncExec calls to finish 37 runEventLoop(); 38 // Ensure that the Thread.interrupted() flag didn't leak. 39 Assert.assertFalse("The main thread should not be interrupted at the end of a test", Thread.interrupted()); 40 } 41 42 /** 43 * Process all queued UI events. If called from background thread, does 44 * nothing. 45 */ runEventLoop()46 public static void runEventLoop() { 47 Display display = Display.getCurrent(); 48 if (display != null && !display.isDisposed()) { 49 while (display.readAndDispatch()) { 50 // Keep pumping events until the queue is empty 51 } 52 } 53 } 54 55 /** 56 * Utility for waiting until the execution of jobs of any family has 57 * finished or timeout is reached. If no jobs are running, the method waits 58 * given minimum wait time. While this method is waiting for jobs, UI events 59 * are processed. 60 * 61 * @param minTimeMs 62 * minimum wait time in milliseconds 63 * @param maxTimeMs 64 * maximum wait time in milliseconds 65 * @return true if the method timed out, false if all the jobs terminated 66 * before the timeout 67 */ waitForJobs(long minTimeMs, long maxTimeMs)68 public static boolean waitForJobs(long minTimeMs, long maxTimeMs) { 69 if (maxTimeMs < minTimeMs) { 70 throw new IllegalArgumentException("Max time is smaller as min time!"); 71 } 72 final long start = System.currentTimeMillis(); 73 while (System.currentTimeMillis() - start < minTimeMs) { 74 runEventLoop(); 75 try { 76 Thread.sleep(100); 77 } catch (InterruptedException e) { 78 // Uninterruptable 79 } 80 } 81 while (!Job.getJobManager().isIdle()) { 82 if (System.currentTimeMillis() - start >= maxTimeMs) { 83 return true; 84 } 85 runEventLoop(); 86 try { 87 Thread.sleep(100); 88 } catch (InterruptedException e) { 89 // Uninterruptable 90 } 91 } 92 return false; 93 } 94 } 95