summaryrefslogtreecommitdiffstats
path: root/tests/src/com
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2013-01-29 14:48:46 -0800
committerJeff Sharkey <jsharkey@android.com>2013-01-29 15:36:51 -0800
commit58eee87b70862a7ced85eabc3c225fad24664065 (patch)
tree306bd82ba9eab04c2e2a4936a406651c08675a7b /tests/src/com
parent38648831a92295e9a11831e19e5a9dab4cbd939e (diff)
downloadandroid_packages_providers_DownloadProvider-58eee87b70862a7ced85eabc3c225fad24664065.tar.gz
android_packages_providers_DownloadProvider-58eee87b70862a7ced85eabc3c225fad24664065.tar.bz2
android_packages_providers_DownloadProvider-58eee87b70862a7ced85eabc3c225fad24664065.zip
Tests for max retries/redirects, ETag switches.
Verify that servers responding with many retries or redirects result in failed download, instead of spinning out of control. Test to verify that changed ETag results in download failing. Also fix handling of HTTP 301 to update Uri in database. Change-Id: Iff2948d79961a245b7900117d107edaa356618c9
Diffstat (limited to 'tests/src/com')
-rw-r--r--tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java8
-rw-r--r--tests/src/com/android/providers/downloads/AbstractPublicApiTest.java8
-rw-r--r--tests/src/com/android/providers/downloads/DownloadProviderFunctionalTest.java1
-rw-r--r--tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java103
-rw-r--r--tests/src/com/android/providers/downloads/ThreadingTest.java2
5 files changed, 108 insertions, 14 deletions
diff --git a/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java b/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java
index 48eb0b47..acfd4736 100644
--- a/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java
+++ b/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java
@@ -52,11 +52,9 @@ public abstract class AbstractDownloadProviderFunctionalTest extends
protected static final String LOG_TAG = "DownloadProviderFunctionalTest";
private static final String PROVIDER_AUTHORITY = "downloads";
protected static final long RETRY_DELAY_MILLIS = 61 * 1000;
- protected static final String FILE_CONTENT = "hello world hello world hello world 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 static final String
+ FILE_CONTENT = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
protected MockWebServer mServer;
protected MockContentResolverWithNotify mResolver;
diff --git a/tests/src/com/android/providers/downloads/AbstractPublicApiTest.java b/tests/src/com/android/providers/downloads/AbstractPublicApiTest.java
index e7f08c90..bff9333a 100644
--- a/tests/src/com/android/providers/downloads/AbstractPublicApiTest.java
+++ b/tests/src/com/android/providers/downloads/AbstractPublicApiTest.java
@@ -27,7 +27,6 @@ import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
import android.util.Log;
-import java.io.FileInputStream;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.UnknownHostException;
@@ -49,6 +48,10 @@ public abstract class AbstractPublicApiTest extends AbstractDownloadProviderFunc
return (int) getLongField(DownloadManager.COLUMN_STATUS);
}
+ public int getReason() {
+ return (int) getLongField(DownloadManager.COLUMN_REASON);
+ }
+
public int getStatusIfExists() {
Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId));
try {
@@ -91,7 +94,8 @@ public abstract class AbstractPublicApiTest extends AbstractDownloadProviderFunc
ParcelFileDescriptor downloadedFile = mManager.openDownloadedFile(mId);
assertTrue("Invalid file descriptor: " + downloadedFile,
downloadedFile.getFileDescriptor().valid());
- InputStream stream = new FileInputStream(downloadedFile.getFileDescriptor());
+ final InputStream stream = new ParcelFileDescriptor.AutoCloseInputStream(
+ downloadedFile);
try {
return readStream(stream);
} finally {
diff --git a/tests/src/com/android/providers/downloads/DownloadProviderFunctionalTest.java b/tests/src/com/android/providers/downloads/DownloadProviderFunctionalTest.java
index d5249378..dbab203c 100644
--- a/tests/src/com/android/providers/downloads/DownloadProviderFunctionalTest.java
+++ b/tests/src/com/android/providers/downloads/DownloadProviderFunctionalTest.java
@@ -17,6 +17,7 @@
package com.android.providers.downloads;
import static android.text.format.DateUtils.SECOND_IN_MILLIS;
+import static java.net.HttpURLConnection.HTTP_OK;
import android.content.ContentValues;
import android.database.Cursor;
diff --git a/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java b/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java
index 09739c0d..84390aad 100644
--- a/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java
+++ b/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java
@@ -16,6 +16,9 @@
package com.android.providers.downloads;
+import static android.app.DownloadManager.STATUS_FAILED;
+import static android.app.DownloadManager.STATUS_PAUSED;
+import static android.text.format.DateUtils.SECOND_IN_MILLIS;
import static com.google.testing.littlemock.LittleMock.anyInt;
import static com.google.testing.littlemock.LittleMock.anyString;
import static com.google.testing.littlemock.LittleMock.atLeastOnce;
@@ -23,6 +26,12 @@ import static com.google.testing.littlemock.LittleMock.isA;
import static com.google.testing.littlemock.LittleMock.never;
import static com.google.testing.littlemock.LittleMock.times;
import static com.google.testing.littlemock.LittleMock.verify;
+import static java.net.HttpURLConnection.HTTP_MOVED_TEMP;
+import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
+import static java.net.HttpURLConnection.HTTP_OK;
+import static java.net.HttpURLConnection.HTTP_PARTIAL;
+import static java.net.HttpURLConnection.HTTP_PRECON_FAILED;
+import static java.net.HttpURLConnection.HTTP_UNAVAILABLE;
import android.app.DownloadManager;
import android.app.Notification;
@@ -33,6 +42,7 @@ import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Environment;
+import android.os.SystemClock;
import android.provider.Downloads;
import android.test.suitebuilder.annotation.LargeTest;
@@ -44,8 +54,8 @@ import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
-import java.net.MalformedURLException;
import java.util.List;
+import java.util.concurrent.TimeoutException;
@LargeTest
public class PublicApiFunctionalTest extends AbstractPublicApiTest {
@@ -189,7 +199,7 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
private MockResponse buildPartialResponse(int start, int end) {
int totalLength = FILE_CONTENT.length();
boolean isFirstResponse = (start == 0);
- int status = isFirstResponse ? HTTP_OK : HTTP_PARTIAL_CONTENT;
+ int status = isFirstResponse ? HTTP_OK : HTTP_PARTIAL;
MockResponse response = buildResponse(status, FILE_CONTENT.substring(start, end))
.setHeader("Content-length", totalLength)
.setHeader("Etag", ETAG);
@@ -383,11 +393,72 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
assertEquals(REQUEST_PATH, lastRequest.getPath());
}
+ public void testRunawayRedirect() throws Exception {
+ for (int i = 0; i < 16; i++) {
+ enqueueResponse(buildEmptyResponse(HTTP_MOVED_TEMP)
+ .setHeader("Location", mServer.getUrl("/" + i).toString()));
+ }
+
+ final Download download = enqueueRequest(getRequest());
+
+ // Ensure that we arrive at failed download, instead of spinning forever
+ download.runUntilStatus(DownloadManager.STATUS_FAILED);
+ assertEquals(DownloadManager.ERROR_TOO_MANY_REDIRECTS, download.getReason());
+ }
+
+ public void testRunawayUnavailable() throws Exception {
+ final int RETRY_DELAY = 120;
+ for (int i = 0; i < 16; i++) {
+ enqueueResponse(
+ buildEmptyResponse(HTTP_UNAVAILABLE).setHeader("Retry-after", RETRY_DELAY));
+ }
+
+ final Download download = enqueueRequest(getRequest());
+ for (int i = 0; i < Constants.MAX_RETRIES - 1; i++) {
+ download.runUntilStatus(DownloadManager.STATUS_PAUSED);
+ mSystemFacade.incrementTimeMillis((RETRY_DELAY + 60) * SECOND_IN_MILLIS);
+ }
+
+ // Ensure that we arrive at failed download, instead of spinning forever
+ download.runUntilStatus(DownloadManager.STATUS_FAILED);
+ }
+
public void testNoEtag() throws Exception {
enqueueResponse(buildPartialResponse(0, 5).removeHeader("Etag"));
runSimpleFailureTest(DownloadManager.ERROR_CANNOT_RESUME);
}
+ public void testEtagChanged() throws Exception {
+ final String A = "kittenz";
+ final String B = "puppiez";
+
+ // 1. Try downloading A, but partial result
+ enqueueResponse(buildResponse(HTTP_OK, A.substring(0, 2))
+ .setHeader("Content-length", A.length())
+ .setHeader("Etag", A));
+
+ // 2. Try resuming A, but fail ETag check
+ enqueueResponse(buildEmptyResponse(HTTP_PRECON_FAILED));
+
+ final Download download = enqueueRequest(getRequest());
+ RecordedRequest req;
+
+ // 1. Try downloading A, but partial result
+ download.runUntilStatus(STATUS_PAUSED);
+ assertEquals(DownloadManager.PAUSED_WAITING_TO_RETRY, download.getReason());
+ req = takeRequest();
+ assertNull(getHeaderValue(req, "Range"));
+ assertNull(getHeaderValue(req, "If-Match"));
+
+ // 2. Try resuming A, but fail ETag check
+ mSystemFacade.incrementTimeMillis(RETRY_DELAY_MILLIS);
+ download.runUntilStatus(STATUS_FAILED);
+ assertEquals(HTTP_PRECON_FAILED, download.getReason());
+ req = takeRequest();
+ assertEquals("bytes=2-", getHeaderValue(req, "Range"));
+ assertEquals(A, getHeaderValue(req, "If-Match"));
+ }
+
public void testSanitizeMediaType() throws Exception {
enqueueResponse(buildEmptyResponse(HTTP_OK)
.setHeader("Content-Type", "text/html; charset=ISO-8859-4"));
@@ -420,8 +491,14 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
assertTrue(rslt);
mManager.remove(download.mId);
- // make sure the row is gone from the database
- download.waitForStatus(-1, -1);
+ // Verify that row is removed from database
+ final long timeout = SystemClock.elapsedRealtime() + (15 * SECOND_IN_MILLIS);
+ while (download.getStatusIfExists() != -1) {
+ if (SystemClock.elapsedRealtime() > timeout) {
+ throw new TimeoutException("Row wasn't removed");
+ }
+ SystemClock.sleep(100);
+ }
}
public void testDownloadCompleteBroadcast() throws Exception {
@@ -550,7 +627,7 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
public void testRetryAfter() throws Exception {
final int delay = 120;
enqueueResponse(
- buildEmptyResponse(HTTP_SERVICE_UNAVAILABLE).setHeader("Retry-after", delay));
+ buildEmptyResponse(HTTP_UNAVAILABLE).setHeader("Retry-after", delay));
enqueueResponse(buildEmptyResponse(HTTP_OK));
Download download = enqueueRequest(getRequest());
@@ -634,8 +711,7 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
* 3) Resume request to complete download
* @return the last request sent to the server, resuming after the interruption
*/
- private RecordedRequest runRedirectionTest(int status)
- throws MalformedURLException, Exception {
+ private RecordedRequest runRedirectionTest(int status) throws Exception {
enqueueResponse(buildEmptyResponse(status)
.setHeader("Location", mServer.getUrl(REDIRECTED_PATH).toString()));
enqueueInterruptedDownloadResponses(5);
@@ -650,4 +726,17 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
return takeRequest();
}
+
+ /**
+ * Return value of requested HTTP header, if it exists.
+ */
+ private static String getHeaderValue(RecordedRequest req, String header) {
+ header = header.toLowerCase() + ":";
+ for (String h : req.getHeaders()) {
+ if (h.toLowerCase().startsWith(header)) {
+ return h.substring(header.length()).trim();
+ }
+ }
+ return null;
+ }
}
diff --git a/tests/src/com/android/providers/downloads/ThreadingTest.java b/tests/src/com/android/providers/downloads/ThreadingTest.java
index e73bae2a..fcb33290 100644
--- a/tests/src/com/android/providers/downloads/ThreadingTest.java
+++ b/tests/src/com/android/providers/downloads/ThreadingTest.java
@@ -16,6 +16,8 @@
package com.android.providers.downloads;
+import static java.net.HttpURLConnection.HTTP_OK;
+
import android.app.DownloadManager;
import android.test.suitebuilder.annotation.LargeTest;