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

Commit b9881e6b authored by Neal Nguyen's avatar Neal Nguyen Committed by Android (Google) Code Review
Browse files

Merge "Adding more DL Manager tests." into gingerbread

parents 8d1513e1 df7a865b
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
@@ -54,8 +54,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;

@@ -69,8 +71,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();
    }

@@ -79,7 +81,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;
    }

@@ -198,4 +200,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