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

Commit cd8f972f authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Tests for BMS.requestBackup()"

parents b7fbab31 34607a0f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -177,7 +177,7 @@ public class TransportManager {
    }

    @Nullable
    String getCurrentTransportName() {
    public String getCurrentTransportName() {
        return mCurrentTransportName;
    }

+19 −1
Original line number Diff line number Diff line
@@ -16,11 +16,12 @@

package com.android.server.backup.internal;

import java.util.Objects;

/**
 * Set of backup services that have pending changes.
 */
public class BackupRequest {

    public String packageName;

    public BackupRequest(String pkgName) {
@@ -30,4 +31,21 @@ public class BackupRequest {
    public String toString() {
        return "BackupRequest{pkg=" + packageName + "}";
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof BackupRequest)) {
            return false;
        }
        BackupRequest that = (BackupRequest) o;
        return Objects.equals(packageName, that.packageName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(packageName);
    }
}
+181 −30
Original line number Diff line number Diff line
@@ -22,7 +22,9 @@ import static com.android.server.backup.testing.TransportData.d2dTransport;
import static com.android.server.backup.testing.TransportData.localTransport;
import static com.android.server.backup.testing.TransportTestUtils.setUpCurrentTransport;
import static com.android.server.backup.testing.TransportTestUtils.setUpTransports;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
@@ -34,6 +36,7 @@ import static org.robolectric.Shadows.shadowOf;
import static org.testng.Assert.expectThrows;

import android.app.backup.BackupManager;
import android.app.backup.IBackupObserver;
import android.app.backup.ISelectBackupTransportCallback;
import android.content.ComponentName;
import android.content.Context;
@@ -43,18 +46,16 @@ import android.os.HandlerThread;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;

import com.android.server.testing.shadows.ShadowAppBackupUtils;
import com.android.server.testing.shadows.ShadowBackupPolicyEnforcer;
import com.android.server.backup.internal.BackupRequest;
import com.android.server.backup.testing.TransportData;
import com.android.server.backup.testing.TransportTestUtils.TransportMock;
import com.android.server.backup.transport.TransportNotRegisteredException;
import com.android.server.testing.FrameworkRobolectricTestRunner;
import com.android.server.testing.SystemLoaderPackages;
import com.android.server.testing.shadows.ShadowAppBackupUtils;
import com.android.server.testing.shadows.ShadowBackupPolicyEnforcer;
import com.android.server.testing.shadows.ShadowPerformBackupTask;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -70,6 +71,9 @@ import org.robolectric.shadows.ShadowPackageManager;
import org.robolectric.shadows.ShadowSettings;
import org.robolectric.shadows.ShadowSystemClock;

import java.io.File;
import java.util.List;

@RunWith(FrameworkRobolectricTestRunner.class)
@Config(
    manifest = Config.NONE,
@@ -80,6 +84,8 @@ import org.robolectric.shadows.ShadowSystemClock;
@Presubmit
public class BackupManagerServiceTest {
    private static final String TAG = "BMSTest";
    private static final String PACKAGE_1 = "some.package.1";
    private static final String PACKAGE_2 = "some.package.2";

    @Mock private TransportManager mTransportManager;
    private HandlerThread mBackupThread;
@@ -90,6 +96,7 @@ public class BackupManagerServiceTest {
    private Context mContext;
    private TransportData mTransport;
    private String mTransportName;
    private ShadowPackageManager mShadowPackageManager;

    @Before
    public void setUp() throws Exception {
@@ -102,6 +109,7 @@ public class BackupManagerServiceTest {
        mShadowBackupLooper = shadowOf(mBackupThread.getLooper());

        ContextWrapper context = RuntimeEnvironment.application;
        mShadowPackageManager = shadowOf(context.getPackageManager());
        mContext = context;
        mShadowContext = shadowOf(context);

@@ -167,57 +175,54 @@ public class BackupManagerServiceTest {
    /* Tests for app eligibility */

    @Test
    public void testIsAppEligibleForBackup_whenAppEligible() throws Exception {
    public void testIsAppEligibleForBackup_whenAppNotEligible() throws Exception {
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        TransportMock transportMock = setUpCurrentTransport(mTransportManager, backupTransport());
        ShadowAppBackupUtils.sAppIsRunningAndEligibleForBackupWithTransport = p -> true;
        setUpCurrentTransport(mTransportManager, mTransport);
        BackupManagerService backupManagerService = createInitializedBackupManagerService();

        boolean result = backupManagerService.isAppEligibleForBackup("app.package");

        assertThat(result).isTrue();
        boolean result = backupManagerService.isAppEligibleForBackup(PACKAGE_1);

        verify(mTransportManager)
                .disposeOfTransportClient(eq(transportMock.transportClient), any());
        assertThat(result).isFalse();
    }

    @Test
    public void testIsAppEligibleForBackup_whenAppNotEligible() throws Exception {
    public void testIsAppEligibleForBackup_whenAppEligible() throws Exception {
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        setUpCurrentTransport(mTransportManager, mTransport);
        ShadowAppBackupUtils.sAppIsRunningAndEligibleForBackupWithTransport = p -> false;
        TransportMock transportMock = setUpCurrentTransport(mTransportManager, backupTransport());
        ShadowAppBackupUtils.setAppRunningAndEligibleForBackupWithTransport(PACKAGE_1);
        BackupManagerService backupManagerService = createInitializedBackupManagerService();

        boolean result = backupManagerService.isAppEligibleForBackup("app.package");
        boolean result = backupManagerService.isAppEligibleForBackup(PACKAGE_1);

        assertThat(result).isFalse();
        assertThat(result).isTrue();
        verify(mTransportManager)
                .disposeOfTransportClient(eq(transportMock.transportClient), any());
    }

    @Test
    public void testIsAppEligibleForBackup_withoutPermission() throws Exception {
        mShadowContext.denyPermissions(android.Manifest.permission.BACKUP);
        setUpCurrentTransport(mTransportManager, mTransport);
        ShadowAppBackupUtils.setAppRunningAndEligibleForBackupWithTransport(PACKAGE_1);
        BackupManagerService backupManagerService = createInitializedBackupManagerService();

        expectThrows(
                SecurityException.class,
                () -> backupManagerService.isAppEligibleForBackup("app.package"));
                () -> backupManagerService.isAppEligibleForBackup(PACKAGE_1));
    }

    @Test
    public void testFilterAppsEligibleForBackup() throws Exception {
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        TransportMock transportMock = setUpCurrentTransport(mTransportManager, mTransport);
        Map<String, Boolean> packagesMap = new HashMap<>();
        packagesMap.put("package.a", true);
        packagesMap.put("package.b", false);
        ShadowAppBackupUtils.sAppIsRunningAndEligibleForBackupWithTransport = packagesMap::get;
        ShadowAppBackupUtils.setAppRunningAndEligibleForBackupWithTransport(PACKAGE_1);
        BackupManagerService backupManagerService = createInitializedBackupManagerService();
        String[] packages = packagesMap.keySet().toArray(new String[packagesMap.size()]);

        String[] filtered = backupManagerService.filterAppsEligibleForBackup(packages);
        String[] filtered =
                backupManagerService.filterAppsEligibleForBackup(
                        new String[] {PACKAGE_1, PACKAGE_2});

        assertThat(filtered).asList().containsExactly("package.a");
        assertThat(filtered).asList().containsExactly(PACKAGE_1);
        verify(mTransportManager)
                .disposeOfTransportClient(eq(transportMock.transportClient), any());
    }
@@ -225,12 +230,11 @@ public class BackupManagerServiceTest {
    @Test
    public void testFilterAppsEligibleForBackup_whenNoneIsEligible() throws Exception {
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        ShadowAppBackupUtils.sAppIsRunningAndEligibleForBackupWithTransport = p -> false;
        BackupManagerService backupManagerService = createInitializedBackupManagerService();

        String[] filtered =
                backupManagerService.filterAppsEligibleForBackup(
                        new String[] {"package.a", "package.b"});
                        new String[] {PACKAGE_1, PACKAGE_2});

        assertThat(filtered).isEmpty();
    }
@@ -245,7 +249,7 @@ public class BackupManagerServiceTest {
                SecurityException.class,
                () ->
                        backupManagerService.filterAppsEligibleForBackup(
                                new String[] {"package.a", "package.b"}));
                                new String[] {PACKAGE_1, PACKAGE_2}));
    }

    /* Tests for select transport */
@@ -608,6 +612,153 @@ public class BackupManagerServiceTest {
                                "dataManagementLabel"));
    }

    /* Tests for request backup */

    @Mock private IBackupObserver mObserver;

    private void setUpForRequestBackup(String... packages) throws Exception {
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        for (String packageName : packages) {
            mShadowPackageManager.addPackage(packageName);
            ShadowAppBackupUtils.setAppRunningAndEligibleForBackupWithTransport(packageName);
        }
        setUpCurrentTransport(mTransportManager, mTransport);
    }

    private void tearDownForRequestBackup() {
        ShadowPerformBackupTask.reset();
    }

    @Test
    public void testRequestBackup_whenPermissionDenied() throws Exception {
        mShadowContext.denyPermissions(android.Manifest.permission.BACKUP);
        BackupManagerService backupManagerService = createInitializedBackupManagerService();

        expectThrows(
                SecurityException.class,
                () -> backupManagerService.requestBackup(new String[] {PACKAGE_1}, mObserver, 0));
    }

    @Test
    public void testRequestBackup_whenPackagesNull() throws Exception {
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        BackupManagerService backupManagerService = createInitializedBackupManagerService();

        expectThrows(
                IllegalArgumentException.class,
                () -> backupManagerService.requestBackup(null, mObserver, 0));
        verify(mObserver).backupFinished(BackupManager.ERROR_TRANSPORT_ABORTED);
    }

    @Test
    public void testRequestBackup_whenPackagesEmpty() throws Exception {
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        BackupManagerService backupManagerService = createInitializedBackupManagerService();

        expectThrows(
                IllegalArgumentException.class,
                () -> backupManagerService.requestBackup(new String[0], mObserver, 0));
        verify(mObserver).backupFinished(BackupManager.ERROR_TRANSPORT_ABORTED);
    }

    @Test
    public void testRequestBackup_whenBackupDisabled() throws Exception {
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        BackupManagerService backupManagerService = createInitializedBackupManagerService();
        backupManagerService.setEnabled(false);

        int result = backupManagerService.requestBackup(new String[] {PACKAGE_1}, mObserver, 0);

        assertThat(result).isEqualTo(BackupManager.ERROR_BACKUP_NOT_ALLOWED);
        verify(mObserver).backupFinished(BackupManager.ERROR_BACKUP_NOT_ALLOWED);
    }

    @Test
    public void testRequestBackup_whenNotProvisioned() throws Exception {
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        BackupManagerService backupManagerService = createInitializedBackupManagerService();
        backupManagerService.setProvisioned(false);

        int result = backupManagerService.requestBackup(new String[] {PACKAGE_1}, mObserver, 0);

        assertThat(result).isEqualTo(BackupManager.ERROR_BACKUP_NOT_ALLOWED);
        verify(mObserver).backupFinished(BackupManager.ERROR_BACKUP_NOT_ALLOWED);
    }

    @Test
    public void testRequestBackup_whenTransportNotRegistered() throws Exception {
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        setUpCurrentTransport(mTransportManager, mTransport.unregistered());
        BackupManagerService backupManagerService = createInitializedBackupManagerService();
        backupManagerService.setEnabled(true);
        backupManagerService.setProvisioned(true);

        int result = backupManagerService.requestBackup(new String[] {PACKAGE_1}, mObserver, 0);

        assertThat(result).isEqualTo(BackupManager.ERROR_TRANSPORT_ABORTED);
        verify(mObserver).backupFinished(BackupManager.ERROR_TRANSPORT_ABORTED);
    }

    @Test
    public void testRequestBackup_whenAppNotEligibleForBackup() throws Exception {
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        mShadowPackageManager.addPackage(PACKAGE_1);
        setUpCurrentTransport(mTransportManager, mTransport);
        BackupManagerService backupManagerService = createInitializedBackupManagerService();
        backupManagerService.setEnabled(true);
        backupManagerService.setProvisioned(true);
        // Haven't set PACKAGE_1 as eligible

        int result = backupManagerService.requestBackup(new String[] {PACKAGE_1}, mObserver, 0);

        assertThat(result).isEqualTo(BackupManager.SUCCESS);
        verify(mObserver).onResult(PACKAGE_1, BackupManager.ERROR_BACKUP_NOT_ALLOWED);
        // TODO: We probably don't need to kick-off PerformBackupTask when list is empty
        tearDownForRequestBackup();
    }

    @Test
    @Config(shadows = ShadowPerformBackupTask.class)
    public void testRequestBackup_whenPackageIsKeyValue() throws Exception {
        setUpForRequestBackup(PACKAGE_1);
        BackupManagerService backupManagerService = createBackupManagerServiceForRequestBackup();

        int result = backupManagerService.requestBackup(new String[] {PACKAGE_1}, mObserver, 0);

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(result).isEqualTo(BackupManager.SUCCESS);
        ShadowPerformBackupTask shadowTask = ShadowPerformBackupTask.getLastCreated();
        assertThat(shadowTask.getQueue()).containsExactly(new BackupRequest(PACKAGE_1));
        assertThat(shadowTask.getPendingFullBackups()).isEmpty();
        // TODO: Assert more about PerformBackupTask
        tearDownForRequestBackup();
    }

    @Test
    @Config(shadows = ShadowPerformBackupTask.class)
    public void testRequestBackup_whenPackageIsFullBackup() throws Exception {
        setUpForRequestBackup(PACKAGE_1);
        ShadowAppBackupUtils.setAppGetsFullBackup(PACKAGE_1);
        BackupManagerService backupManagerService = createBackupManagerServiceForRequestBackup();

        int result = backupManagerService.requestBackup(new String[] {PACKAGE_1}, mObserver, 0);

        mShadowBackupLooper.runToEndOfTasks();
        assertThat(result).isEqualTo(BackupManager.SUCCESS);
        ShadowPerformBackupTask shadowTask = ShadowPerformBackupTask.getLastCreated();
        assertThat(shadowTask.getQueue()).isEmpty();
        assertThat(shadowTask.getPendingFullBackups()).containsExactly(PACKAGE_1);
        // TODO: Assert more about PerformBackupTask
        tearDownForRequestBackup();
    }

    private BackupManagerService createBackupManagerServiceForRequestBackup() {
        BackupManagerService backupManagerService = createInitializedBackupManagerService();
        backupManagerService.setEnabled(true);
        backupManagerService.setProvisioned(true);
        return backupManagerService;
    }

    /* Miscellaneous tests */

    @Test
+13 −2
Original line number Diff line number Diff line
@@ -79,10 +79,21 @@ public class TransportTestUtils {
    /** {@code transportName} has to be in the {@link ComponentName} format (with '/') */
    public static TransportMock setUpCurrentTransport(
            TransportManager transportManager, TransportData transport) throws Exception {
        TransportMock transportMock = setUpTransports(transportManager, transport).get(0);
        if (transportMock.transportClient != null) {
        TransportMock transportMock = setUpTransport(transportManager, transport);
        int status = transport.transportStatus;
        when(transportManager.getCurrentTransportName()).thenReturn(transport.transportName);
        if (status == TransportStatus.REGISTERED_AVAILABLE
                || status == TransportStatus.REGISTERED_UNAVAILABLE) {
            // Transport registered
            when(transportManager.getCurrentTransportClient(any()))
                    .thenReturn(transportMock.transportClient);
            when(transportManager.getCurrentTransportClientOrThrow(any()))
                    .thenReturn(transportMock.transportClient);
        } else {
            // Transport not registered
            when(transportManager.getCurrentTransportClient(any())).thenReturn(null);
            when(transportManager.getCurrentTransportClientOrThrow(any()))
                    .thenThrow(TransportNotRegisteredException.class);
        }
        return transportMock;
    }
+35 −6
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package com.android.server.testing.shadows;

import android.annotation.Nullable;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;

import com.android.server.backup.transport.TransportClient;
@@ -25,22 +27,49 @@ import com.android.server.backup.utils.AppBackupUtils;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;

import java.util.function.Function;
import java.util.HashSet;
import java.util.Set;

@Implements(AppBackupUtils.class)
public class ShadowAppBackupUtils {
    public static Function<String, Boolean> sAppIsRunningAndEligibleForBackupWithTransport;
    static {
        reset();
    private static final Set<String> sAppsRunningAndEligibleForBackupWithTransport =
            new HashSet<>();
    private static final Set<String> sAppsEligibleForBackup = new HashSet<>();
    private static final Set<String> sAppsGetFullBackup = new HashSet<>();

    public static void setAppRunningAndEligibleForBackupWithTransport(String packageName) {
        sAppsEligibleForBackup.add(packageName);
        sAppsRunningAndEligibleForBackupWithTransport.add(packageName);
    }

    public static void setAppEligibleForBackup(String packageName) {
        sAppsEligibleForBackup.add(packageName);
    }

    /** By default the app will be key-value. */
    public static void setAppGetsFullBackup(String packageName) {
        sAppsGetFullBackup.add(packageName);
    }

    @Implementation
    public static boolean appIsRunningAndEligibleForBackupWithTransport(
            @Nullable TransportClient transportClient, String packageName, PackageManager pm) {
        return sAppIsRunningAndEligibleForBackupWithTransport.apply(packageName);
        return sAppsRunningAndEligibleForBackupWithTransport.contains(packageName);
    }

    @Implementation
    public static boolean appIsEligibleForBackup(ApplicationInfo app, PackageManager pm) {
        return sAppsEligibleForBackup.contains(app.packageName);
    }

    @Implementation
    public static boolean appGetsFullBackup(PackageInfo packageInfo) {
        return sAppsGetFullBackup.contains(packageInfo.packageName);
    }

    public static void reset() {
        sAppIsRunningAndEligibleForBackupWithTransport = p -> true;
        sAppsRunningAndEligibleForBackupWithTransport.clear();
        sAppsEligibleForBackup.clear();
        sAppsGetFullBackup.clear();
    }
}
Loading