1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
19import java.io.File;
20import java.util.Random;
21
22import android.app.DownloadManager.Query;
23import android.app.DownloadManager.Request;
24import android.database.Cursor;
25import android.net.Uri;
26import android.os.ParcelFileDescriptor;
27import android.util.Log;
28
29
30public class DownloadManagerStressTest extends DownloadManagerBaseTest {
31    private static String LOG_TAG = "android.net.DownloadManagerStressTest";
32
33    /**
34     * {@inheritDoc}
35     */
36    @Override
37    public void setUp() throws Exception {
38        super.setUp();
39        mServer.play(0);
40        setWiFiStateOn(true);
41        removeAllCurrentDownloads();
42    }
43
44    /**
45     * Attempts to downloading thousands of files simultaneously
46     */
47    public void testDownloadThousands() throws Exception {
48        int NUM_FILES = 1500;
49        int MAX_FILE_SIZE = 3000;
50        long[] reqs = new long[NUM_FILES];
51
52        // need to be sure all current downloads have stopped first
53        MultipleDownloadsCompletedReceiver receiver = registerNewMultipleDownloadsReceiver();
54        Cursor cursor = null;
55        try {
56            Random r = new LoggingRng();
57            for (int i = 0; i < NUM_FILES; ++i) {
58                int size = r.nextInt(MAX_FILE_SIZE);
59                byte[] blobData = generateData(size, DataType.TEXT);
60
61                Uri uri = getServerUri(DEFAULT_FILENAME);
62                Request request = new Request(uri);
63                request.setTitle(String.format("%s--%d", DEFAULT_FILENAME, i));
64
65                // Prepare the mock server with a standard response
66                enqueueResponse(HTTP_OK, blobData);
67
68                Log.i(LOG_TAG, "issuing request: " + i);
69                long reqId = mDownloadManager.enqueue(request);
70                reqs[i] = reqId;
71            }
72
73            // wait for the download to complete or timeout
74            waitForDownloadsOrTimeout(WAIT_FOR_DOWNLOAD_POLL_TIME,
75                    MAX_WAIT_FOR_LARGE_DOWNLOAD_TIME);
76            cursor = mDownloadManager.query(new Query());
77            assertEquals(NUM_FILES, cursor.getCount());
78            Log.i(LOG_TAG, "Verified number of downloads in download manager is what we expect.");
79            while (cursor.moveToNext()) {
80                int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
81                String filename = cursor.getString(cursor.getColumnIndex(
82                        DownloadManager.COLUMN_URI));
83                String errorString = String.format("File %s failed to download successfully. " +
84                        "Status code: %d", filename, status);
85                assertEquals(errorString, DownloadManager.STATUS_SUCCESSFUL, status);
86            }
87            Log.i(LOG_TAG, "Verified each download was successful.");
88            assertEquals(NUM_FILES, receiver.numDownloadsCompleted());
89            Log.i(LOG_TAG, "Verified number of completed downloads in our receiver.");
90
91            // Verify that for each request, we can open the downloaded file
92            for (int i = 0; i < NUM_FILES; ++i) {
93                ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(reqs[i]);
94                pfd.close();
95            }
96            Log.i(LOG_TAG, "Verified we can open each file.");
97        } finally {
98            if (cursor != null) {
99                cursor.close();
100            }
101            mContext.unregisterReceiver(receiver);
102            removeAllCurrentDownloads();
103        }
104    }
105
106    /**
107     * Tests trying to download a large file (50M bytes).
108     */
109    public void testDownloadLargeFile() throws Exception {
110        long fileSize = 50000000L;  // note: kept relatively small to not exceed /cache dir size
111        File largeFile = createFileOnSD(null, fileSize, DataType.TEXT, null);
112        MultipleDownloadsCompletedReceiver receiver = registerNewMultipleDownloadsReceiver();
113
114        try {
115            long dlRequest = doStandardEnqueue(largeFile);
116
117             // wait for the download to complete
118            waitForDownloadOrTimeout(dlRequest);
119
120            ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
121            verifyFileContents(pfd, largeFile);
122            verifyFileSize(pfd, largeFile.length());
123
124            assertEquals(1, receiver.numDownloadsCompleted());
125            mContext.unregisterReceiver(receiver);
126        } catch (Exception e) {
127            throw e;
128        } finally {
129            largeFile.delete();
130        }
131    }
132
133    /**
134     * Tests trying to download a large file (~600M bytes) when there's not enough space in cache
135     */
136    public void testInsufficientSpace() throws Exception {
137        // @TODO: Rework this to fill up cache partition with a dynamically calculated size
138        long fileSize = 600000000L;
139        File largeFile = createFileOnSD(null, fileSize, DataType.TEXT, null);
140
141        Cursor cursor = null;
142        try {
143            long dlRequest = doStandardEnqueue(largeFile);
144
145             // wait for the download to complete
146            waitForDownloadOrTimeout(dlRequest);
147
148            cursor = getCursor(dlRequest);
149            verifyInt(cursor, DownloadManager.COLUMN_STATUS, DownloadManager.STATUS_FAILED);
150            verifyInt(cursor, DownloadManager.COLUMN_REASON,
151                    DownloadManager.ERROR_INSUFFICIENT_SPACE);
152        } finally {
153            if (cursor != null) {
154                cursor.close();
155            }
156            largeFile.delete();
157        }
158    }
159}
160