Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit abb45e67 authored by Neal Nguyen's avatar Neal Nguyen Committed by Android Git Automerger
Browse files

am b9881e6b: Merge "Adding more DL Manager tests." into gingerbread

Merge commit 'b9881e6b' into gingerbread-plus-aosp

* commit 'b9881e6b':
  Adding more DL Manager tests.
parents 96d5c17e b9881e6b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
            android:label="@string/permlab_testDenied"
            android:description="@string/permdesc_testDenied" />

    <uses-permission android:name="android.permission.ACCESS_CACHE_FILESYSTEM" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+31 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.net.NetworkInfo;
import android.net.DownloadManager.Query;
import android.net.DownloadManager.Request;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
@@ -43,9 +44,12 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.TimeoutException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.Vector;

import junit.framework.AssertionFailedError;
@@ -67,6 +71,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {

    protected static final String LOG_TAG = "android.net.DownloadManagerBaseTest";
    protected static final int HTTP_OK = 200;
    protected static final int HTTP_REDIRECT = 307;
    protected static final int HTTP_PARTIAL_CONTENT = 206;
    protected static final int HTTP_NOT_FOUND = 404;
    protected static final int HTTP_SERVICE_UNAVAILABLE = 503;
@@ -119,6 +124,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {

    public static class MultipleDownloadsCompletedReceiver extends BroadcastReceiver {
        private volatile int mNumDownloadsCompleted = 0;
        private Set<Long> downloadIds = Collections.synchronizedSet(new HashSet<Long>());

        /**
         * {@inheritDoc}
@@ -129,6 +135,8 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
                ++mNumDownloadsCompleted;
                Log.i(LOG_TAG, "MultipleDownloadsCompletedReceiver got intent: " +
                        intent.getAction() + " --> total count: " + mNumDownloadsCompleted);
                Bundle extras = intent.getExtras();
                downloadIds.add(new Long(extras.getLong(DownloadManager.EXTRA_DOWNLOAD_ID)));
            }
        }

@@ -142,6 +150,18 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
        public int numDownloadsCompleted() {
            return mNumDownloadsCompleted;
        }

        /**
         * Gets the list of download IDs.
         * @return A Set<Long> with the ids of the completed downloads.
         */
        public Set<Long> getDownloadIds() {
            synchronized(downloadIds) {
                Set<Long> returnIds = new HashSet<Long>(downloadIds);
                return returnIds;
            }
        }

    }

    public static class WiFiChangedReceiver extends BroadcastReceiver {
@@ -195,6 +215,17 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
        // Note: callers overriding this should call mServer.play() with the desired port #
    }

    /**
     * Helper to enqueue a response from the MockWebServer with no body.
     *
     * @param status The HTTP status code to return for this response
     * @return Returns the mock web server response that was queued (which can be modified)
     */
    protected MockResponse enqueueResponse(int status) {
        return doEnqueueResponse(status);

    }

    /**
     * Helper to enqueue a response from the MockWebServer.
     *
+236 −28
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.DownloadManager;
import android.net.DownloadManager.Query;
import android.net.DownloadManager.Request;
import android.net.DownloadManagerBaseTest.DataType;
@@ -28,6 +29,7 @@ import android.net.DownloadManagerBaseTest.MultipleDownloadsCompletedReceiver;
import android.net.wifi.WifiManager;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.os.StatFs;
import android.os.SystemClock;
import android.test.InstrumentationTestCase;
import android.test.suitebuilder.annotation.LargeTest;
@@ -36,10 +38,13 @@ import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.util.Iterator;
import java.util.Random;
import java.util.Set;

import junit.framework.AssertionFailedError;

@@ -51,8 +56,11 @@ import coretestutils.http.MockWebServer;
 */
public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {

    private static String LOG_TAG = "android.net.DownloadManagerIntegrationTest";
    private static String PROHIBITED_DIRECTORY = "/system";
    private final static String LOG_TAG = "android.net.DownloadManagerIntegrationTest";
    private final static String PROHIBITED_DIRECTORY =
            Environment.getRootDirectory().getAbsolutePath();
    private final static String CACHE_DIR =
            Environment.getDownloadCacheDirectory().getAbsolutePath();
    protected MultipleDownloadsCompletedReceiver mReceiver = null;

    /**
@@ -74,25 +82,48 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
    public void tearDown() throws Exception {
        super.tearDown();
        setWiFiStateOn(true);
        removeAllCurrentDownloads();

        if (mReceiver != null) {
            mContext.unregisterReceiver(mReceiver);
            mReceiver = null;
            removeAllCurrentDownloads();
        }
    }

    /**
     * Helper that does the actual basic download verification.
     */
    protected void doBasicDownload(byte[] blobData) throws Exception {
    protected long doBasicDownload(byte[] blobData) throws Exception {
        long dlRequest = doStandardEnqueue(blobData);

        // wait for the download to complete
        waitForDownloadOrTimeout(dlRequest);

        verifyAndCleanupSingleFileDownload(dlRequest, blobData);
        assertEquals(1, mReceiver.numDownloadsCompleted());
        return dlRequest;
    }

    /**
     * Verifies a particular error code was received from a download
     *
     * @param uri The uri to enqueue to the DownloadManager
     * @param error The error code expected
     * @throws an Exception if the test fails
     */
    @LargeTest
    public void doErrorTest(Uri uri, int error) throws Exception {
        Request request = new Request(uri);
        request.setTitle(DEFAULT_FILENAME);

        long dlRequest = mDownloadManager.enqueue(request);
        waitForDownloadOrTimeout(dlRequest);

        Cursor cursor = getCursor(dlRequest);
        try {
            verifyInt(cursor, DownloadManager.COLUMN_ERROR_CODE, error);
        } finally {
            cursor.close();
        }
    }

    /**
@@ -103,7 +134,8 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
        int fileSize = 500 * 1024;  // 500k
        byte[] blobData = generateData(fileSize, DataType.BINARY);

        doBasicDownload(blobData);
        long dlRequest = doBasicDownload(blobData);
        verifyAndCleanupSingleFileDownload(dlRequest, blobData);
    }

    /**
@@ -114,7 +146,8 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
        int fileSize = 300000;
        byte[] blobData = generateData(fileSize, DataType.TEXT);

        doBasicDownload(blobData);
        long dlRequest = doBasicDownload(blobData);
        verifyAndCleanupSingleFileDownload(dlRequest, blobData);
    }

    /**
@@ -348,24 +381,99 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
    }

    /**
     * Tests trying to download two large files (50M bytes, followed by 60M bytes)
     * Tests downloading a file to cache when there isn't enough space in the cache to hold the
     * entire file.
     */
    @LargeTest
    public void testInsufficientSpaceSingleFiles() throws Exception {
        long fileSize1 = 50000000L;
        long fileSize2 = 60000000L;
        File largeFile1 = createFileOnSD(null, fileSize1, DataType.TEXT, null);
        File largeFile2 = createFileOnSD(null, fileSize2, DataType.TEXT, null);
    public void testDownloadToCache_whenFull() throws Exception {
        int DOWNLOAD_FILE_SIZE = 500000;

        StatFs fs = new StatFs(CACHE_DIR);
        Log.i(LOG_TAG, "getAvailableBlocks: " + fs.getAvailableBlocks());
        Log.i(LOG_TAG, "getBlockSize: " + fs.getBlockSize());

        int blockSize = fs.getBlockSize();
        int availableBlocks = fs.getAvailableBlocks();
        int availableBytes = blockSize * availableBlocks;
        File outFile = null;

        try {
            long dlRequest = doStandardEnqueue(largeFile1);
            // fill cache to ensure we don't have enough space - take half the size of the
            // download size, and leave that much freespace left on the cache partition
            if (DOWNLOAD_FILE_SIZE <= availableBytes) {
                int writeSizeBytes = availableBytes - (DOWNLOAD_FILE_SIZE / 2);

                int writeSizeBlocks = writeSizeBytes / blockSize;
                int remainderSizeBlocks = availableBlocks - writeSizeBlocks;

                FileOutputStream fo = null;
                try {
                    outFile = File.createTempFile("DM_TEST", null, new File(CACHE_DIR));
                    Log.v(LOG_TAG, "writing " + writeSizeBlocks + " blocks to file "
                            + outFile.getAbsolutePath());

                    fo = new FileOutputStream(outFile);

                    byte[] buffer = new byte[blockSize];
                    while (fs.getAvailableBlocks() >= remainderSizeBlocks) {
                        fo.write(buffer);
                        fs.restat(CACHE_DIR);
                    }
                } catch (IOException e) {
                    Log.e(LOG_TAG, "error filling file: ", e);
                    throw e;
                } finally {
                    if (fo != null) {
                        fo.close();
                    }
                }
            }

            assertTrue(DOWNLOAD_FILE_SIZE > (fs.getAvailableBlocks() * blockSize));
            byte[] blobData = generateData(DOWNLOAD_FILE_SIZE, DataType.TEXT);
            long dlRequest = doBasicDownload(blobData);
            verifyAndCleanupSingleFileDownload(dlRequest, blobData);

        } finally {
            if (outFile != null) {
                outFile.delete();
            }
        }
    }

    /**
     * Tests that files are not deleted when DOWNLOAD_CACHE_NON_PURGEABLE is set, even if we've
     * run out of space.
     */
    @LargeTest
    public void testDownloadCacheNonPurgeable() throws Exception {
        int fileSize = 10000000;
        byte[] blobData = generateData(fileSize, DataType.BINARY);
        long dlRequest = -1;

        // Fill up the cache partition until there's not enough room for another download.
        // Note that we need to initiate a download first, then check for the available space. This
        // is b/c there could be some files that are still left in the cache that can (and will be)
        // cleared out, but not until DM gets a request for a download and reclaims that
        // space first.
        boolean spaceAvailable = true;
        while (spaceAvailable) {
            dlRequest = doStandardEnqueue(blobData);
            waitForDownloadOrTimeout(dlRequest);
            ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(dlRequest);
            verifyFileContents(pfd, largeFile1);
            verifyFileSize(pfd, largeFile1.length());

            dlRequest = doStandardEnqueue(largeFile2);
            // Check if we've filled up the cache yet
            StatFs fs = new StatFs(CACHE_DIR);
            Log.i(LOG_TAG, "getAvailableBlocks: " + fs.getAvailableBlocks());
            Log.i(LOG_TAG, "getBlockSize: " + fs.getBlockSize());
            int availableBytes = fs.getBlockSize() * fs.getAvailableBlocks();
            spaceAvailable = (availableBytes > fileSize) ? true : false;
        }

        // Now add one more download (should not fit in the space left over)
        dlRequest = doStandardEnqueue(blobData);
        waitForDownloadOrTimeout(dlRequest);

        // For the last download we should have failed b/c there is not enough space left in cache
        Cursor cursor = getCursor(dlRequest);
        try {
            verifyInt(cursor, DownloadManager.COLUMN_ERROR_CODE,
@@ -373,9 +481,109 @@ public class DownloadManagerIntegrationTest extends DownloadManagerBaseTest {
        } finally {
            cursor.close();
        }
    }

    /**
     * Tests that we get the correct download ID from the download notification.
     */
    @LargeTest
    public void testGetDownloadIdOnNotification() throws Exception {
        byte[] blobData = generateData(3000, DataType.TEXT);  // file size = 3000 bytes

        MockResponse response = enqueueResponse(HTTP_OK, blobData);
        long dlRequest = doCommonStandardEnqueue();
        waitForDownloadOrTimeout(dlRequest);

        Set<Long> ids = mReceiver.getDownloadIds();
        assertEquals(1, ids.size());
        Iterator<Long> it = ids.iterator();
        assertEquals("Download ID received from notification does not match initial id!",
                dlRequest, it.next().longValue());
    }

    /**
     * Tests the download failure error after too many redirects (>5).
     */
    @LargeTest
    public void testErrorTooManyRedirects() throws Exception {
        Uri uri = getServerUri(DEFAULT_FILENAME);

        // force 6 redirects
        for (int i = 0; i < 6; ++i) {
            MockResponse response = enqueueResponse(HTTP_REDIRECT);
            response.addHeader("Location", uri.toString());
        }
        doErrorTest(uri, DownloadManager.ERROR_TOO_MANY_REDIRECTS);
    }

    /**
     * Tests the download failure error from an unhandled HTTP status code
     */
    @LargeTest
    public void testErrorUnhandledHttpCode() throws Exception {
        Uri uri = getServerUri(DEFAULT_FILENAME);
        MockResponse response = enqueueResponse(HTTP_PARTIAL_CONTENT);

        doErrorTest(uri, DownloadManager.ERROR_UNHANDLED_HTTP_CODE);
    }

    /**
     * Tests the download failure error from an unhandled HTTP status code
     */
    @LargeTest
    public void testErrorHttpDataError_invalidRedirect() throws Exception {
        Uri uri = getServerUri(DEFAULT_FILENAME);
        MockResponse response = enqueueResponse(HTTP_REDIRECT);
        response.addHeader("Location", "://blah.blah.blah.com");

        doErrorTest(uri, DownloadManager.ERROR_HTTP_DATA_ERROR);
    }

    /**
     * Tests that we can remove a download from the download manager.
     */
    @LargeTest
    public void testRemoveDownload() throws Exception {
        int fileSize = 100 * 1024;  // 100k
        byte[] blobData = generateData(fileSize, DataType.BINARY);

        long dlRequest = doBasicDownload(blobData);
        Cursor cursor = mDownloadManager.query(new Query().setFilterById(dlRequest));
        try {
            assertEquals("The count of downloads with this ID is not 1!", 1, cursor.getCount());
            mDownloadManager.remove(dlRequest);
            cursor.requery();
            assertEquals("The count of downloads with this ID is not 0!", 0, cursor.getCount());
        } finally {
            largeFile1.delete();
            largeFile2.delete();
            cursor.close();
        }
    }

    /**
     * Tests that we can set the title of a download.
     */
    @LargeTest
    public void testSetTitle() throws Exception {
        int fileSize = 50 * 1024;  // 50k
        byte[] blobData = generateData(fileSize, DataType.BINARY);
        MockResponse response = enqueueResponse(HTTP_OK, blobData);

        // An arbitrary unicode string title
        final String title = "\u00a5123;\"\u0152\u017d \u054b \u0a07 \ucce0 \u6820\u03a8\u5c34" +
                "\uf4ad\u0da9\uc0c5\uc1a8 \uf4c5 \uf4aa\u0023\'";

        Uri uri = getServerUri(DEFAULT_FILENAME);
        Request request = new Request(uri);
        request.setTitle(title);

        long dlRequest = mDownloadManager.enqueue(request);
        waitForDownloadOrTimeout(dlRequest);

        Cursor cursor = getCursor(dlRequest);
        try {
            verifyString(cursor, DownloadManager.COLUMN_TITLE, title);
        } finally {
            cursor.close();
        }
    }
}
+22 −5
Original line number Diff line number Diff line
@@ -46,8 +46,10 @@ public class DownloadManagerHostTests extends DeviceTestCase {
    private static final String EXTERNAL_DOWNLOAD_URI_KEY = "external_download_uri";
    // Note: External environment variable ANDROID_TEST_EXTERNAL_URI must be set to point to the
    // external URI under which the files downloaded by the tests can be found. Note that the Uri
    // must be accessible by the device during a test run.
    private static String EXTERNAL_DOWNLOAD_URI_VALUE = null;
    // must be accessible by the device during a test run. Correspondingly,
    // ANDROID_TEST_EXTERNAL_LARGE_URI should point to the external URI of the folder containing
    // large files.
    private static String externalDownloadUriValue = null;

    Hashtable<String, String> mExtraParams = null;

@@ -61,8 +63,8 @@ public class DownloadManagerHostTests extends DeviceTestCase {
        // ensure apk path has been set before test is run
        assertNotNull(getTestAppPath());
        mPMUtils = new PackageManagerHostTestUtils(getDevice());
        EXTERNAL_DOWNLOAD_URI_VALUE = System.getenv("ANDROID_TEST_EXTERNAL_URI");
        assertNotNull(EXTERNAL_DOWNLOAD_URI_VALUE);
        externalDownloadUriValue = System.getenv("ANDROID_TEST_EXTERNAL_URI");
        assertNotNull(externalDownloadUriValue);
        mExtraParams = getExtraParams();
    }

@@ -71,7 +73,7 @@ public class DownloadManagerHostTests extends DeviceTestCase {
     */
    protected Hashtable<String, String> getExtraParams() {
        Hashtable<String, String> extraParams = new Hashtable<String, String>();
        extraParams.put(EXTERNAL_DOWNLOAD_URI_KEY, EXTERNAL_DOWNLOAD_URI_VALUE);
        extraParams.put(EXTERNAL_DOWNLOAD_URI_KEY, externalDownloadUriValue);
        return extraParams;
    }

@@ -190,4 +192,19 @@ public class DownloadManagerHostTests extends DeviceTestCase {
                DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
        assertTrue(testPassed);
    }

    /**
     * Spawns a device-based function to test 15 concurrent downloads of 5,000,000-byte files
     *
     * @throws Exception if the test failed at any point
     */
    public void testDownloadMultipleSimultaneously() throws Exception {
        mPMUtils.installAppAndVerifyExistsOnDevice(String.format("%s%s%s", getTestAppPath(),
                File.separator, FILE_DOWNLOAD_APK), FILE_DOWNLOAD_PKG, true);

        boolean testPassed = mPMUtils.runDeviceTestsDidAllTestsPass(FILE_DOWNLOAD_PKG,
                FILE_DOWNLOAD_CLASS, "runDownloadMultipleSimultaneously",
                DOWNLOAD_TEST_RUNNER_NAME, mExtraParams);
        assertTrue(testPassed);
    }
}
+54 −3
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.util.HashSet;

import coretestutils.http.MockResponse;
import coretestutils.http.MockWebServer;
@@ -55,8 +56,13 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest {
    protected static String DOWNLOAD_10MB_FILENAME = "External10mb.apk";
    protected static long DOWNLOAD_10MB_FILESIZE = 10258741;

    private static final String FILE_CONCURRENT_DOWNLOAD_FILE_PREFIX = "file";
    private static final String FILE_CONCURRENT_DOWNLOAD_FILE_EXTENSION = ".bin";
    protected static long CONCURRENT_DOWNLOAD_FILESIZE = 1000000;

    // Values to be obtained from TestRunner
    private String externalDownloadUriValue = null;
    private String externalLargeDownloadUriValue = null;

    /**
     * {@inheritDoc }
@@ -65,12 +71,24 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest {
    public void setUp() throws Exception {
        super.setUp();
        DownloadManagerTestRunner mRunner = (DownloadManagerTestRunner)getInstrumentation();
        externalDownloadUriValue = mRunner.externalDownloadUriValue;
        externalDownloadUriValue = normalizeUri(mRunner.externalDownloadUriValue);
        assertNotNull(externalDownloadUriValue);

        if (!externalDownloadUriValue.endsWith("/")) {
            externalDownloadUriValue += "/";
        externalLargeDownloadUriValue = normalizeUri(mRunner.externalDownloadUriValue);
        assertNotNull(externalLargeDownloadUriValue);
    }

    /**
     * Normalizes a uri to ensure it ends with a "/"
     *
     * @param uri The uri to normalize (or null)
     * @return The normalized uri, or null if null was passed in
     */
    public String normalizeUri(String uri) {
        if (uri != null && !uri.endsWith("/")) {
            uri += "/";
        }
        return uri;
    }

    /**
@@ -460,4 +478,37 @@ public class DownloadManagerTestApp extends DownloadManagerBaseTest {
            downloadedFile.delete();
        }
    }

    /**
     * Tests 15 concurrent downloads of 1,000,000-byte files.
     *
     * @throws Exception if test failed
     */
    public void runDownloadMultipleSimultaneously() throws Exception {
        final int TOTAL_DOWNLOADS = 15;
        HashSet<Long> downloadIds = new HashSet<Long>(TOTAL_DOWNLOADS);
        MultipleDownloadsCompletedReceiver receiver = registerNewMultipleDownloadsReceiver();

        // Make sure there are no pending downloads currently going on
        removeAllCurrentDownloads();

        try {
            for (int i = 0; i < TOTAL_DOWNLOADS; ++i) {
                long dlRequest = -1;
                String filename = FILE_CONCURRENT_DOWNLOAD_FILE_PREFIX + i
                        + FILE_CONCURRENT_DOWNLOAD_FILE_EXTENSION;
                Uri remoteUri = getExternalFileUri(filename);
                Request request = new Request(remoteUri);
                request.setTitle(filename);
                dlRequest = mDownloadManager.enqueue(request);
                assertTrue(dlRequest != -1);
                downloadIds.add(dlRequest);
            }

            waitForDownloadsOrTimeout(DEFAULT_WAIT_POLL_TIME, 15 * 60 * 2000);  // wait 15 mins max
            assertEquals(TOTAL_DOWNLOADS, receiver.numDownloadsCompleted());
        } finally {
            removeAllCurrentDownloads();
        }
    }
}
Loading