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