140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen/*
240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * Copyright (C) 2010 The Android Open Source Project
340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen *
440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * Licensed under the Apache License, Version 2.0 (the "License");
540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * you may not use this file except in compliance with the License.
640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * You may obtain a copy of the License at
740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen *
840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen *      http://www.apache.org/licenses/LICENSE-2.0
940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen *
1040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * Unless required by applicable law or agreed to in writing, software
1140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * distributed under the License is distributed on an "AS IS" BASIS,
1240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * See the License for the specific language governing permissions and
1440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen * limitations under the License.
1540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen */
1640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
1731fd85f39b554e09b2e6c1c2ccf5c186859880faSteve Howardpackage android.app;
1840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
1940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenimport java.io.File;
2040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenimport java.util.Random;
2140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
2231fd85f39b554e09b2e6c1c2ccf5c186859880faSteve Howardimport android.app.DownloadManager.Query;
2331fd85f39b554e09b2e6c1c2ccf5c186859880faSteve Howardimport android.app.DownloadManager.Request;
2440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenimport android.database.Cursor;
2531fd85f39b554e09b2e6c1c2ccf5c186859880faSteve Howardimport android.net.Uri;
2640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenimport android.os.ParcelFileDescriptor;
2740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenimport android.util.Log;
2840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
2940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
3040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyenpublic class DownloadManagerStressTest extends DownloadManagerBaseTest {
3140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    private static String LOG_TAG = "android.net.DownloadManagerStressTest";
3240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
3340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    /**
3440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * {@inheritDoc}
3540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     */
3640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    @Override
3740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    public void setUp() throws Exception {
3840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        super.setUp();
3940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        mServer.play(0);
40bd06f02d02e07ca15e420ee9e50e35253646ba64Neal Nguyen        setWiFiStateOn(true);
4140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        removeAllCurrentDownloads();
4240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    }
4340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
4440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    /**
4540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * Attempts to downloading thousands of files simultaneously
4640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     */
4740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    public void testDownloadThousands() throws Exception {
4840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        int NUM_FILES = 1500;
4940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        int MAX_FILE_SIZE = 3000;
5040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        long[] reqs = new long[NUM_FILES];
5140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
5240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        // need to be sure all current downloads have stopped first
5340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        MultipleDownloadsCompletedReceiver receiver = registerNewMultipleDownloadsReceiver();
5440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        Cursor cursor = null;
5540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        try {
5640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Random r = new LoggingRng();
5740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            for (int i = 0; i < NUM_FILES; ++i) {
5840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                int size = r.nextInt(MAX_FILE_SIZE);
5940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                byte[] blobData = generateData(size, DataType.TEXT);
6040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
6140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                Uri uri = getServerUri(DEFAULT_FILENAME);
6240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                Request request = new Request(uri);
6340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                request.setTitle(String.format("%s--%d", DEFAULT_FILENAME, i));
6440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
6540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                // Prepare the mock server with a standard response
6640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                enqueueResponse(HTTP_OK, blobData);
6740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
6840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                Log.i(LOG_TAG, "issuing request: " + i);
6940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                long reqId = mDownloadManager.enqueue(request);
7040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                reqs[i] = reqId;
7140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            }
7240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
7340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // wait for the download to complete or timeout
74bd06f02d02e07ca15e420ee9e50e35253646ba64Neal Nguyen            waitForDownloadsOrTimeout(WAIT_FOR_DOWNLOAD_POLL_TIME,
75bd06f02d02e07ca15e420ee9e50e35253646ba64Neal Nguyen                    MAX_WAIT_FOR_LARGE_DOWNLOAD_TIME);
7640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            cursor = mDownloadManager.query(new Query());
7740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            assertEquals(NUM_FILES, cursor.getCount());
7840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Verified number of downloads in download manager is what we expect.");
7940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            while (cursor.moveToNext()) {
8040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
8140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                String filename = cursor.getString(cursor.getColumnIndex(
8240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                        DownloadManager.COLUMN_URI));
8340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                String errorString = String.format("File %s failed to download successfully. " +
8440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                        "Status code: %d", filename, status);
8540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                assertEquals(errorString, DownloadManager.STATUS_SUCCESSFUL, status);
8640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            }
8740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Verified each download was successful.");
8840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            assertEquals(NUM_FILES, receiver.numDownloadsCompleted());
8940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Verified number of completed downloads in our receiver.");
9040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
9140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            // Verify that for each request, we can open the downloaded file
9240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            for (int i = 0; i < NUM_FILES; ++i) {
9340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(reqs[i]);
9440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                pfd.close();
9540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            }
9640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            Log.i(LOG_TAG, "Verified we can open each file.");
9740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        } finally {
9840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            if (cursor != null) {
9940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                cursor.close();
10040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            }
10140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            mContext.unregisterReceiver(receiver);
10240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            removeAllCurrentDownloads();
10340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        }
10440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    }
10540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
10640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    /**
10740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     * Tests trying to download a large file (50M bytes).
10840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     */
10940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    public void testDownloadLargeFile() throws Exception {
11040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        long fileSize = 50000000L;  // note: kept relatively small to not exceed /cache dir size
11140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        File largeFile = createFileOnSD(null, fileSize, DataType.TEXT, null);
11240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        MultipleDownloadsCompletedReceiver receiver = registerNewMultipleDownloadsReceiver();
11340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
11440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        try {
11540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            long dlRequest = doStandardEnqueue(largeFile);
11640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
11740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen             // wait for the download to complete
11840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            waitForDownloadOrTimeout(dlRequest);
11940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
12040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
12140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            verifyFileContents(pfd, largeFile);
12240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            verifyFileSize(pfd, largeFile.length());
12340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
12440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            assertEquals(1, receiver.numDownloadsCompleted());
12540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            mContext.unregisterReceiver(receiver);
12640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        } catch (Exception e) {
12740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            throw e;
12840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        } finally {
12940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            largeFile.delete();
13040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        }
13140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    }
13240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
13340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    /**
134bd06f02d02e07ca15e420ee9e50e35253646ba64Neal Nguyen     * Tests trying to download a large file (~600M bytes) when there's not enough space in cache
13540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen     */
13640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    public void testInsufficientSpace() throws Exception {
137bd06f02d02e07ca15e420ee9e50e35253646ba64Neal Nguyen        // @TODO: Rework this to fill up cache partition with a dynamically calculated size
138bd06f02d02e07ca15e420ee9e50e35253646ba64Neal Nguyen        long fileSize = 600000000L;
13940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        File largeFile = createFileOnSD(null, fileSize, DataType.TEXT, null);
14040ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
14140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        Cursor cursor = null;
14240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        try {
14340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            long dlRequest = doStandardEnqueue(largeFile);
14440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
14540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen             // wait for the download to complete
14640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            waitForDownloadOrTimeout(dlRequest);
14740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen
14840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            cursor = getCursor(dlRequest);
14940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            verifyInt(cursor, DownloadManager.COLUMN_STATUS, DownloadManager.STATUS_FAILED);
1503e8c1d3a467bab889de7f92379be1f43d9c2d81eSteve Howard            verifyInt(cursor, DownloadManager.COLUMN_REASON,
15140ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                    DownloadManager.ERROR_INSUFFICIENT_SPACE);
15240ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        } finally {
15340ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            if (cursor != null) {
15440ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen                cursor.close();
15540ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            }
15640ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen            largeFile.delete();
15740ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen        }
15840ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen    }
15940ef0f49ea9fa7c39eb0018fdb4df4b73a11a77dNeal Nguyen}
160