summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2012-03-29 13:38:24 -0700
committerJeff Sharkey <jsharkey@android.com>2012-03-29 15:10:31 -0700
commitae6856b0fca5215f45619dd031a7e7beae7bd8cc (patch)
treef54a7fcfc663db7a22e57f3f81d77f1c98f70fa9
parentdb4c69fbb558efe193ec81d593fc3868268ba2cf (diff)
downloadandroid_packages_providers_DownloadProvider-ae6856b0fca5215f45619dd031a7e7beae7bd8cc.zip
android_packages_providers_DownloadProvider-ae6856b0fca5215f45619dd031a7e7beae7bd8cc.tar.gz
android_packages_providers_DownloadProvider-ae6856b0fca5215f45619dd031a7e7beae7bd8cc.tar.bz2
Migrate to shared MockWebServer.
Bug: 4726601 Change-Id: Ibe537bd5c2a092dbf974360cd454751881f7f4ea
-rw-r--r--src/com/android/providers/downloads/DownloadThread.java1
-rw-r--r--tests/Android.mk1
-rw-r--r--tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java (renamed from tests/src/com/android/providers/downloads/AbstractDownloadManagerFunctionalTest.java)59
-rw-r--r--tests/src/com/android/providers/downloads/AbstractPublicApiTest.java6
-rw-r--r--tests/src/com/android/providers/downloads/DownloadProviderFunctionalTest.java (renamed from tests/src/com/android/providers/downloads/DownloadManagerFunctionalTest.java)21
-rw-r--r--tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java130
-rw-r--r--tests/src/com/android/providers/downloads/ThreadingTest.java2
-rw-r--r--tests/src/tests/http/MockResponse.java147
-rw-r--r--tests/src/tests/http/MockWebServer.java356
-rw-r--r--tests/src/tests/http/RecordedRequest.java93
10 files changed, 112 insertions, 704 deletions
diff --git a/src/com/android/providers/downloads/DownloadThread.java b/src/com/android/providers/downloads/DownloadThread.java
index 197af66..1d2aceb 100644
--- a/src/com/android/providers/downloads/DownloadThread.java
+++ b/src/com/android/providers/downloads/DownloadThread.java
@@ -974,5 +974,4 @@ public class DownloadThread extends Thread {
mPolicyDirty = true;
}
};
-
}
diff --git a/tests/Android.mk b/tests/Android.mk
index 80a1c76..aaf32ba 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -8,6 +8,7 @@ LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_INSTRUMENTATION_FOR := DownloadProvider
LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_STATIC_JAVA_LIBRARIES := mockwebserver
LOCAL_PACKAGE_NAME := DownloadProviderTests
LOCAL_CERTIFICATE := media
diff --git a/tests/src/com/android/providers/downloads/AbstractDownloadManagerFunctionalTest.java b/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java
index d2ecf3e..1912e84 100644
--- a/tests/src/com/android/providers/downloads/AbstractDownloadManagerFunctionalTest.java
+++ b/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java
@@ -29,9 +29,11 @@ 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 com.google.mockwebserver.MockResponse;
+import com.google.mockwebserver.MockWebServer;
+import com.google.mockwebserver.RecordedRequest;
+import com.google.mockwebserver.SocketPolicy;
import java.io.BufferedReader;
import java.io.File;
@@ -39,14 +41,15 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
+import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
-public abstract class AbstractDownloadManagerFunctionalTest extends
+public abstract class AbstractDownloadProviderFunctionalTest extends
ServiceTestCase<DownloadService> {
- protected static final String LOG_TAG = "DownloadManagerFunctionalTest";
+ 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";
@@ -143,7 +146,7 @@ public abstract class AbstractDownloadManagerFunctionalTest extends
}
}
- public AbstractDownloadManagerFunctionalTest(FakeSystemFacade systemFacade) {
+ public AbstractDownloadProviderFunctionalTest(FakeSystemFacade systemFacade) {
super(DownloadService.class);
mSystemFacade = systemFacade;
}
@@ -212,52 +215,42 @@ public abstract class AbstractDownloadManagerFunctionalTest extends
mResolver.delete(Downloads.Impl.CONTENT_URI, null, null);
}
- /**
- * Enqueue a String response from the MockWebServer.
- */
- MockResponse enqueueResponse(int status, String body) {
- MockResponse response = new MockResponse()
- .setResponseCode(status)
- .setBody(body)
- .addHeader("Content-type", "text/plain")
- .setCloseConnectionAfter(true);
- mServer.enqueue(response);
- return response;
+ void enqueueResponse(MockResponse resp) {
+ mServer.enqueue(resp);
}
- /**
- * Enqueue a byte[] response from the MockWebServer.
- */
- MockResponse enqueueResponse(int status, byte[] body) {
- MockResponse response = new MockResponse()
- .setResponseCode(status)
- .setBody(body)
- .addHeader("Content-type", "text/plain")
- .setCloseConnectionAfter(true);
- mServer.enqueue(response);
- return response;
+
+ MockResponse buildResponse(int status, String body) {
+ return new MockResponse().setResponseCode(status).setBody(body)
+ .setHeader("Content-type", "text/plain")
+ .setSocketPolicy(SocketPolicy.DISCONNECT_AT_END);
+ }
+
+ MockResponse buildResponse(int status, byte[] body) {
+ return new MockResponse().setResponseCode(status).setBody(body)
+ .setHeader("Content-type", "text/plain")
+ .setSocketPolicy(SocketPolicy.DISCONNECT_AT_END);
}
- MockResponse enqueueEmptyResponse(int status) {
- return enqueueResponse(status, "");
+ MockResponse buildEmptyResponse(int status) {
+ return buildResponse(status, "");
}
/**
* Fetch the last request received by the MockWebServer.
*/
protected RecordedRequest takeRequest() throws InterruptedException {
- RecordedRequest request = mServer.takeRequestWithTimeout(0);
+ RecordedRequest request = mServer.takeRequest();
assertNotNull("Expected request was not made", request);
return request;
}
- String getServerUri(String path) throws MalformedURLException {
+ String getServerUri(String path) throws MalformedURLException, UnknownHostException {
return mServer.getUrl(path).toString();
}
public void runService() throws Exception {
startService(null);
mSystemFacade.runAllThreads();
- mServer.checkForExceptions();
}
protected String readStream(InputStream inputStream) throws IOException {
diff --git a/tests/src/com/android/providers/downloads/AbstractPublicApiTest.java b/tests/src/com/android/providers/downloads/AbstractPublicApiTest.java
index c38c2f1..cda607a 100644
--- a/tests/src/com/android/providers/downloads/AbstractPublicApiTest.java
+++ b/tests/src/com/android/providers/downloads/AbstractPublicApiTest.java
@@ -26,11 +26,12 @@ import android.util.Log;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.MalformedURLException;
+import java.net.UnknownHostException;
/**
* Code common to tests that use the download manager public API.
*/
-public abstract class AbstractPublicApiTest extends AbstractDownloadManagerFunctionalTest {
+public abstract class AbstractPublicApiTest extends AbstractDownloadProviderFunctionalTest {
class Download {
final long mId;
@@ -171,7 +172,8 @@ public abstract class AbstractPublicApiTest extends AbstractDownloadManagerFunct
mManager = new DownloadManager(mResolver, PACKAGE_NAME);
}
- protected DownloadManager.Request getRequest() throws MalformedURLException {
+ protected DownloadManager.Request getRequest()
+ throws MalformedURLException, UnknownHostException {
return getRequest(getServerUri(REQUEST_PATH));
}
diff --git a/tests/src/com/android/providers/downloads/DownloadManagerFunctionalTest.java b/tests/src/com/android/providers/downloads/DownloadProviderFunctionalTest.java
index e01b617..bbc5c3e 100644
--- a/tests/src/com/android/providers/downloads/DownloadManagerFunctionalTest.java
+++ b/tests/src/com/android/providers/downloads/DownloadProviderFunctionalTest.java
@@ -25,11 +25,12 @@ import android.provider.Downloads;
import android.test.suitebuilder.annotation.LargeTest;
import android.util.Log;
-import tests.http.MockWebServer;
-import tests.http.RecordedRequest;
+import com.google.mockwebserver.MockWebServer;
+import com.google.mockwebserver.RecordedRequest;
import java.io.InputStream;
import java.net.MalformedURLException;
+import java.net.UnknownHostException;
/**
* This test exercises the entire download manager working together -- it requests downloads through
@@ -38,15 +39,15 @@ import java.net.MalformedURLException;
* device to serve downloads.
*/
@LargeTest
-public class DownloadManagerFunctionalTest extends AbstractDownloadManagerFunctionalTest {
+public class DownloadProviderFunctionalTest extends AbstractDownloadProviderFunctionalTest {
private static final String TAG = "DownloadManagerFunctionalTest";
- public DownloadManagerFunctionalTest() {
+ public DownloadProviderFunctionalTest() {
super(new FakeSystemFacade());
}
public void testDownloadTextFile() throws Exception {
- enqueueResponse(HTTP_OK, FILE_CONTENT);
+ enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
String path = "/download_manager_test_path";
Uri downloadUri = requestDownload(path);
@@ -63,7 +64,8 @@ public class DownloadManagerFunctionalTest extends AbstractDownloadManagerFuncti
}
public void testDownloadToCache() throws Exception {
- enqueueResponse(HTTP_OK, FILE_CONTENT);
+ enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
+
Uri downloadUri = requestDownload("/path");
updateDownload(downloadUri, Downloads.Impl.COLUMN_DESTINATION,
Integer.toString(Downloads.Impl.DESTINATION_CACHE_PARTITION));
@@ -74,11 +76,13 @@ public class DownloadManagerFunctionalTest extends AbstractDownloadManagerFuncti
}
public void testRoaming() throws Exception {
+ enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
+ enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
+
mSystemFacade.mActiveNetworkType = ConnectivityManager.TYPE_MOBILE;
mSystemFacade.mIsRoaming = true;
// for a normal download, roaming is fine
- enqueueResponse(HTTP_OK, FILE_CONTENT);
Uri downloadUri = requestDownload("/path");
runUntilStatus(downloadUri, Downloads.Impl.STATUS_SUCCESS);
@@ -89,7 +93,6 @@ public class DownloadManagerFunctionalTest extends AbstractDownloadManagerFuncti
runUntilStatus(downloadUri, Downloads.Impl.STATUS_WAITING_FOR_NETWORK);
// ...and pick up when we're off roaming
- enqueueResponse(HTTP_OK, FILE_CONTENT);
mSystemFacade.mIsRoaming = false;
runUntilStatus(downloadUri, Downloads.Impl.STATUS_SUCCESS);
}
@@ -145,7 +148,7 @@ public class DownloadManagerFunctionalTest extends AbstractDownloadManagerFuncti
/**
* Request a download from the Download Manager.
*/
- private Uri requestDownload(String path) throws MalformedURLException {
+ private Uri requestDownload(String path) throws MalformedURLException, UnknownHostException {
ContentValues values = new ContentValues();
values.put(Downloads.Impl.COLUMN_URI, getServerUri(path));
values.put(Downloads.Impl.COLUMN_DESTINATION, Downloads.Impl.DESTINATION_EXTERNAL);
diff --git a/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java b/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java
index f2a26f1..2f5282a 100644
--- a/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java
+++ b/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java
@@ -16,7 +16,6 @@
package com.android.providers.downloads;
-
import android.app.DownloadManager;
import android.content.Intent;
import android.database.Cursor;
@@ -25,9 +24,10 @@ import android.net.Uri;
import android.os.Environment;
import android.provider.Downloads;
import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
-import tests.http.MockResponse;
-import tests.http.RecordedRequest;
+import com.google.mockwebserver.MockResponse;
+import com.google.mockwebserver.RecordedRequest;
import java.io.File;
import java.io.FileInputStream;
@@ -76,7 +76,7 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
}
public void testBasicRequest() throws Exception {
- enqueueResponse(HTTP_OK, FILE_CONTENT);
+ enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
Download download = enqueueRequest(getRequest());
assertEquals(DownloadManager.STATUS_PENDING,
@@ -126,12 +126,12 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
}
public void testDownloadError() throws Exception {
- enqueueEmptyResponse(HTTP_NOT_FOUND);
+ enqueueResponse(buildEmptyResponse(HTTP_NOT_FOUND));
runSimpleFailureTest(HTTP_NOT_FOUND);
}
public void testUnhandledHttpStatus() throws Exception {
- enqueueEmptyResponse(1234); // some invalid HTTP status
+ enqueueResponse(buildEmptyResponse(1234)); // some invalid HTTP status
runSimpleFailureTest(DownloadManager.ERROR_UNHANDLED_HTTP_CODE);
}
@@ -168,21 +168,21 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
private void enqueueInterruptedDownloadResponses(int initialLength) {
// the first response has normal headers but unexpectedly closes after initialLength bytes
- enqueuePartialResponse(0, initialLength);
+ enqueueResponse(buildPartialResponse(0, initialLength));
// the second response returns partial content for the rest of the data
- enqueuePartialResponse(initialLength, FILE_CONTENT.length());
+ enqueueResponse(buildPartialResponse(initialLength, FILE_CONTENT.length()));
}
- private MockResponse enqueuePartialResponse(int start, int end) {
+ private MockResponse buildPartialResponse(int start, int end) {
int totalLength = FILE_CONTENT.length();
boolean isFirstResponse = (start == 0);
int status = isFirstResponse ? HTTP_OK : HTTP_PARTIAL_CONTENT;
- MockResponse response = enqueueResponse(status, FILE_CONTENT.substring(start, end))
- .addHeader("Content-length", totalLength)
- .addHeader("Etag", ETAG);
+ MockResponse response = buildResponse(status, FILE_CONTENT.substring(start, end))
+ .setHeader("Content-length", totalLength)
+ .setHeader("Etag", ETAG);
if (!isFirstResponse) {
- response.addHeader("Content-range",
- "bytes " + start + "-" + totalLength + "/" + totalLength);
+ response.setHeader(
+ "Content-range", "bytes " + start + "-" + totalLength + "/" + totalLength);
}
return response;
}
@@ -190,20 +190,21 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
// enqueue a huge response to keep the receiveing thread in DownloadThread.java busy for a while
// give enough time to do something (cancel/remove etc) on that downloadrequest
// while it is in progress
- private void enqueueContinuingResponse() {
+ private MockResponse buildContinuingResponse() {
int numPackets = 100;
- int contentLength = STRING_1K.length() * numPackets;
- enqueueResponse(HTTP_OK, STRING_1K)
- .addHeader("Content-length", contentLength)
- .addHeader("Etag", ETAG)
- .setNumPackets(numPackets);
+ int contentLength = STRING_1K.length() * numPackets;
+ return buildResponse(HTTP_OK, STRING_1K)
+ .setHeader("Content-length", contentLength)
+ .setHeader("Etag", ETAG)
+ .setBytesPerSecond(1024);
}
public void testFiltering() throws Exception {
- enqueueEmptyResponse(HTTP_OK);
+ enqueueResponse(buildEmptyResponse(HTTP_OK));
+ enqueueResponse(buildEmptyResponse(HTTP_NOT_FOUND));
+
Download download1 = enqueueRequest(getRequest());
download1.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
- enqueueEmptyResponse(HTTP_NOT_FOUND);
mSystemFacade.incrementTimeMillis(1); // ensure downloads are correctly ordered by time
Download download2 = enqueueRequest(getRequest());
@@ -240,17 +241,18 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
}
public void testOrdering() throws Exception {
- enqueueResponse(HTTP_OK, "small contents");
+ enqueueResponse(buildResponse(HTTP_OK, "small contents"));
+ enqueueResponse(buildResponse(HTTP_OK, "large contents large contents"));
+ enqueueResponse(buildEmptyResponse(HTTP_NOT_FOUND));
+
Download download1 = enqueueRequest(getRequest());
download1.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
mSystemFacade.incrementTimeMillis(1);
- enqueueResponse(HTTP_OK, "large contents large contents");
Download download2 = enqueueRequest(getRequest());
download2.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
mSystemFacade.incrementTimeMillis(1);
- enqueueEmptyResponse(HTTP_NOT_FOUND);
Download download3 = enqueueRequest(getRequest());
download3.runUntilStatus(DownloadManager.STATUS_FAILED);
@@ -299,7 +301,7 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
}
public void testDestination() throws Exception {
- enqueueResponse(HTTP_OK, FILE_CONTENT);
+ enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
Uri destination = getExternalUri();
Download download = enqueueRequest(getRequest().setDestinationUri(destination));
download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
@@ -320,7 +322,7 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
}
public void testRequestHeaders() throws Exception {
- enqueueEmptyResponse(HTTP_OK);
+ enqueueResponse(buildEmptyResponse(HTTP_OK));
Download download = enqueueRequest(getRequest().addRequestHeader("Header1", "value1")
.addRequestHeader("Header2", "value2"));
download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
@@ -342,17 +344,17 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
}
public void testSizeLimitOverMobile() throws Exception {
- mSystemFacade.mMaxBytesOverMobile = (long) FILE_CONTENT.length() - 1;
+ enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
+ enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
+ mSystemFacade.mMaxBytesOverMobile = (long) FILE_CONTENT.length() - 1;
mSystemFacade.mActiveNetworkType = ConnectivityManager.TYPE_MOBILE;
- enqueueResponse(HTTP_OK, FILE_CONTENT);
Download download = enqueueRequest(getRequest());
download.runUntilStatus(DownloadManager.STATUS_PAUSED);
mSystemFacade.mActiveNetworkType = ConnectivityManager.TYPE_WIFI;
// first response was read, but aborted after the DL manager processed the Content-Length
// header, so we need to enqueue a second one
- enqueueResponse(HTTP_OK, FILE_CONTENT);
download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
}
@@ -369,27 +371,28 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
}
public void testNoEtag() throws Exception {
- enqueuePartialResponse(0, 5).removeHeader("Etag");
+ enqueueResponse(buildPartialResponse(0, 5).removeHeader("Etag"));
runSimpleFailureTest(DownloadManager.ERROR_CANNOT_RESUME);
}
public void testSanitizeMediaType() throws Exception {
- enqueueEmptyResponse(HTTP_OK).addHeader("Content-Type", "text/html; charset=ISO-8859-4");
+ enqueueResponse(buildEmptyResponse(HTTP_OK)
+ .setHeader("Content-Type", "text/html; charset=ISO-8859-4"));
Download download = enqueueRequest(getRequest());
download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
assertEquals("text/html", download.getStringField(DownloadManager.COLUMN_MEDIA_TYPE));
}
public void testNoContentLength() throws Exception {
- enqueueEmptyResponse(HTTP_OK).removeHeader("Content-Length");
+ enqueueResponse(buildEmptyResponse(HTTP_OK).removeHeader("Content-length"));
runSimpleFailureTest(DownloadManager.ERROR_HTTP_DATA_ERROR);
}
public void testInsufficientSpace() throws Exception {
// this would be better done by stubbing the system API to check available space, but in the
// meantime, just use an absurdly large header value
- enqueueEmptyResponse(HTTP_OK).addHeader("Content-Length",
- 1024L * 1024 * 1024 * 1024 * 1024);
+ enqueueResponse(buildEmptyResponse(HTTP_OK)
+ .setHeader("Content-Length", 1024L * 1024 * 1024 * 1024 * 1024));
runSimpleFailureTest(DownloadManager.ERROR_INSUFFICIENT_SPACE);
}
@@ -397,7 +400,7 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
mSystemFacade.setStartThreadsWithoutWaiting(true);
// return 'real time' from FakeSystemFacade so that DownloadThread will report progress
mSystemFacade.setReturnActualTime(true);
- enqueueContinuingResponse();
+ enqueueResponse(buildContinuingResponse());
Download download = enqueueRequest(getRequest());
startService(null);
// give the download time to get started and progress to 1% completion
@@ -413,7 +416,7 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
}
public void testDownloadCompleteBroadcast() throws Exception {
- enqueueEmptyResponse(HTTP_OK);
+ enqueueResponse(buildEmptyResponse(HTTP_OK));
Download download = enqueueRequest(getRequest());
download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
@@ -441,12 +444,11 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
}
public void testBasicConnectivityChanges() throws Exception {
+ enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
+
// without connectivity, download immediately pauses
mSystemFacade.mActiveNetworkType = null;
-
- enqueueResponse(HTTP_OK, FILE_CONTENT);
Download download = enqueueRequest(getRequest());
-
download.runUntilStatus(DownloadManager.STATUS_PAUSED);
// connecting should start the download
@@ -455,10 +457,12 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
}
public void testAllowedNetworkTypes() throws Exception {
+ enqueueResponse(buildEmptyResponse(HTTP_OK));
+ enqueueResponse(buildEmptyResponse(HTTP_OK));
+
mSystemFacade.mActiveNetworkType = ConnectivityManager.TYPE_MOBILE;
// by default, use any connection
- enqueueEmptyResponse(HTTP_OK);
Download download = enqueueRequest(getRequest());
download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
@@ -468,15 +472,16 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
download.runUntilStatus(DownloadManager.STATUS_PAUSED);
// ...then enable wifi
mSystemFacade.mActiveNetworkType = ConnectivityManager.TYPE_WIFI;
- enqueueEmptyResponse(HTTP_OK);
download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
}
public void testRoaming() throws Exception {
+ enqueueResponse(buildEmptyResponse(HTTP_OK));
+ enqueueResponse(buildEmptyResponse(HTTP_OK));
+
mSystemFacade.mIsRoaming = true;
// by default, allow roaming
- enqueueEmptyResponse(HTTP_OK);
Download download = enqueueRequest(getRequest());
download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
@@ -485,12 +490,11 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
download.runUntilStatus(DownloadManager.STATUS_PAUSED);
// ...then turn off roaming
mSystemFacade.mIsRoaming = false;
- enqueueEmptyResponse(HTTP_OK);
download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
}
public void testContentObserver() throws Exception {
- enqueueEmptyResponse(HTTP_OK);
+ enqueueResponse(buildEmptyResponse(HTTP_OK));
enqueueRequest(getRequest());
mResolver.resetNotified();
runService();
@@ -498,13 +502,14 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
}
public void testNotifications() throws Exception {
- enqueueEmptyResponse(HTTP_OK);
+ enqueueResponse(buildEmptyResponse(HTTP_OK));
+ enqueueResponse(buildEmptyResponse(HTTP_OK));
+
Download download = enqueueRequest(getRequest().setShowRunningNotification(false));
download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
assertEquals(0, mSystemFacade.mActiveNotifications.size());
assertEquals(0, mSystemFacade.mCanceledNotifications.size());
- enqueueEmptyResponse(HTTP_OK);
download = enqueueRequest(getRequest()); // notifications by default
download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
assertEquals(1, mSystemFacade.mActiveNotifications.size());
@@ -518,43 +523,43 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
public void testRetryAfter() throws Exception {
final int delay = 120;
- enqueueEmptyResponse(HTTP_SERVICE_UNAVAILABLE).addHeader("Retry-after", delay);
+ enqueueResponse(
+ buildEmptyResponse(HTTP_SERVICE_UNAVAILABLE).setHeader("Retry-after", delay));
+ enqueueResponse(buildEmptyResponse(HTTP_OK));
+
Download download = enqueueRequest(getRequest());
download.runUntilStatus(DownloadManager.STATUS_PAUSED);
// download manager adds random 0-30s offset
mSystemFacade.incrementTimeMillis((delay + 31) * 1000);
-
- enqueueEmptyResponse(HTTP_OK);
download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
}
public void testManyInterruptions() throws Exception {
- int bytesPerResponse = 1;
- int start = 0;
+ final int length = FILE_CONTENT.length();
+ for (int i = 0; i < length; i++) {
+ enqueueResponse(buildPartialResponse(i, i + 1));
+ }
Download download = enqueueRequest(getRequest());
- while (start + bytesPerResponse < FILE_CONTENT.length()) {
- enqueuePartialResponse(start, start + bytesPerResponse);
+ for (int i = 0; i < length - 1; i++) {
download.runUntilStatus(DownloadManager.STATUS_PAUSED);
- takeRequest();
- start += bytesPerResponse;
mSystemFacade.incrementTimeMillis(RETRY_DELAY_MILLIS);
}
- enqueuePartialResponse(start, FILE_CONTENT.length());
download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
checkCompleteDownload(download);
}
public void testExistingFile() throws Exception {
+ enqueueResponse(buildEmptyResponse(HTTP_OK));
+
// download a file which already exists.
// downloadservice should simply create filename with "-" and a number attached
// at the end; i.e., download shouldnot fail.
Uri destination = getExternalUri();
new File(destination.getPath()).createNewFile();
- enqueueEmptyResponse(HTTP_OK);
Download download = enqueueRequest(getRequest().setDestinationUri(destination));
download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
}
@@ -571,11 +576,12 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
}
public void testRestart() throws Exception {
- enqueueEmptyResponse(HTTP_NOT_FOUND);
+ enqueueResponse(buildEmptyResponse(HTTP_NOT_FOUND));
+ enqueueResponse(buildEmptyResponse(HTTP_OK));
+
Download download = enqueueRequest(getRequest());
download.runUntilStatus(DownloadManager.STATUS_FAILED);
- enqueueEmptyResponse(HTTP_OK);
mManager.restartDownload(download.mId);
assertEquals(DownloadManager.STATUS_PENDING,
download.getLongField(DownloadManager.COLUMN_STATUS));
@@ -604,8 +610,8 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest {
*/
private RecordedRequest runRedirectionTest(int status)
throws MalformedURLException, Exception {
- enqueueEmptyResponse(status).addHeader("Location",
- mServer.getUrl(REDIRECTED_PATH).toString());
+ enqueueResponse(buildEmptyResponse(status)
+ .setHeader("Location", mServer.getUrl(REDIRECTED_PATH).toString()));
enqueueInterruptedDownloadResponses(5);
Download download = enqueueRequest(getRequest());
diff --git a/tests/src/com/android/providers/downloads/ThreadingTest.java b/tests/src/com/android/providers/downloads/ThreadingTest.java
index 082579e..8605c76 100644
--- a/tests/src/com/android/providers/downloads/ThreadingTest.java
+++ b/tests/src/com/android/providers/downloads/ThreadingTest.java
@@ -46,7 +46,7 @@ public class ThreadingTest extends AbstractPublicApiTest {
* a download.
*/
public void testFloodServiceWithStarts() throws Exception {
- enqueueResponse(HTTP_OK, FILE_CONTENT);
+ enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
Download download = enqueueRequest(getRequest());
while (download.getStatus() != DownloadManager.STATUS_SUCCESSFUL) {
startService(null);
diff --git a/tests/src/tests/http/MockResponse.java b/tests/src/tests/http/MockResponse.java
deleted file mode 100644
index aec5490..0000000
--- a/tests/src/tests/http/MockResponse.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * 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 tests.http;
-
-import static tests.http.MockWebServer.ASCII;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * A scripted response to be replayed by the mock web server.
- */
-public class MockResponse {
- private static final byte[] EMPTY_BODY = new byte[0];
-
- private String status = "HTTP/1.1 200 OK";
- private Map<String, String> headers = new HashMap<String, String>();
- private byte[] body = EMPTY_BODY;
- private boolean closeConnectionAfter = false;
- private int numPackets = 0;
-
- public MockResponse() {
- addHeader("Content-Length", 0);
- }
-
- /**
- * Returns the HTTP response line, such as "HTTP/1.1 200 OK".
- */
- public String getStatus() {
- return status;
- }
-
- public MockResponse setResponseCode(int code) {
- this.status = "HTTP/1.1 " + code + " OK";
- return this;
- }
-
- /**
- * Returns the HTTP headers, such as "Content-Length: 0".
- */
- public List<String> getHeaders() {
- List<String> headerStrings = new ArrayList<String>();
- for (String header : headers.keySet()) {
- headerStrings.add(header + ": " + headers.get(header));
- }
- return headerStrings;
- }
-
- public MockResponse addHeader(String header, String value) {
- headers.put(header.toLowerCase(), value);
- return this;
- }
-
- public MockResponse addHeader(String header, long value) {
- return addHeader(header, Long.toString(value));
- }
-
- public MockResponse removeHeader(String header) {
- headers.remove(header.toLowerCase());
- return this;
- }
-
- /**
- * Returns an input stream containing the raw HTTP payload.
- */
- public byte[] getBody() {
- return body;
- }
-
- public MockResponse setBody(byte[] body) {
- addHeader("Content-Length", body.length);
- this.body = body;
- return this;
- }
-
- public MockResponse setBody(String body) {
- try {
- return setBody(body.getBytes(ASCII));
- } catch (UnsupportedEncodingException e) {
- throw new AssertionError();
- }
- }
-
- public MockResponse setChunkedBody(byte[] body, int maxChunkSize) throws IOException {
- addHeader("Transfer-encoding", "chunked");
-
- ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
- int pos = 0;
- while (pos < body.length) {
- int chunkSize = Math.min(body.length - pos, maxChunkSize);
- bytesOut.write(Integer.toHexString(chunkSize).getBytes(ASCII));
- bytesOut.write("\r\n".getBytes(ASCII));
- bytesOut.write(body, pos, chunkSize);
- bytesOut.write("\r\n".getBytes(ASCII));
- pos += chunkSize;
- }
- bytesOut.write("0\r\n".getBytes(ASCII));
- this.body = bytesOut.toByteArray();
- return this;
- }
-
- public MockResponse setChunkedBody(String body, int maxChunkSize) throws IOException {
- return setChunkedBody(body.getBytes(ASCII), maxChunkSize);
- }
-
- @Override public String toString() {
- return status;
- }
-
- public boolean shouldCloseConnectionAfter() {
- return closeConnectionAfter;
- }
-
- public MockResponse setCloseConnectionAfter(boolean closeConnectionAfter) {
- this.closeConnectionAfter = closeConnectionAfter;
- return this;
- }
-
- public int getNumPackets() {
- return numPackets;
- }
-
- public MockResponse setNumPackets(int numPackets) {
- this.numPackets = numPackets;
- return this;
- }
-
-}
diff --git a/tests/src/tests/http/MockWebServer.java b/tests/src/tests/http/MockWebServer.java
deleted file mode 100644
index 6096783..0000000
--- a/tests/src/tests/http/MockWebServer.java
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * 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 tests.http;
-
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.MalformedURLException;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-
-/**
- * A scriptable web server. Callers supply canned responses and the server
- * replays them upon request in sequence.
- *
- * TODO: merge with the version from libcore/support/src/tests/java once it's in.
- */
-public final class MockWebServer {
- static final String ASCII = "US-ASCII";
-
- private final BlockingQueue<RecordedRequest> requestQueue
- = new LinkedBlockingQueue<RecordedRequest>();
- private final BlockingQueue<MockResponse> responseQueue
- = new LinkedBlockingQueue<MockResponse>();
- private int bodyLimit = Integer.MAX_VALUE;
- private final ExecutorService executor = Executors.newCachedThreadPool();
- // keep Futures around so we can rethrow any exceptions thrown by Callables
- private final Queue<Future<?>> futures = new LinkedList<Future<?>>();
-
- private int port = -1;
- private ServerSocket serverSocket;
-
- public int getPort() {
- if (port == -1) {
- throw new IllegalStateException("Cannot retrieve port before calling play()");
- }
- return port;
- }
-
- /**
- * Returns a URL for connecting to this server.
- *
- * @param path the request path, such as "/".
- */
- public URL getUrl(String path) throws MalformedURLException {
- return new URL("http://localhost:" + getPort() + path);
- }
-
- /**
- * Sets the number of bytes of the POST body to keep in memory to the given
- * limit.
- */
- public void setBodyLimit(int maxBodyLength) {
- this.bodyLimit = maxBodyLength;
- }
-
- public void enqueue(MockResponse response) {
- responseQueue.add(response);
- }
-
- /**
- * Awaits the next HTTP request, removes it, and returns it. Callers should
- * use this to verify the request sent was as intended.
- */
- public RecordedRequest takeRequest() throws InterruptedException {
- return requestQueue.take();
- }
-
- public RecordedRequest takeRequestWithTimeout(long timeoutMillis) throws InterruptedException {
- return requestQueue.poll(timeoutMillis, TimeUnit.MILLISECONDS);
- }
-
- public List<RecordedRequest> drainRequests() {
- List<RecordedRequest> requests = new ArrayList<RecordedRequest>();
- requestQueue.drainTo(requests);
- return requests;
- }
-
- /**
- * Starts the server, serves all enqueued requests, and shuts the server
- * down.
- */
- public void play() throws IOException {
- serverSocket = new ServerSocket(0);
- serverSocket.setReuseAddress(true);
- port = serverSocket.getLocalPort();
- submitCallable(new Callable<Void>() {
- public Void call() throws Exception {
- int count = 0;
- while (true) {
- if (count > 0 && responseQueue.isEmpty()) {
- serverSocket.close();
- executor.shutdown();
- return null;
- }
-
- serveConnection(serverSocket.accept());
- count++;
- }
- }
- });
- }
-
- /**
- * shutdown the webserver
- */
- public void shutdown() throws IOException {
- responseQueue.clear();
- serverSocket.close();
- executor.shutdown();
- }
-
- private void serveConnection(final Socket s) {
- submitCallable(new Callable<Void>() {
- public Void call() throws Exception {
- InputStream in = new BufferedInputStream(s.getInputStream());
- OutputStream out = new BufferedOutputStream(s.getOutputStream());
-
- int sequenceNumber = 0;
- while (true) {
- RecordedRequest request = readRequest(in, sequenceNumber);
- if (request == null) {
- if (sequenceNumber == 0) {
- throw new IllegalStateException("Connection without any request!");
- } else {
- break;
- }
- }
- requestQueue.add(request);
- MockResponse response = sendResponse(out, request);
- if (response.shouldCloseConnectionAfter()) {
- break;
- }
- sequenceNumber++;
- }
-
- in.close();
- out.close();
- return null;
- }
- });
- }
-
- private void submitCallable(Callable<?> callable) {
- Future<?> future = executor.submit(callable);
- futures.add(future);
- }
-
- /**
- * Check for and raise any exceptions that have been thrown by child threads. Will not block on
- * children still running.
- * @throws ExecutionException for the first child thread that threw an exception
- */
- public void checkForExceptions() throws ExecutionException, InterruptedException {
- final int originalSize = futures.size();
- for (int i = 0; i < originalSize; i++) {
- Future<?> future = futures.remove();
- try {
- future.get(0, TimeUnit.SECONDS);
- } catch (TimeoutException e) {
- futures.add(future); // still running
- }
- }
- }
-
- /**
- * @param sequenceNumber the index of this request on this connection.
- */
- private RecordedRequest readRequest(InputStream in, int sequenceNumber) throws IOException {
- String request = readAsciiUntilCrlf(in);
- if (request.equals("")) {
- return null; // end of data; no more requests
- }
-
- List<String> headers = new ArrayList<String>();
- int contentLength = -1;
- boolean chunked = false;
- String header;
- while (!(header = readAsciiUntilCrlf(in)).equals("")) {
- headers.add(header);
- String lowercaseHeader = header.toLowerCase();
- if (contentLength == -1 && lowercaseHeader.startsWith("content-length:")) {
- contentLength = Integer.parseInt(header.substring(15).trim());
- }
- if (lowercaseHeader.startsWith("transfer-encoding:") &&
- lowercaseHeader.substring(18).trim().equals("chunked")) {
- chunked = true;
- }
- }
-
- boolean hasBody = false;
- TruncatingOutputStream requestBody = new TruncatingOutputStream();
- List<Integer> chunkSizes = new ArrayList<Integer>();
- if (contentLength != -1) {
- hasBody = true;
- transfer(contentLength, in, requestBody);
- } else if (chunked) {
- hasBody = true;
- while (true) {
- int chunkSize = Integer.parseInt(readAsciiUntilCrlf(in).trim(), 16);
- if (chunkSize == 0) {
- readEmptyLine(in);
- break;
- }
- chunkSizes.add(chunkSize);
- transfer(chunkSize, in, requestBody);
- readEmptyLine(in);
- }
- }
-
- if (request.startsWith("GET ")) {
- if (hasBody) {
- throw new IllegalArgumentException("GET requests should not have a body!");
- }
- } else if (request.startsWith("POST ")) {
- if (!hasBody) {
- throw new IllegalArgumentException("POST requests must have a body!");
- }
- } else {
- throw new UnsupportedOperationException("Unexpected method: " + request);
- }
- return new RecordedRequest(request, headers, chunkSizes,
- requestBody.numBytesReceived, requestBody.toByteArray(), sequenceNumber);
- }
-
- /**
- * Returns a response to satisfy {@code request}.
- */
- private MockResponse sendResponse(OutputStream out, RecordedRequest request)
- throws InterruptedException, IOException {
- if (responseQueue.isEmpty()) {
- throw new IllegalStateException("Unexpected request: " + request);
- }
- MockResponse response = responseQueue.take();
- writeResponse(out, response, false);
- if (response.getNumPackets() > 0) {
- // there are continuing packets to send as part of this response.
- for (int i = 0; i < response.getNumPackets(); i++) {
- writeResponse(out, response, true);
- // delay sending next continuing response just a little bit
- Thread.sleep(100);
- }
- }
- return response;
- }
-
- private void writeResponse(OutputStream out, MockResponse response,
- boolean continuingPacket) throws IOException {
- if (continuingPacket) {
- // this is a continuing response - just send the body - no headers, status
- out.write(response.getBody());
- out.flush();
- return;
- }
- out.write((response.getStatus() + "\r\n").getBytes(ASCII));
- for (String header : response.getHeaders()) {
- out.write((header + "\r\n").getBytes(ASCII));
- }
- out.write(("\r\n").getBytes(ASCII));
- out.write(response.getBody());
- out.flush();
- }
-
- /**
- * Transfer bytes from {@code in} to {@code out} until either {@code length}
- * bytes have been transferred or {@code in} is exhausted.
- */
- private void transfer(int length, InputStream in, OutputStream out) throws IOException {
- byte[] buffer = new byte[1024];
- while (length > 0) {
- int count = in.read(buffer, 0, Math.min(buffer.length, length));
- if (count == -1) {
- return;
- }
- out.write(buffer, 0, count);
- length -= count;
- }
- }
-
- /**
- * Returns the text from {@code in} until the next "\r\n", or null if
- * {@code in} is exhausted.
- */
- private String readAsciiUntilCrlf(InputStream in) throws IOException {
- StringBuilder builder = new StringBuilder();
- while (true) {
- int c = in.read();
- if (c == '\n' && builder.length() > 0 && builder.charAt(builder.length() - 1) == '\r') {
- builder.deleteCharAt(builder.length() - 1);
- return builder.toString();
- } else if (c == -1) {
- return builder.toString();
- } else {
- builder.append((char) c);
- }
- }
- }
-
- private void readEmptyLine(InputStream in) throws IOException {
- String line = readAsciiUntilCrlf(in);
- if (!line.equals("")) {
- throw new IllegalStateException("Expected empty but was: " + line);
- }
- }
-
- /**
- * An output stream that drops data after bodyLimit bytes.
- */
- private class TruncatingOutputStream extends ByteArrayOutputStream {
- private int numBytesReceived = 0;
- @Override public void write(byte[] buffer, int offset, int len) {
- numBytesReceived += len;
- super.write(buffer, offset, Math.min(len, bodyLimit - count));
- }
- @Override public void write(int oneByte) {
- numBytesReceived++;
- if (count < bodyLimit) {
- super.write(oneByte);
- }
- }
- }
-}
diff --git a/tests/src/tests/http/RecordedRequest.java b/tests/src/tests/http/RecordedRequest.java
deleted file mode 100644
index 6b67af2..0000000
--- a/tests/src/tests/http/RecordedRequest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * 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 tests.http;
-
-import java.util.List;
-
-/**
- * An HTTP request that came into the mock web server.
- */
-public final class RecordedRequest {
- private final String requestLine;
- private final List<String> headers;
- private final List<Integer> chunkSizes;
- private final int bodySize;
- private final byte[] body;
- private final int sequenceNumber;
-
- RecordedRequest(String requestLine, List<String> headers, List<Integer> chunkSizes,
- int bodySize, byte[] body, int sequenceNumber) {
- this.requestLine = requestLine;
- this.headers = headers;
- this.chunkSizes = chunkSizes;
- this.bodySize = bodySize;
- this.body = body;
- this.sequenceNumber = sequenceNumber;
- }
-
- public String getRequestLine() {
- return requestLine;
- }
-
- public List<String> getHeaders() {
- return headers;
- }
-
- /**
- * Returns the sizes of the chunks of this request's body, or an empty list
- * if the request's body was empty or unchunked.
- */
- public List<Integer> getChunkSizes() {
- return chunkSizes;
- }
-
- /**
- * Returns the total size of the body of this POST request (before
- * truncation).
- */
- public int getBodySize() {
- return bodySize;
- }
-
- /**
- * Returns the body of this POST request. This may be truncated.
- */
- public byte[] getBody() {
- return body;
- }
-
- /**
- * Returns the index of this request on its HTTP connection. Since a single
- * HTTP connection may serve multiple requests, each request is assigned its
- * own sequence number.
- */
- public int getSequenceNumber() {
- return sequenceNumber;
- }
-
- @Override public String toString() {
- return requestLine;
- }
-
- public String getMethod() {
- return getRequestLine().split(" ")[0];
- }
-
- public String getPath() {
- return getRequestLine().split(" ")[1];
- }
-}