xref: /aosp_15_r20/frameworks/base/core/tests/coretests/src/android/app/DownloadManagerStressTest.java (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
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 
17 package android.app;
18 
19 import android.app.DownloadManager.Query;
20 import android.app.DownloadManager.Request;
21 import android.database.Cursor;
22 import android.net.Uri;
23 import android.os.Environment;
24 import android.os.ParcelFileDescriptor;
25 import android.os.StatFs;
26 import android.util.Log;
27 
28 import androidx.test.filters.LargeTest;
29 import androidx.test.filters.Suppress;
30 
31 import java.io.File;
32 import java.io.FileOutputStream;
33 import java.io.IOException;
34 import java.util.Random;
35 
36 /**
37  * Integration tests of the DownloadManager API.
38  */
39 @Suppress  // Failing.
40 public class DownloadManagerStressTest extends DownloadManagerBaseTest {
41     private static final String TAG = "DownloadManagerStressTest";
42     private final static String CACHE_DIR =
43             Environment.getDownloadCacheDirectory().getAbsolutePath();
44 
45     /**
46      * {@inheritDoc}
47      */
48     @Override
setUp()49     public void setUp() throws Exception {
50         super.setUp();
51         setWiFiStateOn(true);
52         removeAllCurrentDownloads();
53     }
54 
55     /**
56      * {@inheritDoc}
57      */
58     @Override
tearDown()59     public void tearDown() throws Exception {
60         super.tearDown();
61         setWiFiStateOn(true);
62         removeAllCurrentDownloads();
63 
64         if (mReceiver != null) {
65             mContext.unregisterReceiver(mReceiver);
66             mReceiver = null;
67         }
68     }
69 
70     /**
71      * Attempts to download several files simultaneously
72      */
73     @LargeTest
testMultipleDownloads()74     public void testMultipleDownloads() throws Exception {
75         // need to be sure all current downloads have stopped first
76         removeAllCurrentDownloads();
77         int NUM_FILES = 10;
78         int MAX_FILE_SIZE = 10 * 1024; // 10 kb
79 
80         Random r = new LoggingRng();
81         for (int i=0; i<NUM_FILES; ++i) {
82             int size = r.nextInt(MAX_FILE_SIZE);
83             byte[] blobData = generateData(size, DataType.TEXT);
84 
85             Uri uri = getServerUri(DEFAULT_FILENAME + i);
86             Request request = new Request(uri);
87             request.setTitle(String.format("%s--%d", DEFAULT_FILENAME + i, i));
88 
89             // Prepare the mock server with a standard response
90             enqueueResponse(buildResponse(HTTP_OK, blobData));
91 
92             long requestID = mDownloadManager.enqueue(request);
93         }
94 
95         waitForDownloadsOrTimeout(WAIT_FOR_DOWNLOAD_POLL_TIME, MAX_WAIT_FOR_DOWNLOAD_TIME);
96         Cursor cursor = mDownloadManager.query(new Query());
97         try {
98             assertEquals(NUM_FILES, cursor.getCount());
99 
100             if (cursor.moveToFirst()) {
101                 do {
102                     int status = cursor.getInt(cursor.getColumnIndex(
103                             DownloadManager.COLUMN_STATUS));
104                     String filename = cursor.getString(cursor.getColumnIndex(
105                             DownloadManager.COLUMN_URI));
106                     String errorString = String.format(
107                             "File %s failed to download successfully. Status code: %d",
108                             filename, status);
109                     assertEquals(errorString, DownloadManager.STATUS_SUCCESSFUL, status);
110                 } while (cursor.moveToNext());
111             }
112 
113             assertEquals(NUM_FILES, mReceiver.numDownloadsCompleted());
114         } finally {
115             cursor.close();
116         }
117     }
118     /**
119      * Tests trying to download a large file (50M bytes).
120      */
121     @LargeTest
testDownloadLargeFile()122     public void testDownloadLargeFile() throws Exception {
123         long fileSize = 50000000L;  // note: kept relatively small to not exceed /cache dir size
124         Log.i(TAG, "creating a file of size: " + fileSize);
125         File largeFile = createFileOnSD(null, fileSize, DataType.TEXT, null);
126         Log.i(TAG, "DONE creating a file of size: " + fileSize);
127         MultipleDownloadsCompletedReceiver receiver = registerNewMultipleDownloadsReceiver();
128 
129         try {
130             long dlRequest = doStandardEnqueue(largeFile);
131 
132             // wait for the download to complete
133             waitForDownloadOrTimeout(dlRequest);
134 
135             ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
136             verifyFileContents(pfd, largeFile);
137             verifyFileSize(pfd, largeFile.length());
138 
139             assertEquals(1, receiver.numDownloadsCompleted());
140             mContext.unregisterReceiver(receiver);
141         } catch (Exception e) {
142             throw e;
143         } finally {
144             largeFile.delete();
145         }
146     }
147 
148 
149     /**
150      * Tests downloading a file to system cache when there isn't enough space in the system cache
151      * to hold the entire file. DownloadManager deletes enough files to make space for the
152      * new download.
153      */
154     @LargeTest
testDownloadToCacheWithAlmostFullCache()155     public void testDownloadToCacheWithAlmostFullCache() throws Exception {
156         int DOWNLOAD_FILE_SIZE = 1024 * 1024; // 1MB
157 
158         StatFs fs = new StatFs(CACHE_DIR);
159         int blockSize = fs.getBlockSize();
160         int availableBlocks = fs.getAvailableBlocks();
161         int availableBytes = blockSize * availableBlocks;
162         Log.i(TAG, "INITIAL stage, available space in /cache: " + availableBytes);
163         File outFile = File.createTempFile("DM_TEST", null, new File(CACHE_DIR));
164         byte[] buffer = new byte[blockSize];
165 
166         try {
167             // fill cache to ensure we don't have enough space - take half the size of the
168             // download size, and leave that much freespace left on the cache partition
169             if (DOWNLOAD_FILE_SIZE <= availableBytes) {
170                 int writeSizeBytes = availableBytes - (DOWNLOAD_FILE_SIZE / 2);
171 
172                 int writeSizeBlocks = writeSizeBytes / blockSize;
173                 int remainderSizeBlocks = availableBlocks - writeSizeBlocks;
174 
175                 FileOutputStream fo = null;
176                 try {
177                     fo = new FileOutputStream(outFile);
178                     while (fs.getAvailableBlocks() >= remainderSizeBlocks) {
179                         fo.write(buffer);
180                         fs.restat(CACHE_DIR);
181                     }
182                 } catch (IOException e) {
183                     Log.e(LOG_TAG, "error filling file: ", e);
184                     throw e;
185                 } finally {
186                     if (fo != null) {
187                         fo.close();
188                     }
189                 }
190             }
191 
192             // /cache should now be almost full.
193             long spaceAvailable = fs.getAvailableBlocks() * blockSize;
194             Log.i(TAG, "BEFORE download, available space in /cache: " + spaceAvailable);
195             assertTrue(DOWNLOAD_FILE_SIZE > spaceAvailable);
196 
197             // try to download 1MB file into /cache - and it should succeed
198             byte[] blobData = generateData(DOWNLOAD_FILE_SIZE, DataType.TEXT);
199             long dlRequest = doBasicDownload(blobData);
200             verifyAndCleanupSingleFileDownload(dlRequest, blobData);
201         } finally {
202             if (outFile != null) {
203                 outFile.delete();
204             }
205         }
206     }
207 }
208