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

Commit 19e12275 authored by Artem Iglikov's avatar Artem Iglikov
Browse files

Add more tests for TransportManager.

Bug: 37616038
Test: make RunFrameworksServicesRoboTests
Change-Id: I1120c181ffc898202e558f0dc73a6f1d2c10330f
parent a1f7fb9b
Loading
Loading
Loading
Loading
+349 −42
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.server.backup;

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

import static org.mockito.Mockito.mock;

import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -30,13 +32,13 @@ import android.platform.test.annotations.Presubmit;
import com.android.server.backup.testing.BackupTransportStub;
import com.android.server.backup.testing.DefaultPackageManagerWithQueryIntentServicesAsUser;
import com.android.server.backup.testing.ShadowBackupTransportStub;
import com.android.server.backup.testing.ShadowContextImplWithBindServiceAsUser;
import com.android.server.backup.testing.ShadowContextImplForBackup;
import com.android.server.backup.testing.TransportBoundListenerStub;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
@@ -56,31 +58,20 @@ import java.util.List;
        manifest = Config.NONE,
        sdk = 23,
        shadows = {
                ShadowContextImplWithBindServiceAsUser.class,
                ShadowContextImplForBackup.class,
                ShadowBackupTransportStub.class
        }
)
@Presubmit
public class TransportManagerTest {
    private static final String PACKAGE_NAME = "some.package.name";
    private static final String TRANSPORT1_NAME = "transport1.name";
    private static final String TRANSPORT2_NAME = "transport2.name";
    private static final List<String> TRANSPORTS_NAMES = Arrays.asList(
            TRANSPORT1_NAME, TRANSPORT2_NAME);
    private static final ComponentName TRANSPORT1_COMPONENT_NAME = new ComponentName(PACKAGE_NAME,
            TRANSPORT1_NAME);
    private static final ComponentName TRANSPORT2_COMPONENT_NAME = new ComponentName(PACKAGE_NAME,
            TRANSPORT2_NAME);
    private static final List<ComponentName> TRANSPORTS_COMPONENT_NAMES = Arrays.asList(
            TRANSPORT1_COMPONENT_NAME, TRANSPORT2_COMPONENT_NAME);
    private static final String ANOTHER_PACKAGE_NAME = "another.package.name";

    private RobolectricPackageManager mPackageManager;
    private TransportInfo mTransport1;
    private TransportInfo mTransport2;

    @Mock private IBinder mTransport1BinderMock;
    @Mock private IBinder mTransport2BinderMock;
    private RobolectricPackageManager mPackageManager;

    private final BackupTransportStub mTransport1Stub = new BackupTransportStub(TRANSPORT1_NAME);
    private final BackupTransportStub mTransport2Stub = new BackupTransportStub(TRANSPORT2_NAME);
    private final TransportBoundListenerStub mTransportBoundListenerStub =
            new TransportBoundListenerStub(true);

@@ -93,38 +84,71 @@ public class TransportManagerTest {
                RuntimeEnvironment.getAppResourceLoader());
        RuntimeEnvironment.setRobolectricPackageManager(mPackageManager);

        ShadowContextImplWithBindServiceAsUser.sComponentBinderMap.put(TRANSPORT1_COMPONENT_NAME,
                mTransport1BinderMock);
        ShadowContextImplWithBindServiceAsUser.sComponentBinderMap.put(TRANSPORT2_COMPONENT_NAME,
                mTransport2BinderMock);
        ShadowBackupTransportStub.sBinderTransportMap.put(mTransport1BinderMock, mTransport1Stub);
        ShadowBackupTransportStub.sBinderTransportMap.put(mTransport2BinderMock, mTransport2Stub);
        mTransport1 = new TransportInfo(PACKAGE_NAME, "transport1.name");
        mTransport2 = new TransportInfo(PACKAGE_NAME, "transport2.name");

