import static com.android.tests.rollback.RollbackTestUtils.getUniqueRollbackInfoForPackage;
import android.Manifest;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.pm.VersionedPackage;
import android.content.rollback.RollbackInfo;
import android.content.rollback.RollbackManager;
+import androidx.test.InstrumentationRegistry;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import org.junit.After;
import org.junit.Before;
private static final String TEST_APP_A = "com.android.tests.rollback.testapp.A";
private static final String TEST_APP_A_V1 = "RollbackTestAppAv1.apk";
private static final String TEST_APP_A_V2 = "RollbackTestAppAv2.apk";
+ private static final String TEST_APP_A_CRASHING_V2 = "RollbackTestAppACrashingV2.apk";
private static final String TEST_APEX_PKG = "com.android.tests.rollback.testapex";
private static final String TEST_APEX_V1 =
"com.android.tests.rollback.testapex.RollbackTestApexV1.apex";
RollbackTestUtils.adoptShellPermissionIdentity(
Manifest.permission.INSTALL_PACKAGES,
Manifest.permission.DELETE_PACKAGES,
- Manifest.permission.TEST_MANAGE_ROLLBACKS);
+ Manifest.permission.TEST_MANAGE_ROLLBACKS,
+ Manifest.permission.KILL_BACKGROUND_PROCESSES);
}
/**
assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
assertTrue(rollback.isStaged());
- RollbackTestUtils.rollback(rollback.getRollbackId());
+ RollbackTestUtils.rollback(rollback.getRollbackId(),
+ new VersionedPackage(TEST_APP_A, 2));
rollback = getUniqueRollbackInfoForPackage(
rm.getRecentlyCommittedRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
+ assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback, new VersionedPackage(TEST_APP_A, 2));
assertTrue(rollback.isStaged());
assertNotEquals(-1, rollback.getCommittedSessionId());
}
/**
+ * Test rollbacks of staged installs involving only apks with bad update.
+ * Enable rollback phase.
+ */
+ @Test
+ public void testBadApkOnlyEnableRollback() throws Exception {
+ RollbackTestUtils.uninstall(TEST_APP_A);
+ assertEquals(-1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+
+ RollbackTestUtils.install(TEST_APP_A_V1, false);
+ assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ RollbackTestUtils.processUserData(TEST_APP_A);
+
+ RollbackTestUtils.installStaged(true, TEST_APP_A_CRASHING_V2);
+
+ // At this point, the host test driver will reboot the device and run
+ // testBadApkOnlyConfirmEnableRollback().
+ }
+
+ /**
+ * Test rollbacks of staged installs involving only apks with bad update.
+ * Confirm that rollback was successfully enabled.
+ */
+ @Test
+ public void testBadApkOnlyConfirmEnableRollback() throws Exception {
+ assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+ RollbackTestUtils.processUserData(TEST_APP_A);
+
+ RollbackManager rm = RollbackTestUtils.getRollbackManager();
+ RollbackInfo rollback = getUniqueRollbackInfoForPackage(
+ rm.getAvailableRollbacks(), TEST_APP_A);
+ assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
+ assertTrue(rollback.isStaged());
+
+ // At this point, the host test driver will run
+ // testBadApkOnlyTriggerRollback().
+ }
+
+ /**
+ * Test rollbacks of staged installs involving only apks with bad update.
+ * Trigger rollback phase. This is expected to fail due to watchdog
+ * rebooting the test out from under it.
+ */
+ @Test
+ public void testBadApkOnlyTriggerRollback() throws Exception {
+ BroadcastReceiver crashCountReceiver = null;
+ Context context = InstrumentationRegistry.getContext();
+ RollbackManager rm = RollbackTestUtils.getRollbackManager();
+
+ try {
+ // Crash TEST_APP_A PackageWatchdog#TRIGGER_FAILURE_COUNT times to trigger rollback
+ crashCountReceiver = RollbackTestUtils.sendCrashBroadcast(context, TEST_APP_A, 5);
+ } finally {
+ if (crashCountReceiver != null) {
+ context.unregisterReceiver(crashCountReceiver);
+ }
+ }
+
+ // We expect the device to be rebooted automatically. Wait for that to
+ // happen. At that point, the host test driver will wait for the
+ // device to come back up and run testApkOnlyConfirmRollback().
+ Thread.sleep(30 * 1000);
+
+ fail("watchdog did not trigger reboot");
+ }
+
+ /**
* Test rollbacks of staged installs involving only apks.
* Confirm rollback phase.
*/
RollbackManager rm = RollbackTestUtils.getRollbackManager();
RollbackInfo rollback = getUniqueRollbackInfoForPackage(
rm.getRecentlyCommittedRollbacks(), TEST_APP_A);
- assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback);
+ assertRollbackInfoEquals(TEST_APP_A, 2, 1, rollback, new VersionedPackage(TEST_APP_A, 2));
assertTrue(rollback.isStaged());
assertNotEquals(-1, rollback.getCommittedSessionId());
}
import static org.junit.Assert.assertTrue;
+import com.android.ddmlib.Log.LogLevel;
import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
}
/**
+ * Tests watchdog triggered staged rollbacks involving only apks.
+ */
+ @Test
+ public void testBadApkOnly() throws Exception {
+ runPhase("testBadApkOnlyEnableRollback");
+ getDevice().reboot();
+ runPhase("testBadApkOnlyConfirmEnableRollback");
+ try {
+ // This is expected to fail due to the device being rebooted out
+ // from underneath the test. If this fails for reasons other than
+ // the device reboot, those failures should result in failure of
+ // the testApkOnlyConfirmRollback phase.
+ CLog.logAndDisplay(LogLevel.INFO, "testBadApkOnlyTriggerRollback is expected to fail");
+ runPhase("testBadApkOnlyTriggerRollback");
+ } catch (AssertionError e) {
+ // AssertionError is expected.
+ }
+
+ getDevice().waitForDeviceAvailable();
+ runPhase("testApkOnlyConfirmRollback");
+ }
+
+ /**
* Tests staged rollbacks involving only apex.
*/
@Test