blob: d0d2edc59861bca10e3f959502abeca73208ee91 [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.rollback;
import static com.google.common.truth.Truth.assertThat;
import android.content.pm.VersionedPackage;
import android.content.rollback.PackageRollbackInfo;
import android.util.IntArray;
import android.util.SparseLongArray;
import com.google.common.truth.Correspondence;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.io.File;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@RunWith(JUnit4.class)
public class RollbackStoreTest {
private static final int ID = 123;
private static final int USER = 0;
private static final String INSTALLER = "some.installer";
private static final Correspondence<VersionedPackage, VersionedPackage> VER_PKG_CORR =
new Correspondence<VersionedPackage, VersionedPackage>() {
@Override
public boolean compare(VersionedPackage a, VersionedPackage b) {
if (a == null || b == null) {
return a == b;
}
return a.equals(b);
}
@Override
public String toString() {
return "is the same as";
}
};
private static final Correspondence<PackageRollbackInfo.RestoreInfo,
PackageRollbackInfo.RestoreInfo>
RESTORE_INFO_CORR =
new Correspondence<PackageRollbackInfo.RestoreInfo, PackageRollbackInfo.RestoreInfo>() {
@Override
public boolean compare(PackageRollbackInfo.RestoreInfo a,
PackageRollbackInfo.RestoreInfo b) {
if (a == null || b == null) {
return a == b;
}
return a.userId == b.userId
&& a.appId == b.appId
&& Objects.equals(a.seInfo, b.seInfo);
}
@Override
public String toString() {
return "is the same as";
}
};
private static final String JSON_ROLLBACK = "{'info':{'rollbackId':123,'packages':"
+ "[{'versionRolledBackFrom':{'packageName':'blah','longVersionCode':55},"
+ "'versionRolledBackTo':{'packageName':'blah1','longVersionCode':50},'pendingBackups':"
+ "[59,1245,124544],'pendingRestores':[{'userId':498,'appId':32322,'seInfo':'wombles'},"
+ "{'userId':-895,'appId':1,'seInfo':'pingu'}],'isApex':false,'isApkInApex':false,"
+ "'installedUsers':"
+ "[498468432,1111,98464],'ceSnapshotInodes':[{'userId':1,'ceSnapshotInode':-6},"
+ "{'userId':2222,'ceSnapshotInode':81641654445},{'userId':546546,"
+ "'ceSnapshotInode':345689375}]},{'versionRolledBackFrom':{'packageName':'chips',"
+ "'longVersionCode':28},'versionRolledBackTo':{'packageName':'com.chips.test',"
+ "'longVersionCode':48},'pendingBackups':[5],'pendingRestores':[{'userId':18,"
+ "'appId':-12,'seInfo':''}],'isApex':false,'isApkInApex':false,"
+ "'installedUsers':[55,79],"
+ "'ceSnapshotInodes':[]}],'isStaged':false,'causePackages':[{'packageName':'hello',"
+ "'longVersionCode':23},{'packageName':'something','longVersionCode':999}],"
+ "'committedSessionId':45654465},'timestamp':'2019-10-01T12:29:08.855Z',"
+ "'stagedSessionId':-1,'state':'enabling','apkSessionId':-1,"
+ "'restoreUserDataInProgress':true, 'userId':0,"
+ "'installerPackageName':'some.installer'}";
@Rule
public TemporaryFolder mFolder = new TemporaryFolder();
private File mRollbackDir;
private RollbackStore mRollbackStore;
@Before
public void setUp() throws Exception {
mRollbackStore = new RollbackStore(mFolder.getRoot());
mRollbackDir = mFolder.newFolder(ID + "");
mFolder.newFile("rollback.json");
}
@Test
public void createNonStaged() {
Rollback rollback = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER);
assertThat(rollback.getBackupDir().getAbsolutePath())
.isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID);
assertThat(rollback.isStaged()).isFalse();
assertThat(rollback.info.getRollbackId()).isEqualTo(ID);
assertThat(rollback.info.getPackages()).isEmpty();
assertThat(rollback.isEnabling()).isTrue();
}
@Test
public void createStaged() {
Rollback rollback = mRollbackStore.createStagedRollback(ID, 897, USER, INSTALLER);
assertThat(rollback.getBackupDir().getAbsolutePath())
.isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID);
assertThat(rollback.isStaged()).isTrue();
assertThat(rollback.getStagedSessionId()).isEqualTo(897);
assertThat(rollback.info.getRollbackId()).isEqualTo(ID);
assertThat(rollback.info.getPackages()).isEmpty();
assertThat(rollback.isEnabling()).isTrue();
}
@Test
public void saveAndLoadRollback() {
Rollback origRb = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER);
origRb.setRestoreUserDataInProgress(true);
origRb.info.getCausePackages().add(new VersionedPackage("com.made.up", 2));
origRb.info.getCausePackages().add(new VersionedPackage("com.pack.age", 99));
origRb.info.setCommittedSessionId(123456);
PackageRollbackInfo pkgInfo1 =
new PackageRollbackInfo(new VersionedPackage("com.made.up", 18),
new VersionedPackage("com.something.else", 5), new IntArray(),
new ArrayList<>(), false, false, new IntArray(), new SparseLongArray());
pkgInfo1.getPendingBackups().add(8);
pkgInfo1.getPendingBackups().add(888);
pkgInfo1.getPendingBackups().add(88885);
pkgInfo1.getCeSnapshotInodes().put(12, 424);
pkgInfo1.getCeSnapshotInodes().put(222772, 10000000000L);
pkgInfo1.getCeSnapshotInodes().put(10, -67);
pkgInfo1.getPendingRestores().add(
new PackageRollbackInfo.RestoreInfo(4980, 3442322, "seInfo"));
pkgInfo1.getPendingRestores().add(
new PackageRollbackInfo.RestoreInfo(-89, 15, "otherSeInfo"));
pkgInfo1.getSnapshottedUsers().add(11);
pkgInfo1.getSnapshottedUsers().add(1);
pkgInfo1.getSnapshottedUsers().add(0);
PackageRollbackInfo pkgInfo2 = new PackageRollbackInfo(
new VersionedPackage("another.package", 2),
new VersionedPackage("com.test.ing", 48888), new IntArray(), new ArrayList<>(),
false, false, new IntArray(), new SparseLongArray());
pkgInfo2.getPendingBackups().add(57);
pkgInfo2.getPendingRestores().add(
new PackageRollbackInfo.RestoreInfo(180, -120, ""));
origRb.info.getPackages().add(pkgInfo1);
origRb.info.getPackages().add(pkgInfo2);
RollbackStore.saveRollback(origRb);
List<Rollback> loadedRollbacks = mRollbackStore.loadRollbacks();
assertThat(loadedRollbacks).hasSize(1);
Rollback loadedRb = loadedRollbacks.get(0);
assertRollbacksAreEquivalent(loadedRb, origRb);
}
@Test
public void loadFromJson() throws Exception {
Rollback expectedRb = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER);
expectedRb.setTimestamp(Instant.parse("2019-10-01T12:29:08.855Z"));
expectedRb.setRestoreUserDataInProgress(true);
expectedRb.info.getCausePackages().add(new VersionedPackage("hello", 23));
expectedRb.info.getCausePackages().add(new VersionedPackage("something", 999));
expectedRb.info.setCommittedSessionId(45654465);
PackageRollbackInfo pkgInfo1 = new PackageRollbackInfo(new VersionedPackage("blah", 55),
new VersionedPackage("blah1", 50), new IntArray(), new ArrayList<>(),
false, false, new IntArray(), new SparseLongArray());
pkgInfo1.getPendingBackups().add(59);
pkgInfo1.getPendingBackups().add(1245);
pkgInfo1.getPendingBackups().add(124544);
pkgInfo1.getCeSnapshotInodes().put(546546, 345689375);
pkgInfo1.getCeSnapshotInodes().put(2222, 81641654445L);
pkgInfo1.getCeSnapshotInodes().put(1, -6);
pkgInfo1.getPendingRestores().add(
new PackageRollbackInfo.RestoreInfo(498, 32322, "wombles"));
pkgInfo1.getPendingRestores().add(
new PackageRollbackInfo.RestoreInfo(-895, 1, "pingu"));
pkgInfo1.getSnapshottedUsers().add(498468432);
pkgInfo1.getSnapshottedUsers().add(1111);
pkgInfo1.getSnapshottedUsers().add(98464);
PackageRollbackInfo pkgInfo2 = new PackageRollbackInfo(new VersionedPackage("chips", 28),
new VersionedPackage("com.chips.test", 48), new IntArray(), new ArrayList<>(),
false, false, new IntArray(), new SparseLongArray());
pkgInfo2.getPendingBackups().add(5);
pkgInfo2.getPendingRestores().add(
new PackageRollbackInfo.RestoreInfo(18, -12, ""));
pkgInfo2.getSnapshottedUsers().add(55);
pkgInfo2.getSnapshottedUsers().add(79);
expectedRb.info.getPackages().add(pkgInfo1);
expectedRb.info.getPackages().add(pkgInfo2);
Rollback parsedRb = RollbackStore.rollbackFromJson(
new JSONObject(JSON_ROLLBACK), expectedRb.getBackupDir());
assertRollbacksAreEquivalent(parsedRb, expectedRb);
}
@Test
public void saveAndDelete() {
Rollback rollback = mRollbackStore.createNonStagedRollback(ID, USER, INSTALLER);
RollbackStore.saveRollback(rollback);
File expectedFile = new File(mRollbackDir.getAbsolutePath() + "/rollback.json");
assertThat(expectedFile.exists()).isTrue();
RollbackStore.deleteRollback(rollback);
assertThat(expectedFile.exists()).isFalse();
}
private void assertRollbacksAreEquivalent(Rollback b, Rollback a) {
assertThat(b.info.getRollbackId()).isEqualTo(ID);
assertThat(b.getBackupDir()).isEqualTo(a.getBackupDir());
assertThat(b.isRestoreUserDataInProgress())
.isEqualTo(a.isRestoreUserDataInProgress());
assertThat(b.getTimestamp()).isEqualTo(a.getTimestamp());
assertThat(b.isEnabling()).isEqualTo(a.isEnabling());
assertThat(b.isAvailable()).isEqualTo(a.isAvailable());
assertThat(b.isCommitted()).isEqualTo(a.isCommitted());
assertThat(b.isStaged()).isEqualTo(a.isStaged());
assertThat(b.getApexPackageNames())
.containsExactlyElementsIn(a.getApexPackageNames());
assertThat(b.getStagedSessionId()).isEqualTo(a.getStagedSessionId());
assertThat(b.info.getCommittedSessionId()).isEqualTo(a.info.getCommittedSessionId());
assertThat(b.info.getCausePackages()).comparingElementsUsing(VER_PKG_CORR)
.containsExactlyElementsIn(a.info.getCausePackages());
assertThat(b.info.getPackages()).hasSize(a.info.getPackages().size());
for (int i = 0; i < b.info.getPackages().size(); i++) {
assertPackageRollbacksAreEquivalent(
b.info.getPackages().get(i), a.info.getPackages().get(i));
}
assertThat(a.getUserId()).isEqualTo(b.getUserId());
assertThat(a.getInstallerPackageName()).isEqualTo(b.getInstallerPackageName());
}
private void assertPackageRollbacksAreEquivalent(PackageRollbackInfo b, PackageRollbackInfo a) {
assertThat(b.getPackageName()).isEqualTo(a.getPackageName());
assertThat(b.getVersionRolledBackFrom()).isEqualTo(a.getVersionRolledBackFrom());
assertThat(b.getVersionRolledBackTo()).isEqualTo(a.getVersionRolledBackTo());
assertThat(b.getPendingBackups().toArray()).isEqualTo(a.getPendingBackups().toArray());
assertThat(b.getPendingRestores()).comparingElementsUsing(RESTORE_INFO_CORR)
.containsExactlyElementsIn(a.getPendingRestores());
assertThat(b.isApex()).isEqualTo(a.isApex());
assertThat(b.getSnapshottedUsers().toArray()).isEqualTo(a.getSnapshottedUsers().toArray());
assertThat(b.getCeSnapshotInodes().toString())
.isEqualTo(a.getCeSnapshotInodes().toString());
}
}