blob: 64d05f07e64e07588fb3fac4165d9413823627a7 [file] [log] [blame]
Oli Land9c78462019-09-30 10:18:48 +01001/*
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
17package com.android.server.rollback;
18
19import static com.google.common.truth.Truth.assertThat;
20
21import android.content.pm.VersionedPackage;
22import android.content.rollback.PackageRollbackInfo;
23import android.util.IntArray;
24import android.util.SparseLongArray;
25
26import com.google.common.truth.Correspondence;
27
28import org.json.JSONObject;
29import org.junit.Before;
30import org.junit.Rule;
31import org.junit.Test;
32import org.junit.rules.TemporaryFolder;
33import org.junit.runner.RunWith;
34import org.junit.runners.JUnit4;
35
36import java.io.File;
37import java.time.Instant;
38import java.util.ArrayList;
39import java.util.List;
40import java.util.Objects;
41
42@RunWith(JUnit4.class)
43public class RollbackStoreTest {
44
45 private static final int ID = 123;
Gavin Corkery0987cb02019-10-07 10:46:55 +010046 private static final int USER = 0;
47 private static final String INSTALLER = "some.installer";
Oli Land9c78462019-09-30 10:18:48 +010048
49 private static final Correspondence<VersionedPackage, VersionedPackage> VER_PKG_CORR =
50 new Correspondence<VersionedPackage, VersionedPackage>() {
51 @Override
52 public boolean compare(VersionedPackage a, VersionedPackage b) {
53 if (a == null || b == null) {
54 return a == b;
55 }
JW Wangf73f94a2020-01-02 09:16:58 +080056 return a.equals(b);
Oli Land9c78462019-09-30 10:18:48 +010057 }
58
59 @Override
60 public String toString() {
61 return "is the same as";
62 }
63 };
64
65 private static final Correspondence<PackageRollbackInfo.RestoreInfo,
66 PackageRollbackInfo.RestoreInfo>
67 RESTORE_INFO_CORR =
68 new Correspondence<PackageRollbackInfo.RestoreInfo, PackageRollbackInfo.RestoreInfo>() {
69 @Override
70 public boolean compare(PackageRollbackInfo.RestoreInfo a,
71 PackageRollbackInfo.RestoreInfo b) {
72 if (a == null || b == null) {
73 return a == b;
74 }
75 return a.userId == b.userId
76 && a.appId == b.appId
77 && Objects.equals(a.seInfo, b.seInfo);
78 }
79
80 @Override
81 public String toString() {
82 return "is the same as";
83 }
84 };
85
86 private static final String JSON_ROLLBACK = "{'info':{'rollbackId':123,'packages':"
87 + "[{'versionRolledBackFrom':{'packageName':'blah','longVersionCode':55},"
88 + "'versionRolledBackTo':{'packageName':'blah1','longVersionCode':50},'pendingBackups':"
89 + "[59,1245,124544],'pendingRestores':[{'userId':498,'appId':32322,'seInfo':'wombles'},"
Mohammad Samiul Islam3fcecfc2019-12-20 17:46:01 +000090 + "{'userId':-895,'appId':1,'seInfo':'pingu'}],'isApex':false,'isApkInApex':false,"
91 + "'installedUsers':"
Oli Land9c78462019-09-30 10:18:48 +010092 + "[498468432,1111,98464],'ceSnapshotInodes':[{'userId':1,'ceSnapshotInode':-6},"
93 + "{'userId':2222,'ceSnapshotInode':81641654445},{'userId':546546,"
94 + "'ceSnapshotInode':345689375}]},{'versionRolledBackFrom':{'packageName':'chips',"
95 + "'longVersionCode':28},'versionRolledBackTo':{'packageName':'com.chips.test',"
96 + "'longVersionCode':48},'pendingBackups':[5],'pendingRestores':[{'userId':18,"
Mohammad Samiul Islam3fcecfc2019-12-20 17:46:01 +000097 + "'appId':-12,'seInfo':''}],'isApex':false,'isApkInApex':false,"
98 + "'installedUsers':[55,79],"
Oli Land9c78462019-09-30 10:18:48 +010099 + "'ceSnapshotInodes':[]}],'isStaged':false,'causePackages':[{'packageName':'hello',"
100 + "'longVersionCode':23},{'packageName':'something','longVersionCode':999}],"
101 + "'committedSessionId':45654465},'timestamp':'2019-10-01T12:29:08.855Z',"
102 + "'stagedSessionId':-1,'state':'enabling','apkSessionId':-1,"
Gavin Corkery0987cb02019-10-07 10:46:55 +0100103 + "'restoreUserDataInProgress':true, 'userId':0,"
104 + "'installerPackageName':'some.installer'}";
Oli Land9c78462019-09-30 10:18:48 +0100105
106 @Rule
107 public TemporaryFolder mFolder = new TemporaryFolder();
108
109 private File mRollbackDir;
110
111 private RollbackStore mRollbackStore;
112
113 @Before
114 public void setUp() throws Exception {
115 mRollbackStore = new RollbackStore(mFolder.getRoot());
116 mRollbackDir = mFolder.newFolder(ID + "");
117 mFolder.newFile("rollback.json");
118 }
119
120 @Test
121 public void createNonStaged() {
JW Wang1aba59b2020-02-03 09:32:52 +0800122 Rollback rollback = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER, null);
Oli Land9c78462019-09-30 10:18:48 +0100123
124 assertThat(rollback.getBackupDir().getAbsolutePath())
125 .isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID);
126
127 assertThat(rollback.isStaged()).isFalse();
128 assertThat(rollback.info.getRollbackId()).isEqualTo(ID);
129 assertThat(rollback.info.getPackages()).isEmpty();
130 assertThat(rollback.isEnabling()).isTrue();
131 }
132
133 @Test
134 public void createStaged() {
JW Wang1aba59b2020-02-03 09:32:52 +0800135 Rollback rollback = mRollbackStore.createStagedRollback(ID, 897, USER, INSTALLER, null);
Oli Land9c78462019-09-30 10:18:48 +0100136
137 assertThat(rollback.getBackupDir().getAbsolutePath())
138 .isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID);
139
140 assertThat(rollback.isStaged()).isTrue();
141 assertThat(rollback.getStagedSessionId()).isEqualTo(897);
142
143 assertThat(rollback.info.getRollbackId()).isEqualTo(ID);
144 assertThat(rollback.info.getPackages()).isEmpty();
145 assertThat(rollback.isEnabling()).isTrue();
146 }
147
148 @Test
149 public void saveAndLoadRollback() {
JW Wang1aba59b2020-02-03 09:32:52 +0800150 Rollback origRb = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER, null);
Oli Land9c78462019-09-30 10:18:48 +0100151
152 origRb.setRestoreUserDataInProgress(true);
153 origRb.info.getCausePackages().add(new VersionedPackage("com.made.up", 2));
154 origRb.info.getCausePackages().add(new VersionedPackage("com.pack.age", 99));
155 origRb.info.setCommittedSessionId(123456);
156
157 PackageRollbackInfo pkgInfo1 =
158 new PackageRollbackInfo(new VersionedPackage("com.made.up", 18),
159 new VersionedPackage("com.something.else", 5), new IntArray(),
Mohammad Samiul Islam3fcecfc2019-12-20 17:46:01 +0000160 new ArrayList<>(), false, false, new IntArray(), new SparseLongArray());
Oli Land9c78462019-09-30 10:18:48 +0100161 pkgInfo1.getPendingBackups().add(8);
162 pkgInfo1.getPendingBackups().add(888);
163 pkgInfo1.getPendingBackups().add(88885);
164 pkgInfo1.getCeSnapshotInodes().put(12, 424);
165 pkgInfo1.getCeSnapshotInodes().put(222772, 10000000000L);
166 pkgInfo1.getCeSnapshotInodes().put(10, -67);
167
168 pkgInfo1.getPendingRestores().add(
169 new PackageRollbackInfo.RestoreInfo(4980, 3442322, "seInfo"));
170 pkgInfo1.getPendingRestores().add(
171 new PackageRollbackInfo.RestoreInfo(-89, 15, "otherSeInfo"));
172
173 pkgInfo1.getSnapshottedUsers().add(11);
174 pkgInfo1.getSnapshottedUsers().add(1);
175 pkgInfo1.getSnapshottedUsers().add(0);
176
177 PackageRollbackInfo pkgInfo2 = new PackageRollbackInfo(
178 new VersionedPackage("another.package", 2),
179 new VersionedPackage("com.test.ing", 48888), new IntArray(), new ArrayList<>(),
Mohammad Samiul Islam3fcecfc2019-12-20 17:46:01 +0000180 false, false, new IntArray(), new SparseLongArray());
Oli Land9c78462019-09-30 10:18:48 +0100181 pkgInfo2.getPendingBackups().add(57);
182
183 pkgInfo2.getPendingRestores().add(
184 new PackageRollbackInfo.RestoreInfo(180, -120, ""));
185
186 origRb.info.getPackages().add(pkgInfo1);
187 origRb.info.getPackages().add(pkgInfo2);
188
189 RollbackStore.saveRollback(origRb);
190
191 List<Rollback> loadedRollbacks = mRollbackStore.loadRollbacks();
192 assertThat(loadedRollbacks).hasSize(1);
193 Rollback loadedRb = loadedRollbacks.get(0);
194
195 assertRollbacksAreEquivalent(loadedRb, origRb);
196 }
197
198 @Test
199 public void loadFromJson() throws Exception {
JW Wang1aba59b2020-02-03 09:32:52 +0800200 Rollback expectedRb = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER, null);
Oli Land9c78462019-09-30 10:18:48 +0100201
202 expectedRb.setTimestamp(Instant.parse("2019-10-01T12:29:08.855Z"));
203 expectedRb.setRestoreUserDataInProgress(true);
204 expectedRb.info.getCausePackages().add(new VersionedPackage("hello", 23));
205 expectedRb.info.getCausePackages().add(new VersionedPackage("something", 999));
206 expectedRb.info.setCommittedSessionId(45654465);
207
208 PackageRollbackInfo pkgInfo1 = new PackageRollbackInfo(new VersionedPackage("blah", 55),
209 new VersionedPackage("blah1", 50), new IntArray(), new ArrayList<>(),
Mohammad Samiul Islam3fcecfc2019-12-20 17:46:01 +0000210 false, false, new IntArray(), new SparseLongArray());
Oli Land9c78462019-09-30 10:18:48 +0100211 pkgInfo1.getPendingBackups().add(59);
212 pkgInfo1.getPendingBackups().add(1245);
213 pkgInfo1.getPendingBackups().add(124544);
214 pkgInfo1.getCeSnapshotInodes().put(546546, 345689375);
215 pkgInfo1.getCeSnapshotInodes().put(2222, 81641654445L);
216 pkgInfo1.getCeSnapshotInodes().put(1, -6);
217
218 pkgInfo1.getPendingRestores().add(
219 new PackageRollbackInfo.RestoreInfo(498, 32322, "wombles"));
220 pkgInfo1.getPendingRestores().add(
221 new PackageRollbackInfo.RestoreInfo(-895, 1, "pingu"));
222
223 pkgInfo1.getSnapshottedUsers().add(498468432);
224 pkgInfo1.getSnapshottedUsers().add(1111);
225 pkgInfo1.getSnapshottedUsers().add(98464);
226
227 PackageRollbackInfo pkgInfo2 = new PackageRollbackInfo(new VersionedPackage("chips", 28),
228 new VersionedPackage("com.chips.test", 48), new IntArray(), new ArrayList<>(),
Mohammad Samiul Islam3fcecfc2019-12-20 17:46:01 +0000229 false, false, new IntArray(), new SparseLongArray());
Oli Land9c78462019-09-30 10:18:48 +0100230 pkgInfo2.getPendingBackups().add(5);
231
232 pkgInfo2.getPendingRestores().add(
233 new PackageRollbackInfo.RestoreInfo(18, -12, ""));
234
235 pkgInfo2.getSnapshottedUsers().add(55);
236 pkgInfo2.getSnapshottedUsers().add(79);
237
238 expectedRb.info.getPackages().add(pkgInfo1);
239 expectedRb.info.getPackages().add(pkgInfo2);
240
241 Rollback parsedRb = RollbackStore.rollbackFromJson(
242 new JSONObject(JSON_ROLLBACK), expectedRb.getBackupDir());
243
244 assertRollbacksAreEquivalent(parsedRb, expectedRb);
245 }
246
247 @Test
248 public void saveAndDelete() {
JW Wang1aba59b2020-02-03 09:32:52 +0800249 Rollback rollback = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER, null);
Oli Land9c78462019-09-30 10:18:48 +0100250
251 RollbackStore.saveRollback(rollback);
252
253 File expectedFile = new File(mRollbackDir.getAbsolutePath() + "/rollback.json");
254
255 assertThat(expectedFile.exists()).isTrue();
256
257 RollbackStore.deleteRollback(rollback);
258
259 assertThat(expectedFile.exists()).isFalse();
260 }
261
262 private void assertRollbacksAreEquivalent(Rollback b, Rollback a) {
263 assertThat(b.info.getRollbackId()).isEqualTo(ID);
264
265 assertThat(b.getBackupDir()).isEqualTo(a.getBackupDir());
266
267 assertThat(b.isRestoreUserDataInProgress())
268 .isEqualTo(a.isRestoreUserDataInProgress());
269
270 assertThat(b.getTimestamp()).isEqualTo(a.getTimestamp());
271
272 assertThat(b.isEnabling()).isEqualTo(a.isEnabling());
273 assertThat(b.isAvailable()).isEqualTo(a.isAvailable());
274 assertThat(b.isCommitted()).isEqualTo(a.isCommitted());
275
276 assertThat(b.isStaged()).isEqualTo(a.isStaged());
277
278 assertThat(b.getApexPackageNames())
279 .containsExactlyElementsIn(a.getApexPackageNames());
280
281 assertThat(b.getStagedSessionId()).isEqualTo(a.getStagedSessionId());
282
283 assertThat(b.info.getCommittedSessionId()).isEqualTo(a.info.getCommittedSessionId());
284
285 assertThat(b.info.getCausePackages()).comparingElementsUsing(VER_PKG_CORR)
286 .containsExactlyElementsIn(a.info.getCausePackages());
287
288 assertThat(b.info.getPackages()).hasSize(a.info.getPackages().size());
289
290 for (int i = 0; i < b.info.getPackages().size(); i++) {
291 assertPackageRollbacksAreEquivalent(
292 b.info.getPackages().get(i), a.info.getPackages().get(i));
293 }
Gavin Corkery0987cb02019-10-07 10:46:55 +0100294
295 assertThat(a.getUserId()).isEqualTo(b.getUserId());
296 assertThat(a.getInstallerPackageName()).isEqualTo(b.getInstallerPackageName());
Oli Land9c78462019-09-30 10:18:48 +0100297 }
298
299 private void assertPackageRollbacksAreEquivalent(PackageRollbackInfo b, PackageRollbackInfo a) {
300 assertThat(b.getPackageName()).isEqualTo(a.getPackageName());
301
JW Wangf73f94a2020-01-02 09:16:58 +0800302 assertThat(b.getVersionRolledBackFrom()).isEqualTo(a.getVersionRolledBackFrom());
303 assertThat(b.getVersionRolledBackTo()).isEqualTo(a.getVersionRolledBackTo());
Oli Land9c78462019-09-30 10:18:48 +0100304
305 assertThat(b.getPendingBackups().toArray()).isEqualTo(a.getPendingBackups().toArray());
306
307 assertThat(b.getPendingRestores()).comparingElementsUsing(RESTORE_INFO_CORR)
308 .containsExactlyElementsIn(a.getPendingRestores());
309
310 assertThat(b.isApex()).isEqualTo(a.isApex());
311
312 assertThat(b.getSnapshottedUsers().toArray()).isEqualTo(a.getSnapshottedUsers().toArray());
313
314 assertThat(b.getCeSnapshotInodes().toString())
315 .isEqualTo(a.getCeSnapshotInodes().toString());
316 }
317
318}