        ShadowContextImplForBackup.sComponentBinderMap.put(mTransport1.componentName,
                mTransport1.binder);
        ShadowContextImplForBackup.sComponentBinderMap.put(mTransport2.componentName,
                mTransport2.binder);
        ShadowBackupTransportStub.sBinderTransportMap.put(mTransport1.binder, mTransport1.stub);
        ShadowBackupTransportStub.sBinderTransportMap.put(mTransport2.binder, mTransport2.stub);
    }

    @After
    public void tearDown() throws Exception {
        ShadowContextImplForBackup.resetBackupShadowState();
    }

    @Test
    public void onPackageAdded_bindsToAllTransports() throws Exception {
        setUpPackageWithTransports(PACKAGE_NAME, TRANSPORTS_NAMES,
        setUpPackageWithTransports(PACKAGE_NAME, Arrays.asList(mTransport1, mTransport2),
                ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

        TransportManager transportManager = new TransportManager(
                RuntimeEnvironment.application.getApplicationContext(),
                new HashSet<>(Arrays.asList(
                        mTransport1.componentName, mTransport2.componentName)),
                null /* defaultTransport */,
                mTransportBoundListenerStub,
                ShadowLooper.getMainLooper());
        transportManager.onPackageAdded(PACKAGE_NAME);

        assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
                Arrays.asList(mTransport1.componentName, mTransport2.componentName));
        assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
                Arrays.asList(mTransport1.name, mTransport2.name));
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1.stub)).isTrue();
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2.stub)).isTrue();
    }

    @Test
    public void onPackageAdded_oneTransportUnavailable_bindsToOnlyOneTransport() throws Exception {
        setUpPackageWithTransports(PACKAGE_NAME, Arrays.asList(mTransport1, mTransport2),
                ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

        ShadowContextImplForBackup.sUnbindableComponents.add(mTransport1.componentName);

        TransportManager transportManager = new TransportManager(
                RuntimeEnvironment.application.getApplicationContext(),
                new HashSet<>(TRANSPORTS_COMPONENT_NAMES),
                new HashSet<>(Arrays.asList(
                        mTransport1.componentName, mTransport2.componentName)),
                null /* defaultTransport */,
                mTransportBoundListenerStub,
                ShadowLooper.getMainLooper());
        transportManager.onPackageAdded(PACKAGE_NAME);

        assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
                TRANSPORTS_COMPONENT_NAMES);
                Collections.singleton(mTransport2.componentName));
        assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
                TRANSPORTS_NAMES);
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1Stub)).isTrue();
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2Stub)).isTrue();
                Collections.singleton(mTransport2.name));
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1.stub)).isFalse();
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2.stub)).isTrue();
    }

    @Test
    public void onPackageAdded_whitelistIsNull_doesNotBindToTransports() throws Exception {
        setUpPackageWithTransports(PACKAGE_NAME, TRANSPORTS_NAMES,
        setUpPackageWithTransports(PACKAGE_NAME, Arrays.asList(mTransport1, mTransport2),
                ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

        TransportManager transportManager = new TransportManager(
@@ -143,32 +167,33 @@ public class TransportManagerTest {
    @Test
    public void onPackageAdded_onlyOneTransportWhitelisted_onlyConnectsToWhitelistedTransport()
            throws Exception {
        setUpPackageWithTransports(PACKAGE_NAME, TRANSPORTS_NAMES,
        setUpPackageWithTransports(PACKAGE_NAME, Arrays.asList(mTransport1, mTransport2),
                ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

        TransportManager transportManager = new TransportManager(
                RuntimeEnvironment.application.getApplicationContext(),
                new HashSet<>(Collections.singleton(TRANSPORT2_COMPONENT_NAME)),
                new HashSet<>(Collections.singleton(mTransport2.componentName)),
                null /* defaultTransport */,
                mTransportBoundListenerStub,
                ShadowLooper.getMainLooper());
        transportManager.onPackageAdded(PACKAGE_NAME);

        assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
                Collections.singleton(TRANSPORT2_COMPONENT_NAME));
                Collections.singleton(mTransport2.componentName));
        assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
                Collections.singleton(TRANSPORT2_NAME));
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1Stub)).isFalse();
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2Stub)).isTrue();
                Collections.singleton(mTransport2.name));
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1.stub)).isFalse();
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2.stub)).isTrue();
    }

    @Test
    public void onPackageAdded_appIsNotPrivileged_doesNotBindToTransports() throws Exception {
        setUpPackageWithTransports(PACKAGE_NAME, TRANSPORTS_NAMES, 0);
        setUpPackageWithTransports(PACKAGE_NAME, Arrays.asList(mTransport1, mTransport2), 0);

        TransportManager transportManager = new TransportManager(
                RuntimeEnvironment.application.getApplicationContext(),
                new HashSet<>(TRANSPORTS_COMPONENT_NAMES),
                new HashSet<>(Arrays.asList(
                        mTransport1.componentName, mTransport2.componentName)),
                null /* defaultTransport */,
                mTransportBoundListenerStub,
                ShadowLooper.getMainLooper());
@@ -179,7 +204,220 @@ public class TransportManagerTest {
        assertThat(mTransportBoundListenerStub.isCalled()).isFalse();
    }

    private void setUpPackageWithTransports(String packageName, List<String> transportNames,
    @Test
    public void onPackageRemoved_transportsUnbound() throws Exception {
        TransportManager transportManager = createTransportManagerAndSetUpTransports(
                Arrays.asList(mTransport1, mTransport2), mTransport1.name);

        transportManager.onPackageRemoved(PACKAGE_NAME);

        assertThat(transportManager.getAllTransportComponents()).isEmpty();
        assertThat(transportManager.getBoundTransportNames()).isEmpty();
    }

    @Test
    public void onPackageRemoved_incorrectPackageName_nothingHappens() throws Exception {
        TransportManager transportManager = createTransportManagerAndSetUpTransports(
                Arrays.asList(mTransport1, mTransport2), mTransport1.name);

        transportManager.onPackageRemoved(ANOTHER_PACKAGE_NAME);

        assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
                Arrays.asList(mTransport1.componentName, mTransport2.componentName));
        assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
                Arrays.asList(mTransport1.name, mTransport2.name));
    }

    @Test
    public void onPackageChanged_oneComponentChanged_onlyOneTransportRebound() throws Exception {
        TransportManager transportManager = createTransportManagerAndSetUpTransports(
                Arrays.asList(mTransport1, mTransport2), mTransport1.name);

        transportManager.onPackageChanged(PACKAGE_NAME, new String[]{mTransport2.name});

        assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
                Arrays.asList(mTransport1.componentName, mTransport2.componentName));
        assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
                Arrays.asList(mTransport1.name, mTransport2.name));
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1.stub)).isFalse();
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2.stub)).isTrue();
    }

    @Test
    public void onPackageChanged_nothingChanged_noTransportsRebound() throws Exception {
        TransportManager transportManager = createTransportManagerAndSetUpTransports(
                Arrays.asList(mTransport1, mTransport2), mTransport1.name);

        transportManager.onPackageChanged(PACKAGE_NAME, new String[0]);

        assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
                Arrays.asList(mTransport1.componentName, mTransport2.componentName));
        assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
                Arrays.asList(mTransport1.name, mTransport2.name));
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1.stub)).isFalse();
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2.stub)).isFalse();
    }

    @Test
    public void onPackageChanged_unexpectedComponentChanged_noTransportsRebound() throws Exception {
        TransportManager transportManager = createTransportManagerAndSetUpTransports(
                Arrays.asList(mTransport1, mTransport2), mTransport1.name);

        transportManager.onPackageChanged(PACKAGE_NAME, new String[]{"unexpected.component"});

        assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
                Arrays.asList(mTransport1.componentName, mTransport2.componentName));
        assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
                Arrays.asList(mTransport1.name, mTransport2.name));
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1.stub)).isFalse();
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2.stub)).isFalse();
    }

    @Test
    public void onPackageChanged_transportsRebound() throws Exception {
        TransportManager transportManager = createTransportManagerAndSetUpTransports(
                Arrays.asList(mTransport1, mTransport2), mTransport1.name);

        transportManager.onPackageChanged(PACKAGE_NAME, new String[]{mTransport2.name});

        assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
                Arrays.asList(mTransport1.componentName, mTransport2.componentName));
        assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
                Arrays.asList(mTransport1.name, mTransport2.name));
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport1.stub)).isFalse();
        assertThat(mTransportBoundListenerStub.isCalledForTransport(mTransport2.stub)).isTrue();
    }

    @Test
    public void getTransportBinder_returnsCorrectBinder() throws Exception {
        TransportManager transportManager = createTransportManagerAndSetUpTransports(
                Arrays.asList(mTransport1, mTransport2), mTransport1.name);

        assertThat(transportManager.getTransportBinder(mTransport1.name)).isEqualTo(
                mTransport1.stub);
        assertThat(transportManager.getTransportBinder(mTransport2.name)).isEqualTo(
                mTransport2.stub);
    }

    @Test
    public void getTransportBinder_incorrectTransportName_returnsNull() throws Exception {
        TransportManager transportManager = createTransportManagerAndSetUpTransports(
                Arrays.asList(mTransport1, mTransport2), mTransport1.name);

        assertThat(transportManager.getTransportBinder("incorrect.transport")).isNull();
    }

    @Test
    public void getTransportBinder_oneTransportUnavailable_returnsCorrectBinder() throws Exception {
        TransportManager transportManager =
                createTransportManagerAndSetUpTransports(Collections.singletonList(mTransport2),
                        Collections.singletonList(mTransport1), mTransport1.name);

        assertThat(transportManager.getTransportBinder(mTransport1.name)).isNull();
        assertThat(transportManager.getTransportBinder(mTransport2.name)).isEqualTo(
                mTransport2.stub);
    }

    @Test
    public void getCurrentTransport_selectTransportNotCalled_returnsDefaultTransport()
            throws Exception {
        TransportManager transportManager = createTransportManagerAndSetUpTransports(
                Arrays.asList(mTransport1, mTransport2), mTransport1.name);

        assertThat(transportManager.getCurrentTransportName()).isEqualTo(mTransport1.name);
    }

    @Test
    public void getCurrentTransport_selectTransportCalled_returnsCorrectTransport()
            throws Exception {
        TransportManager transportManager = createTransportManagerAndSetUpTransports(
                Arrays.asList(mTransport1, mTransport2), mTransport1.name);

        assertThat(transportManager.getCurrentTransportName()).isEqualTo(mTransport1.name);

        transportManager.selectTransport(mTransport2.name);

        assertThat(transportManager.getCurrentTransportName()).isEqualTo(mTransport2.name);
    }

    @Test
    public void getCurrentTransportBinder_returnsCorrectBinder() throws Exception {
        TransportManager transportManager = createTransportManagerAndSetUpTransports(
                Arrays.asList(mTransport1, mTransport2), mTransport1.name);

        assertThat(transportManager.getCurrentTransportBinder()).isEqualTo(mTransport1.stub);
    }

    @Test
    public void getCurrentTransportBinder_transportNotBound_returnsNull() throws Exception {
        TransportManager transportManager =
                createTransportManagerAndSetUpTransports(Collections.singletonList(mTransport2),
                        Collections.singletonList(mTransport1), mTransport2.name);

        transportManager.selectTransport(mTransport1.name);

        assertThat(transportManager.getCurrentTransportBinder()).isNull();
    }

    @Test
    public void getTransportName_returnsCorrectTransportName() throws Exception {
        TransportManager transportManager = createTransportManagerAndSetUpTransports(
                Arrays.asList(mTransport1, mTransport2), mTransport1.name);

        assertThat(transportManager.getTransportName(mTransport1.stub)).isEqualTo(mTransport1.name);
        assertThat(transportManager.getTransportName(mTransport2.stub)).isEqualTo(mTransport2.name);
    }

    @Test
    public void getTransportName_transportNotBound_returnsNull() throws Exception {
        TransportManager transportManager =
                createTransportManagerAndSetUpTransports(Collections.singletonList(mTransport2),
                        Collections.singletonList(mTransport1), mTransport1.name);

        assertThat(transportManager.getTransportName(mTransport1.stub)).isNull();
        assertThat(transportManager.getTransportName(mTransport2.stub)).isEqualTo(mTransport2.name);
    }

    @Test
    public void getTransportWhitelist_returnsCorrectWhiteList() throws Exception {
        TransportManager transportManager = new TransportManager(
                RuntimeEnvironment.application.getApplicationContext(),
                new HashSet<>(Arrays.asList(mTransport1.componentName, mTransport2.componentName)),
                mTransport1.name,
                mTransportBoundListenerStub,
                ShadowLooper.getMainLooper());

        assertThat(transportManager.getTransportWhitelist()).containsExactlyElementsIn(
                Arrays.asList(mTransport1.componentName, mTransport2.componentName));
    }

    @Test
    public void getTransportWhitelist_whiteListIsNull_returnsEmptyArray() throws Exception {
        TransportManager transportManager = new TransportManager(
                RuntimeEnvironment.application.getApplicationContext(),
                null /* whitelist */,
                mTransport1.name,
                mTransportBoundListenerStub,
                ShadowLooper.getMainLooper());

        assertThat(transportManager.getTransportWhitelist()).isEmpty();
    }

    @Test
    public void selectTransport_setsTransportCorrectlyAndReturnsPreviousTransport()
            throws Exception {
        TransportManager transportManager = new TransportManager(
                RuntimeEnvironment.application.getApplicationContext(),
                null /* whitelist */,
                mTransport1.name,
                mTransportBoundListenerStub,
                ShadowLooper.getMainLooper());

        assertThat(transportManager.selectTransport(mTransport2.name)).isEqualTo(mTransport1.name);
        assertThat(transportManager.selectTransport(mTransport1.name)).isEqualTo(mTransport2.name);
    }

    private void setUpPackageWithTransports(String packageName, List<TransportInfo> transports,
            int flags) throws Exception {
        PackageInfo packageInfo = new PackageInfo();
        packageInfo.packageName = packageName;
@@ -189,11 +427,11 @@ public class TransportManagerTest {
        mPackageManager.addPackage(packageInfo);

        List<ResolveInfo> transportsInfo = new ArrayList<>();
        for (String transportName : transportNames) {
        for (TransportInfo transport : transports) {
            ResolveInfo info = new ResolveInfo();
            info.serviceInfo = new ServiceInfo();
            info.serviceInfo.packageName = packageName;
            info.serviceInfo.name = transportName;
            info.serviceInfo.name = transport.name;
            transportsInfo.add(info);
        }

@@ -203,4 +441,73 @@ public class TransportManagerTest {
        mPackageManager.addResolveInfoForIntent(intent, transportsInfo);
    }

    private TransportManager createTransportManagerAndSetUpTransports(
            List<TransportInfo> availableTransports, String defaultTransportName) throws Exception {
        return createTransportManagerAndSetUpTransports(availableTransports,
                Collections.<TransportInfo>emptyList(), defaultTransportName);
    }

    private TransportManager createTransportManagerAndSetUpTransports(
            List<TransportInfo> availableTransports, List<TransportInfo> unavailableTransports,
            String defaultTransportName)
            throws Exception {
        List<String> availableTransportsNames = new ArrayList<>();
        List<ComponentName> availableTransportsComponentNames = new ArrayList<>();
        for (TransportInfo transport : availableTransports) {
            availableTransportsNames.add(transport.name);
            availableTransportsComponentNames.add(transport.componentName);
        }

        List<ComponentName> allTransportsComponentNames = new ArrayList<>();
        allTransportsComponentNames.addAll(availableTransportsComponentNames);
        for (TransportInfo transport : unavailableTransports) {
            allTransportsComponentNames.add(transport.componentName);
        }

        for (TransportInfo transport : unavailableTransports) {
            ShadowContextImplForBackup.sUnbindableComponents.add(transport.componentName);
        }

        setUpPackageWithTransports(PACKAGE_NAME, Arrays.asList(mTransport1, mTransport2),
                ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);

        TransportManager transportManager = new TransportManager(
                RuntimeEnvironment.application.getApplicationContext(),
                new HashSet<>(allTransportsComponentNames),
                defaultTransportName,
                mTransportBoundListenerStub,
                ShadowLooper.getMainLooper());
        transportManager.onPackageAdded(PACKAGE_NAME);

        assertThat(transportManager.getAllTransportComponents()).asList().containsExactlyElementsIn(
                availableTransportsComponentNames);
        assertThat(transportManager.getBoundTransportNames()).asList().containsExactlyElementsIn(
                availableTransportsNames);
        for (TransportInfo transport : availableTransports) {
            assertThat(mTransportBoundListenerStub.isCalledForTransport(transport.stub)).isTrue();
        }
        for (TransportInfo transport : unavailableTransports) {
            assertThat(mTransportBoundListenerStub.isCalledForTransport(transport.stub)).isFalse();
        }

        mTransportBoundListenerStub.resetState();

        return transportManager;
    }

    private static class TransportInfo {
        public final String packageName;
        public final String name;
        public final ComponentName componentName;
        public final BackupTransportStub stub;
        public final IBinder binder;

        TransportInfo(String packageName, String name) {
            this.packageName = packageName;
            this.name = name;
            this.componentName = new ComponentName(packageName, name);
            this.stub = new BackupTransportStub(name);
            this.binder = mock(IBinder.class);
        }
    }
}
+17 −1

File changed and moved.

Preview size limit exceeded, changes collapsed.

+13 −0

File changed.

Preview size limit exceeded, changes collapsed.