From bf1bf9607d37735dc0d0d15ab973ba821a1785bc Mon Sep 17 00:00:00 2001 From: Richard Uhler Date: Wed, 6 Mar 2019 10:39:46 +0000 Subject: [PATCH] Add watchdog triggered staged rollback test Test: atest StagedRollbackTest Bug: 132758573 Bug: 132866890 Change-Id: I80e4ebf3659702992f32504690ea5ec4bab88534 --- .../tests/rollback/StagedRollbackTest.java | 83 ++++++++++++++++++- .../rollback/host/StagedRollbackTest.java | 25 ++++++ 2 files changed, 104 insertions(+), 4 deletions(-) diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java index 3b0e2a56db3c9..b3a9f4933de97 100644 --- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java +++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java @@ -21,13 +21,19 @@ import static com.android.tests.rollback.RollbackTestUtils.getRecentlyCommittedR 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; @@ -50,6 +56,7 @@ public class StagedRollbackTest { 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"; @@ -66,7 +73,8 @@ public class StagedRollbackTest { 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); } /** @@ -112,11 +120,12 @@ public class StagedRollbackTest { 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()); @@ -129,6 +138,72 @@ public class StagedRollbackTest { // testApkOnlyConfirmRollback(). } + /** + * 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. @@ -141,7 +216,7 @@ public class StagedRollbackTest { 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()); } diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java index 1f87ed8630344..2433434a29933 100644 --- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java +++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java @@ -18,7 +18,9 @@ package com.android.tests.rollback.host; 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; @@ -57,6 +59,29 @@ public class StagedRollbackTest extends BaseHostJUnit4Test { runPhase("testApkOnlyConfirmRollback"); } + /** + * 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. */