• 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.app;
18 
19 import static com.android.cts.rollback.lib.RollbackInfoSubject.assertThat;
20 
21 import static com.google.common.truth.Truth.assertThat;
22 
23 import android.Manifest;
24 import android.content.rollback.RollbackInfo;
25 
26 import androidx.test.InstrumentationRegistry;
27 
28 import com.android.cts.rollback.lib.Install;
29 import com.android.cts.rollback.lib.Rollback;
30 import com.android.cts.rollback.lib.TestApp;
31 import com.android.cts.rollback.lib.Utils;
32 
33 import org.junit.After;
34 import org.junit.Before;
35 import org.junit.Test;
36 import org.junit.runner.RunWith;
37 import org.junit.runners.JUnit4;
38 
39 import java.io.IOException;
40 
41 /**
42  * On-device helper test methods used for host-driven rollback tests.
43  */
44 @RunWith(JUnit4.class)
45 public class HostTestHelper {
46 
47     /**
48      * Adopts common permissions needed to test rollbacks.
49      */
50     @Before
setup()51     public void setup() throws InterruptedException, IOException {
52         InstrumentationRegistry.getInstrumentation().getUiAutomation()
53                 .adoptShellPermissionIdentity(
54                     Manifest.permission.INSTALL_PACKAGES,
55                     Manifest.permission.DELETE_PACKAGES,
56                     Manifest.permission.TEST_MANAGE_ROLLBACKS);
57     }
58 
59     /**
60      * Drops adopted shell permissions.
61      */
62     @After
teardown()63     public void teardown() throws InterruptedException, IOException {
64         InstrumentationRegistry.getInstrumentation().getUiAutomation()
65                 .dropShellPermissionIdentity();
66     }
67 
68 
69     /**
70      * Test rollbacks of staged installs involving only apks.
71      * Commits TestApp.A2 as a staged install with rollback enabled.
72      */
73     @Test
testApkOnlyEnableRollback()74     public void testApkOnlyEnableRollback() throws Exception {
75         assertThat(Utils.getInstalledVersion(TestApp.A)).isEqualTo(-1);
76 
77         Install.single(TestApp.A1).commit();
78         Install.single(TestApp.A2).setStaged().setEnableRollback().commit();
79 
80         // At this point, the host test driver will reboot the device and run
81         // testApkOnlyCommitRollback().
82     }
83 
84     /**
85      * Test rollbacks of staged installs involving only apks.
86      * Confirms a staged rollback is available for TestApp.A2 and commits the
87      * rollback.
88      */
89     @Test
testApkOnlyCommitRollback()90     public void testApkOnlyCommitRollback() throws Exception {
91         assertThat(Utils.getInstalledVersion(TestApp.A)).isEqualTo(2);
92         RollbackInfo available = Utils.getAvailableRollback(TestApp.A);
93         assertThat(available).isStaged();
94         assertThat(available).packagesContainsExactly(
95                 Rollback.from(TestApp.A2).to(TestApp.A1));
96         assertThat(Utils.getCommittedRollback(TestApp.A)).isNull();
97 
98         Utils.rollback(available.getRollbackId(), TestApp.A2);
99         RollbackInfo committed = Utils.getCommittedRollback(TestApp.A);
100         assertThat(committed).hasRollbackId(available.getRollbackId());
101         assertThat(committed).isStaged();
102         assertThat(committed).packagesContainsExactly(
103                 Rollback.from(TestApp.A2).to(TestApp.A1));
104         assertThat(committed).causePackagesContainsExactly(TestApp.A2);
105         assertThat(committed.getCommittedSessionId()).isNotEqualTo(-1);
106 
107         // Note: The app is not rolled back until after the rollback is staged
108         // and the device has been rebooted.
109         Utils.waitForSessionReady(committed.getCommittedSessionId());
110         assertThat(Utils.getInstalledVersion(TestApp.A)).isEqualTo(2);
111 
112         // At this point, the host test driver will reboot the device and run
113         // testApkOnlyConfirmRollback().
114     }
115 
116     /**
117      * Test rollbacks of staged installs involving only apks.
118      * Confirms TestApp.A2 was rolled back.
119      */
120     @Test
testApkOnlyConfirmRollback()121     public void testApkOnlyConfirmRollback() throws Exception {
122         assertThat(Utils.getInstalledVersion(TestApp.A)).isEqualTo(1);
123 
124         RollbackInfo committed = Utils.getCommittedRollback(TestApp.A);
125         assertThat(committed).isStaged();
126         assertThat(committed).packagesContainsExactly(
127                 Rollback.from(TestApp.A2).to(TestApp.A1));
128         assertThat(committed).causePackagesContainsExactly(TestApp.A2);
129         assertThat(committed.getCommittedSessionId()).isNotEqualTo(-1);
130     }
131 
132     /**
133      * Test rollbacks of staged installs involving only apex.
134      * Install first version phase.
135      *
136      * <p> We can't rollback to version 1, which is already installed, so we start by installing
137      * version 2. The test ultimately rolls back from 3 to 2.
138      */
139     @Test
testApexOnlyInstallFirstVersion()140     public void testApexOnlyInstallFirstVersion() throws Exception {
141         assertThat(Utils.getInstalledVersion(TestApp.Apex)).isEqualTo(1);
142 
143         Install.single(TestApp.Apex2).setStaged().commit();
144 
145         // At this point, the host test driver will reboot the device and run
146         // testApexOnlyEnableRollback().
147     }
148 
149     /**
150      * Test rollbacks of staged installs involving only apex.
151      * Enable rollback phase.
152      */
153     @Test
testApexOnlyEnableRollback()154     public void testApexOnlyEnableRollback() throws Exception {
155         assertThat(Utils.getInstalledVersion(TestApp.Apex)).isEqualTo(2);
156         Install.single(TestApp.Apex3).setStaged().setEnableRollback().commit();
157 
158         // At this point, the host test driver will reboot the device and run
159         // testApexOnlyCommitRollback().
160     }
161 
162     /**
163      * Test rollbacks of staged installs involving only apex.
164      * Commit rollback phase.
165      */
166     @Test
testApexOnlyCommitRollback()167     public void testApexOnlyCommitRollback() throws Exception {
168         assertThat(Utils.getInstalledVersion(TestApp.Apex)).isEqualTo(3);
169         RollbackInfo available = Utils.getAvailableRollback(TestApp.Apex);
170         assertThat(available).isStaged();
171         assertThat(available).packagesContainsExactly(
172                 Rollback.from(TestApp.Apex3).to(TestApp.Apex2));
173 
174         Utils.rollback(available.getRollbackId(), TestApp.Apex3);
175         RollbackInfo committed = Utils.getCommittedRollbackById(available.getRollbackId());
176         assertThat(committed).isNotNull();
177         assertThat(committed).isStaged();
178         assertThat(committed).packagesContainsExactly(
179                 Rollback.from(TestApp.Apex3).to(TestApp.Apex2));
180         assertThat(committed).causePackagesContainsExactly(TestApp.Apex3);
181         assertThat(committed.getCommittedSessionId()).isNotEqualTo(-1);
182 
183         // Note: The app is not rolled back until after the rollback is staged
184         // and the device has been rebooted.
185         Utils.waitForSessionReady(committed.getCommittedSessionId());
186         assertThat(Utils.getInstalledVersion(TestApp.Apex)).isEqualTo(3);
187 
188         // At this point, the host test driver will reboot the device and run
189         // testApexOnlyConfirmRollback().
190     }
191 
192     /**
193      * Test rollbacks of staged installs involving only apex.
194      * Confirm rollback phase.
195      */
196     @Test
testApexOnlyConfirmRollback()197     public void testApexOnlyConfirmRollback() throws Exception {
198         assertThat(Utils.getInstalledVersion(TestApp.Apex)).isEqualTo(2);
199 
200         // Rollback data for shim apex will remain in storage since the apex cannot be completely
201         // removed and thus the rollback data won't be expired. Unfortunately, we can't also delete
202         // the rollback data manually from storage.
203 
204         // At this point, the host test driver will reboot the device to complete the uninstall.
205     }
206 
207 
208     /**
209      * Test rollbacks of staged installs involving apex and apk.
210      * Install first version phase.
211      *
212      * <p> See {@link #testApexOnlyInstallFirstVersion()}
213      */
214     @Test
testApexAndApkInstallFirstVersion()215     public void testApexAndApkInstallFirstVersion() throws Exception {
216         assertThat(Utils.getInstalledVersion(TestApp.Apex)).isEqualTo(1);
217         assertThat(Utils.getInstalledVersion(TestApp.A)).isEqualTo(-1);
218 
219         Install.multi(TestApp.Apex2, TestApp.A1).setStaged().commit();
220 
221         // At this point, the host test driver will reboot the device and run
222         // testApexOnlyEnableRollback().
223     }
224 
225     /**
226      * Test rollbacks of staged installs involving apex and apk.
227      * Enable rollback phase.
228      */
229     @Test
testApexAndApkEnableRollback()230     public void testApexAndApkEnableRollback() throws Exception {
231         assertThat(Utils.getInstalledVersion(TestApp.Apex)).isEqualTo(2);
232         assertThat(Utils.getInstalledVersion(TestApp.A)).isEqualTo(1);
233         Install.multi(TestApp.Apex3, TestApp.A2).setStaged().setEnableRollback().commit();
234 
235         // At this point, the host test driver will reboot the device and run
236         // testApexOnlyCommitRollback().
237     }
238 
239     /**
240      * Test rollbacks of staged installs involving apex and apk.
241      * Commit rollback phase.
242      */
243     @Test
testApexAndApkCommitRollback()244     public void testApexAndApkCommitRollback() throws Exception {
245         assertThat(Utils.getInstalledVersion(TestApp.Apex)).isEqualTo(3);
246         assertThat(Utils.getInstalledVersion(TestApp.A)).isEqualTo(2);
247         RollbackInfo available = Utils.getAvailableRollback(TestApp.Apex);
248         assertThat(available).isStaged();
249         assertThat(available).packagesContainsExactly(
250                 Rollback.from(TestApp.Apex3).to(TestApp.Apex2),
251                 Rollback.from(TestApp.A2).to(TestApp.A1));
252 
253         Utils.rollback(available.getRollbackId(), TestApp.Apex3, TestApp.A2);
254         RollbackInfo committed = Utils.getCommittedRollback(TestApp.A);
255         assertThat(committed).isNotNull();
256         assertThat(committed).isStaged();
257         assertThat(committed).packagesContainsExactly(
258                 Rollback.from(TestApp.Apex3).to(TestApp.Apex2),
259                 Rollback.from(TestApp.A2).to(TestApp.A1));
260         assertThat(committed).causePackagesContainsExactly(TestApp.Apex3, TestApp.A2);
261         assertThat(committed.getCommittedSessionId()).isNotEqualTo(-1);
262 
263         // Note: The app is not rolled back until after the rollback is staged
264         // and the device has been rebooted.
265         Utils.waitForSessionReady(committed.getCommittedSessionId());
266         assertThat(Utils.getInstalledVersion(TestApp.Apex)).isEqualTo(3);
267         assertThat(Utils.getInstalledVersion(TestApp.A)).isEqualTo(2);
268 
269         // At this point, the host test driver will reboot the device and run
270         // testApexOnlyConfirmRollback().
271     }
272 
273     /**
274      * Test rollbacks of staged installs involving apex and apk.
275      * Confirm rollback phase.
276      */
277     @Test
testApexAndApkConfirmRollback()278     public void testApexAndApkConfirmRollback() throws Exception {
279         assertThat(Utils.getInstalledVersion(TestApp.Apex)).isEqualTo(2);
280 
281         RollbackInfo committed = Utils.getCommittedRollback(TestApp.A);
282         assertThat(committed).isStaged();
283         assertThat(committed).packagesContainsExactly(
284                 Rollback.from(TestApp.Apex3).to(TestApp.Apex2),
285                 Rollback.from(TestApp.A2).to(TestApp.A1));
286         assertThat(committed).causePackagesContainsExactly(TestApp.Apex3, TestApp.A2);
287         assertThat(committed.getCommittedSessionId()).isNotEqualTo(-1);
288 
289         // Rollback data for shim apex will remain in storage since the apex cannot be completely
290         // removed and thus the rollback data won't be expired. Unfortunately, we can't also delete
291         // the rollback data manually from storage due to SEPolicy rules.
292 
293         // At this point, the host test driver will reboot the device to complete the uninstall.
294     }
295 
296     /**
297      * Tests that apex update expires existing rollbacks for that apex.
298      * Enable rollback phase.
299      */
300     @Test
testApexRollbackExpirationEnableRollback()301     public void testApexRollbackExpirationEnableRollback() throws Exception {
302         assertThat(Utils.getInstalledVersion(TestApp.Apex)).isEqualTo(1);
303 
304         Install.single(TestApp.Apex2).setStaged().setEnableRollback().commit();
305 
306         // At this point, the host test driver will reboot the device and run
307         // testApexRollbackExpirationUpdateApex().
308     }
309 
310     /**
311      * Tests that apex update expires existing rollbacks for that apex.
312      * Update apex phase.
313      */
314     @Test
testApexRollbackExpirationUpdateApex()315     public void testApexRollbackExpirationUpdateApex() throws Exception {
316         assertThat(Utils.getInstalledVersion(TestApp.Apex)).isEqualTo(2);
317         assertThat(Utils.getAvailableRollback(TestApp.Apex)).isNotNull();
318         Install.single(TestApp.Apex3).setStaged().commit();
319 
320         // At this point, the host test driver will reboot the device and run
321         // testApexRollbackExpirationConfirmExpiration().
322     }
323 
324     /**
325      * Tests that apex update expires existing rollbacks for that apex.
326      * Confirm expiration phase.
327      */
328     @Test
testApexRollbackExpirationConfirmExpiration()329     public void testApexRollbackExpirationConfirmExpiration() throws Exception {
330         assertThat(Utils.getInstalledVersion(TestApp.Apex)).isEqualTo(3);
331         assertThat(Utils.getAvailableRollback(TestApp.Apex)).isNull();
332     }
333 }
334