1d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru/*
2d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Copyright (C) 2011 The Android Open Source Project
3d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru *
4d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Licensed under the Apache License, Version 2.0 (the "License");
5d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * you may not use this file except in compliance with the License.
6d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * You may obtain a copy of the License at
7d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru *
8d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru *      http://www.apache.org/licenses/LICENSE-2.0
9d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru *
10d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * Unless required by applicable law or agreed to in writing, software
11d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * distributed under the License is distributed on an "AS IS" BASIS,
12d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * See the License for the specific language governing permissions and
14d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru * limitations under the License.
15d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru */
16d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
17d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Querupackage com.android.volley;
18d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
19d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport com.android.volley.Request.Priority;
20d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport com.android.volley.mock.MockNetwork;
21d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport com.android.volley.mock.MockRequest;
22d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport com.android.volley.toolbox.NoCache;
23d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport com.android.volley.utils.CacheTestUtils;
24d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport com.android.volley.utils.ImmediateResponseDelivery;
25d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
26d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport android.os.SystemClock;
27d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport android.test.InstrumentationTestCase;
28d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport android.test.UiThreadTest;
29d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport android.test.suitebuilder.annotation.LargeTest;
30d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
31d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.ArrayList;
32d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.List;
33d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.Random;
34d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.concurrent.Semaphore;
35d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.concurrent.TimeUnit;
36d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queruimport java.util.concurrent.atomic.AtomicInteger;
37d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
38d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru@LargeTest
39d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Querupublic class RequestQueueTest extends InstrumentationTestCase {
40d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    private ResponseDelivery mDelivery;
41d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
42d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    @Override
43d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    protected void setUp() throws Exception {
44d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        super.setUp();
45d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
46d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        mDelivery = new ImmediateResponseDelivery();
47d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
48d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
49d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    /**
50d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru     * Make a list of requests with random priorities.
51d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru     * @param count Number of requests to make
52d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru     */
53d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    private List<MockRequest> makeRequests(int count) {
54d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        Request.Priority[] allPriorities = Request.Priority.values();
55d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        Random random = new Random();
56d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
57d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        List<MockRequest> requests = new ArrayList<MockRequest>();
58d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        for (int i = 0; i < count; i++) {
59d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            MockRequest request = new MockRequest();
60d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            Request.Priority priority = allPriorities[random.nextInt(allPriorities.length)];
61d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            request.setCacheKey(String.valueOf(i));
62d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            request.setPriority(priority);
63d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            requests.add(request);
64d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        }
65d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        return requests;
66d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
67d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
68d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    @UiThreadTest
69d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    public void testAdd_requestProcessedInCorrectOrder() throws Exception {
70d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        int requestsToMake = 100;
71d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
72d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        OrderCheckingNetwork network = new OrderCheckingNetwork();
73d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        RequestQueue queue = new RequestQueue(new NoCache(), network, 1, mDelivery);
74d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
75d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        for (Request<?> request : makeRequests(requestsToMake)) {
76d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            queue.add(request);
77d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        }
78d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
79d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        network.setExpectedRequests(requestsToMake);
80d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        queue.start();
81d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        network.waitUntilExpectedDone(2000); // 2 seconds
82d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        queue.stop();
83d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
84d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
85d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    public void testAdd_dedupeByCacheKey() throws Exception {
86d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        OrderCheckingNetwork network = new OrderCheckingNetwork();
87d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        final AtomicInteger parsed = new AtomicInteger();
88d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        final AtomicInteger delivered = new AtomicInteger();
89d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        // Enqueue 2 requests with the same cache key. The first request takes 1.5s. Assert that the
90d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        // second request is only handled after the first one has been parsed and delivered.
91d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        DelayedRequest req1 = new DelayedRequest(1500, parsed, delivered);
92d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        DelayedRequest req2 = new DelayedRequest(0, parsed, delivered) {
93d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            @Override
94d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            protected Response<Object> parseNetworkResponse(NetworkResponse response) {
95d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru                assertEquals(1, parsed.get());  // req1 must have been parsed.
96d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru                assertEquals(1, delivered.get());  // req1 must have been parsed.
97d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru                return super.parseNetworkResponse(response);
98d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            }
99d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        };
100d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        network.setExpectedRequests(2);
101d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        RequestQueue queue = new RequestQueue(new NoCache(), network, 3, mDelivery);
102d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        queue.add(req1);
103d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        queue.add(req2);
104d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        queue.start();
105d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        network.waitUntilExpectedDone(2000);
106d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        queue.stop();
107d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
108d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
109d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    public void testCancelAll_onlyCorrectTag() throws Exception {
110d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        MockNetwork network = new MockNetwork();
111d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        RequestQueue queue = new RequestQueue(new NoCache(), network, 3, mDelivery);
112d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        Object tagA = new Object();
113d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        Object tagB = new Object();
114d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        MockRequest req1 = new MockRequest();
115d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        req1.setTag(tagA);
116d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        MockRequest req2 = new MockRequest();
117d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        req2.setTag(tagB);
118d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        MockRequest req3 = new MockRequest();
119d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        req3.setTag(tagA);
120d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        MockRequest req4 = new MockRequest();
121d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        req4.setTag(tagA);
122d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
123d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        queue.add(req1); // A
124d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        queue.add(req2); // B
125d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        queue.add(req3); // A
126d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        queue.cancelAll(tagA);
127d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        queue.add(req4); // A
128d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
129d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertTrue(req1.cancel_called); // A cancelled
130d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertFalse(req2.cancel_called); // B not cancelled
131d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertTrue(req3.cancel_called); // A cancelled
132d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        assertFalse(req4.cancel_called); // A added after cancel not cancelled
133d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
134d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
135d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    private class OrderCheckingNetwork implements Network {
136d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        private Priority mLastPriority = Priority.IMMEDIATE;
137d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        private int mLastSequence = -1;
138d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        private Semaphore mSemaphore;
139d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
140d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        public void setExpectedRequests(int expectedRequests) {
141d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            // Leave one permit available so the waiter can find it.
142d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            expectedRequests--;
143d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            mSemaphore = new Semaphore(-expectedRequests);
144d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        }
145d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
146d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        public void waitUntilExpectedDone(long timeout)
147d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru                throws InterruptedException, TimeoutError {
148d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            if (mSemaphore.tryAcquire(timeout, TimeUnit.MILLISECONDS) == false) {
149d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru                throw new TimeoutError();
150d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            }
151d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        }
152d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
153d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        @Override
154d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        public NetworkResponse performRequest(Request<?> request) {
155d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            Priority thisPriority = request.getPriority();
156d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            int thisSequence = request.getSequence();
157d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
158d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            int priorityDiff = thisPriority.compareTo(mLastPriority);
159d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
160d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            // Should never experience a higher priority after a lower priority
161d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            assertFalse(priorityDiff > 0);
162d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
163d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            // If we're not transitioning to a new priority block, check sequence numbers
164d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            if (priorityDiff == 0) {
165d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru                assertTrue(thisSequence > mLastSequence);
166d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            }
167d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            mLastSequence = thisSequence;
168d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            mLastPriority = thisPriority;
169d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
170d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            mSemaphore.release();
171d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            return new NetworkResponse(new byte[16]);
172d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        }
173d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
174d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
175d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    private class DelayedRequest extends Request<Object> {
176d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        private final long mDelayMillis;
177d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        private final AtomicInteger mParsedCount;
178d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        private final AtomicInteger mDeliveredCount;
179d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
180d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        public DelayedRequest(long delayMillis, AtomicInteger parsed, AtomicInteger delivered) {
18135d5cc345a7bc5c7391aeda3d3fce711c6376c7bFicus Kirkpatrick            super(Request.Method.GET, "http://buganizer/", null);
182d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            mDelayMillis = delayMillis;
183d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            mParsedCount = parsed;
184d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            mDeliveredCount = delivered;
185d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        }
186d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
187d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        @Override
188d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        protected Response<Object> parseNetworkResponse(NetworkResponse response) {
189d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            mParsedCount.incrementAndGet();
190d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            SystemClock.sleep(mDelayMillis);
191d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            return Response.success(new Object(), CacheTestUtils.makeRandomCacheEntry(null));
192d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        }
193d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
194d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        @Override
195d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        protected void deliverResponse(Object response) {
196d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru            mDeliveredCount.incrementAndGet();
197d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru        }
198d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru    }
199d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru
200d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru}
201