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 Original line Diff line number Diff line
@@ -177,7 +177,7 @@ public class TransportManager {
    }
    }


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


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


package com.android.server.backup.internal;
package com.android.server.backup.internal;


import java.util.Objects;

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

    public String packageName;
    public String packageName;


    public BackupRequest(String pkgName) {
    public BackupRequest(String pkgName) {
@@ -30,4 +31,21 @@ public class BackupRequest {
    public String toString() {
    public String toString() {
        return "BackupRequest{pkg=" + packageName + "}";
        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 Original line 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.TransportData.localTransport;
import static com.android.server.backup.testing.TransportTestUtils.setUpCurrentTransport;
import static com.android.server.backup.testing.TransportTestUtils.setUpCurrentTransport;
import static com.android.server.backup.testing.TransportTestUtils.setUpTransports;
import static com.android.server.backup.testing.TransportTestUtils.setUpTransports;

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

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


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


import com.android.server.testing.shadows.ShadowAppBackupUtils;
import com.android.server.backup.internal.BackupRequest;
import com.android.server.testing.shadows.ShadowBackupPolicyEnforcer;
import com.android.server.backup.testing.TransportData;
import com.android.server.backup.testing.TransportData;
import com.android.server.backup.testing.TransportTestUtils.TransportMock;
import com.android.server.backup.testing.TransportTestUtils.TransportMock;
import com.android.server.backup.transport.TransportNotRegisteredException;
import com.android.server.backup.transport.TransportNotRegisteredException;
import com.android.server.testing.FrameworkRobolectricTestRunner;
import com.android.server.testing.FrameworkRobolectricTestRunner;
import com.android.server.testing.SystemLoaderPackages;
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.After;
import org.junit.Before;
import org.junit.Before;
import org.junit.Test;
import org.junit.Test;
@@ -70,6 +71,9 @@ import org.robolectric.shadows.ShadowPackageManager;
import org.robolectric.shadows.ShadowSettings;
import org.robolectric.shadows.ShadowSettings;
import org.robolectric.shadows.ShadowSystemClock;
import org.robolectric.shadows.ShadowSystemClock;


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

@RunWith(FrameworkRobolectricTestRunner.class)
@RunWith(FrameworkRobolectricTestRunner.class)
@Config(
@Config(
    manifest = Config.NONE,
    manifest = Config.NONE,
@@ -80,6 +84,8 @@ import org.robolectric.shadows.ShadowSystemClock;
@Presubmit
@Presubmit
public class BackupManagerServiceTest {
public class BackupManagerServiceTest {
    private static final String TAG = "BMSTest";
    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;
    @Mock private TransportManager mTransportManager;
    private HandlerThread mBackupThread;
    private HandlerThread mBackupThread;
@@ -90,6 +96,7 @@ public class BackupManagerServiceTest {
    private Context mContext;
    private Context mContext;
    private TransportData mTransport;
    private TransportData mTransport;
    private String mTransportName;
    private String mTransportName;
    private ShadowPackageManager mShadowPackageManager;


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


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


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


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


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

        assertThat(result).isTrue();


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


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


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


    @Test
    @Test
    public void testFilterAppsEligibleForBackup() throws Exception {
    public void testFilterAppsEligibleForBackup() throws Exception {
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        TransportMock transportMock = setUpCurrentTransport(mTransportManager, mTransport);
        TransportMock transportMock = setUpCurrentTransport(mTransportManager, mTransport);
        Map<String, Boolean> packagesMap = new HashMap<>();
        ShadowAppBackupUtils.setAppRunningAndEligibleForBackupWithTransport(PACKAGE_1);
        packagesMap.put("package.a", true);
        packagesMap.put("package.b", false);
        ShadowAppBackupUtils.sAppIsRunningAndEligibleForBackupWithTransport = packagesMap::get;
        BackupManagerService backupManagerService = createInitializedBackupManagerService();
        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)
        verify(mTransportManager)
                .disposeOfTransportClient(eq(transportMock.transportClient), any());
                .disposeOfTransportClient(eq(transportMock.transportClient), any());
    }
    }
@@ -225,12 +230,11 @@ public class BackupManagerServiceTest {
    @Test
    @Test
    public void testFilterAppsEligibleForBackup_whenNoneIsEligible() throws Exception {
    public void testFilterAppsEligibleForBackup_whenNoneIsEligible() throws Exception {
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        mShadowContext.grantPermissions(android.Manifest.permission.BACKUP);
        ShadowAppBackupUtils.sAppIsRunningAndEligibleForBackupWithTransport = p -> false;
        BackupManagerService backupManagerService = createInitializedBackupManagerService();
        BackupManagerService backupManagerService = createInitializedBackupManagerService();


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


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


    /* Tests for select transport */
    /* Tests for select transport */
@@ -608,6 +612,153 @@ public class BackupManagerServiceTest {
                                "dataManagementLabel"));
                                "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 */
    /* Miscellaneous tests */


    @Test
    @Test
+13 −2
Original line number Original line Diff line number Diff line
@@ -79,10 +79,21 @@ public class TransportTestUtils {
    /** {@code transportName} has to be in the {@link ComponentName} format (with '/') */
    /** {@code transportName} has to be in the {@link ComponentName} format (with '/') */
    public static TransportMock setUpCurrentTransport(
    public static TransportMock setUpCurrentTransport(
            TransportManager transportManager, TransportData transport) throws Exception {
            TransportManager transportManager, TransportData transport) throws Exception {
        TransportMock transportMock = setUpTransports(transportManager, transport).get(0);
        TransportMock transportMock = setUpTransport(transportManager, transport);
        if (transportMock.transportClient != null) {
        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()))
            when(transportManager.getCurrentTransportClient(any()))
                    .thenReturn(transportMock.transportClient);
                    .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;
        return transportMock;
    }
    }
+35 −6
Original line number Original line Diff line number Diff line
@@ -17,6 +17,8 @@
package com.android.server.testing.shadows;
package com.android.server.testing.shadows;


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


import com.android.server.backup.transport.TransportClient;
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.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.Implements;


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


@Implements(AppBackupUtils.class)
@Implements(AppBackupUtils.class)
public class ShadowAppBackupUtils {
public class ShadowAppBackupUtils {
    public static Function<String, Boolean> sAppIsRunningAndEligibleForBackupWithTransport;
    private static final Set<String> sAppsRunningAndEligibleForBackupWithTransport =
    static {
            new HashSet<>();
        reset();
    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
    @Implementation
    public static boolean appIsRunningAndEligibleForBackupWithTransport(
    public static boolean appIsRunningAndEligibleForBackupWithTransport(
            @Nullable TransportClient transportClient, String packageName, PackageManager pm) {
            @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() {
    public static void reset() {
        sAppIsRunningAndEligibleForBackupWithTransport = p -> true;
        sAppsRunningAndEligibleForBackupWithTransport.clear();
        sAppsEligibleForBackup.clear();
        sAppsGetFullBackup.clear();
    }
    }
}
}
Loading