diff options
Diffstat (limited to 'tests/src/com')
-rw-r--r-- | tests/src/com/android/providers/downloads/DownloadManagerFunctionalTest.java | 150 | ||||
-rw-r--r-- | tests/src/com/android/providers/downloads/FakeSystemFacade.java | 13 |
2 files changed, 111 insertions, 52 deletions
diff --git a/tests/src/com/android/providers/downloads/DownloadManagerFunctionalTest.java b/tests/src/com/android/providers/downloads/DownloadManagerFunctionalTest.java index 76b3d589..8d4655bb 100644 --- a/tests/src/com/android/providers/downloads/DownloadManagerFunctionalTest.java +++ b/tests/src/com/android/providers/downloads/DownloadManagerFunctionalTest.java @@ -26,7 +26,9 @@ import android.database.Cursor; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; +import android.os.Environment; import android.provider.Downloads; +import android.test.MoreAsserts; import android.test.RenamingDelegatingContext; import android.test.ServiceTestCase; import android.test.mock.MockContentResolver; @@ -55,18 +57,23 @@ import java.util.Set; */ @LargeTest public class DownloadManagerFunctionalTest extends ServiceTestCase<DownloadService> { - private static final int HTTP_PARTIAL_CONTENT = 206; + private static final String LOG_TAG = "DownloadManagerFunctionalTest"; + private static final String PROVIDER_AUTHORITY = "downloads"; + private static final int RETRY_DELAY_MILLIS = 61 * 1000; + private static final long REQUEST_TIMEOUT_MILLIS = 10 * 1000; + private static final String FILE_CONTENT = "hello world"; + private static final int HTTP_OK = 200; - private static final String LOG_TAG = "DownloadManagerFunctionalTest"; + private static final int HTTP_PARTIAL_CONTENT = 206; private static final int HTTP_NOT_FOUND = 404; - private static final String FILE_CONTENT = "hello world"; - private static final long REQUEST_TIMEOUT_MILLIS = 5000; + private static final int HTTP_SERVICE_UNAVAILABLE = 503; private MockWebServer mServer; // resolves requests to the DownloadProvider we set up private MockContentResolver mResolver; private TestContext mTestContext; + private FakeSystemFacade mSystemFacade; /** * Context passed to the provider and the service. Allows most methods to pass through to the @@ -148,6 +155,9 @@ public class DownloadManagerFunctionalTest extends ServiceTestCase<DownloadServi mTestContext.setResolver(mResolver); setContext(mTestContext); + setupService(); + mSystemFacade = new FakeSystemFacade(); + getService().mSystemFacade = mSystemFacade; mServer = new MockWebServer(); mServer.play(); @@ -205,26 +215,55 @@ public class DownloadManagerFunctionalTest extends ServiceTestCase<DownloadServi assertEquals(Downloads.STATUS_PENDING, getDownloadStatus(downloadUri)); assertTrue(mTestContext.mHasServiceBeenStarted); - startService(null); - - RecordedRequest request = takeRequest(); + RecordedRequest request = runUntilStatus(downloadUri, Downloads.STATUS_SUCCESS); assertEquals("GET", request.getMethod()); assertEquals(path, request.getPath()); + assertEquals(FILE_CONTENT, getDownloadContents(downloadUri)); + assertStartsWith(Environment.getExternalStorageDirectory().getPath(), + getDownloadFilename(downloadUri)); + } - waitForDownloadToStop(downloadUri, Downloads.STATUS_SUCCESS); + public void testDownloadToCache() throws Exception { + enqueueResponse(HTTP_OK, FILE_CONTENT); + Uri downloadUri = requestDownload("/path"); + updateDownload(downloadUri, Downloads.COLUMN_DESTINATION, + Integer.toString(Downloads.DESTINATION_CACHE_PARTITION)); + runUntilStatus(downloadUri, Downloads.STATUS_SUCCESS); assertEquals(FILE_CONTENT, getDownloadContents(downloadUri)); - checkForUnexpectedRequests(); + assertStartsWith(Environment.getDownloadCacheDirectory().getPath(), + getDownloadFilename(downloadUri)); } public void testFileNotFound() throws Exception { enqueueEmptyResponse(HTTP_NOT_FOUND); Uri downloadUri = requestDownload("/nonexistent_path"); assertEquals(Downloads.STATUS_PENDING, getDownloadStatus(downloadUri)); + runUntilStatus(downloadUri, HTTP_NOT_FOUND); + } - startService(null); - takeRequest(); - waitForDownloadToStop(downloadUri, HTTP_NOT_FOUND); - checkForUnexpectedRequests(); + public void testRetryAfter() throws Exception { + final int delay = 120; + enqueueEmptyResponse(HTTP_SERVICE_UNAVAILABLE).addHeader("Retry-after", delay); + Uri downloadUri = requestDownload("/path"); + runUntilStatus(downloadUri, Downloads.STATUS_RUNNING_PAUSED); + + // download manager adds random 0-30s offset + mSystemFacade.incrementTimeMillis((delay + 31) * 1000); + + enqueueResponse(HTTP_OK, FILE_CONTENT); + runUntilStatus(downloadUri, Downloads.STATUS_SUCCESS); + } + + public void testRedirect() throws Exception { + enqueueEmptyResponse(301).addHeader("Location", mServer.getUrl("/other_path").toString()); + enqueueResponse(HTTP_OK, FILE_CONTENT); + Uri downloadUri = requestDownload("/path"); + RecordedRequest request = runUntilStatus(downloadUri, Downloads.STATUS_RUNNING_PAUSED); + assertEquals("/path", request.getPath()); + + mSystemFacade.incrementTimeMillis(RETRY_DELAY_MILLIS); + request = runUntilStatus(downloadUri, Downloads.STATUS_SUCCESS); + assertEquals("/other_path", request.getPath()); } public void testBasicConnectivityChanges() throws Exception { @@ -235,18 +274,13 @@ public class DownloadManagerFunctionalTest extends ServiceTestCase<DownloadServi mTestContext.mFakeIConnectivityManager.setNetworkState(NetworkInfo.State.DISCONNECTED); startService(null); waitForDownloadToStop(downloadUri, Downloads.STATUS_RUNNING_PAUSED); - checkForUnexpectedRequests(); // connecting should start the download mTestContext.mFakeIConnectivityManager.setNetworkState(NetworkInfo.State.CONNECTED); - startService(null); // normally done by DownloadReceiver - takeRequest(); - waitForDownloadToStop(downloadUri, Downloads.STATUS_SUCCESS); - checkForUnexpectedRequests(); + runUntilStatus(downloadUri, Downloads.STATUS_SUCCESS); } - // disabled due to excessive sleep - public void disabledTestInterruptedDownload() throws Exception { + public void testInterruptedDownload() throws Exception { int initialLength = 5; String etag = "my_etag"; int totalLength = FILE_CONTENT.length(); @@ -257,12 +291,9 @@ public class DownloadManagerFunctionalTest extends ServiceTestCase<DownloadServi .setCloseConnectionAfter(true); Uri downloadUri = requestDownload("/path"); - startService(null); - takeRequest(); - waitForDownloadToStop(downloadUri, Downloads.STATUS_RUNNING_PAUSED); + runUntilStatus(downloadUri, Downloads.STATUS_RUNNING_PAUSED); - Thread.sleep(61 * 1000); // TODO: avoid this by stubbing the system clock - mServer.drainRequests(); + mSystemFacade.incrementTimeMillis(RETRY_DELAY_MILLIS); // the second response returns partial content for the rest of the data enqueueResponse(HTTP_PARTIAL_CONTENT, FILE_CONTENT.substring(initialLength)) .addHeader("Content-range", @@ -270,17 +301,18 @@ public class DownloadManagerFunctionalTest extends ServiceTestCase<DownloadServi .addHeader("Etag", etag); // TODO: ideally we wouldn't need to call startService again, but there's a bug where the // service won't retry a download until an intent comes in - startService(null); - waitForDownloadToStop(downloadUri, Downloads.STATUS_SUCCESS); + RecordedRequest request = runUntilStatus(downloadUri, Downloads.STATUS_SUCCESS); - RecordedRequest request = takeRequest(); List<String> headers = request.getHeaders(); assertTrue("No Range header: " + headers, headers.contains("Range: bytes=" + initialLength + "-")); assertTrue("No ETag header: " + headers, headers.contains("If-Match: " + etag)); - assertEquals(FILE_CONTENT, getDownloadContents(downloadUri)); - checkForUnexpectedRequests(); + } + + private void assertStartsWith(String expectedPrefix, String actual) { + String regex = "^" + expectedPrefix + ".*"; + MoreAsserts.assertMatchesRegex(regex, actual); } /** @@ -295,8 +327,19 @@ public class DownloadManagerFunctionalTest extends ServiceTestCase<DownloadServi return response; } - private void enqueueEmptyResponse(int status) { - enqueueResponse(status, ""); + private MockResponse enqueueEmptyResponse(int status) { + return enqueueResponse(status, ""); + } + + /** + * Run the service and wait for a request and for the download to reach the given status. + * @return the request received + */ + private RecordedRequest runUntilStatus(Uri downloadUri, int status) throws Exception { + startService(null); + RecordedRequest request = takeRequest(); + waitForDownloadToStop(downloadUri, status); + return request; } /** @@ -324,7 +367,7 @@ public class DownloadManagerFunctionalTest extends ServiceTestCase<DownloadServi * Wait for a download to given a given status, with a timeout. Fails if the download reaches * any other final status. */ - private void waitForDownloadToStop(Uri downloadUri, int expectedStatus) { + private void waitForDownloadToStop(Uri downloadUri, int expectedStatus) throws Exception { // TODO(showard): find a better way to accomplish this long startTimeMillis = System.currentTimeMillis(); int status = getDownloadStatus(downloadUri); @@ -335,11 +378,8 @@ public class DownloadManagerFunctionalTest extends ServiceTestCase<DownloadServi if (System.currentTimeMillis() > startTimeMillis + REQUEST_TIMEOUT_MILLIS) { fail("Download timed out with status " + status); } - try { - Thread.sleep(100); - } catch (InterruptedException exc) { - // no problem - } + Thread.sleep(100); + mServer.checkForExceptions(); status = getDownloadStatus(downloadUri); } @@ -348,12 +388,20 @@ public class DownloadManagerFunctionalTest extends ServiceTestCase<DownloadServi } private int getDownloadStatus(Uri downloadUri) { - final String[] columns = new String[] {Downloads.COLUMN_STATUS}; + return Integer.valueOf(getDownloadField(downloadUri, Downloads.COLUMN_STATUS)); + } + + private String getDownloadFilename(Uri downloadUri) { + return getDownloadField(downloadUri, Downloads._DATA); + } + + private String getDownloadField(Uri downloadUri, String column) { + final String[] columns = new String[] {column}; Cursor cursor = mResolver.query(downloadUri, columns, null, null, null); try { assertEquals(1, cursor.getCount()); cursor.moveToFirst(); - return cursor.getInt(0); + return cursor.getString(0); } finally { cursor.close(); } @@ -369,6 +417,16 @@ public class DownloadManagerFunctionalTest extends ServiceTestCase<DownloadServi return mResolver.insert(Downloads.CONTENT_URI, values); } + /** + * Update one field of a download in the provider. + */ + private void updateDownload(Uri downloadUri, String column, String value) { + ContentValues values = new ContentValues(); + values.put(column, value); + int numChanged = mResolver.update(downloadUri, values, null, null); + assertEquals(1, numChanged); + } + private String readStream(InputStream inputStream) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); try { @@ -380,16 +438,4 @@ public class DownloadManagerFunctionalTest extends ServiceTestCase<DownloadServi reader.close(); } } - - /** - * Check for any extra requests made to the MockWebServer that weren't consumed with - * {@link #takeRequest()}. - */ - private void checkForUnexpectedRequests() { - if (mServer == null) { - return; - } - List<RecordedRequest> extraRequests = mServer.drainRequests(); - assertEquals("Invalid requests: " + extraRequests.toString(), 0, extraRequests.size()); - } } diff --git a/tests/src/com/android/providers/downloads/FakeSystemFacade.java b/tests/src/com/android/providers/downloads/FakeSystemFacade.java new file mode 100644 index 00000000..b75e663a --- /dev/null +++ b/tests/src/com/android/providers/downloads/FakeSystemFacade.java @@ -0,0 +1,13 @@ +package com.android.providers.downloads; + +public class FakeSystemFacade implements SystemFacade { + private long mTimeMillis = 0; + + void incrementTimeMillis(long delta) { + mTimeMillis += delta; + } + + public long currentTimeMillis() { + return mTimeMillis; + } +} |