diff options
author | Jeff Sharkey <jsharkey@android.com> | 2013-03-01 11:18:38 -0800 |
---|---|---|
committer | Jeff Sharkey <jsharkey@android.com> | 2013-03-01 11:18:40 -0800 |
commit | 5ba69740a47857fcebd36866e07963ba798269d5 (patch) | |
tree | 676f2501844882633a9b9f14324397cb8a8411c8 /tests/src/com/android/providers/downloads/ThreadingTest.java | |
parent | 80a535d83ea9ed21f443fdc701c743569ae53eec (diff) | |
download | android_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/src/com/android/providers/downloads/ThreadingTest.java')
-rw-r--r-- | tests/src/com/android/providers/downloads/ThreadingTest.java | 46 |
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); + } + } } |