d5249378d18da1b59075a4f3e367fff26c455c9b
[android/platform/packages/providers/DownloadProvider.git] / tests / src / com / android / providers / downloads / DownloadProviderFunctionalTest.java
1 /*
2  * Copyright (C) 2010 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.providers.downloads;
18
19 import static android.text.format.DateUtils.SECOND_IN_MILLIS;
20
21 import android.content.ContentValues;
22 import android.database.Cursor;
23 import android.net.ConnectivityManager;
24 import android.net.Uri;
25 import android.os.Environment;
26 import android.os.SystemClock;
27 import android.provider.Downloads;
28 import android.test.suitebuilder.annotation.LargeTest;
29
30 import com.google.mockwebserver.MockWebServer;
31 import com.google.mockwebserver.RecordedRequest;
32
33 import java.io.InputStream;
34 import java.net.MalformedURLException;
35 import java.net.UnknownHostException;
36 import java.util.concurrent.TimeoutException;
37
38 /**
39  * This test exercises the entire download manager working together -- it requests downloads through
40  * the {@link DownloadProvider}, just like a normal client would, and runs the
41  * {@link DownloadService} with start intents.  It sets up a {@link MockWebServer} running on the
42  * device to serve downloads.
43  */
44 @LargeTest
45 public class DownloadProviderFunctionalTest extends AbstractDownloadProviderFunctionalTest {
46     private static final String TAG = "DownloadManagerFunctionalTest";
47
48     public DownloadProviderFunctionalTest() {
49         super(new FakeSystemFacade());
50     }
51
52     public void testDownloadTextFile() throws Exception {
53         enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
54
55         String path = "/download_manager_test_path";
56         Uri downloadUri = requestDownload(path);
57         assertEquals(Downloads.Impl.STATUS_PENDING, getDownloadStatus(downloadUri));
58         assertTrue(mTestContext.mHasServiceBeenStarted);
59
60         runUntilStatus(downloadUri, Downloads.Impl.STATUS_SUCCESS);
61         RecordedRequest request = takeRequest();
62         assertEquals("GET", request.getMethod());
63         assertEquals(path, request.getPath());
64         assertEquals(FILE_CONTENT, getDownloadContents(downloadUri));
65         assertStartsWith(Environment.getExternalStorageDirectory().getPath(),
66                          getDownloadFilename(downloadUri));
67     }
68
69     public void testDownloadToCache() throws Exception {
70         enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
71
72         Uri downloadUri = requestDownload("/path");
73         updateDownload(downloadUri, Downloads.Impl.COLUMN_DESTINATION,
74                        Integer.toString(Downloads.Impl.DESTINATION_CACHE_PARTITION));
75         runUntilStatus(downloadUri, Downloads.Impl.STATUS_SUCCESS);
76         assertEquals(FILE_CONTENT, getDownloadContents(downloadUri));
77         assertStartsWith(getContext().getCacheDir().getAbsolutePath(),
78                          getDownloadFilename(downloadUri));
79     }
80
81     public void testRoaming() throws Exception {
82         enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
83         enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
84
85         mSystemFacade.mActiveNetworkType = ConnectivityManager.TYPE_MOBILE;
86         mSystemFacade.mIsRoaming = true;
87
88         // for a normal download, roaming is fine
89         Uri downloadUri = requestDownload("/path");
90         runUntilStatus(downloadUri, Downloads.Impl.STATUS_SUCCESS);
91
92         // when roaming is disallowed, the download should pause...
93         downloadUri = requestDownload("/path");
94         updateDownload(downloadUri, Downloads.Impl.COLUMN_DESTINATION,
95                        Integer.toString(Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING));
96         runUntilStatus(downloadUri, Downloads.Impl.STATUS_WAITING_FOR_NETWORK);
97
98         // ...and pick up when we're off roaming
99         mSystemFacade.mIsRoaming = false;
100         runUntilStatus(downloadUri, Downloads.Impl.STATUS_SUCCESS);
101     }
102
103     /**
104      * Read a downloaded file from disk.
105      */
106     private String getDownloadContents(Uri downloadUri) throws Exception {
107         InputStream inputStream = mResolver.openInputStream(downloadUri);
108         try {
109             return readStream(inputStream);
110         } finally {
111             inputStream.close();
112         }
113     }
114
115     private void runUntilStatus(Uri downloadUri, int expected) throws Exception {
116         startService(null);
117         
118         int actual = -1;
119
120         final long timeout = SystemClock.elapsedRealtime() + (15 * SECOND_IN_MILLIS);
121         while (SystemClock.elapsedRealtime() < timeout) {
122             actual = getDownloadStatus(downloadUri);
123             if (expected == actual) {
124                 return;
125             }
126
127             SystemClock.sleep(100);
128         }
129
130         throw new TimeoutException("Expected status " + expected + "; only reached " + actual);
131     }
132
133     protected int getDownloadStatus(Uri downloadUri) {
134         return Integer.valueOf(getDownloadField(downloadUri, Downloads.Impl.COLUMN_STATUS));
135     }
136
137     private String getDownloadFilename(Uri downloadUri) {
138         return getDownloadField(downloadUri, Downloads.Impl._DATA);
139     }
140
141     private String getDownloadField(Uri downloadUri, String column) {
142         final String[] columns = new String[] {column};
143         Cursor cursor = mResolver.query(downloadUri, columns, null, null, null);
144         try {
145             assertEquals(1, cursor.getCount());
146             cursor.moveToFirst();
147             return cursor.getString(0);
148         } finally {
149             cursor.close();
150         }
151     }
152
153     /**
154      * Request a download from the Download Manager.
155      */
156     private Uri requestDownload(String path) throws MalformedURLException, UnknownHostException {
157         ContentValues values = new ContentValues();
158         values.put(Downloads.Impl.COLUMN_URI, getServerUri(path));
159         values.put(Downloads.Impl.COLUMN_DESTINATION, Downloads.Impl.DESTINATION_EXTERNAL);
160         return mResolver.insert(Downloads.Impl.CONTENT_URI, values);
161     }
162
163     /**
164      * Update one field of a download in the provider.
165      */
166     private void updateDownload(Uri downloadUri, String column, String value) {
167         ContentValues values = new ContentValues();
168         values.put(column, value);
169         int numChanged = mResolver.update(downloadUri, values, null, null);
170         assertEquals(1, numChanged);
171     }
172 }