Home | History | Annotate | Download | only in task
      1 /*
      2  * Copyright 2016, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.managedprovisioning.task;
     18 
     19 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE;
     20 
     21 import static com.android.managedprovisioning.task.DownloadPackageTask.ERROR_DOWNLOAD_FAILED;
     22 import static com.android.managedprovisioning.task.DownloadPackageTask.ERROR_OTHER;
     23 
     24 import static org.junit.Assert.assertEquals;
     25 import static org.mockito.Matchers.any;
     26 import static org.mockito.Matchers.anyString;
     27 import static org.mockito.Mockito.doReturn;
     28 import static org.mockito.Matchers.nullable;
     29 import static org.mockito.Mockito.verify;
     30 import static org.mockito.Mockito.verifyNoMoreInteractions;
     31 import static org.mockito.Mockito.when;
     32 
     33 import android.app.DownloadManager;
     34 import android.app.DownloadManager.Query;
     35 import android.app.DownloadManager.Request;
     36 import android.content.BroadcastReceiver;
     37 import android.content.Context;
     38 import android.content.Intent;
     39 import android.content.IntentFilter;
     40 import android.database.MatrixCursor;
     41 import android.os.Handler;
     42 import android.os.Looper;
     43 import android.support.test.filters.FlakyTest;
     44 import android.support.test.filters.SmallTest;
     45 
     46 import com.android.managedprovisioning.common.Utils;
     47 import com.android.managedprovisioning.model.PackageDownloadInfo;
     48 import com.android.managedprovisioning.model.ProvisioningParams;
     49 
     50 import org.junit.Before;
     51 import org.junit.Test;
     52 import org.mockito.ArgumentCaptor;
     53 import org.mockito.Mock;
     54 import org.mockito.MockitoAnnotations;
     55 
     56 @SmallTest
     57 @FlakyTest // TODO: http://b/34117742
     58 public class DownloadPackageTaskTest {
     59     @Mock private Context mContext;
     60     @Mock private AbstractProvisioningTask.Callback mCallback;
     61     @Mock private DownloadManager mDownloadManager;
     62     @Mock private Utils mUtils;
     63 
     64     private static final String TEST_PACKAGE_NAME = "sample.package.name";
     65     private static final String TEST_PACKAGE_LOCATION = "http://www.some.uri.com";
     66     private static final String TEST_LOCAL_FILENAME = "/local/filename";
     67     private static final int TEST_USER_ID = 123;
     68     private static final byte[] TEST_SIGNATURE = new byte[] {'a', 'b', 'c', 'd'};
     69 
     70     private static final long TEST_DOWNLOAD_ID = 1234;
     71     private static final int PACKAGE_VERSION = 43;
     72     private static final PackageDownloadInfo TEST_DOWNLOAD_INFO = new PackageDownloadInfo.Builder()
     73             .setLocation(TEST_PACKAGE_LOCATION)
     74             .setSignatureChecksum(TEST_SIGNATURE)
     75             .setMinVersion(PACKAGE_VERSION)
     76             .build();
     77     private static final ProvisioningParams PARAMS = new ProvisioningParams.Builder()
     78             .setDeviceAdminPackageName(TEST_PACKAGE_NAME)
     79             .setProvisioningAction(ACTION_PROVISION_MANAGED_DEVICE)
     80             .setDeviceAdminDownloadInfo(TEST_DOWNLOAD_INFO)
     81             .build();
     82 
     83     private DownloadPackageTask mTask;
     84 
     85     @Before
     86     public void setUp() throws Exception {
     87         MockitoAnnotations.initMocks(this);
     88 
     89         when(mContext.getSystemService(Context.DOWNLOAD_SERVICE)).thenReturn(mDownloadManager);
     90         when(mUtils.packageRequiresUpdate(TEST_PACKAGE_NAME, PACKAGE_VERSION, mContext))
     91                 .thenReturn(true);
     92 
     93         mTask = new DownloadPackageTask(
     94                 mUtils,
     95                 mContext,
     96                 PARAMS,
     97                 mCallback);
     98     }
     99 
    100     @Test
    101     public void testAlreadyInstalled() throws Exception {
    102         // GIVEN the package is already installed, with the right version
    103         when(mUtils.packageRequiresUpdate(TEST_PACKAGE_NAME, PACKAGE_VERSION, mContext))
    104                 .thenReturn(false);
    105 
    106         // WHEN running the download package task
    107         runTask();
    108 
    109         // THEN we get a success callback directly
    110         verifyOnTaskFinished(null);
    111         verifyNoMoreInteractions(mCallback);
    112     }
    113 
    114     @Test
    115     public void testNotConnected() throws Exception {
    116         // GIVEN we're not connected to a network
    117         doReturn(false).when(mUtils).isConnectedToNetwork(mContext);
    118 
    119         // WHEN running the download package task
    120         runTask();
    121 
    122         // THEN we get an error callback
    123         verify(mCallback).onError(mTask, ERROR_OTHER);
    124         verifyNoMoreInteractions(mCallback);
    125     }
    126 
    127     @Test
    128     public void testDownloadFailed() throws Exception {
    129         // GIVEN the download succeeds
    130         mockSuccessfulDownload(DownloadManager.STATUS_FAILED);
    131 
    132         // WHEN running the download package task
    133         runTask();
    134 
    135         // THEN a download receiver was registered
    136         BroadcastReceiver receiver = verifyDownloadReceiver();
    137 
    138         // WHEN invoking download complete
    139         receiver.onReceive(mContext, new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    140 
    141         // THEN we get a success callback
    142         verify(mCallback).onError(mTask, ERROR_DOWNLOAD_FAILED);
    143         verifyNoMoreInteractions(mCallback);
    144     }
    145 
    146     @Test
    147     public void testDownloadSucceeded() throws Exception {
    148         // GIVEN the download succeeds
    149         mockSuccessfulDownload(DownloadManager.STATUS_SUCCESSFUL);
    150 
    151         // WHEN running the download package task
    152         runTask();
    153 
    154         // THEN a download receiver was registered
    155         BroadcastReceiver receiver = verifyDownloadReceiver();
    156 
    157         // WHEN invoking download complete
    158         receiver.onReceive(mContext, new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    159 
    160         // THEN we get a success callback
    161         verifyOnTaskFinished(TEST_LOCAL_FILENAME);
    162         verifyNoMoreInteractions(mCallback);
    163     }
    164 
    165     /** Test that it works fine even if DownloadManager sends the broadcast twice */
    166     @Test
    167     public void testSendBroadcastTwice() throws Exception {
    168         // GIVEN the download succeeds
    169         mockSuccessfulDownload(DownloadManager.STATUS_SUCCESSFUL);
    170 
    171         // WHEN running the download package task
    172         runTask();
    173 
    174         // THEN a download receiver was registered
    175         BroadcastReceiver receiver = verifyDownloadReceiver();
    176 
    177         // WHEN invoking download complete twice
    178         receiver.onReceive(mContext, new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    179         receiver.onReceive(mContext, new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    180 
    181         // THEN we still get only one success callback
    182         verifyOnTaskFinished(TEST_LOCAL_FILENAME);
    183         verifyNoMoreInteractions(mCallback);
    184     }
    185 
    186     private void mockSuccessfulDownload(int downloadStatus) {
    187         doReturn(true).when(mUtils).isConnectedToNetwork(any(Context.class));
    188         when(mDownloadManager.enqueue(any(Request.class))).thenReturn(TEST_DOWNLOAD_ID);
    189         MatrixCursor cursor = new MatrixCursor(new String[]{
    190                 DownloadManager.COLUMN_STATUS,
    191                 DownloadManager.COLUMN_LOCAL_FILENAME});
    192         cursor.addRow(new Object[]{downloadStatus, TEST_LOCAL_FILENAME});
    193         when(mDownloadManager.query(any(Query.class))).thenReturn(cursor);
    194     }
    195 
    196     private BroadcastReceiver verifyDownloadReceiver() {
    197         verify(mDownloadManager).setAccessFilename(true);
    198         ArgumentCaptor<BroadcastReceiver> receiverCaptor = ArgumentCaptor.forClass(
    199                 BroadcastReceiver.class);
    200         ArgumentCaptor<IntentFilter> filterCaptor = ArgumentCaptor.forClass(
    201                 IntentFilter.class);
    202         verify(mContext).registerReceiver(
    203                 receiverCaptor.capture(),
    204                 filterCaptor.capture(),
    205                 nullable(String.class),
    206                 any(Handler.class));
    207         assertEquals(filterCaptor.getValue().getAction(0),
    208                 DownloadManager.ACTION_DOWNLOAD_COMPLETE);
    209         return receiverCaptor.getValue();
    210     }
    211 
    212     private void verifyOnTaskFinished(String location) {
    213         verify(mCallback).onSuccess(mTask);
    214         assertEquals(location, mTask.getDownloadedPackageLocation());
    215     }
    216 
    217     private void runTask() {
    218         if (Looper.myLooper() == null) {
    219             Looper.prepare();
    220         }
    221         mTask.run(TEST_USER_ID);
    222     }
    223 }
    224