Reuse the ExecutorService in DelegateRunnerWithTimeout so all tests are run on the same thread. Summary: It appears that all tests that use `ShadowLooper` in Robolectric need to be started from the same thread so that its `resetThreadLoopers()` method works as expected. Test Plan: Sandcastle builds. I promise to write an integration test in a follow-up diff.
diff --git a/src/com/facebook/buck/junit/DelegateRunnerWithTimeout.java b/src/com/facebook/buck/junit/DelegateRunnerWithTimeout.java index 07c2ec3..7cbacb2 100644 --- a/src/com/facebook/buck/junit/DelegateRunnerWithTimeout.java +++ b/src/com/facebook/buck/junit/DelegateRunnerWithTimeout.java
@@ -31,6 +31,16 @@ */ class DelegateRunnerWithTimeout extends Runner { + /** + * Shared {@link ExecutorService} on which all tests run by this {@link Runner} are executed. + * <p> + * In Robolectric, the {@code ShadowLooper.resetThreadLoopers()} asserts that the current thread + * is the same as the thread on which the {@code ShadowLooper} class was loaded. Therefore, to + * preserve the behavior of the {@code org.robolectric.RobolectricTestRunner}, we use an + * {@link ExecutorService} with a single thread to run all of the tests. + */ + private static final ExecutorService executor = MoreExecutors.newSingleThreadExecutor(); + private final Runner delegate; private final long defaultTestTimeoutMillis; @@ -63,7 +73,6 @@ delegate, notifier, defaultTestTimeoutMillis); // We run the Runner in an Executor so that we can tear it down if we need to. - ExecutorService executor = MoreExecutors.newSingleThreadExecutor(); Future<?> future = executor.submit(new Runnable() { @Override public void run() {