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