1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.tests.rollback.host; 18 19 import static org.junit.Assert.assertTrue; 20 import static org.junit.Assert.fail; 21 22 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; 23 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; 24 25 import org.junit.After; 26 import org.junit.Before; 27 import org.junit.Rule; 28 import org.junit.Test; 29 import org.junit.runner.RunWith; 30 31 import java.util.concurrent.TimeUnit; 32 33 /** 34 * Runs rollback tests for multiple users. 35 */ 36 @RunWith(DeviceJUnit4ClassRunner.class) 37 public class MultiUserRollbackTest extends BaseHostJUnit4Test { 38 // The user that was running originally when the test starts. 39 private int mOriginalUserId; 40 private int mSecondaryUserId = -1; 41 private static final long SWITCH_USER_COMPLETED_NUMBER_OF_POLLS = 60; 42 private static final long SWITCH_USER_COMPLETED_POLL_INTERVAL_IN_MILLIS = 1000; 43 44 @Rule 45 public AbandonSessionsRule mHostTestRule = new AbandonSessionsRule(this); 46 47 @After tearDown()48 public void tearDown() throws Exception { 49 removeSecondaryUserIfNecessary(); 50 runPhaseForUsers("cleanUp", mOriginalUserId); 51 uninstallPackage("com.android.cts.install.lib.testapp.A"); 52 uninstallPackage("com.android.cts.install.lib.testapp.B"); 53 } 54 55 @Before setup()56 public void setup() throws Exception { 57 mOriginalUserId = getDevice().getCurrentUser(); 58 createAndStartSecondaryUser(); 59 installPackage("RollbackTest.apk", "--user all"); 60 runPhaseForUsers("cleanUp", mOriginalUserId); 61 } 62 63 @Test testBasicForSecondaryUser()64 public void testBasicForSecondaryUser() throws Exception { 65 runPhaseForUsers("testBasic", mSecondaryUserId); 66 } 67 68 /** 69 * Tests staged install/rollback works correctly on the 2nd user. 70 */ 71 @Test testStagedRollback()72 public void testStagedRollback() throws Exception { 73 runPhaseForUsers("testStagedRollback_Phase1", mSecondaryUserId); 74 getDevice().reboot(); 75 76 // Need to unlock the user for device tests to run successfully 77 getDevice().startUser(mSecondaryUserId); 78 awaitUserUnlocked(mSecondaryUserId); 79 runPhaseForUsers("testStagedRollback_Phase2", mSecondaryUserId); 80 getDevice().reboot(); 81 82 getDevice().startUser(mSecondaryUserId); 83 awaitUserUnlocked(mSecondaryUserId); 84 runPhaseForUsers("testStagedRollback_Phase3", mSecondaryUserId); 85 getDevice().reboot(); 86 87 getDevice().startUser(mSecondaryUserId); 88 awaitUserUnlocked(mSecondaryUserId); 89 runPhaseForUsers("testStagedRollback_Phase4", mSecondaryUserId); 90 } 91 92 @Test testBadUpdateRollback()93 public void testBadUpdateRollback() throws Exception { 94 // Need to switch user in order to send broadcasts in device tests 95 assertTrue(getDevice().switchUser(mSecondaryUserId)); 96 runPhaseForUsers("testBadUpdateRollback", mSecondaryUserId); 97 } 98 99 @Test testMultipleUsers()100 public void testMultipleUsers() throws Exception { 101 runPhaseForUsers("testMultipleUsersInstallV1", mOriginalUserId, mSecondaryUserId); 102 runPhaseForUsers("testMultipleUsersUpgradeToV2", mOriginalUserId); 103 runPhaseForUsers("testMultipleUsersUpdateUserData", mOriginalUserId, mSecondaryUserId); 104 getDevice().executeShellCommand("pm rollback-app com.android.cts.install.lib.testapp.A"); 105 runPhaseForUsers("testMultipleUsersVerifyUserdataRollback", mOriginalUserId, 106 mSecondaryUserId); 107 } 108 109 /** 110 * Run the phase for the given user ids, in the order they are given. 111 */ runPhaseForUsers(String phase, int... userIds)112 private void runPhaseForUsers(String phase, int... userIds) throws Exception { 113 final long timeout = TimeUnit.MINUTES.toMillis(10); 114 for (int userId: userIds) { 115 assertTrue(runDeviceTests(getDevice(), "com.android.tests.rollback", 116 "com.android.tests.rollback.MultiUserRollbackTest", 117 phase, userId, timeout)); 118 } 119 } 120 removeSecondaryUserIfNecessary()121 private void removeSecondaryUserIfNecessary() throws Exception { 122 if (mSecondaryUserId != -1) { 123 // Can't remove the 2nd user without switching out of it 124 assertTrue(getDevice().switchUser(mOriginalUserId)); 125 getDevice().removeUser(mSecondaryUserId); 126 mSecondaryUserId = -1; 127 } 128 } 129 awaitUserUnlocked(int userId)130 private void awaitUserUnlocked(int userId) throws Exception { 131 for (int i = 0; i < SWITCH_USER_COMPLETED_NUMBER_OF_POLLS; ++i) { 132 String userState = getDevice().executeShellCommand("am get-started-user-state " 133 + userId); 134 if (userState.contains("RUNNING_UNLOCKED")) { 135 return; 136 } 137 Thread.sleep(SWITCH_USER_COMPLETED_POLL_INTERVAL_IN_MILLIS); 138 } 139 fail("Timed out in unlocking user: " + userId); 140 } 141 createAndStartSecondaryUser()142 private void createAndStartSecondaryUser() throws Exception { 143 String name = "MultiUserRollbackTest_User" + System.currentTimeMillis(); 144 mSecondaryUserId = getDevice().createUser(name); 145 getDevice().startUser(mSecondaryUserId); 146 // Note we can't install apps on a locked user 147 awaitUserUnlocked(mSecondaryUserId); 148 } 149 } 150