diff options
Diffstat (limited to 'tests/src/com/android')
5 files changed, 155 insertions, 19 deletions
diff --git a/tests/src/com/android/providers/downloads/AbstractDownloadManagerFunctionalTest.java b/tests/src/com/android/providers/downloads/AbstractDownloadManagerFunctionalTest.java index a06597f1..5283d425 100644 --- a/tests/src/com/android/providers/downloads/AbstractDownloadManagerFunctionalTest.java +++ b/tests/src/com/android/providers/downloads/AbstractDownloadManagerFunctionalTest.java @@ -59,6 +59,14 @@ public abstract class AbstractDownloadManagerFunctionalTest extends protected MockContentResolverWithNotify mResolver; protected TestContext mTestContext; protected FakeSystemFacade mSystemFacade; + protected static String STRING_1K; + static { + StringBuilder buff = new StringBuilder(); + for (int i = 0; i < 1024; i++) { + buff.append("a" + i % 26); + } + STRING_1K = buff.toString(); + } static class MockContentResolverWithNotify extends MockContentResolver { public boolean mNotifyWasCalled = false; @@ -161,6 +169,7 @@ public abstract class AbstractDownloadManagerFunctionalTest extends @Override protected void tearDown() throws Exception { cleanUpDownloads(); + mServer.shutdown(); super.tearDown(); } @@ -205,7 +214,7 @@ public abstract class AbstractDownloadManagerFunctionalTest extends } /** - * Enqueue a response from the MockWebServer. + * Enqueue a String response from the MockWebServer. */ MockResponse enqueueResponse(int status, String body) { MockResponse response = new MockResponse() @@ -216,6 +225,18 @@ public abstract class AbstractDownloadManagerFunctionalTest extends mServer.enqueue(response); return response; } + /** + * 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 enqueueEmptyResponse(int status) { return enqueueResponse(status, ""); diff --git a/tests/src/com/android/providers/downloads/AbstractPublicApiTest.java b/tests/src/com/android/providers/downloads/AbstractPublicApiTest.java index ed443b01..c38c2f1d 100644 --- a/tests/src/com/android/providers/downloads/AbstractPublicApiTest.java +++ b/tests/src/com/android/providers/downloads/AbstractPublicApiTest.java @@ -20,6 +20,8 @@ import android.app.DownloadManager; import android.database.Cursor; import android.net.Uri; import android.os.ParcelFileDescriptor; +import android.provider.Downloads; +import android.util.Log; import java.io.FileInputStream; import java.io.InputStream; @@ -41,6 +43,22 @@ public abstract class AbstractPublicApiTest extends AbstractDownloadManagerFunct return (int) getLongField(DownloadManager.COLUMN_STATUS); } + public int getStatusIfExists() { + Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId)); + try { + if (cursor.getCount() > 0) { + cursor.moveToFirst(); + return (int) cursor.getLong(cursor.getColumnIndexOrThrow( + DownloadManager.COLUMN_STATUS)); + } else { + // the row doesn't exist + return -1; + } + } finally { + cursor.close(); + } + } + String getStringField(String field) { Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId)); try { @@ -79,6 +97,63 @@ public abstract class AbstractPublicApiTest extends AbstractDownloadManagerFunct runService(); assertEquals(status, getStatus()); } + + // max time to wait before giving up on the current download operation. + private static final int MAX_TIME_TO_WAIT_FOR_OPERATION = 5; + // while waiting for the above time period, sleep this long to yield to the + // download thread + private static final int TIME_TO_SLEEP = 1000; + + int runUntilDone() throws InterruptedException { + int sleepCounter = MAX_TIME_TO_WAIT_FOR_OPERATION * 1000 / TIME_TO_SLEEP; + for (int i = 0; i < sleepCounter; i++) { + int status = getStatusIfExists(); + if (status == -1 || Downloads.Impl.isStatusCompleted(getStatus())) { + // row doesn't exist or the download is done + return status; + } + // download not done yet. sleep a while and try again + Thread.sleep(TIME_TO_SLEEP); + } + return 0; // failed + } + + // waits until progress_so_far is >= (progress)% + boolean runUntilProgress(int progress) throws InterruptedException { + int sleepCounter = MAX_TIME_TO_WAIT_FOR_OPERATION * 1000 / TIME_TO_SLEEP; + int numBytesReceivedSoFar = 0; + int totalBytes = 0; + for (int i = 0; i < sleepCounter; i++) { + Cursor cursor = mManager.query(new DownloadManager.Query().setFilterById(mId)); + try { + assertEquals(1, cursor.getCount()); + cursor.moveToFirst(); + numBytesReceivedSoFar = cursor.getInt( + cursor.getColumnIndexOrThrow( + DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR)); + totalBytes = cursor.getInt( + cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES)); + } finally { + cursor.close(); + } + Log.i(LOG_TAG, "in runUntilProgress, numBytesReceivedSoFar: " + + numBytesReceivedSoFar + ", totalBytes: " + totalBytes); + if (totalBytes == 0) { + fail("total_bytes should not be zero"); + return false; + } else { + if (numBytesReceivedSoFar * 100 / totalBytes >= progress) { + // progress_so_far is >= progress%. we are done + return true; + } + } + // download not done yet. sleep a while and try again + Thread.sleep(TIME_TO_SLEEP); + } + Log.i(LOG_TAG, "FAILED in runUntilProgress, numBytesReceivedSoFar: " + + numBytesReceivedSoFar + ", totalBytes: " + totalBytes); + return false; // failed + } } protected static final String PACKAGE_NAME = "my.package.name"; diff --git a/tests/src/com/android/providers/downloads/DownloadManagerFunctionalTest.java b/tests/src/com/android/providers/downloads/DownloadManagerFunctionalTest.java index bc3de1d7..7a2bfdff 100644 --- a/tests/src/com/android/providers/downloads/DownloadManagerFunctionalTest.java +++ b/tests/src/com/android/providers/downloads/DownloadManagerFunctionalTest.java @@ -41,7 +41,7 @@ public class DownloadManagerFunctionalTest extends AbstractDownloadManagerFuncti super(new FakeSystemFacade()); } - public void testBasicRequest() throws Exception { + public void testDownloadTextFile() throws Exception { enqueueResponse(HTTP_OK, FILE_CONTENT); String path = "/download_manager_test_path"; diff --git a/tests/src/com/android/providers/downloads/FakeSystemFacade.java b/tests/src/com/android/providers/downloads/FakeSystemFacade.java index 5263015c..9620ffc3 100644 --- a/tests/src/com/android/providers/downloads/FakeSystemFacade.java +++ b/tests/src/com/android/providers/downloads/FakeSystemFacade.java @@ -23,12 +23,16 @@ public class FakeSystemFacade implements SystemFacade { Map<Long,Notification> mActiveNotifications = new HashMap<Long,Notification>(); List<Notification> mCanceledNotifications = new ArrayList<Notification>(); Queue<Thread> mStartedThreads = new LinkedList<Thread>(); + private boolean returnActualTime = false; void incrementTimeMillis(long delta) { mTimeMillis += delta; } public long currentTimeMillis() { + if (returnActualTime) { + return System.currentTimeMillis(); + } return mTimeMillis; } @@ -81,9 +85,18 @@ public class FakeSystemFacade implements SystemFacade { } } + public boolean startThreadsWithoutWaiting = false; + public void setStartThreadsWithoutWaiting(boolean flag) { + this.startThreadsWithoutWaiting = flag; + } + @Override public void startThread(Thread thread) { - mStartedThreads.add(thread); + if (startThreadsWithoutWaiting) { + thread.start(); + } else { + mStartedThreads.add(thread); + } } public void runAllThreads() { @@ -91,4 +104,8 @@ public class FakeSystemFacade implements SystemFacade { mStartedThreads.poll().run(); } } + + public void setReturnActualTime(boolean flag) { + returnActualTime = flag; + } } diff --git a/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java b/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java index cad01df6..5d149308 100644 --- a/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java +++ b/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java @@ -16,6 +16,7 @@ package com.android.providers.downloads; + import android.app.DownloadManager; import android.content.Intent; import android.database.Cursor; @@ -53,17 +54,18 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest { mTestDirectory = new File(Environment.getExternalStorageDirectory() + File.separator + "download_manager_functional_test"); if (mTestDirectory.exists()) { - mTestDirectory.delete(); - } - if (!mTestDirectory.mkdir()) { - throw new RuntimeException("Couldn't create test directory: " - + mTestDirectory.getPath()); + for (File file : mTestDirectory.listFiles()) { + file.delete(); + } + } else { + mTestDirectory.mkdir(); } + mSystemFacade.setStartThreadsWithoutWaiting(false); } @Override protected void tearDown() throws Exception { - if (mTestDirectory != null) { + if (mTestDirectory != null && mTestDirectory.exists()) { for (File file : mTestDirectory.listFiles()) { file.delete(); } @@ -184,6 +186,18 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest { return response; } + // 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() { + int numPackets = 100; + int contentLength = STRING_1K.length() * numPackets; + enqueueResponse(HTTP_OK, STRING_1K) + .addHeader("Content-length", contentLength) + .addHeader("Etag", ETAG) + .setNumPackets(numPackets); + } + public void testFiltering() throws Exception { enqueueEmptyResponse(HTTP_OK); Download download1 = enqueueRequest(getRequest()); @@ -301,7 +315,7 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest { } private Uri getExternalUri() { - return Uri.fromFile(mTestDirectory).buildUpon().appendPath("testfile").build(); + return Uri.fromFile(mTestDirectory).buildUpon().appendPath("testfile.txt").build(); } public void testRequestHeaders() throws Exception { @@ -379,14 +393,22 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest { } public void testCancel() throws Exception { - enqueuePartialResponse(0, 5); + mSystemFacade.setStartThreadsWithoutWaiting(true); + // return 'real time' from FakeSystemFacade so that DownloadThread will report progress + mSystemFacade.setReturnActualTime(true); + enqueueContinuingResponse(); Download download = enqueueRequest(getRequest()); - download.runUntilStatus(DownloadManager.STATUS_PAUSED); - + startService(null); + // give the download time to get started and progress to 1% completion + // before cancelling it. + boolean rslt = download.runUntilProgress(1); + assertTrue(rslt); mManager.remove(download.mId); - mSystemFacade.incrementTimeMillis(RETRY_DELAY_MILLIS); - runService(); - // if the cancel didn't work, we should get an unexpected request to the HTTP server + startService(null); + int status = download.runUntilDone(); + // make sure the row is gone from the database + assertEquals(-1, status); + mSystemFacade.setReturnActualTime(false); } public void testDownloadCompleteBroadcast() throws Exception { @@ -524,14 +546,15 @@ public class PublicApiFunctionalTest extends AbstractPublicApiTest { } public void testExistingFile() throws Exception { + // 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_FAILED); - assertEquals(DownloadManager.ERROR_FILE_ALREADY_EXISTS, - download.getLongField(DownloadManager.COLUMN_REASON)); + download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL); } public void testEmptyFields() throws Exception { |