• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.cts.rollback.host;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.hamcrest.CoreMatchers.endsWith;
22 import static org.hamcrest.CoreMatchers.equalTo;
23 import static org.hamcrest.CoreMatchers.not;
24 import static org.junit.Assume.assumeThat;
25 import static org.junit.Assume.assumeTrue;
26 import static org.junit.Assume.assumeThat;
27 
28 import android.cts.install.lib.host.InstallUtilsHost;
29 
30 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
31 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
32 
33 import org.junit.After;
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 
38 /**
39  * CTS host tests for RollbackManager APIs.
40  */
41 @RunWith(DeviceJUnit4ClassRunner.class)
42 public class RollbackManagerHostTest extends BaseHostJUnit4Test {
43 
44     private static final String TAG = "RollbackManagerHostTest";
45     private final InstallUtilsHost mHostUtils = new InstallUtilsHost(this);
46 
47     /**
48      * Runs the helper app test method on device.
49      * Throws an exception if the test method fails.
50      * <p>
51      * For example, <code>run("testApkOnlyEnableRollback");</code>
52      */
run(String method)53     private void run(String method) throws Exception {
54         assertThat(runDeviceTests("com.android.cts.rollback.host.app",
55                 "com.android.cts.rollback.host.app.HostTestHelper",
56                 method)).isTrue();
57     }
58 
59     /**
60      * Runs the helper app test method on device targeted for
61      * com.android.cts.rollback.host.app2.HostTestHelper.
62      */
run2(String method)63     private void run2(String method) throws Exception {
64         assertThat(runDeviceTests("com.android.cts.rollback.host.app2",
65                 "com.android.cts.rollback.host.app2.HostTestHelper",
66                 method)).isTrue();
67     }
68 
69     /**
70      * Uninstalls any version greater than 1 of shim apex and reboots the device if necessary
71      * to complete the uninstall.
72      *
73      * <p>This is needed because the apex cannot be deleted using PackageInstaller API.
74      *
75      * Also abandon sessions left by previous tests so staged-installs won't fail.
76      */
77     @Before
78     @After
cleanUp()79     public void cleanUp() throws Exception {
80         getDevice().executeShellCommand("for i in $(pm list staged-sessions --only-sessionid "
81                 + "--only-parent); do pm install-abandon $i; done");
82         getDevice().executeShellCommand("pm uninstall com.android.cts.install.lib.testapp.A");
83         getDevice().executeShellCommand("pm uninstall com.android.cts.install.lib.testapp.B");
84         getDevice().executeShellCommand("pm uninstall com.android.cts.install.lib.testapp.C");
85         run("cleanUp");
86         mHostUtils.uninstallShimApexIfNecessary();
87     }
88 
89     /**
90      * Tests staged rollbacks involving only apks.
91      */
92     @Test
testApkOnlyStagedRollback()93     public void testApkOnlyStagedRollback() throws Exception {
94         run("testApkOnlyStagedRollback_Phase1_Install");
95         getDevice().reboot();
96         run("testApkOnlyStagedRollback_Phase2_RollBack");
97         getDevice().reboot();
98         run("testApkOnlyStagedRollback_Phase3_Confirm");
99     }
100 
101     /**
102      * Tests multiple staged rollbacks involving only apks.
103      */
104     @Test
testApkOnlyMultipleStagedRollback()105     public void testApkOnlyMultipleStagedRollback() throws Exception {
106         assumeTrue("Device does not support file-system checkpoint",
107                 mHostUtils.isCheckpointSupported());
108 
109         run("testApkOnlyMultipleStagedRollback_Phase1_Install");
110         getDevice().reboot();
111         run("testApkOnlyMultipleStagedRollback_Phase2_RollBack");
112         getDevice().reboot();
113         run("testApkOnlyMultipleStagedRollback_Phase3_Confirm");
114     }
115 
116     /**
117      * Tests multiple staged partial rollbacks involving only apks.
118      */
119     @Test
testApkOnlyMultipleStagedPartialRollback()120     public void testApkOnlyMultipleStagedPartialRollback() throws Exception {
121         assumeTrue("Device does not support file-system checkpoint",
122                 mHostUtils.isCheckpointSupported());
123 
124         run("testApkOnlyMultipleStagedPartialRollback_Phase1_Install");
125         getDevice().reboot();
126         run("testApkOnlyMultipleStagedPartialRollback_Phase2_RollBack");
127         getDevice().reboot();
128         run("testApkOnlyMultipleStagedPartialRollback_Phase3_Confirm");
129     }
130 
131     /**
132      * Tests staged rollbacks involving only apex.
133      */
134     @Test
testApexOnlyStagedRollback()135     public void testApexOnlyStagedRollback() throws Exception {
136         assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
137 
138         run("testApexOnlyStagedRollback_Phase1_InstallFirst");
139         getDevice().reboot();
140         run("testApexOnlyStagedRollback_Phase2_InstallSecond");
141         getDevice().reboot();
142         run("testApexOnlyStagedRollback_Phase3_RollBack");
143         getDevice().reboot();
144         run("testApexOnlyStagedRollback_Phase4_Confirm");
145     }
146 
147     /**
148      * Tests staged rollbacks to system version involving only apex.
149      */
150     @Test
testApexOnlySystemVersionStagedRollback()151     public void testApexOnlySystemVersionStagedRollback() throws Exception {
152         assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
153 
154         run("testApexOnlySystemVersionStagedRollback_Phase1_Install");
155         getDevice().reboot();
156         run("testApexOnlySystemVersionStagedRollback_Phase2_RollBack");
157         getDevice().reboot();
158         run("testApexOnlySystemVersionStagedRollback_Phase3_Confirm");
159     }
160 
161     /**
162      * Tests staged rollbacks involving apex and apk.
163      */
164     @Test
testApexAndApkStagedRollback()165     public void testApexAndApkStagedRollback() throws Exception {
166         assumeSystemUser();
167         assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
168 
169         run("testApexAndApkStagedRollback_Phase1_InstallFirst");
170         getDevice().reboot();
171         run("testApexAndApkStagedRollback_Phase2_InstallSecond");
172         getDevice().reboot();
173         run("testApexAndApkStagedRollback_Phase3_RollBack");
174         getDevice().reboot();
175         run("testApexAndApkStagedRollback_Phase4_Confirm");
176     }
177 
assumeSystemUser()178     private void assumeSystemUser() throws Exception {
179         String systemUser = "0";
180         assumeThat("Current user is not system user",
181                 getDevice().executeShellCommand("am get-current-user").trim(), equalTo(systemUser));
182     }
183 
184     /**
185      * Tests that apex update expires existing rollbacks for that apex.
186      */
187     @Test
testApexRollbackExpiration()188     public void testApexRollbackExpiration() throws Exception {
189         assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
190 
191         run("testApexRollbackExpiration_Phase1_InstallFirst");
192         getDevice().reboot();
193         run("testApexRollbackExpiration_Phase2_InstallSecond");
194         getDevice().reboot();
195         run("testApexRollbackExpiration_Phase3_Confirm");
196     }
197 
198     /**
199      * Tests staged rollbacks involving apex with rotated keys.
200      */
201     @Test
testApexKeyRotationStagedRollback()202     public void testApexKeyRotationStagedRollback() throws Exception {
203         assumeTrue("Device does not support updating APEX", mHostUtils.isApexUpdateSupported());
204 
205         run("testApexKeyRotationStagedRollback_Phase1_Install");
206         getDevice().reboot();
207         run("testApexKeyRotationStagedRollback_Phase2_RollBack");
208         getDevice().reboot();
209         run("testApexKeyRotationStagedRollback_Phase3_Confirm");
210     }
211 
212     /**
213      * Tests installer B can't rollback a package installed by A.
214      */
215     @Test
testApkRollbackByAnotherInstaller()216     public void testApkRollbackByAnotherInstaller() throws Exception {
217         run("testApkRollbackByAnotherInstaller_Phase1_FirstInstaller");
218         run2("testApkRollbackByAnotherInstaller_Phase2_SecondInstaller");
219     }
220 
221     /**
222      * Tests that existing staged sessions are failed when rollback is committed
223      */
224     @Test
testRollbackFailsOtherSessions()225     public void testRollbackFailsOtherSessions() throws Exception {
226         assumeTrue("Device does not support file-system checkpoint",
227                 mHostUtils.isCheckpointSupported());
228 
229         run("testRollbackFailsOtherSessions_Phase1_Install");
230         getDevice().reboot();
231         run("testRollbackFailsOtherSessions_Phase2_RollBack");
232         getDevice().reboot();
233         run("testRollbackFailsOtherSessions_Phase3_Confirm");
234     }
235 
236     /**
237      * Tests that simultaneous rollbacks both succeed - neither causes the other to fail.
238      */
239     @Test
testSimultaneousRollbacksBothSucceed()240     public void testSimultaneousRollbacksBothSucceed() throws Exception {
241         assumeTrue("Device does not support file-system checkpoint",
242                 mHostUtils.isCheckpointSupported());
243 
244         run("testSimultaneousRollbacksBothSucceed_Phase1_Install");
245         getDevice().reboot();
246         run("testSimultaneousRollbacksBothSucceed_Phase2_RollBack");
247         getDevice().reboot();
248         run("testSimultaneousRollbacksBothSucceed_Phase3_Confirm");
249     }
250 
251     /**
252      * Tests that rollbacks are invalidated upon fingerprint changes.
253      */
254     @Test
testFingerprintChange()255     public void testFingerprintChange() throws Exception {
256         assumeThat(getDevice().getBuildFlavor(), not(endsWith("-user")));
257 
258         try {
259             getDevice().executeShellCommand("setprop persist.pm.mock-upgrade true");
260 
261             run("testFingerprintChange_Phase1_Install");
262             getDevice().reboot();
263             run("testFingerprintChange_Phase2_Confirm");
264         } finally {
265             getDevice().executeShellCommand("setprop persist.pm.mock-upgrade false");
266         }
267     }
268 }
269