UserChecker: add option to cleanup users
Bug: 135057192
Bug: 130047592
Test: unit tests
Test: Ran cts test with --user-type secondary and --user-cleanup. User
was switch-back and deleted at the end.
Test: did above AND manually created user mid-test. User was deleted at
end.
Change-Id: I76f6f408ff19c67dea09bf4a49abce339edde161
Merged-In: I76f6f408ff19c67dea09bf4a49abce339edde161
diff --git a/src/com/android/tradefed/suite/checker/UserChecker.java b/src/com/android/tradefed/suite/checker/UserChecker.java
index 8c2841a..205eef9 100644
--- a/src/com/android/tradefed/suite/checker/UserChecker.java
+++ b/src/com/android/tradefed/suite/checker/UserChecker.java
@@ -40,6 +40,17 @@
description = "The type of user to switch to before each module run.")
private UserInfo.UserType mUserToSwitchTo = UserInfo.UserType.CURRENT;
+ @Option(
+ name = "user-cleanup",
+ description =
+ "If true, attempt to cleanup any changes made to users:"
+ + "\n - switch to previous current-user"
+ + "\n - remove any created users"
+ + "\n\nThis does NOT:"
+ + "\n - attempt to re-create a user that was deleted"
+ + "\n - start/stop existing users if their running status changed")
+ private boolean mCleanup = false;
+
private UserInfo mPreCurrentUserInfo = null;
private Map<Integer, UserInfo> mPreUsersInfo = null;
private int mSwitchedToUserId = -1;
@@ -97,7 +108,15 @@
"User %d was the currentUser before, has changed to %d",
mPreCurrentUserInfo.userId(), postCurrentUserInfo.userId()));
}
- // TODO(b/130047592): do cleanup
+ if (mCleanup) {
+ if (!device.switchUser(mPreCurrentUserInfo.userId())) {
+ errors.add(
+ String.format(
+ "Failed to switch back to previous current user %d."
+ + " Check if it was removed.",
+ mPreCurrentUserInfo.userId()));
+ }
+ }
}
for (UserInfo preUserInfo : mPreUsersInfo.values()) {
@@ -122,7 +141,11 @@
String.format(
"User %d was created during test and not deleted", postUserId));
}
- // TODO(b/130047592): do cleanup
+ if (mCleanup) {
+ if (!device.removeUser(postUserId)) {
+ errors.add(String.format("Failed to remove new user %d", postUserId));
+ }
+ }
}
}
diff --git a/tests/src/com/android/tradefed/suite/checker/UserCheckerTest.java b/tests/src/com/android/tradefed/suite/checker/UserCheckerTest.java
index 5b73842..88c27fc 100644
--- a/tests/src/com/android/tradefed/suite/checker/UserCheckerTest.java
+++ b/tests/src/com/android/tradefed/suite/checker/UserCheckerTest.java
@@ -20,6 +20,7 @@
import java.util.HashMap;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import com.android.tradefed.config.OptionSetter;
import com.android.tradefed.device.ITestDevice;
@@ -113,6 +114,75 @@
}
@Test
+ public void testCreateCleanup() throws Exception {
+ UserChecker checker = new UserChecker();
+ OptionSetter mOptionSetter = new OptionSetter(checker);
+ mOptionSetter.setOptionValue("user-type", "secondary");
+ mOptionSetter.setOptionValue("user-cleanup", "true");
+ ITestDevice preDevice =
+ mockDeviceUserState(
+ /* currentUser= */ 0,
+ /* userIds= */ new Integer[] {0},
+ /* flags= */ new Integer[] {0},
+ /* isRunning= */ new Boolean[] {true});
+ when(preDevice.createUser("Tfsecondary", false, false)).thenReturn(10);
+ when(preDevice.switchUser(10)).thenReturn(true);
+
+ assertEquals(CheckStatus.SUCCESS, checker.preExecutionCheck(preDevice).getStatus());
+ verify(preDevice, times(1)).createUser("Tfsecondary", false, false);
+ verify(preDevice, times(1)).switchUser(10);
+
+ ITestDevice postDevice =
+ mockDeviceUserState(
+ /* currentUser= */ 10,
+ /* userIds= */ new Integer[] {0, 10},
+ /* flags= */ new Integer[] {0, 0},
+ /* isRunning= */ new Boolean[] {true, true});
+ when(postDevice.switchUser(0)).thenReturn(true);
+ when(postDevice.removeUser(10)).thenReturn(true);
+ assertEquals(CheckStatus.SUCCESS, checker.postExecutionCheck(postDevice).getStatus());
+ verify(postDevice, times(1)).switchUser(0);
+ verify(postDevice, times(1)).removeUser(10);
+ }
+
+ @Test
+ public void testCreateCleanup_cleanupFail() throws Exception {
+ UserChecker checker = new UserChecker();
+ OptionSetter mOptionSetter = new OptionSetter(checker);
+ mOptionSetter.setOptionValue("user-type", "secondary");
+ mOptionSetter.setOptionValue("user-cleanup", "true");
+ ITestDevice preDevice =
+ mockDeviceUserState(
+ /* currentUser= */ 0,
+ /* userIds= */ new Integer[] {0},
+ /* flags= */ new Integer[] {0},
+ /* isRunning= */ new Boolean[] {true});
+ when(preDevice.createUser("Tfsecondary", false, false)).thenReturn(10);
+ when(preDevice.switchUser(10)).thenReturn(true);
+
+ assertEquals(CheckStatus.SUCCESS, checker.preExecutionCheck(preDevice).getStatus());
+ verify(preDevice, times(1)).createUser("Tfsecondary", false, false);
+ verify(preDevice, times(1)).switchUser(10);
+
+ ITestDevice postDevice =
+ mockDeviceUserState(
+ /* currentUser= */ 10,
+ /* userIds= */ new Integer[] {0, 10},
+ /* flags= */ new Integer[] {0, 0},
+ /* isRunning= */ new Boolean[] {true, true});
+ when(postDevice.switchUser(0)).thenReturn(false);
+ when(postDevice.removeUser(10)).thenReturn(false);
+ StatusCheckerResult result = checker.postExecutionCheck(postDevice);
+ verify(postDevice, times(1)).switchUser(0);
+ verify(postDevice, times(1)).removeUser(10);
+ assertEquals(CheckStatus.FAILED, result.getStatus());
+ assertTrue(
+ result.getErrorMessage()
+ .contains("Failed to switch back to previous current user 0"));
+ assertTrue(result.getErrorMessage().contains("Failed to remove new user 10"));
+ }
+
+ @Test
/** Returns FAILED in the precessense of errors */
public void testAllErrorsIsFailed() throws Exception {
UserChecker checker = new UserChecker();