diff options
author | Robert Horvath <robhor@google.com> | 2020-03-23 14:46:25 +0100 |
---|---|---|
committer | Robert Horvath <robhor@google.com> | 2020-03-23 16:37:13 +0100 |
commit | e75cf0ac168039c6a15edf5543d7fbd7578432bf (patch) | |
tree | 014d9e6608368cb090ea2d4eb7821b1bff3d6c25 /tests/utils | |
parent | 0a9aff3ac39cc1aa9641eabab0ad681a2ad1ebd7 (diff) |
Deterministic PowerManagerServiceTest
To make PowerManagerServiceTest deterministic,
remove dependency on real time clock by mocking it out.
Use TestLooper, which allows making Handler behaviour deterministic as
well.
Test: atest PowerManagerServiceTest
Bug: 152193749
Change-Id: I4d9cd686ac672261bbb038249c0358e451b58710
Diffstat (limited to 'tests/utils')
-rw-r--r-- | tests/utils/testutils/java/android/os/test/TestLooper.java | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/tests/utils/testutils/java/android/os/test/TestLooper.java b/tests/utils/testutils/java/android/os/test/TestLooper.java index 01bd47b9c608..a826646f69f3 100644 --- a/tests/utils/testutils/java/android/os/test/TestLooper.java +++ b/tests/utils/testutils/java/android/os/test/TestLooper.java @@ -48,6 +48,8 @@ public class TestLooper { private static final Method MESSAGE_MARK_IN_USE_METHOD; private static final String TAG = "TestLooper"; + private final Clock mClock; + private AutoDispatchThread mAutoDispatchThread; static { @@ -69,8 +71,25 @@ public class TestLooper { } } - + /** + * Creates a TestLooper and installs it as the looper for the current thread. + */ public TestLooper() { + this(SystemClock::uptimeMillis); + } + + /** + * Creates a TestLooper with a custom clock and installs it as the looper for the current + * thread. + * + * Messages are dispatched when their {@link Message#when} is before or at {@link + * Clock#uptimeMillis()}. + * Use a custom clock with care. When using an offsettable clock like {@link + * com.android.server.testutils.OffsettableClock} be sure not to double offset messages by + * offsetting the clock and calling {@link #moveTimeForward(long)}. Instead, offset the clock + * and call {@link #dispatchAll()}. + */ + public TestLooper(Clock clock) { try { mLooper = LOOPER_CONSTRUCTOR.newInstance(false); @@ -80,6 +99,8 @@ public class TestLooper { } catch (IllegalAccessException | InstantiationException | InvocationTargetException e) { throw new RuntimeException("Reflection error constructing or accessing looper", e); } + + mClock = clock; } public Looper getLooper() { @@ -116,9 +137,13 @@ public class TestLooper { } } + private long currentTime() { + return mClock.uptimeMillis(); + } + private Message messageQueueNext() { try { - long now = SystemClock.uptimeMillis(); + long now = currentTime(); Message prevMsg = null; Message msg = getMessageLinkedList(); @@ -157,7 +182,7 @@ public class TestLooper { public synchronized boolean isIdle() { Message messageList = getMessageLinkedList(); - return messageList != null && SystemClock.uptimeMillis() >= messageList.getWhen(); + return messageList != null && currentTime() >= messageList.getWhen(); } /** @@ -187,6 +212,7 @@ public class TestLooper { /** * Dispatch all messages currently in the queue * Will not fail if there are no messages pending + * * @return the number of messages dispatched */ public synchronized int dispatchAll() { @@ -198,6 +224,10 @@ public class TestLooper { return count; } + public interface Clock { + long uptimeMillis(); + } + /** * Thread used to dispatch messages when the main thread is blocked waiting for a response. */ |