Tests for max retries/redirects, ETag switches.
[android/platform/packages/providers/DownloadProvider.git] / tests / src / com / android / providers / downloads / AbstractPublicApiTest.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.app.DownloadManager.STATUS_FAILED;
20 import static android.app.DownloadManager.STATUS_SUCCESSFUL;
21 import static android.text.format.DateUtils.SECOND_IN_MILLIS;
22
23 import android.app.DownloadManager;
24 import android.database.Cursor;
25 import android.net.Uri;
26 import android.os.ParcelFileDescriptor;
27 import android.os.SystemClock;
28 import android.util.Log;
29
30 import java.io.InputStream;
31 import java.net.MalformedURLException;
32 import java.net.UnknownHostException;
33 import java.util.concurrent.TimeoutException;
34
35 /**
36  * Code common to tests that use the download manager public API.
37  */
38 public abstract class AbstractPublicApiTest extends AbstractDownloadProviderFunctionalTest {
39
40     class Download {
41         final long mId;
42
43         private Download(long downloadId) {
44             this.mId = downloadId;
45         }
46
47         public int getStatus() {
48             return (int) getLongField(DownloadManager.COLUMN_STATUS);
49         }
50
51         public int getReason() {
52             return (int) getLongField(DownloadManager.COLUMN_REASON);
53         }
54
55         public int getStatusIfExists() {
56             Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
57             try {
58                 if (cursor.getCount() > 0) {
59                     cursor.moveToFirst();
60                     return (int) cursor.getLong(cursor.getColumnIndexOrThrow(
61                             DownloadManager.COLUMN_STATUS));
62                 } else {
63                     // the row doesn't exist
64                     return -1;
65                 }
66             } finally {
67                 cursor.close();
68             }
69         }
70
71         String getStringField(String field) {
72             Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
73             try {
74                 assertEquals(1, cursor.getCount());
75                 cursor.moveToFirst();
76                 return cursor.getString(cursor.getColumnIndexOrThrow(field));
77             } finally {
78                 cursor.close();
79             }
80         }
81
82         long getLongField(String field) {
83             Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
84             try {
85                 assertEquals(1, cursor.getCount());
86                 cursor.moveToFirst();
87                 return cursor.getLong(cursor.getColumnIndexOrThrow(field));
88             } finally {
89                 cursor.close();
90             }
91         }
92
93         String getContents() throws Exception {
94             ParcelFileDescriptor downloadedFile = mManager.openDownloadedFile(mId);
95             assertTrue("Invalid file descriptor: " + downloadedFile,
96                        downloadedFile.getFileDescriptor().valid());
97             final InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(
98                     downloadedFile);
99             try {
100                 return readStream(stream);
101             } finally {
102                 stream.close();
103             }
104         }
105
106         void runUntilStatus(int status) throws TimeoutException {
107             final long startMillis = mSystemFacade.currentTimeMillis();
108             startService(null);
109             waitForStatus(status, startMillis);
110         }
111
112         void waitForStatus(int expected, long afterMillis) throws TimeoutException {
113             int actual = -1;
114
115             final long timeout = SystemClock.elapsedRealtime() + (15 * SECOND_IN_MILLIS);
116             while (SystemClock.elapsedRealtime() < timeout) {
117                 if (getLongField(DownloadManager.COLUMN_LAST_MODIFIED_TIMESTAMP) >= afterMillis) {
118                     actual = getStatus();
119                     if (actual == STATUS_SUCCESSFUL || actual == STATUS_FAILED) {
120                         assertEquals(expected, actual);
121                         return;
122                     } else if (actual == expected) {
123                         return;
124                     }
125                 }
126
127                 SystemClock.sleep(100);
128             }
129
130             throw new TimeoutException("Expected status " + expected + "; only reached " + actual);
131         }
132
133         // max time to wait before giving up on the current download operation.
134         private static final int MAX_TIME_TO_WAIT_FOR_OPERATION = 5;
135         // while waiting for the above time period, sleep this long to yield to the
136         // download thread
137         private static final int TIME_TO_SLEEP = 1000;
138
139         // waits until progress_so_far is >= (progress)%
140         boolean runUntilProgress(int progress) throws InterruptedException {
141             startService(null);
142
143             int sleepCounter = MAX_TIME_TO_WAIT_FOR_OPERATION * 1000 / TIME_TO_SLEEP;
144             int numBytesReceivedSoFar = 0;
145             int totalBytes = 0;
146             for (int i = 0; i < sleepCounter; i++) {
147                 Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
148                 try {
149                     assertEquals(1, cursor.getCount());
150                     cursor.moveToFirst();
151                     numBytesReceivedSoFar = cursor.getInt(
152                             cursor.getColumnIndexOrThrow(
153                                     DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
154                     totalBytes = cursor.getInt(
155                             cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
156                 } finally {
157                     cursor.close();
158                 }
159                 Log.i(LOG_TAG, "in runUntilProgress, numBytesReceivedSoFar: " +
160                         numBytesReceivedSoFar + ", totalBytes: " + totalBytes);
161                 if (totalBytes == 0) {
162                     fail("total_bytes should not be zero");
163                     return false;
164                 } else {
165                     if (numBytesReceivedSoFar * 100 / totalBytes >= progress) {
166                         // progress_so_far is >= progress%. we are done
167                         return true;
168                     }
169                 }
170                 // download not done yet. sleep a while and try again
171                 Thread.sleep(TIME_TO_SLEEP);
172             }
173             Log.i(LOG_TAG, "FAILED in runUntilProgress, numBytesReceivedSoFar: " +
174                     numBytesReceivedSoFar + ", totalBytes: " + totalBytes);
175             return false; // failed
176         }
177     }
178
179     protected static final String PACKAGE_NAME = "my.package.name";
180     protected static final String REQUEST_PATH = "/path";
181
182     protected DownloadManager mManager;
183
184     public AbstractPublicApiTest(FakeSystemFacade systemFacade) {
185         super(systemFacade);
186     }
187
188     @Override
189     protected void setUp() throws Exception {
190         super.setUp();
191         mManager = new DownloadManager(mResolver, PACKAGE_NAME);
192     }
193
194     protected DownloadManager.Request getRequest()
195             throws MalformedURLException, UnknownHostException {
196         return getRequest(getServerUri(REQUEST_PATH));
197     }
198
199     protected DownloadManager.Request getRequest(String path) {
200         return new DownloadManager.Request(Uri.parse(path));
201     }
202
203     protected Download enqueueRequest(DownloadManager.Request request) {
204         return new Download(mManager.enqueue(request));
205     }
206 }