diff options
| -rw-r--r-- | apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java | 66 | ||||
| -rw-r--r-- | apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java | 101 |
2 files changed, 71 insertions, 96 deletions
diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java b/apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java index 515ddc8d1d49..a4128a3de52f 100644 --- a/apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java +++ b/apct-tests/perftests/multiuser/src/android/multiuser/BenchmarkRunner.java @@ -19,13 +19,16 @@ import android.annotation.Nullable; import android.os.Bundle; import android.os.SystemClock; import android.perftests.utils.ShellHelper; +import android.util.Log; import java.util.ArrayList; +import java.util.concurrent.TimeoutException; // Based on //platform/frameworks/base/apct-tests/perftests/utils/BenchmarkState.java public class BenchmarkRunner { - - private static final long COOL_OFF_PERIOD_MS = 1000; + private static final String TAG = BenchmarkRunner.class.getSimpleName(); + private static final int TIMEOUT_IN_SECONDS = 45; + private static final int CPU_IDLE_THRESHOLD_PERCENTAGE = 90; private static final int NUM_ITERATIONS = 4; @@ -79,8 +82,7 @@ public class BenchmarkRunner { } private void prepareForNextRun() { - SystemClock.sleep(COOL_OFF_PERIOD_MS); - ShellHelper.runShellCommand("am wait-for-broadcast-idle --flush-broadcast-loopers"); + waitCoolDownPeriod(); mStartTimeNs = System.nanoTime(); mPausedDurationNs = 0; } @@ -102,7 +104,7 @@ public class BenchmarkRunner { * to avoid unnecessary waiting. */ public void resumeTiming() { - ShellHelper.runShellCommand("am wait-for-broadcast-idle --flush-broadcast-loopers"); + waitCoolDownPeriod(); resumeTimer(); } @@ -162,4 +164,58 @@ public class BenchmarkRunner { } return null; } + + /** Waits for the CPU cores and the broadcast queue to be idle. */ + public void waitCoolDownPeriod() { + waitForCpuIdle(); + waitForBroadcastIdle(); + } + + private void waitForBroadcastIdle() { + try { + ShellHelper.runShellCommandWithTimeout( + "am wait-for-broadcast-idle --flush-broadcast-loopers", TIMEOUT_IN_SECONDS); + } catch (TimeoutException e) { + Log.e(TAG, "Ending waitForBroadcastIdle because it didn't finish in " + + TIMEOUT_IN_SECONDS + " seconds", e); + } + } + + private void waitForCpuIdle() { + int count = 0; + int idleCpuPercentage; + while (count++ < TIMEOUT_IN_SECONDS) { + idleCpuPercentage = getIdleCpuPercentage(); + Log.d(TAG, "Waiting for CPU idle #" + count + "=" + idleCpuPercentage + "%"); + if (idleCpuPercentage > CPU_IDLE_THRESHOLD_PERCENTAGE) { + return; + } + SystemClock.sleep(1000); + } + Log.e(TAG, "Ending waitForCpuIdle because it didn't finish in " + + TIMEOUT_IN_SECONDS + " seconds"); + } + + private int getIdleCpuPercentage() { + String output = ShellHelper.runShellCommand("top -m 1 -n 1"); + + String[] tokens = output.split("\\s+"); + + float totalCpu = -1; + float idleCpu = -1; + for (String token : tokens) { + if (token.contains("%cpu")) { + totalCpu = Float.parseFloat(token.split("%")[0]); + } else if (token.contains("%idle")) { + idleCpu = Float.parseFloat(token.split("%")[0]); + } + } + + if (totalCpu < 0 || idleCpu < 0) { + Log.e(TAG, "Could not get idle cpu percentage, output=" + output); + return -1; + } + + return (int) (100 * idleCpu / totalCpu); + } }
\ No newline at end of file diff --git a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java index 762e2af09cd3..98ab0c290e40 100644 --- a/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java +++ b/apct-tests/perftests/multiuser/src/android/multiuser/UserLifecycleTests.java @@ -188,21 +188,6 @@ public class UserLifecycleTests { } } - /** Tests creating a new user, with wait times between iterations. */ - @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) - public void createUser_realistic() throws RemoteException { - while (mRunner.keepRunning()) { - Log.i(TAG, "Starting timer"); - final int userId = createUserNoFlags(); - - mRunner.pauseTiming(); - Log.i(TAG, "Stopping timer"); - removeUser(userId); - waitCoolDownPeriod(); - mRunner.resumeTimingForNextIteration(); - } - } - /** Tests creating and starting a new user. */ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) public void createAndStartUser() throws RemoteException { @@ -239,7 +224,6 @@ public class UserLifecycleTests { mRunner.pauseTiming(); Log.d(TAG, "Stopping timer"); removeUser(userId); - waitCoolDownPeriod(); mRunner.resumeTimingForNextIteration(); } } @@ -254,7 +238,6 @@ public class UserLifecycleTests { mRunner.pauseTiming(); final int userId = createUserNoFlags(); - waitForBroadcastIdle(); runThenWaitForBroadcasts(userId, () -> { mRunner.resumeTiming(); Log.i(TAG, "Starting timer"); @@ -309,9 +292,6 @@ public class UserLifecycleTests { preStartUser(userId, numberOfIterationsToSkip); - waitForBroadcastIdle(); - waitCoolDownPeriod(); - runThenWaitForBroadcasts(userId, () -> { mRunner.resumeTiming(); Log.i(TAG, "Starting timer"); @@ -353,9 +333,6 @@ public class UserLifecycleTests { while (mRunner.keepRunning()) { mRunner.pauseTiming(); - waitForBroadcastIdle(); - waitCoolDownPeriod(); - runThenWaitForBroadcasts(userId, () -> { mRunner.resumeTiming(); Log.i(TAG, "Starting timer"); @@ -420,7 +397,6 @@ public class UserLifecycleTests { while (mRunner.keepRunning()) { mRunner.pauseTiming(); - waitCoolDownPeriod(); mRunner.resumeTiming(); Log.i(TAG, "Starting timer"); @@ -454,7 +430,6 @@ public class UserLifecycleTests { mRunner.pauseTiming(); Log.d(TAG, "Stopping timer"); removeUser(userId); - waitCoolDownPeriod(); mRunner.resumeTimingForNextIteration(); } } @@ -466,6 +441,7 @@ public class UserLifecycleTests { mRunner.pauseTiming(); final int startUser = mAm.getCurrentUser(); final int userId = createUserNoFlags(); + mRunner.resumeTiming(); Log.i(TAG, "Starting timer"); @@ -479,27 +455,6 @@ public class UserLifecycleTests { } } - /** Tests switching to an uninitialized user with wait times between iterations. */ - @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) - public void switchUser_realistic() throws Exception { - while (mRunner.keepRunning()) { - mRunner.pauseTiming(); - final int startUser = ActivityManager.getCurrentUser(); - final int userId = createUserNoFlags(); - waitCoolDownPeriod(); - Log.d(TAG, "Starting timer"); - mRunner.resumeTiming(); - - switchUser(userId); - - mRunner.pauseTiming(); - Log.d(TAG, "Stopping timer"); - switchUserNoCheck(startUser); - removeUser(userId); - mRunner.resumeTimingForNextIteration(); - } - } - /** Tests switching to a previously-started, but no-longer-running, user. */ @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) public void switchUser_stopped() throws RemoteException { @@ -507,6 +462,7 @@ public class UserLifecycleTests { mRunner.pauseTiming(); final int startUser = mAm.getCurrentUser(); final int testUser = initializeNewUserAndSwitchBack(/* stopNewUser */ true); + mRunner.resumeTiming(); Log.i(TAG, "Starting timer"); @@ -536,7 +492,6 @@ public class UserLifecycleTests { while (mRunner.keepRunning()) { mRunner.pauseTiming(); - waitCoolDownPeriod(); Log.d(TAG, "Starting timer"); mRunner.resumeTiming(); @@ -562,7 +517,6 @@ public class UserLifecycleTests { /* useStaticWallpaper */true); while (mRunner.keepRunning()) { mRunner.pauseTiming(); - waitCoolDownPeriod(); Log.d(TAG, "Starting timer"); mRunner.resumeTiming(); @@ -606,7 +560,6 @@ public class UserLifecycleTests { final int testUser = initializeNewUserAndSwitchBack(/* stopNewUser */ false); while (mRunner.keepRunning()) { mRunner.pauseTiming(); - waitCoolDownPeriod(); Log.d(TAG, "Starting timer"); mRunner.resumeTiming(); @@ -614,7 +567,6 @@ public class UserLifecycleTests { mRunner.pauseTiming(); Log.d(TAG, "Stopping timer"); - waitForBroadcastIdle(); switchUserNoCheck(startUser); mRunner.resumeTimingForNextIteration(); } @@ -631,7 +583,6 @@ public class UserLifecycleTests { /* useStaticWallpaper */ true); while (mRunner.keepRunning()) { mRunner.pauseTiming(); - waitCoolDownPeriod(); Log.d(TAG, "Starting timer"); mRunner.resumeTiming(); @@ -639,7 +590,6 @@ public class UserLifecycleTests { mRunner.pauseTiming(); Log.d(TAG, "Stopping timer"); - waitForBroadcastIdle(); switchUserNoCheck(startUser); mRunner.resumeTimingForNextIteration(); } @@ -675,13 +625,11 @@ public class UserLifecycleTests { @Test(timeout = TIMEOUT_MAX_TEST_TIME_MS) public void stopUser_realistic() throws RemoteException { final int userId = createUserNoFlags(); - waitCoolDownPeriod(); while (mRunner.keepRunning()) { mRunner.pauseTiming(); runThenWaitForBroadcasts(userId, ()-> { mIam.startUserInBackground(userId); }, Intent.ACTION_USER_STARTED, Intent.ACTION_MEDIA_MOUNTED); - waitCoolDownPeriod(); Log.d(TAG, "Starting timer"); mRunner.resumeTiming(); @@ -703,7 +651,7 @@ public class UserLifecycleTests { final int startUser = mAm.getCurrentUser(); final int userId = createUserNoFlags(); - waitForBroadcastIdle(); + mRunner.waitCoolDownPeriod(); mUserSwitchWaiter.runThenWaitUntilBootCompleted(userId, () -> { mRunner.resumeTiming(); Log.i(TAG, "Starting timer"); @@ -726,7 +674,7 @@ public class UserLifecycleTests { final int startUser = ActivityManager.getCurrentUser(); final int userId = createUserNoFlags(); - waitCoolDownPeriod(); + mRunner.waitCoolDownPeriod(); mUserSwitchWaiter.runThenWaitUntilBootCompleted(userId, () -> { mRunner.resumeTiming(); Log.d(TAG, "Starting timer"); @@ -752,7 +700,7 @@ public class UserLifecycleTests { switchUser(userId); }, Intent.ACTION_MEDIA_MOUNTED); - waitForBroadcastIdle(); + mRunner.waitCoolDownPeriod(); mUserSwitchWaiter.runThenWaitUntilSwitchCompleted(startUser, () -> { runThenWaitForBroadcasts(userId, () -> { mRunner.resumeTiming(); @@ -781,7 +729,7 @@ public class UserLifecycleTests { switchUser(userId); }, Intent.ACTION_MEDIA_MOUNTED); - waitCoolDownPeriod(); + mRunner.waitCoolDownPeriod(); mUserSwitchWaiter.runThenWaitUntilSwitchCompleted(startUser, () -> { runThenWaitForBroadcasts(userId, () -> { mRunner.resumeTiming(); @@ -827,7 +775,6 @@ public class UserLifecycleTests { Log.d(TAG, "Stopping timer"); attestTrue("Failed creating profile " + userId, mUm.isManagedProfile(userId)); removeUser(userId); - waitCoolDownPeriod(); mRunner.resumeTimingForNextIteration(); } } @@ -868,7 +815,6 @@ public class UserLifecycleTests { mRunner.pauseTiming(); Log.d(TAG, "Stopping timer"); removeUser(userId); - waitCoolDownPeriod(); mRunner.resumeTimingForNextIteration(); } } @@ -913,7 +859,6 @@ public class UserLifecycleTests { mRunner.pauseTiming(); Log.d(TAG, "Stopping timer"); - waitCoolDownPeriod(); mRunner.resumeTimingForNextIteration(); } removeUser(userId); @@ -965,7 +910,6 @@ public class UserLifecycleTests { mRunner.pauseTiming(); Log.d(TAG, "Stopping timer"); removeUser(userId); - waitCoolDownPeriod(); mRunner.resumeTimingForNextIteration(); } } @@ -1030,7 +974,6 @@ public class UserLifecycleTests { mRunner.pauseTiming(); Log.d(TAG, "Stopping timer"); removeUser(userId); - waitCoolDownPeriod(); mRunner.resumeTimingForNextIteration(); } } @@ -1071,7 +1014,6 @@ public class UserLifecycleTests { mRunner.pauseTiming(); Log.d(TAG, "Stopping timer"); removeUser(userId); - waitCoolDownPeriod(); mRunner.resumeTimingForNextIteration(); } } @@ -1124,7 +1066,6 @@ public class UserLifecycleTests { mRunner.pauseTiming(); Log.d(TAG, "Stopping timer"); removeUser(userId); - waitCoolDownPeriod(); mRunner.resumeTimingForNextIteration(); } } @@ -1164,7 +1105,6 @@ public class UserLifecycleTests { runThenWaitForBroadcasts(userId, () -> { startUserInBackgroundAndWaitForUnlock(userId); }, Intent.ACTION_MEDIA_MOUNTED); - waitCoolDownPeriod(); mRunner.resumeTiming(); Log.d(TAG, "Starting timer"); @@ -1280,6 +1220,7 @@ public class UserLifecycleTests { * If lack of success should fail the test, use {@link #switchUser(int)} instead. */ private boolean switchUserNoCheck(int userId) throws RemoteException { + mRunner.waitCoolDownPeriod(); final boolean[] success = {true}; mUserSwitchWaiter.runThenWaitUntilSwitchCompleted(userId, () -> { mAm.switchUser(userId); @@ -1296,7 +1237,7 @@ public class UserLifecycleTests { */ private void stopUserAfterWaitingForBroadcastIdle(int userId) throws RemoteException { - waitForBroadcastIdle(); + mRunner.waitCoolDownPeriod(); stopUser(userId); } @@ -1438,6 +1379,8 @@ public class UserLifecycleTests { */ private void runThenWaitForBroadcasts(int userId, FunctionalUtils.ThrowingRunnable runnable, String... actions) { + mRunner.waitCoolDownPeriod(); + final String unreceivedAction = mBroadcastWaiter.runThenWaitForBroadcasts(userId, runnable, actions); @@ -1538,28 +1481,4 @@ public class UserLifecycleTests { assertEquals("", ShellHelper.runShellCommand("setprop " + name + " " + value)); return TextUtils.firstNotEmpty(oldValue, "invalid"); } - - private void waitForBroadcastIdle() { - try { - ShellHelper.runShellCommandWithTimeout( - "am wait-for-broadcast-idle --flush-broadcast-loopers", TIMEOUT_IN_SECOND); - } catch (TimeoutException e) { - Log.e(TAG, "Ending waitForBroadcastIdle because it is taking too long", e); - } - } - - private void sleep(long ms) { - try { - Thread.sleep(ms); - } catch (InterruptedException e) { - // Ignore - } - } - - private void waitCoolDownPeriod() { - // Heuristic value based on local tests. Stability increased compared to no waiting. - final int tenSeconds = 1000 * 10; - waitForBroadcastIdle(); - sleep(tenSeconds); - } } |