• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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_root.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.Context;
25 import android.content.SharedPreferences;
26 import android.content.pm.PackageInstaller;
27 import android.content.pm.PackageManager;
28 import android.content.rollback.RollbackInfo;
29 import android.content.rollback.RollbackManager;
30 import android.os.storage.StorageManager;
31 import android.provider.DeviceConfig;
32 
33 import androidx.test.platform.app.InstrumentationRegistry;
34 
35 import com.android.cts.install.lib.Install;
36 import com.android.cts.install.lib.InstallUtils;
37 import com.android.cts.install.lib.TestApp;
38 import com.android.cts.rollback.lib.Rollback;
39 import com.android.cts.rollback.lib.RollbackUtils;
40 
41 import org.junit.After;
42 import org.junit.Before;
43 import org.junit.Test;
44 import org.junit.runner.RunWith;
45 import org.junit.runners.JUnit4;
46 
47 import java.util.concurrent.TimeUnit;
48 
49 /**
50  * On-device helper test methods used for host-driven rollback tests.
51  */
52 @RunWith(JUnit4.class)
53 public class HostTestHelper {
54     private static final String PROPERTY_WATCHDOG_TRIGGER_FAILURE_COUNT =
55             "watchdog_trigger_failure_count";
56 
57     @Before
setup()58     public void setup() {
59         InstallUtils.adoptShellPermissionIdentity(
60                     Manifest.permission.INSTALL_PACKAGES,
61                     Manifest.permission.DELETE_PACKAGES,
62                     Manifest.permission.TEST_MANAGE_ROLLBACKS,
63                     Manifest.permission.FORCE_STOP_PACKAGES,
64                     Manifest.permission.WRITE_DEVICE_CONFIG);
65     }
66 
67     @After
teardown()68     public void teardown() {
69         InstallUtils.dropShellPermissionIdentity();
70     }
71 
72     @Test
cleanUp()73     public void cleanUp() {
74         // Remove all pending rollbacks
75         RollbackManager rm = RollbackUtils.getRollbackManager();
76         rm.getAvailableRollbacks().stream().flatMap(info -> info.getPackages().stream())
77                 .map(info -> info.getPackageName()).forEach(rm::expireRollbackForPackage);
78     }
79 
80     @Test
testRollbackDataPolicy_Phase1_Install()81     public void testRollbackDataPolicy_Phase1_Install() throws Exception {
82         Install.multi(TestApp.A1, TestApp.B1, TestApp.C1).commit();
83         // Write user data version = 1
84         InstallUtils.processUserData(TestApp.A);
85         InstallUtils.processUserData(TestApp.B);
86         InstallUtils.processUserData(TestApp.C);
87 
88         Install a2 = Install.single(TestApp.A2).setStaged()
89                 .setEnableRollback(PackageManager.ROLLBACK_DATA_POLICY_WIPE);
90         Install b2 = Install.single(TestApp.B2).setStaged()
91                 .setEnableRollback(PackageManager.ROLLBACK_DATA_POLICY_RESTORE);
92         Install c2 = Install.single(TestApp.C2).setStaged()
93                 .setEnableRollback(PackageManager.ROLLBACK_DATA_POLICY_RETAIN);
94         Install.multi(a2, b2, c2).setEnableRollback().setStaged().commit();
95     }
96 
97     @Test
testRollbackDataPolicy_Phase2_Rollback()98     public void testRollbackDataPolicy_Phase2_Rollback() throws Exception {
99         assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
100         assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
101         // Write user data version = 2
102         InstallUtils.processUserData(TestApp.A);
103         InstallUtils.processUserData(TestApp.B);
104         InstallUtils.processUserData(TestApp.C);
105 
106         RollbackInfo info = RollbackUtils.getAvailableRollback(TestApp.A);
107         RollbackUtils.rollback(info.getRollbackId());
108     }
109 
110     @Test
testRollbackDataPolicy_Phase3_VerifyRollback()111     public void testRollbackDataPolicy_Phase3_VerifyRollback() throws Exception {
112         assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
113         assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(1);
114         assertThat(InstallUtils.getInstalledVersion(TestApp.C)).isEqualTo(1);
115         // Read user data version from userdata.txt
116         // A's user data version is -1 for user data is wiped.
117         // B's user data version is 1 for user data is restored.
118         // C's user data version is 2 for user data is retained.
119         assertThat(InstallUtils.getUserDataVersion(TestApp.A)).isEqualTo(-1);
120         assertThat(InstallUtils.getUserDataVersion(TestApp.B)).isEqualTo(1);
121         assertThat(InstallUtils.getUserDataVersion(TestApp.C)).isEqualTo(2);
122     }
123 
124     @Test
testRollbackApkDataDirectories_Phase1_InstallV1()125     public void testRollbackApkDataDirectories_Phase1_InstallV1() throws Exception {
126         Install.single(TestApp.A1).commit();
127     }
128 
129     @Test
testRollbackApkDataDirectories_Phase2_InstallV2()130     public void testRollbackApkDataDirectories_Phase2_InstallV2() throws Exception {
131         Install.single(TestApp.A2).setStaged().setEnableRollback().commit();
132     }
133 
134     @Test
testRollbackApkDataDirectories_Phase3_Rollback()135     public void testRollbackApkDataDirectories_Phase3_Rollback() throws Exception {
136         RollbackInfo available = RollbackUtils.getAvailableRollback(TestApp.A);
137         RollbackUtils.rollback(available.getRollbackId(), TestApp.A2);
138     }
139 
140     @Test
testExpireSession_Phase1_Install()141     public void testExpireSession_Phase1_Install() throws Exception {
142         Install.single(TestApp.A1).commit();
143         int sessionId = Install.single(TestApp.A2).setEnableRollback().setStaged().commit();
144 
145         Context context = InstrumentationRegistry.getInstrumentation().getContext();
146         SharedPreferences prefs = context.getSharedPreferences("test", 0);
147         prefs.edit().putInt("sessionId", sessionId).commit();
148     }
149 
150     @Test
testExpireSession_Phase2_VerifyInstall()151     public void testExpireSession_Phase2_VerifyInstall() throws Exception {
152         assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
153         RollbackInfo rollback = RollbackUtils.getAvailableRollback(TestApp.A);
154         assertThat(rollback).isNotNull();
155     }
156 
157     @Test
testExpireSession_Phase3_VerifyRollback()158     public void testExpireSession_Phase3_VerifyRollback() throws Exception {
159         RollbackInfo rollback = RollbackUtils.getAvailableRollback(TestApp.A);
160         assertThat(rollback).isNotNull();
161 
162         // Check the session is expired
163         Context context = InstrumentationRegistry.getInstrumentation().getContext();
164         SharedPreferences prefs = context.getSharedPreferences("test", 0);
165         int sessionId = prefs.getInt("sessionId", -1);
166         PackageInstaller.SessionInfo info = InstallUtils.getStagedSessionInfo(sessionId);
167         assertThat(info).isNull();
168     }
169 
170     @Test
testRollbackApexDataDirectories_Phase1_Install()171     public void testRollbackApexDataDirectories_Phase1_Install() throws Exception {
172         Install.single(TestApp.Apex2).setStaged().setEnableRollback().commit();
173     }
174 
175     @Test
testBadApkOnly_Phase1_Install()176     public void testBadApkOnly_Phase1_Install() throws Exception {
177         Install.single(TestApp.A1).commit();
178         Install.single(TestApp.ACrashing2).setEnableRollback().setStaged().commit();
179     }
180 
181     @Test
testBadApkOnly_Phase2_VerifyInstall()182     public void testBadApkOnly_Phase2_VerifyInstall() throws Exception {
183         assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
184 
185         RollbackInfo rollback = RollbackUtils.getAvailableRollback(TestApp.A);
186         assertThat(rollback).isNotNull();
187         assertThat(rollback).packagesContainsExactly(Rollback.from(TestApp.A2).to(TestApp.A1));
188         assertThat(rollback.isStaged()).isTrue();
189 
190         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK,
191                 PROPERTY_WATCHDOG_TRIGGER_FAILURE_COUNT,
192                 Integer.toString(5), false);
193         RollbackUtils.sendCrashBroadcast(TestApp.A, 4);
194         // Sleep for a while to make sure we don't trigger rollback
195         Thread.sleep(TimeUnit.SECONDS.toMillis(30));
196     }
197 
198     @Test
testBadApkOnly_Phase3_VerifyRollback()199     public void testBadApkOnly_Phase3_VerifyRollback() throws Exception {
200         assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
201 
202         RollbackInfo rollback = RollbackUtils.getCommittedRollback(TestApp.A);
203         assertThat(rollback).isNotNull();
204         assertThat(rollback).packagesContainsExactly(Rollback.from(TestApp.A2).to(TestApp.A1));
205         assertThat(rollback).causePackagesContainsExactly(TestApp.ACrashing2);
206         assertThat(rollback).isStaged();
207         assertThat(rollback.getCommittedSessionId()).isNotEqualTo(-1);
208     }
209 
210     @Test
testNativeWatchdogTriggersRollback_Phase1_Install()211     public void testNativeWatchdogTriggersRollback_Phase1_Install() throws Exception {
212         Install.single(TestApp.A1).commit();
213         Install.single(TestApp.A2).setEnableRollback().setStaged().commit();
214     }
215 
216     @Test
testNativeWatchdogTriggersRollback_Phase2_VerifyInstall()217     public void testNativeWatchdogTriggersRollback_Phase2_VerifyInstall() throws Exception {
218         assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
219         RollbackInfo rollback = RollbackUtils.getAvailableRollback(TestApp.A);
220         assertThat(rollback).isNotNull();
221     }
222 
223     @Test
testNativeWatchdogTriggersRollback_Phase3_VerifyRollback()224     public void testNativeWatchdogTriggersRollback_Phase3_VerifyRollback() throws Exception {
225         assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
226         RollbackInfo rollback = RollbackUtils.getCommittedRollback(TestApp.A);
227         assertThat(rollback).isNotNull();
228     }
229 
230     @Test
testNativeWatchdogTriggersRollbackForAll_Phase1_Install()231     public void testNativeWatchdogTriggersRollbackForAll_Phase1_Install() throws Exception {
232         Install.single(TestApp.A1).commit();
233         Install.single(TestApp.B1).commit();
234         Install.single(TestApp.A2).setEnableRollback().setStaged().commit();
235         Install.single(TestApp.B2).setEnableRollback().setStaged().commit();
236     }
237 
238     @Test
testNativeWatchdogTriggersRollbackForAll_Phase2_VerifyInstall()239     public void testNativeWatchdogTriggersRollbackForAll_Phase2_VerifyInstall() throws Exception {
240         assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
241         assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2);
242         RollbackInfo rollbackA = RollbackUtils.getAvailableRollback(TestApp.A);
243         RollbackInfo rollbackB = RollbackUtils.getAvailableRollback(TestApp.B);
244         assertThat(rollbackA).isNotNull();
245         assertThat(rollbackB).isNotNull();
246         assertThat(rollbackA.getRollbackId()).isNotEqualTo(rollbackB.getRollbackId());
247     }
248 
249     @Test
testNativeWatchdogTriggersRollbackForAll_Phase3_VerifyRollback()250     public void testNativeWatchdogTriggersRollbackForAll_Phase3_VerifyRollback() throws Exception {
251         assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
252         assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(1);
253         RollbackInfo rollbackA = RollbackUtils.getCommittedRollback(TestApp.A);
254         RollbackInfo rollbackB = RollbackUtils.getCommittedRollback(TestApp.B);
255         assertThat(rollbackA).isNotNull();
256         assertThat(rollbackB).isNotNull();
257         assertThat(rollbackA.getRollbackId()).isNotEqualTo(rollbackB.getRollbackId());
258     }
259 
260     @Test
isCheckpointSupported()261     public void isCheckpointSupported() {
262         Context context = InstrumentationRegistry.getInstrumentation().getContext();
263         StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
264         assertThat(sm.isCheckpointSupported()).isTrue();
265     }
266 }
267