summaryrefslogtreecommitdiff
path: root/tests/utils
diff options
context:
space:
mode:
authorRobert Horvath <robhor@google.com>2020-03-23 14:46:25 +0100
committerRobert Horvath <robhor@google.com>2020-03-23 16:37:13 +0100
commite75cf0ac168039c6a15edf5543d7fbd7578432bf (patch)
tree014d9e6608368cb090ea2d4eb7821b1bff3d6c25 /tests/utils
parent0a9aff3ac39cc1aa9641eabab0ad681a2ad1ebd7 (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.java36
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.
*/