UserLifecycleTests - give proper errors on fail
More 'attestation' messages are added, which provide logcat messages in the case of failed tests while telling the benchmarkrunner to mark the test as having failed (and return a value of -10). Tests no longer throw checked exceptions; we catch all such exceptions and log them properly. The exception is RemoteException, which we have allowed to throw for now but may handle in a future cl. Test: atest UserLifecycleTests Bug: 159650471 Change-Id: I4ca9d7186d195388f928f6a6037c6d4ccd79a0ea
This commit is contained in:
@@ -39,6 +39,7 @@ import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.IProgressListener;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
@@ -153,7 +154,7 @@ public class UserLifecycleTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createAndStartUser() throws Exception {
|
||||
public void createAndStartUser() throws RemoteException {
|
||||
while (mRunner.keepRunning()) {
|
||||
final int userId = createUserNoFlags();
|
||||
|
||||
@@ -162,7 +163,7 @@ public class UserLifecycleTests {
|
||||
// Don't use this.startUserInBackgroundAndWaitForUnlock() since only waiting until
|
||||
// ACTION_USER_STARTED.
|
||||
mIam.startUserInBackground(userId);
|
||||
latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
|
||||
waitForLatch("Failed to achieve ACTION_USER_STARTED for user " + userId, latch);
|
||||
|
||||
mRunner.pauseTiming();
|
||||
removeUser(userId);
|
||||
@@ -174,7 +175,7 @@ public class UserLifecycleTests {
|
||||
* Measures the time until ACTION_USER_STARTED is received.
|
||||
*/
|
||||
@Test
|
||||
public void startUser() throws Exception {
|
||||
public void startUser() throws RemoteException {
|
||||
while (mRunner.keepRunning()) {
|
||||
mRunner.pauseTiming();
|
||||
final int userId = createUserNoFlags();
|
||||
@@ -183,7 +184,7 @@ public class UserLifecycleTests {
|
||||
mRunner.resumeTiming();
|
||||
|
||||
mIam.startUserInBackground(userId);
|
||||
latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
|
||||
waitForLatch("Failed to achieve ACTION_USER_STARTED for user " + userId, latch);
|
||||
|
||||
mRunner.pauseTiming();
|
||||
removeUser(userId);
|
||||
@@ -195,7 +196,7 @@ public class UserLifecycleTests {
|
||||
* Measures the time until unlock listener is triggered and user is unlocked.
|
||||
*/
|
||||
@Test
|
||||
public void startAndUnlockUser() throws Exception {
|
||||
public void startAndUnlockUser() {
|
||||
while (mRunner.keepRunning()) {
|
||||
mRunner.pauseTiming();
|
||||
final int userId = createUserNoFlags();
|
||||
@@ -210,10 +211,8 @@ public class UserLifecycleTests {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void switchUser() throws Exception {
|
||||
public void switchUser() throws RemoteException {
|
||||
while (mRunner.keepRunning()) {
|
||||
mRunner.pauseTiming();
|
||||
final int startUser = mAm.getCurrentUser();
|
||||
@@ -223,7 +222,7 @@ public class UserLifecycleTests {
|
||||
switchUser(userId);
|
||||
|
||||
mRunner.pauseTiming();
|
||||
switchUser(startUser);
|
||||
switchUserNoCheck(startUser);
|
||||
removeUser(userId);
|
||||
mRunner.resumeTiming();
|
||||
}
|
||||
@@ -231,7 +230,7 @@ public class UserLifecycleTests {
|
||||
|
||||
/** Tests switching to an already-created, but no-longer-running, user. */
|
||||
@Test
|
||||
public void switchUser_stopped() throws Exception {
|
||||
public void switchUser_stopped() throws RemoteException {
|
||||
while (mRunner.keepRunning()) {
|
||||
mRunner.pauseTiming();
|
||||
final int startUser = mAm.getCurrentUser();
|
||||
@@ -241,11 +240,11 @@ public class UserLifecycleTests {
|
||||
mRunner.resumeTiming();
|
||||
|
||||
mAm.switchUser(testUser);
|
||||
boolean success = latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
|
||||
waitForLatch("Failed to achieve 2nd ACTION_USER_UNLOCKED for user " + testUser, latch);
|
||||
|
||||
|
||||
mRunner.pauseTiming();
|
||||
attestTrue("Failed to achieve 2nd ACTION_USER_UNLOCKED for user " + testUser, success);
|
||||
switchUser(startUser);
|
||||
switchUserNoCheck(startUser);
|
||||
removeUser(testUser);
|
||||
mRunner.resumeTiming();
|
||||
}
|
||||
@@ -253,7 +252,7 @@ public class UserLifecycleTests {
|
||||
|
||||
/** Tests switching to an already-created already-running non-owner user. */
|
||||
@Test
|
||||
public void switchUser_running() throws Exception {
|
||||
public void switchUser_running() throws RemoteException {
|
||||
while (mRunner.keepRunning()) {
|
||||
mRunner.pauseTiming();
|
||||
final int startUser = mAm.getCurrentUser();
|
||||
@@ -263,22 +262,21 @@ public class UserLifecycleTests {
|
||||
switchUser(testUser);
|
||||
|
||||
mRunner.pauseTiming();
|
||||
attestTrue("Failed to switch to user " + testUser, mAm.isUserRunning(testUser));
|
||||
switchUser(startUser);
|
||||
switchUserNoCheck(startUser);
|
||||
removeUser(testUser);
|
||||
mRunner.resumeTiming();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stopUser() throws Exception {
|
||||
public void stopUser() throws RemoteException {
|
||||
while (mRunner.keepRunning()) {
|
||||
mRunner.pauseTiming();
|
||||
final int userId = createUserNoFlags();
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
registerBroadcastReceiver(Intent.ACTION_USER_STARTED, latch, userId);
|
||||
mIam.startUserInBackground(userId);
|
||||
latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
|
||||
waitForLatch("Failed to achieve ACTION_USER_STARTED for user " + userId, latch);
|
||||
mRunner.resumeTiming();
|
||||
|
||||
stopUser(userId, false);
|
||||
@@ -290,7 +288,7 @@ public class UserLifecycleTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lockedBootCompleted() throws Exception {
|
||||
public void lockedBootCompleted() throws RemoteException {
|
||||
while (mRunner.keepRunning()) {
|
||||
mRunner.pauseTiming();
|
||||
final int startUser = mAm.getCurrentUser();
|
||||
@@ -300,17 +298,17 @@ public class UserLifecycleTests {
|
||||
mRunner.resumeTiming();
|
||||
|
||||
mAm.switchUser(userId);
|
||||
latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
|
||||
waitForLatch("Failed to achieve onLockedBootComplete for user " + userId, latch);
|
||||
|
||||
mRunner.pauseTiming();
|
||||
switchUser(startUser);
|
||||
switchUserNoCheck(startUser);
|
||||
removeUser(userId);
|
||||
mRunner.resumeTiming();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ephemeralUserStopped() throws Exception {
|
||||
public void ephemeralUserStopped() throws RemoteException {
|
||||
while (mRunner.keepRunning()) {
|
||||
mRunner.pauseTiming();
|
||||
final int startUser = mAm.getCurrentUser();
|
||||
@@ -331,10 +329,14 @@ public class UserLifecycleTests {
|
||||
mRunner.resumeTiming();
|
||||
|
||||
mAm.switchUser(startUser);
|
||||
latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
|
||||
waitForLatch("Failed to achieve ACTION_USER_STOPPED for user " + userId, latch);
|
||||
|
||||
mRunner.pauseTiming();
|
||||
switchLatch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
|
||||
try {
|
||||
switchLatch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(TAG, "Thread interrupted unexpectedly while waiting for switch.", e);
|
||||
}
|
||||
removeUser(userId);
|
||||
mRunner.resumeTiming();
|
||||
}
|
||||
@@ -342,7 +344,7 @@ public class UserLifecycleTests {
|
||||
|
||||
/** Tests creating a new profile. */
|
||||
@Test
|
||||
public void managedProfileCreate() throws Exception {
|
||||
public void managedProfileCreate() {
|
||||
assumeTrue(mHasManagedUserFeature);
|
||||
|
||||
while (mRunner.keepRunning()) {
|
||||
@@ -357,7 +359,7 @@ public class UserLifecycleTests {
|
||||
|
||||
/** Tests starting (unlocking) a newly-created profile. */
|
||||
@Test
|
||||
public void managedProfileUnlock() throws Exception {
|
||||
public void managedProfileUnlock() {
|
||||
assumeTrue(mHasManagedUserFeature);
|
||||
|
||||
while (mRunner.keepRunning()) {
|
||||
@@ -375,7 +377,7 @@ public class UserLifecycleTests {
|
||||
|
||||
/** Tests starting (unlocking) an already-created, but no-longer-running, profile. */
|
||||
@Test
|
||||
public void managedProfileUnlock_stopped() throws Exception {
|
||||
public void managedProfileUnlock_stopped() throws RemoteException {
|
||||
assumeTrue(mHasManagedUserFeature);
|
||||
|
||||
while (mRunner.keepRunning()) {
|
||||
@@ -398,7 +400,7 @@ public class UserLifecycleTests {
|
||||
* Tests starting (unlocking) and launching an already-installed app in a newly-created profile.
|
||||
*/
|
||||
@Test
|
||||
public void managedProfileUnlockAndLaunchApp() throws Exception {
|
||||
public void managedProfileUnlockAndLaunchApp() throws RemoteException {
|
||||
assumeTrue(mHasManagedUserFeature);
|
||||
|
||||
while (mRunner.keepRunning()) {
|
||||
@@ -424,7 +426,7 @@ public class UserLifecycleTests {
|
||||
* {@link #managedProfileUnlock_stopped}}.
|
||||
*/
|
||||
@Test
|
||||
public void managedProfileUnlockAndLaunchApp_stopped() throws Exception {
|
||||
public void managedProfileUnlockAndLaunchApp_stopped() throws RemoteException {
|
||||
assumeTrue(mHasManagedUserFeature);
|
||||
|
||||
while (mRunner.keepRunning()) {
|
||||
@@ -435,7 +437,7 @@ public class UserLifecycleTests {
|
||||
startUserInBackgroundAndWaitForUnlock(userId);
|
||||
startApp(userId, DUMMY_PACKAGE_NAME);
|
||||
stopUser(userId, true);
|
||||
TimeUnit.SECONDS.sleep(1); // Brief cool-down before re-starting profile.
|
||||
SystemClock.sleep(1_000); // 1 second cool-down before re-starting profile.
|
||||
mRunner.resumeTiming();
|
||||
|
||||
startUserInBackgroundAndWaitForUnlock(userId);
|
||||
@@ -449,7 +451,7 @@ public class UserLifecycleTests {
|
||||
|
||||
/** Tests installing a pre-existing app in a newly-created profile. */
|
||||
@Test
|
||||
public void managedProfileInstall() throws Exception {
|
||||
public void managedProfileInstall() throws RemoteException {
|
||||
assumeTrue(mHasManagedUserFeature);
|
||||
|
||||
while (mRunner.keepRunning()) {
|
||||
@@ -470,7 +472,7 @@ public class UserLifecycleTests {
|
||||
* and launching that app in it.
|
||||
*/
|
||||
@Test
|
||||
public void managedProfileCreateUnlockInstallAndLaunchApp() throws Exception {
|
||||
public void managedProfileCreateUnlockInstallAndLaunchApp() throws RemoteException {
|
||||
assumeTrue(mHasManagedUserFeature);
|
||||
|
||||
while (mRunner.keepRunning()) {
|
||||
@@ -491,7 +493,7 @@ public class UserLifecycleTests {
|
||||
|
||||
/** Tests stopping a profile. */
|
||||
@Test
|
||||
public void managedProfileStopped() throws Exception {
|
||||
public void managedProfileStopped() throws RemoteException {
|
||||
assumeTrue(mHasManagedUserFeature);
|
||||
|
||||
while (mRunner.keepRunning()) {
|
||||
@@ -511,7 +513,7 @@ public class UserLifecycleTests {
|
||||
// TODO: This is just a POC. Do this properly and add more.
|
||||
/** Tests starting (unlocking) a newly-created profile using the user-type-pkg-whitelist. */
|
||||
@Test
|
||||
public void managedProfileUnlock_usingWhitelist() throws Exception {
|
||||
public void managedProfileUnlock_usingWhitelist() {
|
||||
assumeTrue(mHasManagedUserFeature);
|
||||
final int origMode = getUserTypePackageWhitelistMode();
|
||||
setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE
|
||||
@@ -535,7 +537,7 @@ public class UserLifecycleTests {
|
||||
}
|
||||
/** Tests starting (unlocking) a newly-created profile NOT using the user-type-pkg-whitelist. */
|
||||
@Test
|
||||
public void managedProfileUnlock_notUsingWhitelist() throws Exception {
|
||||
public void managedProfileUnlock_notUsingWhitelist() {
|
||||
assumeTrue(mHasManagedUserFeature);
|
||||
final int origMode = getUserTypePackageWhitelistMode();
|
||||
setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE);
|
||||
@@ -573,10 +575,8 @@ public class UserLifecycleTests {
|
||||
private int createManagedProfile() {
|
||||
final UserInfo userInfo = mUm.createProfileForUser(TEST_USER_NAME,
|
||||
UserManager.USER_TYPE_PROFILE_MANAGED, /* flags */ 0, mAm.getCurrentUser());
|
||||
if (userInfo == null) {
|
||||
throw new IllegalStateException("Creating managed profile failed. Most likely there is "
|
||||
+ "already a pre-existing profile on the device.");
|
||||
}
|
||||
attestFalse("Creating managed profile failed. Most likely there is "
|
||||
+ "already a pre-existing profile on the device.", userInfo == null);
|
||||
mUsersToRemove.add(userInfo.id);
|
||||
return userInfo.id;
|
||||
}
|
||||
@@ -589,24 +589,40 @@ public class UserLifecycleTests {
|
||||
*/
|
||||
private void startUserInBackgroundAndWaitForUnlock(int userId) {
|
||||
final ProgressWaiter waiter = new ProgressWaiter();
|
||||
boolean success = false;
|
||||
try {
|
||||
mIam.startUserInBackgroundWithListener(userId, waiter);
|
||||
boolean success = waiter.waitForFinish(TIMEOUT_IN_SECOND);
|
||||
attestTrue("Failed to start user " + userId + " in background.", success);
|
||||
success = waiter.waitForFinish(TIMEOUT_IN_SECOND);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "startUserInBackgroundAndWaitForUnlock failed", e);
|
||||
}
|
||||
attestTrue("Failed to start user " + userId + " in background.", success);
|
||||
}
|
||||
|
||||
/** Starts the given user in the foreground. */
|
||||
private void switchUser(int userId) throws Exception {
|
||||
private void switchUser(int userId) throws RemoteException {
|
||||
boolean success = switchUserNoCheck(userId);
|
||||
attestTrue("Failed to properly switch to user " + userId, success);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the given user in the foreground.
|
||||
* Returns true if successful. Does not fail the test if unsuccessful.
|
||||
* If lack of success should fail the test, use {@link #switchUser(int)} instead.
|
||||
*/
|
||||
private boolean switchUserNoCheck(int userId) throws RemoteException {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
registerUserSwitchObserver(latch, null, userId);
|
||||
mAm.switchUser(userId);
|
||||
latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
|
||||
try {
|
||||
return latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(TAG, "Thread interrupted unexpectedly.", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void stopUser(int userId, boolean force) throws Exception {
|
||||
private void stopUser(int userId, boolean force) throws RemoteException {
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
mIam.stopUser(userId, force /* force */, new IStopUserCallback.Stub() {
|
||||
@Override
|
||||
@@ -618,7 +634,7 @@ public class UserLifecycleTests {
|
||||
public void userStopAborted(int userId) throws RemoteException {
|
||||
}
|
||||
});
|
||||
latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
|
||||
waitForLatch("Failed to properly stop user " + userId, latch);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -628,15 +644,14 @@ public class UserLifecycleTests {
|
||||
* @param stopNewUser whether to stop the new user after switching to otherUser.
|
||||
* @return userId of the newly created user.
|
||||
*/
|
||||
private int initializeNewUserAndSwitchBack(boolean stopNewUser) throws Exception {
|
||||
private int initializeNewUserAndSwitchBack(boolean stopNewUser) throws RemoteException {
|
||||
final int origUser = mAm.getCurrentUser();
|
||||
// First, create and switch to testUser, waiting for its ACTION_USER_UNLOCKED
|
||||
final int testUser = createUserNoFlags();
|
||||
final CountDownLatch latch1 = new CountDownLatch(1);
|
||||
registerBroadcastReceiver(Intent.ACTION_USER_UNLOCKED, latch1, testUser);
|
||||
mAm.switchUser(testUser);
|
||||
attestTrue("Failed to achieve initial ACTION_USER_UNLOCKED for user " + testUser,
|
||||
latch1.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS));
|
||||
waitForLatch("Failed to achieve initial ACTION_USER_UNLOCKED for user " + testUser, latch1);
|
||||
|
||||
// Second, switch back to origUser, waiting merely for switchUser() to finish
|
||||
switchUser(origUser);
|
||||
@@ -669,11 +684,7 @@ public class UserLifecycleTests {
|
||||
PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
|
||||
PackageManager.INSTALL_REASON_UNKNOWN, sender, userId, null);
|
||||
|
||||
try {
|
||||
latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(TAG, "Thread interrupted unexpectedly.", e);
|
||||
}
|
||||
waitForLatch("Failed to install app " + packageName + " on user " + userId, latch);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -691,7 +702,7 @@ public class UserLifecycleTests {
|
||||
}
|
||||
|
||||
private void registerUserSwitchObserver(final CountDownLatch switchLatch,
|
||||
final CountDownLatch bootCompleteLatch, final int userId) throws Exception {
|
||||
final CountDownLatch bootCompleteLatch, final int userId) throws RemoteException {
|
||||
ActivityManager.getService().registerUserSwitchObserver(
|
||||
new UserSwitchObserver() {
|
||||
@Override
|
||||
@@ -747,6 +758,17 @@ public class UserLifecycleTests {
|
||||
}
|
||||
}
|
||||
|
||||
/** Waits TIMEOUT_IN_SECOND for the latch to complete, otherwise declares the given error. */
|
||||
private void waitForLatch(String errMsg, CountDownLatch latch) {
|
||||
boolean success = false;
|
||||
try {
|
||||
success = latch.await(TIMEOUT_IN_SECOND, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
Log.e(TAG, "Thread interrupted unexpectedly.", e);
|
||||
}
|
||||
attestTrue(errMsg, success);
|
||||
}
|
||||
|
||||
/** Gets the PACKAGE_WHITELIST_MODE_PROP System Property. */
|
||||
private int getUserTypePackageWhitelistMode() {
|
||||
return SystemProperties.getInt(PACKAGE_WHITELIST_MODE_PROP,
|
||||
@@ -786,8 +808,8 @@ public class UserLifecycleTests {
|
||||
Log.i(TAG, "Found previous test user " + user.id + ". Removing it.");
|
||||
if (mAm.getCurrentUser() == user.id) {
|
||||
try {
|
||||
switchUser(UserHandle.USER_SYSTEM);
|
||||
} catch (Exception e) {
|
||||
switchUserNoCheck(UserHandle.USER_SYSTEM);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to correctly switch to system user", e);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user