summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2013-03-01 11:18:38 -0800
committerJeff Sharkey <jsharkey@android.com>2013-03-01 11:18:40 -0800
commit5ba69740a47857fcebd36866e07963ba798269d5 (patch)
tree676f2501844882633a9b9f14324397cb8a8411c8 /tests
parent80a535d83ea9ed21f443fdc701c743569ae53eec (diff)
downloadandroid_packages_providers_DownloadProvider-5ba69740a47857fcebd36866e07963ba798269d5.tar.gz
android_packages_providers_DownloadProvider-5ba69740a47857fcebd36866e07963ba798269d5.tar.bz2
android_packages_providers_DownloadProvider-5ba69740a47857fcebd36866e07963ba798269d5.zip
Fix race conditions around filename claiming.
When multiple downloads are running in parallel, they can end up claiming the same filename and clobber over each other. This change introduces locking around filename generation, and touches the claimed filename so other threads fail the File.exists() check and keep looking. Tests to verify. Bug: 8255596 Change-Id: Ie75ed047c199cf679832c75159056ca036eac18d
Diffstat (limited to 'tests')
-rw-r--r--tests/src/com/android/providers/downloads/ThreadingTest.java46
1 files changed, 46 insertions, 0 deletions
diff --git a/tests/src/com/android/providers/downloads/ThreadingTest.java b/tests/src/com/android/providers/downloads/ThreadingTest.java
index fcb33290..920f703b 100644
--- a/tests/src/com/android/providers/downloads/ThreadingTest.java
+++ b/tests/src/com/android/providers/downloads/ThreadingTest.java
@@ -20,6 +20,15 @@ import static java.net.HttpURLConnection.HTTP_OK;
import android.app.DownloadManager;
import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Pair;
+
+import com.google.android.collect.Lists;
+import com.google.android.collect.Sets;
+import com.google.mockwebserver.MockResponse;
+import com.google.mockwebserver.SocketPolicy;
+
+import java.util.List;
+import java.util.Set;
/**
* Download manager tests that require multithreading.
@@ -48,4 +57,41 @@ public class ThreadingTest extends AbstractPublicApiTest {
Thread.sleep(10);
}
}
+
+ public void testFilenameRace() throws Exception {
+ final List<Pair<Download, String>> downloads = Lists.newArrayList();
+
+ // Request dozen files at once with same name
+ for (int i = 0; i < 12; i++) {
+ final String body = "DOWNLOAD " + i + " CONTENTS";
+ enqueueResponse(new MockResponse().setResponseCode(HTTP_OK).setBody(body)
+ .setHeader("Content-type", "text/plain")
+ .setSocketPolicy(SocketPolicy.DISCONNECT_AT_END));
+
+ final Download d = enqueueRequest(getRequest());
+ downloads.add(Pair.create(d, body));
+ }
+
+ // Kick off downloads in parallel
+ final long startMillis = mSystemFacade.currentTimeMillis();
+ startService(null);
+
+ for (Pair<Download,String> d : downloads) {
+ d.first.waitForStatus(DownloadManager.STATUS_SUCCESSFUL, startMillis);
+ }
+
+ // Ensure that contents are clean and filenames unique
+ final Set<String> seenFiles = Sets.newHashSet();
+
+ for (Pair<Download, String> d : downloads) {
+ final String file = d.first.getStringField(DownloadManager.COLUMN_LOCAL_FILENAME);
+ if (!seenFiles.add(file)) {
+ fail("Another download already claimed " + file);
+ }
+
+ final String expected = d.second;
+ final String actual = d.first.getContents();
+ assertEquals(expected, actual);
+ }
+ }
}