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

Commit b14ad8cc authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Migrate to shared MockWebServer.

Bug: 4726601
Change-Id: Ibbe71b5785a64bd2883c46b83e721fba9a25afa2
parent e32a4ac8
Loading
Loading
Loading
Loading
+30 −36
Original line number Diff line number Diff line
@@ -16,12 +16,8 @@

package android.app;

import coretestutils.http.MockResponse;
import coretestutils.http.MockWebServer;

import android.app.DownloadManager.Query;
import android.app.DownloadManager.Request;
import android.app.DownloadManagerBaseTest.DataType;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -39,10 +35,14 @@ import android.provider.Settings;
import android.test.InstrumentationTestCase;
import android.util.Log;

import com.google.mockwebserver.MockResponse;
import com.google.mockwebserver.MockWebServer;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
@@ -53,13 +53,15 @@ import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeoutException;

import libcore.io.Streams;

/**
 * Base class for Instrumented tests for the Download Manager.
 */
public class DownloadManagerBaseTest extends InstrumentationTestCase {
    private static final String TAG = "DownloadManagerBaseTest";
    protected DownloadManager mDownloadManager = null;
    protected MockWebServer mServer = null;
    private MockWebServer mServer = null;
    protected String mFileType = "text/plain";
    protected Context mContext = null;
    protected MultipleDownloadsCompletedReceiver mReceiver = null;
@@ -237,63 +239,57 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
        mContext = getInstrumentation().getContext();
        mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE);
        mServer = new MockWebServer();
        mServer.play();
        mReceiver = registerNewMultipleDownloadsReceiver();
        // Note: callers overriding this should call mServer.play() with the desired port #
    }

    /**
     * Helper to enqueue a response from the MockWebServer with no body.
     * Helper to build 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);

    protected MockResponse buildResponse(int status) {
        MockResponse response = new MockResponse().setResponseCode(status);
        response.setHeader("Content-type", mFileType);
        return response;
    }

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

    protected MockResponse buildResponse(int status, byte[] body) {
        return buildResponse(status).setBody(body);
    }

    /**
     * Helper to enqueue a response from the MockWebServer.
     * Helper to build a response from the MockWebServer.
     *
     * @param status The HTTP status code to return for this response
     * @param bodyFile The body to return in this response
     * @return Returns the mock web server response that was queued (which can be modified)
     */
    protected MockResponse enqueueResponse(int status, File bodyFile) {
        return doEnqueueResponse(status).setBody(bodyFile);
    protected MockResponse buildResponse(int status, File bodyFile)
            throws FileNotFoundException, IOException {
        final byte[] body = Streams.readFully(new FileInputStream(bodyFile));
        return buildResponse(status).setBody(body);
    }

    /**
     * Helper for enqueue'ing a response from the MockWebServer.
     *
     * @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 doEnqueueResponse(int status) {
        MockResponse response = new MockResponse().setResponseCode(status);
        response.addHeader("Content-type", mFileType);
        mServer.enqueue(response);
        return response;
    protected void enqueueResponse(MockResponse resp) {
        mServer.enqueue(resp);
    }

    /**
     * Helper to generate a random blob of bytes.
     *
     * @param size The size of the data to generate
     * @param type The type of data to generate: currently, one of {@link DataType.TEXT} or
     *         {@link DataType.BINARY}.
     * @param type The type of data to generate: currently, one of {@link DataType#TEXT} or
     *         {@link DataType#BINARY}.
     * @return The random data that is generated.
     */
    protected byte[] generateData(int size, DataType type) {
@@ -304,8 +300,8 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
     * Helper to generate a random blob of bytes using a given RNG.
     *
     * @param size The size of the data to generate
     * @param type The type of data to generate: currently, one of {@link DataType.TEXT} or
     *         {@link DataType.BINARY}.
     * @param type The type of data to generate: currently, one of {@link DataType#TEXT} or
     *         {@link DataType#BINARY}.
     * @param rng (optional) The RNG to use; pass null to use
     * @return The random data that is generated.
     */
@@ -492,8 +488,6 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
            assertEquals(1, cursor.getCount());
            assertTrue(cursor.moveToFirst());

            mServer.checkForExceptions();

            verifyFileSize(pfd, fileSize);
            verifyFileContents(pfd, fileData);
        } finally {
@@ -928,7 +922,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {

    protected long enqueueDownloadRequest(byte[] body, int location) throws Exception {
        // Prepare the mock server with a standard response
        enqueueResponse(HTTP_OK, body);
        mServer.enqueue(buildResponse(HTTP_OK, body));
        return doEnqueue(location);
    }

@@ -943,7 +937,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {

    protected long enqueueDownloadRequest(File body, int location) throws Exception {
        // Prepare the mock server with a standard response
        enqueueResponse(HTTP_OK, body);
        mServer.enqueue(buildResponse(HTTP_OK, body));
        return doEnqueue(location);
    }

+19 −36
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package android.app;

import coretestutils.http.MockResponse;

import android.app.DownloadManager.Query;
import android.app.DownloadManager.Request;
import android.database.Cursor;
@@ -26,6 +24,8 @@ import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.test.suitebuilder.annotation.LargeTest;

import com.google.mockwebserver.MockResponse;

import java.io.File;
import java.util.Iterator;
import java.util.Set;
@@ -47,7 +47,6 @@ public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest {
    public void setUp() throws Exception {
        super.setUp();
        setWiFiStateOn(true);
        mServer.play();
        removeAllCurrentDownloads();
    }

@@ -132,8 +131,6 @@ public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest {
            assertEquals(1, cursor.getCount());
            assertTrue(cursor.moveToFirst());

            mServer.checkForExceptions();

            verifyFileSize(pfd, fileSize);
            verifyFileContents(pfd, fileData);
            int colIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME);
@@ -154,7 +151,7 @@ public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest {
        byte[] blobData = generateData(DEFAULT_FILE_SIZE, DataType.TEXT);

        // Prepare the mock server with a standard response
        enqueueResponse(HTTP_OK, blobData);
        enqueueResponse(buildResponse(HTTP_OK, blobData));

        try {
            Uri uri = getServerUri(DEFAULT_FILENAME);
@@ -193,7 +190,7 @@ public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest {
            byte[] blobData = generateData(DEFAULT_FILE_SIZE, DataType.TEXT);

            // Prepare the mock server with a standard response
            enqueueResponse(HTTP_OK, blobData);
            enqueueResponse(buildResponse(HTTP_OK, blobData));

            Uri uri = getServerUri(DEFAULT_FILENAME);
            Request request = new Request(uri);
@@ -224,7 +221,7 @@ public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest {
            byte[] blobData = generateData(DEFAULT_FILE_SIZE, DataType.TEXT);

            // Prepare the mock server with a standard response
            enqueueResponse(HTTP_OK, blobData);
            enqueueResponse(buildResponse(HTTP_OK, blobData));

            Uri uri = getServerUri(DEFAULT_FILENAME);
            Request request = new Request(uri);
@@ -251,7 +248,7 @@ public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest {
    public void testGetDownloadIdOnNotification() throws Exception {
        byte[] blobData = generateData(3000, DataType.TEXT);  // file size = 3000 bytes

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

@@ -271,8 +268,9 @@ public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest {

        // force 6 redirects
        for (int i = 0; i < 6; ++i) {
            MockResponse response = enqueueResponse(HTTP_REDIRECT);
            response.addHeader("Location", uri.toString());
            final MockResponse resp = buildResponse(HTTP_REDIRECT);
            resp.setHeader("Location", uri.toString());
            enqueueResponse(resp);
        }
        doErrorTest(uri, DownloadManager.ERROR_TOO_MANY_REDIRECTS);
    }
@@ -283,7 +281,7 @@ public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest {
    @LargeTest
    public void testErrorUnhandledHttpCode() throws Exception {
        Uri uri = getServerUri(DEFAULT_FILENAME);
        MockResponse response = enqueueResponse(HTTP_PARTIAL_CONTENT);
        enqueueResponse(buildResponse(HTTP_PARTIAL_CONTENT));

        doErrorTest(uri, DownloadManager.ERROR_UNHANDLED_HTTP_CODE);
    }
@@ -294,8 +292,9 @@ public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest {
    @LargeTest
    public void testErrorHttpDataError_invalidRedirect() throws Exception {
        Uri uri = getServerUri(DEFAULT_FILENAME);
        MockResponse response = enqueueResponse(HTTP_REDIRECT);
        response.addHeader("Location", "://blah.blah.blah.com");
        final MockResponse resp = buildResponse(HTTP_REDIRECT);
        resp.setHeader("Location", "://blah.blah.blah.com");
        enqueueResponse(resp);

        doErrorTest(uri, DownloadManager.ERROR_HTTP_DATA_ERROR);
    }
@@ -327,7 +326,7 @@ public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest {
    public void testSetTitle() throws Exception {
        int fileSize = 1024;
        byte[] blobData = generateData(fileSize, DataType.BINARY);
        MockResponse response = enqueueResponse(HTTP_OK, blobData);
        enqueueResponse(buildResponse(HTTP_OK, blobData));

        // An arbitrary unicode string title
        final String title = "\u00a5123;\"\u0152\u017d \u054b \u0a07 \ucce0 \u6820\u03a8\u5c34" +
@@ -359,7 +358,7 @@ public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest {
        byte[] blobData = generateData(fileSize, DataType.TEXT);

        setWiFiStateOn(false);
        enqueueResponse(HTTP_OK, blobData);
        enqueueResponse(buildResponse(HTTP_OK, blobData));

        try {
            Uri uri = getServerUri(DEFAULT_FILENAME);
@@ -382,24 +381,6 @@ public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest {
        }
    }

    /**
     * Tests when the server drops the connection after all headers (but before any data send).
     */
    @LargeTest
    public void testDropConnection_headers() throws Exception {
        byte[] blobData = generateData(DEFAULT_FILE_SIZE, DataType.TEXT);

        MockResponse response = enqueueResponse(HTTP_OK, blobData);
        response.setCloseConnectionAfterHeader("content-length");
        long dlRequest = doCommonStandardEnqueue();

        // Download will never complete when header is dropped
        boolean success = waitForDownloadOrTimeoutNoThrow(dlRequest, DEFAULT_WAIT_POLL_TIME,
                DEFAULT_MAX_WAIT_TIME);

        assertFalse(success);
    }

    /**
     * Tests that we get an error code when the server drops the connection during a download.
     */
@@ -407,8 +388,10 @@ public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest {
    public void testServerDropConnection_body() throws Exception {
        byte[] blobData = generateData(25000, DataType.TEXT);  // file size = 25000 bytes

        MockResponse response = enqueueResponse(HTTP_OK, blobData);
        response.setCloseConnectionAfterXBytes(15382);
        final MockResponse resp = buildResponse(HTTP_OK, blobData);
        resp.setHeader("Content-Length", "50000");
        enqueueResponse(resp);

        long dlRequest = doCommonStandardEnqueue();
        waitForDownloadOrTimeout(dlRequest);

+2 −3
Original line number Diff line number Diff line
@@ -46,7 +46,6 @@ public class DownloadManagerStressTest extends DownloadManagerBaseTest {
    public void setUp() throws Exception {
        super.setUp();
        setWiFiStateOn(true);
        mServer.play();
        removeAllCurrentDownloads();
    }

@@ -85,7 +84,7 @@ public class DownloadManagerStressTest extends DownloadManagerBaseTest {
            request.setTitle(String.format("%s--%d", DEFAULT_FILENAME + i, i));

            // Prepare the mock server with a standard response
            enqueueResponse(HTTP_OK, blobData);
            enqueueResponse(buildResponse(HTTP_OK, blobData));

            long requestID = mDownloadManager.enqueue(request);
        }
+1 −1
Original line number Diff line number Diff line
@@ -20,7 +20,7 @@ LOCAL_MODULE_TAGS := tests

LOCAL_SRC_FILES := $(call all-java-files-under, src)

LOCAL_STATIC_JAVA_LIBRARIES := android-common frameworks-core-util-lib
LOCAL_STATIC_JAVA_LIBRARIES := android-common mockwebserver
LOCAL_SDK_VERSION := current

LOCAL_PACKAGE_NAME := DownloadManagerTestApp
+2 −237
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.frameworks.downloadmanagertests;

import android.app.DownloadManager;
import android.app.DownloadManager.Query;
import android.app.DownloadManager.Request;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -26,37 +25,19 @@ import android.content.IntentFilter;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.os.SystemClock;
import android.os.ParcelFileDescriptor.AutoCloseInputStream;
import android.provider.Settings;
import android.test.InstrumentationTestCase;
import android.util.Log;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
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;

import coretestutils.http.MockResponse;
import coretestutils.http.MockWebServer;
import java.util.concurrent.TimeoutException;

/**
 * Base class for Instrumented tests for the Download Manager.
@@ -64,7 +45,6 @@ import coretestutils.http.MockWebServer;
public class DownloadManagerBaseTest extends InstrumentationTestCase {

    protected DownloadManager mDownloadManager = null;
    protected MockWebServer mServer = null;
    protected String mFileType = "text/plain";
    protected Context mContext = null;
    protected MultipleDownloadsCompletedReceiver mReceiver = null;
@@ -77,7 +57,6 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
    protected static final int HTTP_PARTIAL_CONTENT = 206;
    protected static final int HTTP_NOT_FOUND = 404;
    protected static final int HTTP_SERVICE_UNAVAILABLE = 503;
    protected String DEFAULT_FILENAME = "somefile.txt";

    protected static final int DEFAULT_MAX_WAIT_TIME = 2 * 60 * 1000;  // 2 minutes
    protected static final int DEFAULT_WAIT_POLL_TIME = 5 * 1000;  // 5 seconds
@@ -86,48 +65,6 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
    protected static final int MAX_WAIT_FOR_DOWNLOAD_TIME = 5 * 60 * 1000; // 5 minutes
    protected static final int MAX_WAIT_FOR_LARGE_DOWNLOAD_TIME = 15 * 60 * 1000; // 15 minutes

    protected static final int DOWNLOAD_TO_SYSTEM_CACHE = 1;
    protected static final int DOWNLOAD_TO_DOWNLOAD_CACHE_DIR = 2;

    // Just a few popular file types used to return from a download
    protected enum DownloadFileType {
        PLAINTEXT,
        APK,
        GIF,
        GARBAGE,
        UNRECOGNIZED,
        ZIP
    }

    protected enum DataType {
        TEXT,
        BINARY
    }

    public static class LoggingRng extends Random {

        /**
         * Constructor
         *
         * Creates RNG with self-generated seed value.
         */
        public LoggingRng() {
            this(SystemClock.uptimeMillis());
        }

        /**
         * Constructor
         *
         * Creats RNG with given initial seed value

         * @param seed The initial seed value
         */
        public LoggingRng(long seed) {
            super(seed);
            Log.i(LOG_TAG, "Seeding RNG with value: " + seed);
        }
    }

    public static class MultipleDownloadsCompletedReceiver extends BroadcastReceiver {
        private volatile int mNumDownloadsCompleted = 0;
        private Set<Long> downloadIds = Collections.synchronizedSet(new HashSet<Long>());
@@ -171,7 +108,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {

        /**
         * Gets the number of times the {@link #onReceive} callback has been called for the
         * {@link DownloadManager.ACTION_DOWNLOAD_COMPLETED} action, indicating the number of
         * {@link DownloadManager#ACTION_DOWNLOAD_COMPLETE} action, indicating the number of
         * downloads completed thus far.
         *
         * @return the number of downloads completed so far.
@@ -241,76 +178,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
    public void setUp() throws Exception {
        mContext = getInstrumentation().getContext();
        mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE);
        mServer = new MockWebServer();
        mReceiver = registerNewMultipleDownloadsReceiver();
        // Note: callers overriding this should call mServer.play() with the desired port #
    }

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

    }

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

    /**
     * Helper for enqueue'ing a response from the MockWebServer.
     *
     * @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)
     */
    private MockResponse doEnqueueResponse(int status) {
        MockResponse response = new MockResponse().setResponseCode(status);
        response.addHeader("Content-type", mFileType);
        mServer.enqueue(response);
        return response;
    }

    /**
     * Helper to generate a random blob of bytes using a given RNG.
     *
     * @param size The size of the data to generate
     * @param type The type of data to generate: currently, one of {@link DataType.TEXT} or
     *         {@link DataType.BINARY}.
     * @param rng (optional) The RNG to use; pass null to use
     * @return The random data that is generated.
     */
    private byte[] generateData(int size, DataType type, Random rng) {
        int min = Byte.MIN_VALUE;
        int max = Byte.MAX_VALUE;

        // Only use chars in the HTTP ASCII printable character range for Text
        if (type == DataType.TEXT) {
            min = 32;
            max = 126;
        }
        byte[] result = new byte[size];
        Log.i(LOG_TAG, "Generating data of size: " + size);

        if (rng == null) {
            rng = new LoggingRng();
        }

        for (int i = 0; i < size; ++i) {
            result[i] = (byte) (min + rng.nextInt(max - min + 1));
        }
        return result;
    }

    /**
@@ -323,76 +191,6 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
        assertEquals(pfd.getStatSize(), size);
    }

    /**
     * Helper to verify the contents of a downloaded file versus a byte[].
     *
     * @param actual The file of whose contents to verify
     * @param expected The data we expect to find in the aforementioned file
     * @throws IOException if there was a problem reading from the file
     */
    private void verifyFileContents(ParcelFileDescriptor actual, byte[] expected)
            throws IOException {
        AutoCloseInputStream input = new ParcelFileDescriptor.AutoCloseInputStream(actual);
        long fileSize = actual.getStatSize();

        assertTrue(fileSize <= Integer.MAX_VALUE);
        assertEquals(expected.length, fileSize);

        byte[] actualData = new byte[expected.length];
        assertEquals(input.read(actualData), fileSize);
        compareByteArrays(actualData, expected);
    }

    /**
     * Helper to compare 2 byte arrays.
     *
     * @param actual The array whose data we want to verify
     * @param expected The array of data we expect to see
     */
    private void compareByteArrays(byte[] actual, byte[] expected) {
        assertEquals(actual.length, expected.length);
        int length = actual.length;
        for (int i = 0; i < length; ++i) {
            // assert has a bit of overhead, so only do the assert when the values are not the same
            if (actual[i] != expected[i]) {
                fail("Byte arrays are not equal.");
            }
        }
    }

    /**
     * Gets the MIME content string for a given type
     *
     * @param type The MIME type to return
     * @return the String representation of that MIME content type
     */
    protected String getMimeMapping(DownloadFileType type) {
        switch (type) {
            case APK:
                return "application/vnd.android.package-archive";
            case GIF:
                return "image/gif";
            case ZIP:
                return "application/x-zip-compressed";
            case GARBAGE:
                return "zip\\pidy/doo/da";
            case UNRECOGNIZED:
                return "application/new.undefined.type.of.app";
        }
        return "text/plain";
    }

    /**
     * Gets the Uri that should be used to access the mock server
     *
     * @param filename The name of the file to try to retrieve from the mock server
     * @return the Uri to use for access the file on the mock server
     */
    private Uri getServerUri(String filename) throws Exception {
        URL url = mServer.getUrl("/" + filename);
        return Uri.parse(url.toString());
    }

    /**
     * Helper to create and register a new MultipleDownloadCompletedReciever
     *
@@ -737,39 +535,6 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase {
        }
    }

    /**
     * Helper to perform a standard enqueue of data to the mock server.
     * download is performed to the downloads cache dir (NOT systemcache dir)
     *
     * @param body The body to return in the response from the server
     */
    private long doStandardEnqueue(byte[] body) throws Exception {
        // Prepare the mock server with a standard response
        enqueueResponse(HTTP_OK, body);
        return doCommonStandardEnqueue();
    }

    /**
     * Helper to perform a standard enqueue of data to the mock server.
     *
     * @param body The body to return in the response from the server, contained in the file
     */
    private long doStandardEnqueue(File body) throws Exception {
        // Prepare the mock server with a standard response
        enqueueResponse(HTTP_OK, body);
        return doCommonStandardEnqueue();
    }

    /**
     * Helper to do the additional steps (setting title and Uri of default filename) when
     * doing a standard enqueue request to the server.
     */
    private long doCommonStandardEnqueue() throws Exception {
        Uri uri = getServerUri(DEFAULT_FILENAME);
        Request request = new Request(uri).setTitle(DEFAULT_FILENAME);
        return mDownloadManager.enqueue(request);
    }

    /**
     * Helper to verify an int value in a Cursor
     *
Loading