PublicApiFunctionalTest.java revision 323f5ae0cafdc72f61defefaa5ba938f1b4d0dda
1df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard/*
2df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard * Copyright (C) 2010 The Android Open Source Project
3df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard *
4df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard * Licensed under the Apache License, Version 2.0 (the "License");
5df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard * you may not use this file except in compliance with the License.
6df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard * You may obtain a copy of the License at
7df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard *
8df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard *      http://www.apache.org/licenses/LICENSE-2.0
9df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard *
10df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard * Unless required by applicable law or agreed to in writing, software
11df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard * distributed under the License is distributed on an "AS IS" BASIS,
12df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard * See the License for the specific language governing permissions and
14df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard * limitations under the License.
15df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard */
16df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
17df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howardpackage com.android.providers.downloads;
18df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
1958eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkeyimport static android.app.DownloadManager.STATUS_FAILED;
2058eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkeyimport static android.app.DownloadManager.STATUS_PAUSED;
217ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkeyimport static android.net.TrafficStats.GB_IN_BYTES;
2258eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkeyimport static android.text.format.DateUtils.SECOND_IN_MILLIS;
2358eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkeyimport static java.net.HttpURLConnection.HTTP_MOVED_TEMP;
2458eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkeyimport static java.net.HttpURLConnection.HTTP_NOT_FOUND;
2558eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkeyimport static java.net.HttpURLConnection.HTTP_OK;
2658eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkeyimport static java.net.HttpURLConnection.HTTP_PARTIAL;
2758eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkeyimport static java.net.HttpURLConnection.HTTP_PRECON_FAILED;
2858eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkeyimport static java.net.HttpURLConnection.HTTP_UNAVAILABLE;
2970c0e1eff5ff7cd5051738f76cecd6cb87353a43Jeff Sharkeyimport static org.mockito.Matchers.anyInt;
3070c0e1eff5ff7cd5051738f76cecd6cb87353a43Jeff Sharkeyimport static org.mockito.Matchers.anyString;
3170c0e1eff5ff7cd5051738f76cecd6cb87353a43Jeff Sharkeyimport static org.mockito.Matchers.isA;
3270c0e1eff5ff7cd5051738f76cecd6cb87353a43Jeff Sharkeyimport static org.mockito.Mockito.atLeastOnce;
3370c0e1eff5ff7cd5051738f76cecd6cb87353a43Jeff Sharkeyimport static org.mockito.Mockito.never;
3470c0e1eff5ff7cd5051738f76cecd6cb87353a43Jeff Sharkeyimport static org.mockito.Mockito.times;
3570c0e1eff5ff7cd5051738f76cecd6cb87353a43Jeff Sharkeyimport static org.mockito.Mockito.verify;
3636612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey
3714961f94d762e733a733e3268fca1074d8da5f8cSteve Howardimport android.app.DownloadManager;
3836612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkeyimport android.app.Notification;
3936612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkeyimport android.app.NotificationManager;
4036612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkeyimport android.content.Context;
410a77c62a82503b38c484e0079648f0231dd85d53Steve Howardimport android.content.Intent;
42df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howardimport android.database.Cursor;
43071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howardimport android.net.ConnectivityManager;
44df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howardimport android.net.Uri;
45df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howardimport android.os.Environment;
4658eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkeyimport android.os.SystemClock;
470a77c62a82503b38c484e0079648f0231dd85d53Steve Howardimport android.provider.Downloads;
48071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howardimport android.test.suitebuilder.annotation.LargeTest;
497ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkeyimport android.test.suitebuilder.annotation.Suppress;
507ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkeyimport android.text.format.DateUtils;
51a1cbbb41a7423c6f87b2f461075aad4c665f19ddVasu Nori
52ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkeyimport com.google.mockwebserver.MockResponse;
53ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkeyimport com.google.mockwebserver.RecordedRequest;
547ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkeyimport com.google.mockwebserver.SocketPolicy;
55df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
566d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howardimport java.io.File;
57df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howardimport java.io.FileInputStream;
583d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howardimport java.io.FileNotFoundException;
593d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howardimport java.io.IOException;
60df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howardimport java.io.InputStream;
61b5629da794cb3c1ca1970d206343743b165b9644Steve Howardimport java.util.List;
6258eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkeyimport java.util.concurrent.TimeoutException;
63df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
64071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard@LargeTest
65e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howardpublic class PublicApiFunctionalTest extends AbstractPublicApiTest {
66b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    private static final String REDIRECTED_PATH = "/other_path";
67b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    private static final String ETAG = "my_etag";
68df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
69e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    protected File mTestDirectory;
7036612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey    private NotificationManager mNotifManager;
71df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
72e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    public PublicApiFunctionalTest() {
73e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        super(new FakeSystemFacade());
74df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    }
75df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
76df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    @Override
77df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    protected void setUp() throws Exception {
78df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        super.setUp();
796d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard
8036612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey        mNotifManager = (NotificationManager) getContext()
8136612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey                .getSystemService(Context.NOTIFICATION_SERVICE);
8236612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey
836d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        mTestDirectory = new File(Environment.getExternalStorageDirectory() + File.separator
846d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard                                  + "download_manager_functional_test");
856d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        if (mTestDirectory.exists()) {
865d217003acf21aea852975af0dff3b398cea6768Vasu Nori            for (File file : mTestDirectory.listFiles()) {
875d217003acf21aea852975af0dff3b398cea6768Vasu Nori                file.delete();
885d217003acf21aea852975af0dff3b398cea6768Vasu Nori            }
895d217003acf21aea852975af0dff3b398cea6768Vasu Nori        } else {
905d217003acf21aea852975af0dff3b398cea6768Vasu Nori            mTestDirectory.mkdir();
916d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        }
926d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard    }
936d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard
946d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard    @Override
956d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard    protected void tearDown() throws Exception {
965d217003acf21aea852975af0dff3b398cea6768Vasu Nori        if (mTestDirectory != null && mTestDirectory.exists()) {
976d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard            for (File file : mTestDirectory.listFiles()) {
986d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard                file.delete();
996d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard            }
1006d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard            mTestDirectory.delete();
1016d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        }
1026d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        super.tearDown();
103df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    }
104df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
105df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    public void testBasicRequest() throws Exception {
106ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
107df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
108df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        Download download = enqueueRequest(getRequest());
109df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        assertEquals(DownloadManager.STATUS_PENDING,
110df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard                     download.getLongField(DownloadManager.COLUMN_STATUS));
111df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        assertEquals(getServerUri(REQUEST_PATH),
112df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard                     download.getStringField(DownloadManager.COLUMN_URI));
113df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        assertEquals(download.mId, download.getLongField(DownloadManager.COLUMN_ID));
1146d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        assertEquals(mSystemFacade.currentTimeMillis(),
1156d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard                     download.getLongField(DownloadManager.COLUMN_LAST_MODIFIED_TIMESTAMP));
116df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
1176d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        mSystemFacade.incrementTimeMillis(10);
118e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
119e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        RecordedRequest request = takeRequest();
120df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        assertEquals("GET", request.getMethod());
121df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        assertEquals(REQUEST_PATH, request.getPath());
122df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
123df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        Uri localUri = Uri.parse(download.getStringField(DownloadManager.COLUMN_LOCAL_URI));
1243d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard        assertEquals("content", localUri.getScheme());
1253d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard        checkUriContent(localUri);
126df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        assertEquals("text/plain", download.getStringField(DownloadManager.COLUMN_MEDIA_TYPE));
127df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
128df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        int size = FILE_CONTENT.length();
129df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        assertEquals(size, download.getLongField(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
130df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        assertEquals(size, download.getLongField(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
1316d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        assertEquals(mSystemFacade.currentTimeMillis(),
1326d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard                     download.getLongField(DownloadManager.COLUMN_LAST_MODIFIED_TIMESTAMP));
133df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
134dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard        checkCompleteDownload(download);
135df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    }
136df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
1377ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkey    @Suppress
1387ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkey    public void testExtremelyLarge() throws Exception {
1397ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkey        // NOTE: suppressed since this takes several minutes to run
1407ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkey        final long length = 3 * GB_IN_BYTES;
1417ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkey        final InputStream body = new FakeInputStream(length);
1427ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkey
143323f5ae0cafdc72f61defefaa5ba938f1b4d0ddaJeff Sharkey        enqueueResponse(new MockResponse().setResponseCode(HTTP_OK).setBody(body, length)
1447ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkey                .setHeader("Content-type", "text/plain")
1457ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkey                .setSocketPolicy(SocketPolicy.DISCONNECT_AT_END));
1467ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkey
1477ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkey        final Download download = enqueueRequest(getRequest()
1487ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkey                .setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "extreme.bin"));
1497ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkey        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL, 10 * DateUtils.MINUTE_IN_MILLIS);
1507ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkey
1517ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkey        assertEquals(length, download.getLongField(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
1527ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkey        assertEquals(length, download.getLongField(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
1537ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkey    }
1547ce206b2108714035eeed29c1dc268a3f1ccf359Jeff Sharkey
1553d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard    private void checkUriContent(Uri uri) throws FileNotFoundException, IOException {
1563d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard        InputStream inputStream = mResolver.openInputStream(uri);
1573d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard        try {
1583d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard            assertEquals(FILE_CONTENT, readStream(inputStream));
1593d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard        } finally {
1603d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard            inputStream.close();
1613d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard        }
1623d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard    }
1633d55d829c03fe78ad8cdab119293efb6c6e49c64Steve Howard
164df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    public void testTitleAndDescription() throws Exception {
165df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        Download download = enqueueRequest(getRequest()
166df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard                                           .setTitle("my title")
167df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard                                           .setDescription("my description"));
168df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        assertEquals("my title", download.getStringField(DownloadManager.COLUMN_TITLE));
169df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        assertEquals("my description",
170df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard                     download.getStringField(DownloadManager.COLUMN_DESCRIPTION));
171df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    }
172df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
173df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    public void testDownloadError() throws Exception {
174ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_NOT_FOUND));
175b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        runSimpleFailureTest(HTTP_NOT_FOUND);
176df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    }
177df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
178df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    public void testUnhandledHttpStatus() throws Exception {
179ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(1234)); // some invalid HTTP status
180b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        runSimpleFailureTest(DownloadManager.ERROR_UNHANDLED_HTTP_CODE);
181df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    }
182df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
183df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    public void testInterruptedDownload() throws Exception {
184df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        int initialLength = 5;
185b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        enqueueInterruptedDownloadResponses(initialLength);
186df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
187b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        Download download = enqueueRequest(getRequest());
188df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        download.runUntilStatus(DownloadManager.STATUS_PAUSED);
189df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        assertEquals(initialLength,
190df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard                     download.getLongField(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
191b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        assertEquals(FILE_CONTENT.length(),
192b5629da794cb3c1ca1970d206343743b165b9644Steve Howard                     download.getLongField(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
193e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        takeRequest(); // get the first request out of the queue
194df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
195df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        mSystemFacade.incrementTimeMillis(RETRY_DELAY_MILLIS);
196e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
197dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard        checkCompleteDownload(download);
198b5629da794cb3c1ca1970d206343743b165b9644Steve Howard
199e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        List<String> headers = takeRequest().getHeaders();
200b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        assertTrue("No Range header: " + headers,
201b5629da794cb3c1ca1970d206343743b165b9644Steve Howard                   headers.contains("Range: bytes=" + initialLength + "-"));
202b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        assertTrue("No ETag header: " + headers, headers.contains("If-Match: " + ETAG));
203b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    }
204b5629da794cb3c1ca1970d206343743b165b9644Steve Howard
205f6b4c24b4a876daa3f4e91d6da418983222b9dfdSteve Howard    public void testInterruptedExternalDownload() throws Exception {
206f6b4c24b4a876daa3f4e91d6da418983222b9dfdSteve Howard        enqueueInterruptedDownloadResponses(5);
207dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard        Download download = enqueueRequest(getRequest().setDestinationUri(getExternalUri()));
208f6b4c24b4a876daa3f4e91d6da418983222b9dfdSteve Howard        download.runUntilStatus(DownloadManager.STATUS_PAUSED);
209f6b4c24b4a876daa3f4e91d6da418983222b9dfdSteve Howard        mSystemFacade.incrementTimeMillis(RETRY_DELAY_MILLIS);
210f6b4c24b4a876daa3f4e91d6da418983222b9dfdSteve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
211dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard        checkCompleteDownload(download);
212f6b4c24b4a876daa3f4e91d6da418983222b9dfdSteve Howard    }
213f6b4c24b4a876daa3f4e91d6da418983222b9dfdSteve Howard
214b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    private void enqueueInterruptedDownloadResponses(int initialLength) {
215b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        // the first response has normal headers but unexpectedly closes after initialLength bytes
216ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildPartialResponse(0, initialLength));
217df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        // the second response returns partial content for the rest of the data
218ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildPartialResponse(initialLength, FILE_CONTENT.length()));
219b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    }
220b5629da794cb3c1ca1970d206343743b165b9644Steve Howard
221ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey    private MockResponse buildPartialResponse(int start, int end) {
222dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard        int totalLength = FILE_CONTENT.length();
223dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard        boolean isFirstResponse = (start == 0);
22458eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        int status = isFirstResponse ? HTTP_OK : HTTP_PARTIAL;
225ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        MockResponse response = buildResponse(status, FILE_CONTENT.substring(start, end))
226ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey                .setHeader("Content-length", totalLength)
227ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey                .setHeader("Etag", ETAG);
228dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard        if (!isFirstResponse) {
229ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey            response.setHeader(
230ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey                    "Content-range", "bytes " + start + "-" + totalLength + "/" + totalLength);
231dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard        }
232dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard        return response;
233df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    }
234df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
2355d217003acf21aea852975af0dff3b398cea6768Vasu Nori    // enqueue a huge response to keep the receiveing thread in DownloadThread.java busy for a while
2365d217003acf21aea852975af0dff3b398cea6768Vasu Nori    // give enough time to do something (cancel/remove etc) on that downloadrequest
2375d217003acf21aea852975af0dff3b398cea6768Vasu Nori    // while it is in progress
238ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey    private MockResponse buildContinuingResponse() {
2395d217003acf21aea852975af0dff3b398cea6768Vasu Nori        int numPackets = 100;
240ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        int contentLength = STRING_1K.length() * numPackets;
241ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        return buildResponse(HTTP_OK, STRING_1K)
242ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey               .setHeader("Content-length", contentLength)
243ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey               .setHeader("Etag", ETAG)
244ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey               .setBytesPerSecond(1024);
2455d217003acf21aea852975af0dff3b398cea6768Vasu Nori    }
2465d217003acf21aea852975af0dff3b398cea6768Vasu Nori
247df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    public void testFiltering() throws Exception {
248ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_OK));
249ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_NOT_FOUND));
250ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey
251df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        Download download1 = enqueueRequest(getRequest());
252df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        download1.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
2536d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard
2546d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        mSystemFacade.incrementTimeMillis(1); // ensure downloads are correctly ordered by time
255df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        Download download2 = enqueueRequest(getRequest());
256df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        download2.runUntilStatus(DownloadManager.STATUS_FAILED);
2576d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard
2586d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        mSystemFacade.incrementTimeMillis(1);
259df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        Download download3 = enqueueRequest(getRequest());
260df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
261df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        Cursor cursor = mManager.query(new DownloadManager.Query());
2626d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        checkAndCloseCursor(cursor, download3, download2, download1);
263df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
264df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        cursor = mManager.query(new DownloadManager.Query().setFilterById(download2.mId));
265df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        checkAndCloseCursor(cursor, download2);
266df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
267df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        cursor = mManager.query(new DownloadManager.Query()
268df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard                                .setFilterByStatus(DownloadManager.STATUS_PENDING));
269df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        checkAndCloseCursor(cursor, download3);
270df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
271df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        cursor = mManager.query(new DownloadManager.Query()
272df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard                                .setFilterByStatus(DownloadManager.STATUS_FAILED
273df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard                                              | DownloadManager.STATUS_SUCCESSFUL));
2746d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        checkAndCloseCursor(cursor, download2, download1);
275df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
276df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        cursor = mManager.query(new DownloadManager.Query()
277df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard                                .setFilterByStatus(DownloadManager.STATUS_RUNNING));
278df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        checkAndCloseCursor(cursor);
27971e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard
28071e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        mSystemFacade.incrementTimeMillis(1);
28171e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        Download invisibleDownload = enqueueRequest(getRequest().setVisibleInDownloadsUi(false));
28271e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        cursor = mManager.query(new DownloadManager.Query());
28371e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        checkAndCloseCursor(cursor, invisibleDownload, download3, download2, download1);
28471e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        cursor = mManager.query(new DownloadManager.Query().setOnlyIncludeVisibleInDownloadsUi(true));
28571e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        checkAndCloseCursor(cursor, download3, download2, download1);
28671e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard    }
28771e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard
28871e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard    public void testOrdering() throws Exception {
289ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildResponse(HTTP_OK, "small contents"));
290ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildResponse(HTTP_OK, "large contents large contents"));
291ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_NOT_FOUND));
292ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey
29371e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        Download download1 = enqueueRequest(getRequest());
29471e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        download1.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
29571e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard
29671e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        mSystemFacade.incrementTimeMillis(1);
29771e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        Download download2 = enqueueRequest(getRequest());
29871e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        download2.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
29971e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard
30071e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        mSystemFacade.incrementTimeMillis(1);
30171e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        Download download3 = enqueueRequest(getRequest());
30271e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        download3.runUntilStatus(DownloadManager.STATUS_FAILED);
30371e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard
30471e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        // default ordering -- by timestamp descending
30571e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        Cursor cursor = mManager.query(new DownloadManager.Query());
30671e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        checkAndCloseCursor(cursor, download3, download2, download1);
30771e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard
30871e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        cursor = mManager.query(new DownloadManager.Query()
30971e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard                .orderBy(DownloadManager.COLUMN_LAST_MODIFIED_TIMESTAMP,
31071e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard                        DownloadManager.Query.ORDER_ASCENDING));
31171e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        checkAndCloseCursor(cursor, download1, download2, download3);
31271e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard
31371e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        cursor = mManager.query(new DownloadManager.Query()
31471e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard                .orderBy(DownloadManager.COLUMN_TOTAL_SIZE_BYTES,
31571e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard                        DownloadManager.Query.ORDER_DESCENDING));
31671e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        checkAndCloseCursor(cursor, download2, download1, download3);
31771e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard
31871e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        cursor = mManager.query(new DownloadManager.Query()
31971e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard                .orderBy(DownloadManager.COLUMN_TOTAL_SIZE_BYTES,
32071e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard                        DownloadManager.Query.ORDER_ASCENDING));
32171e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        checkAndCloseCursor(cursor, download3, download1, download2);
322df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    }
323df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
324df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    private void checkAndCloseCursor(Cursor cursor, Download... downloads) {
325df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        try {
326df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard            int idIndex = cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_ID);
327df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard            assertEquals(downloads.length, cursor.getCount());
328df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard            cursor.moveToFirst();
329df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard            for (Download download : downloads) {
330df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard                assertEquals(download.mId, cursor.getLong(idIndex));
331df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard                cursor.moveToNext();
332df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard            }
333df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        } finally {
334df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard            cursor.close();
335df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        }
336df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    }
337df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
338df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    public void testInvalidUri() throws Exception {
339df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        try {
340df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard            enqueueRequest(getRequest("/no_host"));
341df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        } catch (IllegalArgumentException exc) { // expected
342df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard            return;
343df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        }
344df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
345df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard        fail("No exception thrown for invalid URI");
346df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    }
347df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard
3486d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard    public void testDestination() throws Exception {
349ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
350f6b4c24b4a876daa3f4e91d6da418983222b9dfdSteve Howard        Uri destination = getExternalUri();
3516d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        Download download = enqueueRequest(getRequest().setDestinationUri(destination));
3526d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
3536d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard
3546d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        Uri localUri = Uri.parse(download.getStringField(DownloadManager.COLUMN_LOCAL_URI));
3556d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        assertEquals(destination, localUri);
3566d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard
357b9a0ad7182209d4aca708e13e876e9b1b43ffafcSteve Howard        InputStream stream = new FileInputStream(destination.getPath());
3586d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        try {
3596d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard            assertEquals(FILE_CONTENT, readStream(stream));
3606d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        } finally {
3616d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard            stream.close();
3626d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard        }
3636d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard    }
3646d9b98282c817b86a00f9c19a705da4cb19bc3a6Steve Howard
365f6b4c24b4a876daa3f4e91d6da418983222b9dfdSteve Howard    private Uri getExternalUri() {
3665d217003acf21aea852975af0dff3b398cea6768Vasu Nori        return Uri.fromFile(mTestDirectory).buildUpon().appendPath("testfile.txt").build();
367f6b4c24b4a876daa3f4e91d6da418983222b9dfdSteve Howard    }
368f6b4c24b4a876daa3f4e91d6da418983222b9dfdSteve Howard
3695224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard    public void testRequestHeaders() throws Exception {
370ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_OK));
371ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard        Download download = enqueueRequest(getRequest().addRequestHeader("Header1", "value1")
372ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard                                           .addRequestHeader("Header2", "value2"));
373e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
3745224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard
375e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        List<String> headers = takeRequest().getHeaders();
376e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        assertTrue(headers.contains("Header1: value1"));
377e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        assertTrue(headers.contains("Header2: value2"));
3785224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard    }
3795224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard
3805224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard    public void testDelete() throws Exception {
381ebb555c0687061993dd6a22d15f6aab2437ee8c5Steve Howard        Download download = enqueueRequest(getRequest().addRequestHeader("header", "value"));
3825224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard        mManager.remove(download.mId);
3835224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard        Cursor cursor = mManager.query(new DownloadManager.Query());
3845224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard        try {
3855224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard            assertEquals(0, cursor.getCount());
3865224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard        } finally {
3875224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard            cursor.close();
3885224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard        }
3895224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard    }
3905224c6fbf20b4803a580ef449ab87ebfbbfedb78Steve Howard
391071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard    public void testSizeLimitOverMobile() throws Exception {
392ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
393ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
394071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard
395ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        mSystemFacade.mMaxBytesOverMobile = (long) FILE_CONTENT.length() - 1;
396071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard        mSystemFacade.mActiveNetworkType = ConnectivityManager.TYPE_MOBILE;
397071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard        Download download = enqueueRequest(getRequest());
398071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard        download.runUntilStatus(DownloadManager.STATUS_PAUSED);
399071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard
400071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard        mSystemFacade.mActiveNetworkType = ConnectivityManager.TYPE_WIFI;
401071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard        // first response was read, but aborted after the DL manager processed the Content-Length
402071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard        // header, so we need to enqueue a second one
403071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
404071bd7acb3185f4f1e807855605c5e6018e9742fSteve Howard    }
4050a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
406b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    public void testRedirect301() throws Exception {
407b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        RecordedRequest lastRequest = runRedirectionTest(301);
408f85aa9ef563f2fbb3c0db6c980121122a14d953fSteve Howard        // for 301, upon retry/resume, we reuse the redirected URI
409b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        assertEquals(REDIRECTED_PATH, lastRequest.getPath());
410b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    }
411b5629da794cb3c1ca1970d206343743b165b9644Steve Howard
412f85aa9ef563f2fbb3c0db6c980121122a14d953fSteve Howard    public void testRedirect302() throws Exception {
413b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        RecordedRequest lastRequest = runRedirectionTest(302);
414f85aa9ef563f2fbb3c0db6c980121122a14d953fSteve Howard        // for 302, upon retry/resume, we use the original URI
415b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        assertEquals(REQUEST_PATH, lastRequest.getPath());
416b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    }
417b5629da794cb3c1ca1970d206343743b165b9644Steve Howard
41858eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey    public void testRunawayRedirect() throws Exception {
41958eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        for (int i = 0; i < 16; i++) {
42058eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey            enqueueResponse(buildEmptyResponse(HTTP_MOVED_TEMP)
42158eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey                    .setHeader("Location", mServer.getUrl("/" + i).toString()));
42258eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        }
42358eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey
42458eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        final Download download = enqueueRequest(getRequest());
42558eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey
42658eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        // Ensure that we arrive at failed download, instead of spinning forever
42758eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        download.runUntilStatus(DownloadManager.STATUS_FAILED);
42858eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        assertEquals(DownloadManager.ERROR_TOO_MANY_REDIRECTS, download.getReason());
42958eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey    }
43058eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey
43158eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey    public void testRunawayUnavailable() throws Exception {
43258eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        final int RETRY_DELAY = 120;
43358eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        for (int i = 0; i < 16; i++) {
43458eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey            enqueueResponse(
43558eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey                    buildEmptyResponse(HTTP_UNAVAILABLE).setHeader("Retry-after", RETRY_DELAY));
43658eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        }
43758eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey
43858eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        final Download download = enqueueRequest(getRequest());
43958eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        for (int i = 0; i < Constants.MAX_RETRIES - 1; i++) {
44058eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey            download.runUntilStatus(DownloadManager.STATUS_PAUSED);
44158eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey            mSystemFacade.incrementTimeMillis((RETRY_DELAY + 60) * SECOND_IN_MILLIS);
44258eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        }
44358eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey
44458eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        // Ensure that we arrive at failed download, instead of spinning forever
44558eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        download.runUntilStatus(DownloadManager.STATUS_FAILED);
44658eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey    }
44758eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey
448b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    public void testNoEtag() throws Exception {
449ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildPartialResponse(0, 5).removeHeader("Etag"));
450adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard        runSimpleFailureTest(DownloadManager.ERROR_CANNOT_RESUME);
451b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    }
452b5629da794cb3c1ca1970d206343743b165b9644Steve Howard
45358eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey    public void testEtagChanged() throws Exception {
45458eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        final String A = "kittenz";
45558eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        final String B = "puppiez";
45658eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey
45758eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        // 1. Try downloading A, but partial result
45858eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        enqueueResponse(buildResponse(HTTP_OK, A.substring(0, 2))
45958eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey                .setHeader("Content-length", A.length())
46058eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey                .setHeader("Etag", A));
46158eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey
46258eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        // 2. Try resuming A, but fail ETag check
46358eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_PRECON_FAILED));
46458eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey
46558eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        final Download download = enqueueRequest(getRequest());
46658eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        RecordedRequest req;
46758eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey
46858eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        // 1. Try downloading A, but partial result
46958eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        download.runUntilStatus(STATUS_PAUSED);
47058eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        assertEquals(DownloadManager.PAUSED_WAITING_TO_RETRY, download.getReason());
47158eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        req = takeRequest();
47258eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        assertNull(getHeaderValue(req, "Range"));
47358eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        assertNull(getHeaderValue(req, "If-Match"));
47458eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey
47558eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        // 2. Try resuming A, but fail ETag check
47658eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        mSystemFacade.incrementTimeMillis(RETRY_DELAY_MILLIS);
47758eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        download.runUntilStatus(STATUS_FAILED);
47858eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        assertEquals(HTTP_PRECON_FAILED, download.getReason());
47958eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        req = takeRequest();
48058eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        assertEquals("bytes=2-", getHeaderValue(req, "Range"));
48158eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        assertEquals(A, getHeaderValue(req, "If-Match"));
48258eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey    }
48358eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey
484b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    public void testSanitizeMediaType() throws Exception {
485ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_OK)
486ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey                .setHeader("Content-Type", "text/html; charset=ISO-8859-4"));
487b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        Download download = enqueueRequest(getRequest());
488b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
489b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        assertEquals("text/html", download.getStringField(DownloadManager.COLUMN_MEDIA_TYPE));
490b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    }
491b5629da794cb3c1ca1970d206343743b165b9644Steve Howard
492b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    public void testNoContentLength() throws Exception {
493ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_OK).removeHeader("Content-length"));
49412f5dc46aaa8e28cabfbe25d55f0af68f24ab306Jeff Sharkey        runSimpleFailureTest(DownloadManager.ERROR_CANNOT_RESUME);
495b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    }
496b5629da794cb3c1ca1970d206343743b165b9644Steve Howard
497b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    public void testInsufficientSpace() throws Exception {
498b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        // this would be better done by stubbing the system API to check available space, but in the
499b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        // meantime, just use an absurdly large header value
500ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_OK)
501ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey                .setHeader("Content-Length", 1024L * 1024 * 1024 * 1024 * 1024));
502b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        runSimpleFailureTest(DownloadManager.ERROR_INSUFFICIENT_SPACE);
503b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    }
504b5629da794cb3c1ca1970d206343743b165b9644Steve Howard
505b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    public void testCancel() throws Exception {
5065d217003acf21aea852975af0dff3b398cea6768Vasu Nori        // return 'real time' from FakeSystemFacade so that DownloadThread will report progress
5075d217003acf21aea852975af0dff3b398cea6768Vasu Nori        mSystemFacade.setReturnActualTime(true);
508ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildContinuingResponse());
509b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        Download download = enqueueRequest(getRequest());
5105d217003acf21aea852975af0dff3b398cea6768Vasu Nori        // give the download time to get started and progress to 1% completion
5115d217003acf21aea852975af0dff3b398cea6768Vasu Nori        // before cancelling it.
5125d217003acf21aea852975af0dff3b398cea6768Vasu Nori        boolean rslt = download.runUntilProgress(1);
5135d217003acf21aea852975af0dff3b398cea6768Vasu Nori        assertTrue(rslt);
514b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        mManager.remove(download.mId);
5158ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey
51658eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        // Verify that row is removed from database
51758eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        final long timeout = SystemClock.elapsedRealtime() + (15 * SECOND_IN_MILLIS);
51858eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        while (download.getStatusIfExists() != -1) {
51958eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey            if (SystemClock.elapsedRealtime() > timeout) {
52058eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey                throw new TimeoutException("Row wasn't removed");
52158eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey            }
52258eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey            SystemClock.sleep(100);
52358eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        }
5240a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    }
5250a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
5260a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    public void testDownloadCompleteBroadcast() throws Exception {
527ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_OK));
5280a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        Download download = enqueueRequest(getRequest());
5290a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
5300a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
5310a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        assertEquals(1, mSystemFacade.mBroadcastsSent.size());
5320a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        Intent broadcast = mSystemFacade.mBroadcastsSent.get(0);
5330a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        assertEquals(DownloadManager.ACTION_DOWNLOAD_COMPLETE, broadcast.getAction());
5340a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        assertEquals(PACKAGE_NAME, broadcast.getPackage());
5350a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        long intentId = broadcast.getExtras().getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
5360a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        assertEquals(download.mId, intentId);
5370a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    }
5380a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
5390a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    public void testNotificationClickedBroadcast() throws Exception {
5409da9df3d6e84a3c4b04dd22d277e0e6d8f7f1ccbSteve Howard        Download download = enqueueRequest(getRequest());
5410a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
5420a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        DownloadReceiver receiver = new DownloadReceiver();
5430a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        receiver.mSystemFacade = mSystemFacade;
5440a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        Intent intent = new Intent(Constants.ACTION_LIST);
5450a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        intent.setData(Uri.parse(Downloads.Impl.CONTENT_URI + "/" + download.mId));
546a40a349c0107660bfb4004467550725a3ca3ec97Jeff Sharkey        intent.putExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS,
547a40a349c0107660bfb4004467550725a3ca3ec97Jeff Sharkey                new long[] { download.mId });
5480a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        receiver.onReceive(mContext, intent);
5490a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
5500a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        assertEquals(1, mSystemFacade.mBroadcastsSent.size());
5510a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        Intent broadcast = mSystemFacade.mBroadcastsSent.get(0);
5520a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        assertEquals(DownloadManager.ACTION_NOTIFICATION_CLICKED, broadcast.getAction());
5530a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        assertEquals(PACKAGE_NAME, broadcast.getPackage());
5540a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    }
5550a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
556e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    public void testBasicConnectivityChanges() throws Exception {
557ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildResponse(HTTP_OK, FILE_CONTENT));
558ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey
559961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey        // without connectivity, download immediately pauses
560961024389b3782936a40a7d090d670290bb66c3cJeff Sharkey        mSystemFacade.mActiveNetworkType = null;
561e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        Download download = enqueueRequest(getRequest());
562e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        download.runUntilStatus(DownloadManager.STATUS_PAUSED);
563e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
564e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        // connecting should start the download
565e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        mSystemFacade.mActiveNetworkType = ConnectivityManager.TYPE_WIFI;
566e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
567e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    }
568e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
5690a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    public void testAllowedNetworkTypes() throws Exception {
570ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_OK));
571ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_OK));
572ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey
5730a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        mSystemFacade.mActiveNetworkType = ConnectivityManager.TYPE_MOBILE;
5740a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
5750a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        // by default, use any connection
5760a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        Download download = enqueueRequest(getRequest());
5770a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
5780a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
5790a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        // restrict a download to wifi...
5800a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        download = enqueueRequest(getRequest()
5810a77c62a82503b38c484e0079648f0231dd85d53Steve Howard                                  .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI));
582e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        download.runUntilStatus(DownloadManager.STATUS_PAUSED);
5830a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        // ...then enable wifi
5840a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        mSystemFacade.mActiveNetworkType = ConnectivityManager.TYPE_WIFI;
5850a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
5860a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    }
5870a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
5880a77c62a82503b38c484e0079648f0231dd85d53Steve Howard    public void testRoaming() throws Exception {
589ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_OK));
590ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_OK));
591ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey
5920a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        mSystemFacade.mIsRoaming = true;
5930a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
5940a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        // by default, allow roaming
5950a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        Download download = enqueueRequest(getRequest());
5960a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
5970a77c62a82503b38c484e0079648f0231dd85d53Steve Howard
5980a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        // disallow roaming for a download...
5990a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        download = enqueueRequest(getRequest().setAllowedOverRoaming(false));
600e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        download.runUntilStatus(DownloadManager.STATUS_PAUSED);
6010a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        // ...then turn off roaming
6020a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        mSystemFacade.mIsRoaming = false;
6030a77c62a82503b38c484e0079648f0231dd85d53Steve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
604b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    }
605b5629da794cb3c1ca1970d206343743b165b9644Steve Howard
606691fc58e9a61d99ab5018c5ddc8349ed413e4470Steve Howard    public void testContentObserver() throws Exception {
607ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_OK));
608691fc58e9a61d99ab5018c5ddc8349ed413e4470Steve Howard        mResolver.resetNotified();
6098ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey        final Download download = enqueueRequest(getRequest());
6108ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
611691fc58e9a61d99ab5018c5ddc8349ed413e4470Steve Howard        assertTrue(mResolver.mNotifyWasCalled);
612691fc58e9a61d99ab5018c5ddc8349ed413e4470Steve Howard    }
613691fc58e9a61d99ab5018c5ddc8349ed413e4470Steve Howard
61436612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey    public void testNotificationNever() throws Exception {
615ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_OK));
616ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey
61736612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey        final Download download = enqueueRequest(
61836612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey                getRequest().setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN));
61993155e1da7e89d4925e244f5afa94afb8ada7381Steve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
62036612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey
6218ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey        verify(mNotifManager, times(1)).cancelAll();
622a40a349c0107660bfb4004467550725a3ca3ec97Jeff Sharkey        verify(mNotifManager, never()).notify(anyString(), anyInt(), isA(Notification.class));
62336612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey    }
62436612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey
62536612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey    public void testNotificationVisible() throws Exception {
62636612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_OK));
627e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
62836612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey        // only shows in-progress notifications
62936612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey        final Download download = enqueueRequest(getRequest());
63093155e1da7e89d4925e244f5afa94afb8ada7381Steve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
63136612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey
63236612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey        // TODO: verify different notif types with tags
6338ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey        verify(mNotifManager, times(1)).cancelAll();
634a40a349c0107660bfb4004467550725a3ca3ec97Jeff Sharkey        verify(mNotifManager, atLeastOnce()).notify(anyString(), anyInt(), isA(Notification.class));
63536612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey    }
636e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
63736612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey    public void testNotificationVisibleComplete() throws Exception {
63836612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_OK));
63936612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey
64036612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey        final Download download = enqueueRequest(getRequest().setNotificationVisibility(
64136612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey                DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED));
64236612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
64336612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey
64436612d27b67ff2e79ffff8eb12d95d2058abde02Jeff Sharkey        // TODO: verify different notif types with tags
6458ac10e0e0667a4fe35191deebb5fa9786bf4226cJeff Sharkey        verify(mNotifManager, times(1)).cancelAll();
646a40a349c0107660bfb4004467550725a3ca3ec97Jeff Sharkey        verify(mNotifManager, atLeastOnce()).notify(anyString(), anyInt(), isA(Notification.class));
647e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    }
648e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
649e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard    public void testRetryAfter() throws Exception {
650e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        final int delay = 120;
651ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(
65258eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey                buildEmptyResponse(HTTP_UNAVAILABLE).setHeader("Retry-after", delay));
653ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_OK));
654ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey
655e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        Download download = enqueueRequest(getRequest());
656e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        download.runUntilStatus(DownloadManager.STATUS_PAUSED);
657e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard
658e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        // download manager adds random 0-30s offset
659e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        mSystemFacade.incrementTimeMillis((delay + 31) * 1000);
660e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
66193155e1da7e89d4925e244f5afa94afb8ada7381Steve Howard    }
66293155e1da7e89d4925e244f5afa94afb8ada7381Steve Howard
663dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard    public void testManyInterruptions() throws Exception {
664ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        final int length = FILE_CONTENT.length();
665ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        for (int i = 0; i < length; i++) {
666ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey            enqueueResponse(buildPartialResponse(i, i + 1));
667ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        }
668dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard
669dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard        Download download = enqueueRequest(getRequest());
670ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        for (int i = 0; i < length - 1; i++) {
671dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard            download.runUntilStatus(DownloadManager.STATUS_PAUSED);
672dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard            mSystemFacade.incrementTimeMillis(RETRY_DELAY_MILLIS);
673dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard        }
674dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard
675dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
676dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard        checkCompleteDownload(download);
677dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard    }
678dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard
679adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard    public void testExistingFile() throws Exception {
680ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_OK));
681ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey
6825d217003acf21aea852975af0dff3b398cea6768Vasu Nori        // download a file which already exists.
6835d217003acf21aea852975af0dff3b398cea6768Vasu Nori        // downloadservice should simply create filename with "-" and a number attached
6845d217003acf21aea852975af0dff3b398cea6768Vasu Nori        // at the end; i.e., download shouldnot fail.
685adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard        Uri destination = getExternalUri();
686b9a0ad7182209d4aca708e13e876e9b1b43ffafcSteve Howard        new File(destination.getPath()).createNewFile();
687adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard
688adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard        Download download = enqueueRequest(getRequest().setDestinationUri(destination));
6895d217003acf21aea852975af0dff3b398cea6768Vasu Nori        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
690adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard    }
691adb6887d3270d180c94eaf90878d5b67d74a8f28Steve Howard
692a89321ea04ced76d06f60f5909be203cb654a830Steve Howard    public void testEmptyFields() throws Exception {
693a89321ea04ced76d06f60f5909be203cb654a830Steve Howard        Download download = enqueueRequest(getRequest());
694a89321ea04ced76d06f60f5909be203cb654a830Steve Howard        assertEquals("", download.getStringField(DownloadManager.COLUMN_TITLE));
695a89321ea04ced76d06f60f5909be203cb654a830Steve Howard        assertEquals("", download.getStringField(DownloadManager.COLUMN_DESCRIPTION));
696a89321ea04ced76d06f60f5909be203cb654a830Steve Howard        assertNull(download.getStringField(DownloadManager.COLUMN_MEDIA_TYPE));
697a89321ea04ced76d06f60f5909be203cb654a830Steve Howard        assertEquals(0, download.getLongField(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
698a89321ea04ced76d06f60f5909be203cb654a830Steve Howard        assertEquals(-1, download.getLongField(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
699a89321ea04ced76d06f60f5909be203cb654a830Steve Howard        // just ensure no exception is thrown
700b108a273b150e81bf26553b8851d6241bc711f98Steve Howard        download.getLongField(DownloadManager.COLUMN_REASON);
701a89321ea04ced76d06f60f5909be203cb654a830Steve Howard    }
702a89321ea04ced76d06f60f5909be203cb654a830Steve Howard
70371e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard    public void testRestart() throws Exception {
704ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_NOT_FOUND));
705ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(HTTP_OK));
706ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey
70771e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        Download download = enqueueRequest(getRequest());
70871e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        download.runUntilStatus(DownloadManager.STATUS_FAILED);
70971e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard
71071e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        mManager.restartDownload(download.mId);
71171e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        assertEquals(DownloadManager.STATUS_PENDING,
71271e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard                download.getLongField(DownloadManager.COLUMN_STATUS));
71371e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
71471e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard    }
71571e7fda9135a0915af1fd419d07ebf85ad09beb4Steve Howard
716dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard    private void checkCompleteDownload(Download download) throws Exception {
717dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard        assertEquals(FILE_CONTENT.length(),
718dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard                     download.getLongField(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
719dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard        assertEquals(FILE_CONTENT, download.getContents());
720dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard    }
721dea0a5f8e5804d3aba40eaa7de763dd88058384eSteve Howard
722b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    private void runSimpleFailureTest(int expectedErrorCode) throws Exception {
723b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        Download download = enqueueRequest(getRequest());
724b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        download.runUntilStatus(DownloadManager.STATUS_FAILED);
725b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        assertEquals(expectedErrorCode,
726b108a273b150e81bf26553b8851d6241bc711f98Steve Howard                     download.getLongField(DownloadManager.COLUMN_REASON));
727b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    }
728b5629da794cb3c1ca1970d206343743b165b9644Steve Howard
729b5629da794cb3c1ca1970d206343743b165b9644Steve Howard    /**
730b5629da794cb3c1ca1970d206343743b165b9644Steve Howard     * Run a redirection test consisting of
731b5629da794cb3c1ca1970d206343743b165b9644Steve Howard     * 1) Request to REQUEST_PATH with 3xx response redirecting to another URI
732b5629da794cb3c1ca1970d206343743b165b9644Steve Howard     * 2) Request to REDIRECTED_PATH with interrupted partial response
733b5629da794cb3c1ca1970d206343743b165b9644Steve Howard     * 3) Resume request to complete download
734b5629da794cb3c1ca1970d206343743b165b9644Steve Howard     * @return the last request sent to the server, resuming after the interruption
735b5629da794cb3c1ca1970d206343743b165b9644Steve Howard     */
73658eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey    private RecordedRequest runRedirectionTest(int status) throws Exception {
737ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey        enqueueResponse(buildEmptyResponse(status)
738ae6856b0fca5215f45619dd031a7e7beae7bd8ccJeff Sharkey                .setHeader("Location", mServer.getUrl(REDIRECTED_PATH).toString()));
739b5629da794cb3c1ca1970d206343743b165b9644Steve Howard        enqueueInterruptedDownloadResponses(5);
740b5629da794cb3c1ca1970d206343743b165b9644Steve Howard
741a85832b4772626852142b60c4806ff5384a76478Jeff Sharkey        final Download download = enqueueRequest(getRequest());
742a85832b4772626852142b60c4806ff5384a76478Jeff Sharkey        download.runUntilStatus(DownloadManager.STATUS_PAUSED);
743a85832b4772626852142b60c4806ff5384a76478Jeff Sharkey        mSystemFacade.incrementTimeMillis(RETRY_DELAY_MILLIS);
744a85832b4772626852142b60c4806ff5384a76478Jeff Sharkey        download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
745a85832b4772626852142b60c4806ff5384a76478Jeff Sharkey
746e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        assertEquals(REQUEST_PATH, takeRequest().getPath());
747e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        assertEquals(REDIRECTED_PATH, takeRequest().getPath());
748b5629da794cb3c1ca1970d206343743b165b9644Steve Howard
749e6a05a1aa4697440e9630d12b741b3bae321fe49Steve Howard        return takeRequest();
750df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard    }
75158eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey
75258eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey    /**
75358eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey     * Return value of requested HTTP header, if it exists.
75458eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey     */
75558eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey    private static String getHeaderValue(RecordedRequest req, String header) {
75658eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        header = header.toLowerCase() + ":";
75758eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        for (String h : req.getHeaders()) {
75858eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey            if (h.toLowerCase().startsWith(header)) {
75958eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey                return h.substring(header.length()).trim();
76058eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey            }
76158eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        }
76258eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey        return null;
76358eee87b70862a7ced85eabc3c225fad24664065Jeff Sharkey    }
764df71633a02ce2f1b6228dad1ba3198185edf6107Steve Howard}
765