Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b98e9223 authored by Richard Uhler's avatar Richard Uhler Committed by Android (Google) Code Review
Browse files

Merge "Expire rollback when apex is updated." into qt-dev

parents 1e09d0e4 1924d6db
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -588,6 +589,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            // rollback sessions been applied.
            List<RollbackData> enabling = new ArrayList<>();
            List<RollbackData> restoreInProgress = new ArrayList<>();
            Set<String> apexPackageNames = new HashSet<>();
            synchronized (mLock) {
                ensureRollbackDataLoadedLocked();
                for (RollbackData data : mRollbacks) {
@@ -597,6 +599,12 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                        } else if (data.restoreUserDataInProgress) {
                            restoreInProgress.add(data);
                        }

                        for (PackageRollbackInfo info : data.info.getPackages()) {
                            if (info.isApex()) {
                                apexPackageNames.add(info.getPackageName());
                            }
                        }
                    }
                }
            }
@@ -634,6 +642,14 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                }
            }

            for (String apexPackageName : apexPackageNames) {
                // We will not recieve notifications when an apex is updated,
                // so check now in case any rollbacks ought to be expired. The
                // onPackagedReplace function is safe to call if the package
                // hasn't actually been updated.
                onPackageReplaced(apexPackageName);
            }

            mPackageHealthObserver.onBootCompleted();
        });
    }
+10 −0
Original line number Diff line number Diff line
@@ -88,6 +88,15 @@ apex {
    installable: false,
}

apex {
    name: "com.android.tests.rollback.testapex.RollbackTestApexV3",
    manifest: "TestApex/RollbackTestApexV3.json",
    file_contexts: "apex.test",
    prebuilts: ["RollbackTestApex.prebuilt.txt"],
    key: "RollbackTestApex.key",
    installable: false,
}

apex_key {
    name: "RollbackTestApex.key",
    public_key: "TestApex/com.android.tests.rollback.testapex.avbpubkey",
@@ -116,6 +125,7 @@ android_test {
        ":RollbackTestAppASplitV2",
        ":com.android.tests.rollback.testapex.RollbackTestApexV1",
        ":com.android.tests.rollback.testapex.RollbackTestApexV2",
        ":com.android.tests.rollback.testapex.RollbackTestApexV3",
    ],
    test_config: "RollbackTest.xml",
    sdk_version: "test_current",
+53 −32
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.content.rollback.RollbackManager;

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 org.junit.After;
@@ -54,6 +55,8 @@ public class StagedRollbackTest {
            "com.android.tests.rollback.testapex.RollbackTestApexV1.apex";
    private static final String TEST_APEX_V2 =
            "com.android.tests.rollback.testapex.RollbackTestApexV2.apex";
    private static final String TEST_APEX_V3 =
            "com.android.tests.rollback.testapex.RollbackTestApexV3.apex";

    /**
     * Adopts common shell permissions needed for rollback tests.
@@ -143,28 +146,15 @@ public class StagedRollbackTest {
        assertNotEquals(-1, rollback.getCommittedSessionId());
    }

    /**
     * Test rollbacks of staged installs an apk and an apex.
     * Prepare apex (and apk) phase.
     */
    @Test
    public void testApkAndApexPrepare() throws Exception {
        RollbackTestUtils.uninstall(TEST_APP_A);
        assertEquals(-1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));

        // Note: can't uninstall the apex. See note in #testApexOnlyPrepareApex().
        RollbackTestUtils.installStaged(false, TEST_APP_A_V1, TEST_APEX_V1);

        // At this point, the host test driver will reboot the device and run
        // testApkAndApexEnableRollback().
    }

    /**
     * Test rollbacks of staged installs an apk and an apex.
     * Enable rollback phase.
     */
    @Test
    public void testApkAndApexEnableRollback() throws Exception {
        RollbackTestUtils.uninstall(TEST_APP_A);
        RollbackTestUtils.install(TEST_APP_A_V1, false);

        assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APEX_PKG));
        assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APP_A));

