• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 package org.chromium.base.task.test;
5 
6 import android.os.Looper;
7 
8 import org.junit.rules.ExternalResource;
9 import org.robolectric.Shadows;
10 import org.robolectric.android.util.concurrent.PausedExecutorService;
11 
12 import org.chromium.base.task.PostTask;
13 
14 import java.util.concurrent.TimeUnit;
15 
16 /** Allows tests to manually schedule background tasks posted via PostTask APIs. */
17 public class PausedExecutorTestRule extends ExternalResource {
18     private final PausedExecutorService mPausedExecutor = new PausedExecutorService();
19 
20     @Override
before()21     protected void before() {
22         PostTask.setPrenativeThreadPoolExecutorForTesting(mPausedExecutor);
23     }
24 
25     @Override
after()26     protected void after() {
27         mPausedExecutor.shutdownNow();
28         try {
29             mPausedExecutor.awaitTermination(1, TimeUnit.SECONDS);
30         } catch (InterruptedException e) {
31             throw new RuntimeException(e);
32         }
33     }
34 
35     /**
36      * Runs all currently background tasks and waits for them to finish.
37      * Warning: This will deadlock if a background tasks blocks on the UI thread.
38      * @return Whether any background tasks were run.
39      */
runAllBackgroundAndUi()40     public boolean runAllBackgroundAndUi() {
41         int taskCount = 0;
42         for (int i = 0; i < 100; ++i) {
43             Shadows.shadowOf(Looper.getMainLooper()).idle();
44             if (!mPausedExecutor.hasQueuedTasks()) {
45                 return taskCount > 0;
46             }
47             taskCount += mPausedExecutor.runAll();
48         }
49         throw new AssertionError("Infinite loop of background->foreground->background jobs");
50     }
51 }
52