Loading services/core/java/com/android/server/pm/ApexManager.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -327,6 +327,7 @@ public abstract class ApexManager { /** /** * Restores the snapshot of the CE apex data directory for the given {@code userId}. * Restores the snapshot of the CE apex data directory for the given {@code userId}. * Note the snapshot will be deleted after restoration succeeded. * * * @return boolean true if the restore was successful * @return boolean true if the restore was successful */ */ Loading tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java +48 −0 Original line number Original line Diff line number Diff line Loading @@ -21,9 +21,12 @@ import static com.android.tests.rollback.host.WatchdogEventLogger.watchdogEventO import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; import static org.junit.Assume.assumeTrue; import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; import com.android.tradefed.device.DeviceNotAvailableException; import com.android.tradefed.device.IFileEntry; import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; import com.android.tradefed.util.CommandResult; import com.android.tradefed.util.CommandResult; Loading @@ -35,8 +38,10 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runner.RunWith; import java.io.File; import java.io.File; import java.util.Collections; import java.util.List; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** /** * Runs the staged rollback tests. * Runs the staged rollback tests. Loading Loading @@ -304,6 +309,7 @@ public class StagedRollbackTest extends BaseHostJUnit4Test { */ */ @Test @Test public void testRollbackApexDataDirectories_DeSys() throws Exception { public void testRollbackApexDataDirectories_DeSys() throws Exception { List<String> before = getSnapshotDirectories("/data/misc/apexrollback"); pushTestApex(); pushTestApex(); // Push files to apex data directory // Push files to apex data directory Loading Loading @@ -335,6 +341,12 @@ public class StagedRollbackTest extends BaseHostJUnit4Test { assertEquals(TEST_STRING_2, getDevice().pullFileContents(oldFilePath2)); assertEquals(TEST_STRING_2, getDevice().pullFileContents(oldFilePath2)); assertNull(getDevice().pullFile(newFilePath3)); assertNull(getDevice().pullFile(newFilePath3)); assertNull(getDevice().pullFile(newFilePath4)); assertNull(getDevice().pullFile(newFilePath4)); // Verify snapshots are deleted after restoration List<String> after = getSnapshotDirectories("/data/misc/apexrollback"); // Only check directories newly created during the test after.removeAll(before); after.forEach(dir -> assertDirectoryIsEmpty(dir)); } } /** /** Loading @@ -342,6 +354,7 @@ public class StagedRollbackTest extends BaseHostJUnit4Test { */ */ @Test @Test public void testRollbackApexDataDirectories_DeUser() throws Exception { public void testRollbackApexDataDirectories_DeUser() throws Exception { List<String> before = getSnapshotDirectories("/data/misc_de/0/apexrollback"); pushTestApex(); pushTestApex(); // Push files to apex data directory // Push files to apex data directory Loading Loading @@ -375,6 +388,12 @@ public class StagedRollbackTest extends BaseHostJUnit4Test { assertEquals(TEST_STRING_2, getDevice().pullFileContents(oldFilePath2)); assertEquals(TEST_STRING_2, getDevice().pullFileContents(oldFilePath2)); assertNull(getDevice().pullFile(newFilePath3)); assertNull(getDevice().pullFile(newFilePath3)); assertNull(getDevice().pullFile(newFilePath4)); assertNull(getDevice().pullFile(newFilePath4)); // Verify snapshots are deleted after restoration List<String> after = getSnapshotDirectories("/data/misc_de/0/apexrollback"); // Only check directories newly created during the test after.removeAll(before); after.forEach(dir -> assertDirectoryIsEmpty(dir)); } } /** /** Loading @@ -382,6 +401,7 @@ public class StagedRollbackTest extends BaseHostJUnit4Test { */ */ @Test @Test public void testRollbackApexDataDirectories_Ce() throws Exception { public void testRollbackApexDataDirectories_Ce() throws Exception { List<String> before = getSnapshotDirectories("/data/misc_ce/0/apexrollback"); pushTestApex(); pushTestApex(); // Push files to apex data directory // Push files to apex data directory Loading Loading @@ -413,6 +433,12 @@ public class StagedRollbackTest extends BaseHostJUnit4Test { assertEquals(TEST_STRING_2, getDevice().pullFileContents(oldFilePath2)); assertEquals(TEST_STRING_2, getDevice().pullFileContents(oldFilePath2)); assertNull(getDevice().pullFile(newFilePath3)); assertNull(getDevice().pullFile(newFilePath3)); assertNull(getDevice().pullFile(newFilePath4)); assertNull(getDevice().pullFile(newFilePath4)); // Verify snapshots are deleted after restoration List<String> after = getSnapshotDirectories("/data/misc_ce/0/apexrollback"); // Only check directories newly created during the test after.removeAll(before); after.forEach(dir -> assertDirectoryIsEmpty(dir)); } } private void pushTestApex() throws Exception { private void pushTestApex() throws Exception { Loading @@ -439,6 +465,28 @@ public class StagedRollbackTest extends BaseHostJUnit4Test { return String.format("/data/misc_ce/%d/apexdata/%s", userId, apexName); return String.format("/data/misc_ce/%d/apexdata/%s", userId, apexName); } } private List<String> getSnapshotDirectories(String baseDir) { try { return getDevice().getFileEntry(baseDir).getChildren(false) .stream().filter(entry -> entry.getName().matches("\\d+(-prerestore)?")) .map(entry -> entry.getFullPath()) .collect(Collectors.toList()); } catch (Exception e) { // Return an empty list if any error return Collections.EMPTY_LIST; } } private void assertDirectoryIsEmpty(String path) { try { IFileEntry file = getDevice().getFileEntry(path); assertTrue("Not a directory: " + path, file.isDirectory()); assertTrue("Directory not empty: " + path, file.getChildren(false).isEmpty()); } catch (DeviceNotAvailableException e) { fail("Can't access directory: " + path); } } private void crashProcess(String processName, int numberOfCrashes) throws Exception { private void crashProcess(String processName, int numberOfCrashes) throws Exception { String pid = ""; String pid = ""; String lastPid = "invalid"; String lastPid = "invalid"; Loading Loading
services/core/java/com/android/server/pm/ApexManager.java +1 −0 Original line number Original line Diff line number Diff line Loading @@ -327,6 +327,7 @@ public abstract class ApexManager { /** /** * Restores the snapshot of the CE apex data directory for the given {@code userId}. * Restores the snapshot of the CE apex data directory for the given {@code userId}. * Note the snapshot will be deleted after restoration succeeded. * * * @return boolean true if the restore was successful * @return boolean true if the restore was successful */ */ Loading
tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java +48 −0 Original line number Original line Diff line number Diff line Loading @@ -21,9 +21,12 @@ import static com.android.tests.rollback.host.WatchdogEventLogger.watchdogEventO import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.junit.Assume.assumeTrue; import static org.junit.Assume.assumeTrue; import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; import com.android.tradefed.device.DeviceNotAvailableException; import com.android.tradefed.device.IFileEntry; import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test; import com.android.tradefed.util.CommandResult; import com.android.tradefed.util.CommandResult; Loading @@ -35,8 +38,10 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runner.RunWith; import java.io.File; import java.io.File; import java.util.Collections; import java.util.List; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** /** * Runs the staged rollback tests. * Runs the staged rollback tests. Loading Loading @@ -304,6 +309,7 @@ public class StagedRollbackTest extends BaseHostJUnit4Test { */ */ @Test @Test public void testRollbackApexDataDirectories_DeSys() throws Exception { public void testRollbackApexDataDirectories_DeSys() throws Exception { List<String> before = getSnapshotDirectories("/data/misc/apexrollback"); pushTestApex(); pushTestApex(); // Push files to apex data directory // Push files to apex data directory Loading Loading @@ -335,6 +341,12 @@ public class StagedRollbackTest extends BaseHostJUnit4Test { assertEquals(TEST_STRING_2, getDevice().pullFileContents(oldFilePath2)); assertEquals(TEST_STRING_2, getDevice().pullFileContents(oldFilePath2)); assertNull(getDevice().pullFile(newFilePath3)); assertNull(getDevice().pullFile(newFilePath3)); assertNull(getDevice().pullFile(newFilePath4)); assertNull(getDevice().pullFile(newFilePath4)); // Verify snapshots are deleted after restoration List<String> after = getSnapshotDirectories("/data/misc/apexrollback"); // Only check directories newly created during the test after.removeAll(before); after.forEach(dir -> assertDirectoryIsEmpty(dir)); } } /** /** Loading @@ -342,6 +354,7 @@ public class StagedRollbackTest extends BaseHostJUnit4Test { */ */ @Test @Test public void testRollbackApexDataDirectories_DeUser() throws Exception { public void testRollbackApexDataDirectories_DeUser() throws Exception { List<String> before = getSnapshotDirectories("/data/misc_de/0/apexrollback"); pushTestApex(); pushTestApex(); // Push files to apex data directory // Push files to apex data directory Loading Loading @@ -375,6 +388,12 @@ public class StagedRollbackTest extends BaseHostJUnit4Test { assertEquals(TEST_STRING_2, getDevice().pullFileContents(oldFilePath2)); assertEquals(TEST_STRING_2, getDevice().pullFileContents(oldFilePath2)); assertNull(getDevice().pullFile(newFilePath3)); assertNull(getDevice().pullFile(newFilePath3)); assertNull(getDevice().pullFile(newFilePath4)); assertNull(getDevice().pullFile(newFilePath4)); // Verify snapshots are deleted after restoration List<String> after = getSnapshotDirectories("/data/misc_de/0/apexrollback"); // Only check directories newly created during the test after.removeAll(before); after.forEach(dir -> assertDirectoryIsEmpty(dir)); } } /** /** Loading @@ -382,6 +401,7 @@ public class StagedRollbackTest extends BaseHostJUnit4Test { */ */ @Test @Test public void testRollbackApexDataDirectories_Ce() throws Exception { public void testRollbackApexDataDirectories_Ce() throws Exception { List<String> before = getSnapshotDirectories("/data/misc_ce/0/apexrollback"); pushTestApex(); pushTestApex(); // Push files to apex data directory // Push files to apex data directory Loading Loading @@ -413,6 +433,12 @@ public class StagedRollbackTest extends BaseHostJUnit4Test { assertEquals(TEST_STRING_2, getDevice().pullFileContents(oldFilePath2)); assertEquals(TEST_STRING_2, getDevice().pullFileContents(oldFilePath2)); assertNull(getDevice().pullFile(newFilePath3)); assertNull(getDevice().pullFile(newFilePath3)); assertNull(getDevice().pullFile(newFilePath4)); assertNull(getDevice().pullFile(newFilePath4)); // Verify snapshots are deleted after restoration List<String> after = getSnapshotDirectories("/data/misc_ce/0/apexrollback"); // Only check directories newly created during the test after.removeAll(before); after.forEach(dir -> assertDirectoryIsEmpty(dir)); } } private void pushTestApex() throws Exception { private void pushTestApex() throws Exception { Loading @@ -439,6 +465,28 @@ public class StagedRollbackTest extends BaseHostJUnit4Test { return String.format("/data/misc_ce/%d/apexdata/%s", userId, apexName); return String.format("/data/misc_ce/%d/apexdata/%s", userId, apexName); } } private List<String> getSnapshotDirectories(String baseDir) { try { return getDevice().getFileEntry(baseDir).getChildren(false) .stream().filter(entry -> entry.getName().matches("\\d+(-prerestore)?")) .map(entry -> entry.getFullPath()) .collect(Collectors.toList()); } catch (Exception e) { // Return an empty list if any error return Collections.EMPTY_LIST; } } private void assertDirectoryIsEmpty(String path) { try { IFileEntry file = getDevice().getFileEntry(path); assertTrue("Not a directory: " + path, file.isDirectory()); assertTrue("Directory not empty: " + path, file.getChildren(false).isEmpty()); } catch (DeviceNotAvailableException e) { fail("Can't access directory: " + path); } } private void crashProcess(String processName, int numberOfCrashes) throws Exception { private void crashProcess(String processName, int numberOfCrashes) throws Exception { String pid = ""; String pid = ""; String lastPid = "invalid"; String lastPid = "invalid"; Loading