summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/src/com/android/providers/downloads/AbstractDownloadManagerFunctionalTest.java281
-rw-r--r--tests/src/com/android/providers/downloads/DownloadManagerFunctionalTest.java262
-rw-r--r--tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java238
3 files changed, 535 insertions, 246 deletions
diff --git a/tests/src/com/android/providers/downloads/AbstractDownloadManagerFunctionalTest.java b/tests/src/com/android/providers/downloads/AbstractDownloadManagerFunctionalTest.java
new file mode 100644
index 00000000..1394a17d
--- /dev/null
+++ b/tests/src/com/android/providers/downloads/AbstractDownloadManagerFunctionalTest.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.downloads;
+
+import android.content.ComponentName;
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.ConnectivityManager;
+import android.provider.Downloads;
+import android.test.MoreAsserts;
+import android.test.RenamingDelegatingContext;
+import android.test.ServiceTestCase;
+import android.test.mock.MockContentResolver;
+import android.util.Log;
+import tests.http.MockResponse;
+import tests.http.MockWebServer;
+import tests.http.RecordedRequest;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.MalformedURLException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public abstract class AbstractDownloadManagerFunctionalTest extends
+ ServiceTestCase<DownloadService> {
+
+ protected static final String LOG_TAG = "DownloadManagerFunctionalTest";
+ private static final String PROVIDER_AUTHORITY = "downloads";
+ protected static final long REQUEST_TIMEOUT_MILLIS = 10 * 1000;
+ protected static final long RETRY_DELAY_MILLIS = 61 * 1000;
+ protected static final String FILE_CONTENT = "hello world";
+ protected static final int HTTP_OK = 200;
+ protected static final int HTTP_PARTIAL_CONTENT = 206;
+ protected static final int HTTP_NOT_FOUND = 404;
+ protected static final int HTTP_SERVICE_UNAVAILABLE = 503;
+ protected MockWebServer mServer;
+ protected MockContentResolver mResolver;
+ protected TestContext mTestContext;
+ protected FakeSystemFacade mSystemFacade;
+
+ static interface StatusReader {
+ public int getStatus();
+ public boolean isComplete(int status);
+ }
+
+ /**
+ * Context passed to the provider and the service. Allows most methods to pass through to the
+ * real Context (this is a LargeTest), with a few exceptions, including renaming file operations
+ * to avoid file and DB conflicts (via RenamingDelegatingContext).
+ */
+ static class TestContext extends RenamingDelegatingContext {
+ private static final String FILENAME_PREFIX = "test.";
+
+ private Context mRealContext;
+ private Set<String> mAllowedSystemServices;
+ private ContentResolver mResolver;
+
+ boolean mHasServiceBeenStarted = false;
+ FakeIConnectivityManager mFakeIConnectivityManager;
+
+ public TestContext(Context realContext) {
+ super(realContext, FILENAME_PREFIX);
+ mRealContext = realContext;
+ mAllowedSystemServices = new HashSet<String>(Arrays.asList(new String[] {
+ Context.NOTIFICATION_SERVICE,
+ Context.POWER_SERVICE,
+ }));
+ mFakeIConnectivityManager = new FakeIConnectivityManager();
+ }
+
+ public void setResolver(ContentResolver resolver) {
+ mResolver = resolver;
+ }
+
+ /**
+ * Direct DownloadService to our test instance of DownloadProvider.
+ */
+ @Override
+ public ContentResolver getContentResolver() {
+ assert mResolver != null;
+ return mResolver;
+ }
+
+ /**
+ * Stub some system services, allow access to others, and block the rest.
+ */
+ @Override
+ public Object getSystemService(String name) {
+ if (name.equals(Context.CONNECTIVITY_SERVICE)) {
+ return new ConnectivityManager(mFakeIConnectivityManager);
+ }
+ if (mAllowedSystemServices.contains(name)) {
+ return mRealContext.getSystemService(name);
+ }
+ return super.getSystemService(name);
+ }
+
+ /**
+ * Record when DownloadProvider starts DownloadService.
+ */
+ @Override
+ public ComponentName startService(Intent service) {
+ if (service.getComponent().getClassName().equals(DownloadService.class.getName())) {
+ mHasServiceBeenStarted = true;
+ return service.getComponent();
+ }
+ throw new UnsupportedOperationException("Unexpected service: " + service);
+ }
+ }
+
+ public AbstractDownloadManagerFunctionalTest() {
+ super(DownloadService.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ Context realContext = getContext();
+ mTestContext = new TestContext(realContext);
+ setupProviderAndResolver();
+ assert isDatabaseEmpty(); // ensure we're not messing with real data
+
+ mTestContext.setResolver(mResolver);
+ setContext(mTestContext);
+ setupService();
+ mSystemFacade = new FakeSystemFacade();
+ getService().mSystemFacade = mSystemFacade;
+
+ mServer = new MockWebServer();
+ mServer.play();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ cleanUpDownloads();
+ super.tearDown();
+ }
+
+ private boolean isDatabaseEmpty() {
+ Cursor cursor = mResolver.query(Downloads.CONTENT_URI, null, null, null, null);
+ try {
+ return cursor.getCount() == 0;
+ } finally {
+ cursor.close();
+ }
+ }
+
+ void setupProviderAndResolver() {
+ ContentProvider provider = new DownloadProvider();
+ provider.attachInfo(mTestContext, null);
+ mResolver = new MockContentResolver();
+ mResolver.addProvider(PROVIDER_AUTHORITY, provider);
+ }
+
+ /**
+ * Remove any downloaded files and delete any lingering downloads.
+ */
+ void cleanUpDownloads() {
+ if (mResolver == null) {
+ return;
+ }
+ String[] columns = new String[] {Downloads._DATA};
+ Cursor cursor = mResolver.query(Downloads.CONTENT_URI, columns, null, null, null);
+ try {
+ for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
+ String filePath = cursor.getString(0);
+ if (filePath == null) continue;
+ Log.d(LOG_TAG, "Deleting " + filePath);
+ new File(filePath).delete();
+ }
+ } finally {
+ cursor.close();
+ }
+ mResolver.delete(Downloads.CONTENT_URI, null, null);
+ }
+
+ /**
+ * Enqueue a response from the MockWebServer.
+ */
+ MockResponse enqueueResponse(int status, String body) {
+ MockResponse response = new MockResponse()
+ .setResponseCode(status)
+ .setBody(body)
+ .addHeader("Content-type", "text/plain");
+ mServer.enqueue(response);
+ return response;
+ }
+
+ MockResponse enqueueEmptyResponse(int status) {
+ return enqueueResponse(status, "");
+ }
+
+ /**
+ * Wait for a request to come to the MockWebServer and return it.
+ */
+ RecordedRequest takeRequest() throws InterruptedException {
+ RecordedRequest request = mServer.takeRequestWithTimeout(REQUEST_TIMEOUT_MILLIS);
+ assertNotNull("Timed out waiting for request", request);
+ return request;
+ }
+
+ String getServerUri(String path) throws MalformedURLException {
+ return mServer.getUrl(path).toString();
+ }
+
+ /**
+ * Run the service and wait for a request and for the download to reach the given status.
+ * @return the request received
+ */
+ protected RecordedRequest runUntilStatus(StatusReader reader, int status) throws Exception {
+ startService(null);
+ RecordedRequest request = takeRequest();
+ waitForDownloadToStop(reader, status);
+ return request;
+ }
+
+ /**
+ * Wait for a download to given a given status, with a timeout. Fails if the download reaches
+ * any other final status.
+ */
+ protected void waitForDownloadToStop(StatusReader reader, int expectedStatus)
+ throws Exception {
+ // TODO(showard): find a better way to accomplish this
+ long startTimeMillis = System.currentTimeMillis();
+ int status = reader.getStatus();
+ while (status != expectedStatus) {
+ if (reader.isComplete(status)) {
+ fail("Download completed with unexpected status: " + status);
+ }
+ if (System.currentTimeMillis() > startTimeMillis + REQUEST_TIMEOUT_MILLIS) {
+ fail("Download timed out with status " + status);
+ }
+ Thread.sleep(100);
+ mServer.checkForExceptions();
+ status = reader.getStatus();
+ }
+
+ long delta = System.currentTimeMillis() - startTimeMillis;
+ Log.d(LOG_TAG, "Status " + status + " reached after " + delta + "ms");
+ }
+
+ protected String readStream(InputStream inputStream) throws IOException {
+ BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
+ try {
+ char[] buffer = new char[1024];
+ int length = reader.read(buffer);
+ assertTrue("Failed to read anything from input stream", length > -1);
+ return String.valueOf(buffer, 0, length);
+ } finally {
+ reader.close();
+ }
+ }
+
+ protected void assertStartsWith(String expectedPrefix, String actual) {
+ String regex = "^" + expectedPrefix + ".*";
+ MoreAsserts.assertMatchesRegex(regex, actual);
+ }
+}
diff --git a/tests/src/com/android/providers/downloads/DownloadManagerFunctionalTest.java b/tests/src/com/android/providers/downloads/DownloadManagerFunctionalTest.java
index 8d4655bb..7de90de5 100644
--- a/tests/src/com/android/providers/downloads/DownloadManagerFunctionalTest.java
+++ b/tests/src/com/android/providers/downloads/DownloadManagerFunctionalTest.java
@@ -16,38 +16,19 @@
package com.android.providers.downloads;
-import android.content.ComponentName;
-import android.content.ContentProvider;
-import android.content.ContentResolver;
import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
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;
import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import tests.http.MockResponse;
import tests.http.MockWebServer;
import tests.http.RecordedRequest;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
import java.io.InputStream;
-import java.io.InputStreamReader;
import java.net.MalformedURLException;
-import java.util.Arrays;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
/**
* This test exercises the entire download manager working together -- it requests downloads through
@@ -56,157 +37,7 @@ import java.util.Set;
* device to serve downloads.
*/
@LargeTest
-public class DownloadManagerFunctionalTest extends ServiceTestCase<DownloadService> {
- 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 int HTTP_PARTIAL_CONTENT = 206;
- private static final int HTTP_NOT_FOUND = 404;
- 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
- * real Context (this is a LargeTest), with a few exceptions, including renaming file operations
- * to avoid file and DB conflicts (via RenamingDelegatingContext).
- */
- private static class TestContext extends RenamingDelegatingContext {
- private static final String FILENAME_PREFIX = "test.";
-
- private Context mRealContext;
- private Set<String> mAllowedSystemServices;
- private ContentResolver mResolver;
-
- boolean mHasServiceBeenStarted = false;
- FakeIConnectivityManager mFakeIConnectivityManager;
-
- public TestContext(Context realContext) {
- super(realContext, FILENAME_PREFIX);
- mRealContext = realContext;
- mAllowedSystemServices = new HashSet<String>(Arrays.asList(new String[] {
- Context.NOTIFICATION_SERVICE,
- Context.POWER_SERVICE,
- }));
- mFakeIConnectivityManager = new FakeIConnectivityManager();
- }
-
- public void setResolver(ContentResolver resolver) {
- mResolver = resolver;
- }
-
- /**
- * Direct DownloadService to our test instance of DownloadProvider.
- */
- @Override
- public ContentResolver getContentResolver() {
- assert mResolver != null;
- return mResolver;
- }
-
- /**
- * Stub some system services, allow access to others, and block the rest.
- */
- @Override
- public Object getSystemService(String name) {
- if (name.equals(Context.CONNECTIVITY_SERVICE)) {
- return new ConnectivityManager(mFakeIConnectivityManager);
- }
- if (mAllowedSystemServices.contains(name)) {
- return mRealContext.getSystemService(name);
- }
- return super.getSystemService(name);
- }
-
- /**
- * Record when DownloadProvider starts DownloadService.
- */
- @Override
- public ComponentName startService(Intent service) {
- if (service.getComponent().getClassName().equals(DownloadService.class.getName())) {
- mHasServiceBeenStarted = true;
- return service.getComponent();
- }
- throw new UnsupportedOperationException("Unexpected service: " + service);
- }
- }
-
- public DownloadManagerFunctionalTest() {
- super(DownloadService.class);
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- Context realContext = getContext();
- mTestContext = new TestContext(realContext);
- setupProviderAndResolver();
- assert isDatabaseEmpty(); // ensure we're not messing with real data
-
- mTestContext.setResolver(mResolver);
- setContext(mTestContext);
- setupService();
- mSystemFacade = new FakeSystemFacade();
- getService().mSystemFacade = mSystemFacade;
-
- mServer = new MockWebServer();
- mServer.play();
- }
-
- private void setupProviderAndResolver() {
- ContentProvider provider = new DownloadProvider();
- provider.attachInfo(mTestContext, null);
- mResolver = new MockContentResolver();
- mResolver.addProvider(PROVIDER_AUTHORITY, provider);
- }
-
- private boolean isDatabaseEmpty() {
- Cursor cursor = mResolver.query(Downloads.CONTENT_URI, null, null, null, null);
- try {
- return cursor.getCount() == 0;
- } finally {
- cursor.close();
- }
- }
-
- @Override
- protected void tearDown() throws Exception {
- cleanUpDownloads();
- super.tearDown();
- }
-
- /**
- * Remove any downloaded files and delete any lingering downloads.
- */
- private void cleanUpDownloads() {
- if (mResolver == null) {
- return;
- }
- String[] columns = new String[] {Downloads._DATA};
- Cursor cursor = mResolver.query(Downloads.CONTENT_URI, columns, null, null, null);
- try {
- for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
- String filePath = cursor.getString(0);
- if (filePath == null) continue;
- Log.d(LOG_TAG, "Deleting " + filePath);
- new File(filePath).delete();
- }
- } finally {
- cursor.close();
- }
- mResolver.delete(Downloads.CONTENT_URI, null, null);
- }
-
+public class DownloadManagerFunctionalTest extends AbstractDownloadManagerFunctionalTest {
public void testBasicRequest() throws Exception {
enqueueResponse(HTTP_OK, FILE_CONTENT);
@@ -273,7 +104,7 @@ public class DownloadManagerFunctionalTest extends ServiceTestCase<DownloadServi
// without connectivity, download immediately pauses
mTestContext.mFakeIConnectivityManager.setNetworkState(NetworkInfo.State.DISCONNECTED);
startService(null);
- waitForDownloadToStop(downloadUri, Downloads.STATUS_RUNNING_PAUSED);
+ super.waitForDownloadToStop(getStatusReader(downloadUri), Downloads.STATUS_RUNNING_PAUSED);
// connecting should start the download
mTestContext.mFakeIConnectivityManager.setNetworkState(NetworkInfo.State.CONNECTED);
@@ -310,47 +141,6 @@ public class DownloadManagerFunctionalTest extends ServiceTestCase<DownloadServi
assertEquals(FILE_CONTENT, getDownloadContents(downloadUri));
}
- private void assertStartsWith(String expectedPrefix, String actual) {
- String regex = "^" + expectedPrefix + ".*";
- MoreAsserts.assertMatchesRegex(regex, actual);
- }
-
- /**
- * Enqueue a response from the MockWebServer.
- */
- private MockResponse enqueueResponse(int status, String body) {
- MockResponse response = new MockResponse()
- .setResponseCode(status)
- .setBody(body)
- .addHeader("Content-type", "text/plain");
- mServer.enqueue(response);
- return response;
- }
-
- 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;
- }
-
- /**
- * Wait for a request to come to the MockWebServer and return it.
- */
- private RecordedRequest takeRequest() throws InterruptedException {
- RecordedRequest request = mServer.takeRequestWithTimeout(REQUEST_TIMEOUT_MILLIS);
- assertNotNull("Timed out waiting for request", request);
- return request;
- }
-
/**
* Read a downloaded file from disk.
*/
@@ -363,31 +153,23 @@ 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) throws Exception {
- // TODO(showard): find a better way to accomplish this
- long startTimeMillis = System.currentTimeMillis();
- int status = getDownloadStatus(downloadUri);
- while (status != expectedStatus) {
- if (!Downloads.isStatusInformational(status)) {
- fail("Download completed with unexpected status: " + status);
- }
- if (System.currentTimeMillis() > startTimeMillis + REQUEST_TIMEOUT_MILLIS) {
- fail("Download timed out with status " + status);
+ private RecordedRequest runUntilStatus(Uri downloadUri, int status) throws Exception {
+ return super.runUntilStatus(getStatusReader(downloadUri), status);
+ }
+
+ private StatusReader getStatusReader(final Uri downloadUri) {
+ return new StatusReader() {
+ public int getStatus() {
+ return getDownloadStatus(downloadUri);
}
- Thread.sleep(100);
- mServer.checkForExceptions();
- status = getDownloadStatus(downloadUri);
- }
- long delta = System.currentTimeMillis() - startTimeMillis;
- Log.d(LOG_TAG, "Status " + status + " reached after " + delta + "ms");
+ public boolean isComplete(int status) {
+ return !Downloads.isStatusInformational(status);
+ }
+ };
}
- private int getDownloadStatus(Uri downloadUri) {
+ protected int getDownloadStatus(Uri downloadUri) {
return Integer.valueOf(getDownloadField(downloadUri, Downloads.COLUMN_STATUS));
}
@@ -412,7 +194,7 @@ public class DownloadManagerFunctionalTest extends ServiceTestCase<DownloadServi
*/
private Uri requestDownload(String path) throws MalformedURLException {
ContentValues values = new ContentValues();
- values.put(Downloads.COLUMN_URI, mServer.getUrl(path).toString());
+ values.put(Downloads.COLUMN_URI, getServerUri(path));
values.put(Downloads.COLUMN_DESTINATION, Downloads.DESTINATION_EXTERNAL);
return mResolver.insert(Downloads.CONTENT_URI, values);
}
@@ -426,16 +208,4 @@ public class DownloadManagerFunctionalTest extends ServiceTestCase<DownloadServi
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 {
- char[] buffer = new char[1024];
- int length = reader.read(buffer);
- assertTrue("Failed to read anything from input stream", length > -1);
- return String.valueOf(buffer, 0, length);
- } finally {
- reader.close();
- }
- }
}
diff --git a/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java b/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java
new file mode 100644
index 00000000..1927545f
--- /dev/null
+++ b/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.providers.downloads;
+
+import android.database.Cursor;
+import android.net.DownloadManager;
+import android.net.Uri;
+import android.os.Environment;
+import tests.http.RecordedRequest;
+
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+
+public class PublicApiFunctionalTest extends AbstractDownloadManagerFunctionalTest {
+ /**
+ *
+ */
+ private static final String REQUEST_PATH = "/path";
+
+ class Download implements StatusReader {
+ final long mId;
+
+ private Download(long downloadId) {
+ this.mId = downloadId;
+ }
+
+ public int getStatus() {
+ return (int) getLongField(DownloadManager.COLUMN_STATUS);
+ }
+
+ public boolean isComplete(int status) {
+ return status != DownloadManager.STATUS_PENDING
+ && status != DownloadManager.STATUS_RUNNING
+ && status != DownloadManager.STATUS_PAUSED;
+ }
+
+ String getStringField(String field) {
+ Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
+ try {
+ assertEquals(1, cursor.getCount());
+ cursor.moveToFirst();
+ return cursor.getString(cursor.getColumnIndexOrThrow(field));
+ } finally {
+ cursor.close();
+ }
+ }
+
+ long getLongField(String field) {
+ Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
+ try {
+ assertEquals(1, cursor.getCount());
+ cursor.moveToFirst();
+ return cursor.getLong(cursor.getColumnIndexOrThrow(field));
+ } finally {
+ cursor.close();
+ }
+ }
+
+ String getContents() throws Exception {
+ InputStream stream = new FileInputStream(
+ mManager.openDownloadedFile(mId).getFileDescriptor());
+ try {
+ return readStream(stream);
+ } finally {
+ stream.close();
+ }
+ }
+
+ RecordedRequest runUntilStatus(int status) throws Exception {
+ return PublicApiFunctionalTest.this.runUntilStatus(this, status);
+ }
+ }
+
+ private DownloadManager mManager;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mManager = new DownloadManager(mResolver);
+ }
+
+ public void testBasicRequest() throws Exception {
+ enqueueResponse(HTTP_OK, FILE_CONTENT);
+
+ Download download = enqueueRequest(getRequest());
+ assertEquals(DownloadManager.STATUS_PENDING,
+ download.getLongField(DownloadManager.COLUMN_STATUS));
+ assertEquals(getServerUri(REQUEST_PATH),
+ download.getStringField(DownloadManager.COLUMN_URI));
+ assertEquals(download.mId, download.getLongField(DownloadManager.COLUMN_ID));
+
+ RecordedRequest request = download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
+ assertEquals("GET", request.getMethod());
+ assertEquals(REQUEST_PATH, request.getPath());
+
+ Uri localUri = Uri.parse(download.getStringField(DownloadManager.COLUMN_LOCAL_URI));
+ assertEquals("file", localUri.getScheme());
+ assertStartsWith(Environment.getDownloadCacheDirectory().getPath(),
+ localUri.getSchemeSpecificPart());
+ assertEquals("text/plain", download.getStringField(DownloadManager.COLUMN_MEDIA_TYPE));
+
+ int size = FILE_CONTENT.length();
+ assertEquals(size, download.getLongField(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
+ assertEquals(size, download.getLongField(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
+
+ assertEquals(FILE_CONTENT, download.getContents());
+ }
+
+ public void testTitleAndDescription() throws Exception {
+ Download download = enqueueRequest(getRequest()
+ .setTitle("my title")
+ .setDescription("my description"));
+ assertEquals("my title", download.getStringField(DownloadManager.COLUMN_TITLE));
+ assertEquals("my description",
+ download.getStringField(DownloadManager.COLUMN_DESCRIPTION));
+ }
+
+ public void testDownloadError() throws Exception {
+ enqueueEmptyResponse(HTTP_NOT_FOUND);
+ Download download = enqueueRequest(getRequest());
+ download.runUntilStatus(DownloadManager.STATUS_FAILED);
+ assertEquals(HTTP_NOT_FOUND, download.getLongField(DownloadManager.COLUMN_ERROR_CODE));
+ }
+
+ public void testUnhandledHttpStatus() throws Exception {
+ enqueueEmptyResponse(1234); // some invalid HTTP status
+ Download download = enqueueRequest(getRequest());
+ download.runUntilStatus(DownloadManager.STATUS_FAILED);
+ assertEquals(DownloadManager.ERROR_UNHANDLED_HTTP_CODE,
+ download.getLongField(DownloadManager.COLUMN_ERROR_CODE));
+ }
+
+ public void testInterruptedDownload() throws Exception {
+ int initialLength = 5;
+ String etag = "my_etag";
+ int totalLength = FILE_CONTENT.length();
+ // the first response has normal headers but unexpectedly closes after initialLength bytes
+ enqueueResponse(HTTP_OK, FILE_CONTENT.substring(0, initialLength))
+ .addHeader("Content-length", totalLength)
+ .addHeader("Etag", etag)
+ .setCloseConnectionAfter(true);
+ Download download = enqueueRequest(getRequest());
+
+ download.runUntilStatus(DownloadManager.STATUS_PAUSED);
+ assertEquals(initialLength,
+ download.getLongField(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
+
+ 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",
+ "bytes " + initialLength + "-" + totalLength + "/" + totalLength)
+ .addHeader("Etag", etag);
+ download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
+ assertEquals(totalLength,
+ download.getLongField(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
+ }
+
+ public void testFiltering() throws Exception {
+ enqueueEmptyResponse(HTTP_OK);
+ Download download1 = enqueueRequest(getRequest());
+ download1.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
+ enqueueEmptyResponse(HTTP_NOT_FOUND);
+ Download download2 = enqueueRequest(getRequest());
+ download2.runUntilStatus(DownloadManager.STATUS_FAILED);
+ Download download3 = enqueueRequest(getRequest());
+
+ Cursor cursor = mManager.query(new DownloadManager.Query());
+ checkAndCloseCursor(cursor, download1, download2, download3);
+
+ cursor = mManager.query(new DownloadManager.Query().setFilterById(download2.mId));
+ checkAndCloseCursor(cursor, download2);
+
+ cursor = mManager.query(new DownloadManager.Query()
+ .setFilterByStatus(DownloadManager.STATUS_PENDING));
+ checkAndCloseCursor(cursor, download3);
+
+ cursor = mManager.query(new DownloadManager.Query()
+ .setFilterByStatus(DownloadManager.STATUS_FAILED
+ | DownloadManager.STATUS_SUCCESSFUL));
+ checkAndCloseCursor(cursor, download1, download2);
+
+ cursor = mManager.query(new DownloadManager.Query()
+ .setFilterByStatus(DownloadManager.STATUS_RUNNING));
+ checkAndCloseCursor(cursor);
+ }
+
+ private void checkAndCloseCursor(Cursor cursor, Download... downloads) {
+ try {
+ int idIndex = cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_ID);
+ assertEquals(downloads.length, cursor.getCount());
+ cursor.moveToFirst();
+ for (Download download : downloads) {
+ assertEquals(download.mId, cursor.getLong(idIndex));
+ cursor.moveToNext();
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+
+ public void testInvalidUri() throws Exception {
+ try {
+ enqueueRequest(getRequest("/no_host"));
+ } catch (IllegalArgumentException exc) { // expected
+ return;
+ }
+
+ fail("No exception thrown for invalid URI");
+ }
+
+ private DownloadManager.Request getRequest() throws MalformedURLException {
+ return getRequest(getServerUri(REQUEST_PATH));
+ }
+
+ private DownloadManager.Request getRequest(String path) {
+ return new DownloadManager.Request(Uri.parse(path));
+ }
+
+ private Download enqueueRequest(DownloadManager.Request request) {
+ return new Download(mManager.enqueue(request));
+ }
+}