RequestQueueTest.java revision d56b88ae161057e848e7410d1b9ce5b0b8c427fc
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 @UiThreadTest 176d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru @SuppressWarnings("deprecation") 177d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public void testDrain_suppressesEarlierResponses() { 178d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru MockNetwork network = new MockNetwork(); 179d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru network.setDataToReturn(new byte[128]); 180d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru RequestQueue queue = new RequestQueue(new NoCache(), network, 4, mDelivery); 181d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 182d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru int requestsBefore = 40; 183d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru AtomicInteger parsedBefore = new AtomicInteger(); 184d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru AtomicInteger deliveredBefore = new AtomicInteger(); 185d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 186d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Start the queue and add a bunch of requests to it. 187d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru queue.start(); 188d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru for (int i = 0; i < requestsBefore; i++) { 189d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Make each request take 50 ms. 190d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru DelayedRequest request = new DelayedRequest(50, parsedBefore, deliveredBefore); 191d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru queue.add(request); 192d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 193d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Sleep for a jiffy to let some of the slow requests be scheduled. 194d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru SystemClock.sleep(5); 195d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 196d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Drain the queue. None of the original requests should be delivered 197d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // because they are still waiting to parse. 198d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru queue.drain(); 199d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 200d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Add some requests afterward to make sure not only that the ones before 201d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // the drain were not delivered, but that ones afterward are. 202d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru int requestsAfter = 10; 203d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru AtomicInteger parsedAfter = new AtomicInteger(); 204d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru AtomicInteger deliveredAfter = new AtomicInteger(); 205d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru for (int i = 0; i < requestsAfter; i++) { 206d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // These ones are much faster... 207d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru DelayedRequest request = new DelayedRequest(1, parsedAfter, deliveredAfter); 208d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru queue.add(request); 209d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 210d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 211d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Wait up to 1 second to finish 212d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru for (int i = 0; i < 10; i++) { 213d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (deliveredAfter.get() != requestsAfter) { 214d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru SystemClock.sleep(100); 215d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru continue; 216d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 217d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 218d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru assertEquals(deliveredAfter.get(), requestsAfter); 219d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Make sure that all "after" requests were parsed 220d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru assertEquals(parsedAfter.get(), requestsAfter); 221d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 222d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Make sure that at least one of the "before" requests was parsed 223d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru assertTrue(parsedBefore.get() > 0); 224d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // And that none of them are delivered 225d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru assertEquals(0, deliveredBefore.get()); 226d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru queue.stop(); 227d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return; 228d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 229d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 230d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru fail("Timed out waiting for requests to complete"); 231d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 232d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 233d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru @UiThreadTest 234d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru @SuppressWarnings("deprecation") 235d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public void testDrain_preservesUndrainable() { 236d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru MockNetwork network = new MockNetwork(); 237d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru network.setDataToReturn(new byte[128]); 238d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru RequestQueue queue = new RequestQueue(new NoCache(), network, 4, mDelivery); 239d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 240d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Make a bunch of requests 241d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru List<MockRequest> requests = makeRequests(50); 242d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 243d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Pick one to be invincible. 244d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru MockRequest invincible = requests.get(new Random().nextInt(requests.size())); 245d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru invincible.setDrainable(false); 246d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 247d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Add them all to the queue. 248d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru for (MockRequest request : requests) { 249d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru queue.add(request); 250d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 251d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 252d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Drain the queue. 253d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru queue.drain(); 254d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 255d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Start the queue. 256d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru queue.start(); 257d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 258d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // Wait up to 1 second to finish 259d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru for (int i = 0; i < 10; i++) { 260d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru if (!invincible.parseResponse_called) { 261d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru SystemClock.sleep(100); 262d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru continue; 263d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 264d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru // If parseResponse got called, that's good enough 265d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru queue.stop(); 266d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return; 267d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 268d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 269d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru fail("Undrainable request should have been parsed"); 270d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 271d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 272d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private class DelayedRequest extends Request<Object> { 273d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private final long mDelayMillis; 274d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private final AtomicInteger mParsedCount; 275d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru private final AtomicInteger mDeliveredCount; 276d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 277d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru public DelayedRequest(long delayMillis, AtomicInteger parsed, AtomicInteger delivered) { 278d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru super("http://buganizer/", null); 279d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mDelayMillis = delayMillis; 280d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mParsedCount = parsed; 281d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mDeliveredCount = delivered; 282d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 283d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 284d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru @Override 285d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru protected Response<Object> parseNetworkResponse(NetworkResponse response) { 286d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mParsedCount.incrementAndGet(); 287d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru SystemClock.sleep(mDelayMillis); 288d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru return Response.success(new Object(), CacheTestUtils.makeRandomCacheEntry(null)); 289d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 290d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 291d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru @Override 292d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru protected void deliverResponse(Object response) { 293d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru mDeliveredCount.incrementAndGet(); 294d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 295d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru } 296d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru 297d56b88ae161057e848e7410d1b9ce5b0b8c427fcJean-Baptiste Queru} 298