@@ -223,22 +213,6 @@ public class StagedRollbackTest {
        RollbackTestUtils.processUserData(TEST_APP_A);
    }

    /**
     * Test rollbacks of staged installs involving only apex.
     * Prepare apex phase.
     */
    @Test
    public void testApexOnlyPrepareApex() throws Exception {
        // Note: We can't uninstall the apex if it is already on device,
        // because that isn't supported yet (b/123667725). As long as nothing
        // is failing, this should be fine because we don't expect the tests
        // to leave the device with v2 of the apex installed.
        RollbackTestUtils.installStaged(false, TEST_APEX_V1);

        // At this point, the host test driver will reboot the device and run
        // testApexOnlyEnableRollback().
    }

    /**
     * Test rollbacks of staged installs involving only apex.
     * Enable rollback phase.
@@ -291,4 +265,51 @@ public class StagedRollbackTest {
    public void testApexOnlyConfirmRollback() throws Exception {
        assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APEX_PKG));
    }

    /**
     * Tests that apex update expires existing rollbacks for that apex.
     * Enable rollback phase.
     */
    @Test
    public void testApexRollbackExpirationEnableRollback() throws Exception {
        assertEquals(1, RollbackTestUtils.getInstalledVersion(TEST_APEX_PKG));
        RollbackTestUtils.installStaged(true, TEST_APEX_V2);

        // At this point, the host test driver will reboot the device and run
        // testApexRollbackExpirationUpdateApex().
    }

    /**
     * Tests that apex update expires existing rollbacks for that apex.
     * Update apex phase.
     */
    @Test
    public void testApexRollbackExpirationUpdateApex() throws Exception {
        assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APEX_PKG));
        RollbackTestUtils.installStaged(false, TEST_APEX_V3);

        // At this point, the host test driver will reboot the device and run
        // testApexRollbackExpirationConfirmExpiration().
    }

    /**
     * Tests that apex update expires existing rollbacks for that apex.
     * Confirm expiration phase.
     */
    @Test
    public void testApexRollbackExpirationConfirmExpiration() throws Exception {
        assertEquals(3, RollbackTestUtils.getInstalledVersion(TEST_APEX_PKG));

        RollbackManager rm = RollbackTestUtils.getRollbackManager();
        assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APEX_PKG));
    }

    /**
     * Helper function called by the host test to install v1 of the test apex,
     * assuming the test apex is not installed.
     */
    @Test
    public void installTestApexV1() throws Exception {
        RollbackTestUtils.installStaged(false, TEST_APEX_V1);
    }
}
+39 −4
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.tests.rollback.host;

import static org.junit.Assert.assertTrue;

import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;

@@ -30,6 +31,8 @@ import org.junit.runner.RunWith;
@RunWith(DeviceJUnit4ClassRunner.class)
public class StagedRollbackTest extends BaseHostJUnit4Test {

    private static final String TEST_APEX_PKG = "com.android.tests.rollback.testapex";

    /**
     * Runs the given phase of a test by calling into the device.
     * Throws an exception if the test phase fails.
@@ -59,8 +62,7 @@ public class StagedRollbackTest extends BaseHostJUnit4Test {
     */
    @Test
    public void testApexOnly() throws Exception {
        runPhase("testApexOnlyPrepareApex");
        getDevice().reboot();
        installTestApexV1();
        runPhase("testApexOnlyEnableRollback");
        getDevice().reboot();
        runPhase("testApexOnlyCommitRollback");
@@ -73,12 +75,45 @@ public class StagedRollbackTest extends BaseHostJUnit4Test {
     */
    @Test
    public void testApkAndApex() throws Exception {
        runPhase("testApkAndApexPrepare");
        getDevice().reboot();
        installTestApexV1();
        runPhase("testApkAndApexEnableRollback");
        getDevice().reboot();
        runPhase("testApkAndApexCommitRollback");
        getDevice().reboot();
        runPhase("testApkAndApexConfirmRollback");
    }

    /**
     * Tests that apex update expires existing rollbacks for that apex.
     */
    @Test
    public void testApexRollbackExpiration() throws Exception {
        installTestApexV1();
        runPhase("testApexRollbackExpirationEnableRollback");
        getDevice().reboot();
        runPhase("testApexRollbackExpirationUpdateApex");
        getDevice().reboot();
        runPhase("testApexRollbackExpirationConfirmExpiration");
    }

    /**
     * Do whatever is necessary to get version 1 of the test apex installed on
     * the device. Try to do so without extra reboots where possible to keep
     * the test execution time down.
     */
    private void installTestApexV1() throws Exception {
        for (ITestDevice.ApexInfo apexInfo : getDevice().getActiveApexes()) {
            if (TEST_APEX_PKG.equals(apexInfo.name)) {
                if (apexInfo.versionCode == 1) {
                    return;
                }
                getDevice().uninstallPackage(TEST_APEX_PKG);
                getDevice().reboot();
                break;
            }
        }

        runPhase("installTestApexV1");
        getDevice().reboot();
    }
}
+4 −0
Original line number Diff line number Diff line
{
    "name": "com.android.tests.rollback.testapex",
    "version": 3
}