blob: a2bfbc6c8f98a0f6fd18622fd806e14e6a6a3235 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.volley;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import com.android.volley.Request.Priority;
import com.android.volley.RequestQueue.RequestFinishedListener;
import com.android.volley.mock.MockRequest;
import com.android.volley.mock.ShadowSystemClock;
import com.android.volley.toolbox.NoCache;
import com.android.volley.utils.ImmediateResponseDelivery;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
/**
* Integration tests for {@link RequestQueue} that verify its behavior in conjunction with real
* dispatcher, queues and Requests.
*
* <p>The Network is mocked out.
*/
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowSystemClock.class})
public class RequestQueueIntegrationTest {
private ResponseDelivery mDelivery;
@Mock private Network mMockNetwork;
@Mock private RequestFinishedListener<byte[]> mMockListener;
@Mock private RequestFinishedListener<byte[]> mMockListener2;
@Before
public void setUp() throws Exception {
mDelivery = new ImmediateResponseDelivery();
initMocks(this);
}
@Test
public void add_requestProcessedInCorrectOrder() throws Exception {
// Enqueue 2 requests with different cache keys, and different priorities. The second,
// higher priority request takes 20ms.
// Assert that the first request is only handled after the first one has been parsed and
// delivered.
MockRequest lowerPriorityReq = new MockRequest();
MockRequest higherPriorityReq = new MockRequest();
lowerPriorityReq.setCacheKey("1");
higherPriorityReq.setCacheKey("2");
lowerPriorityReq.setPriority(Priority.LOW);
higherPriorityReq.setPriority(Priority.HIGH);
Answer<NetworkResponse> delayAnswer =
new Answer<NetworkResponse>() {
@Override
public NetworkResponse answer(InvocationOnMock invocationOnMock)
throws Throwable {
Thread.sleep(20);
return mock(NetworkResponse.class);
}
};
// delay only for higher request
when(mMockNetwork.performRequest(higherPriorityReq)).thenAnswer(delayAnswer);
when(mMockNetwork.performRequest(lowerPriorityReq)).thenReturn(mock(NetworkResponse.class));
RequestQueue queue = new RequestQueue(new NoCache(), mMockNetwork, 1, mDelivery);
queue.addRequestFinishedListener(mMockListener);
queue.add(lowerPriorityReq);
queue.add(higherPriorityReq);
queue.start();
InOrder inOrder = inOrder(mMockListener);
// verify higherPriorityReq goes through first
inOrder.verify(mMockListener, timeout(10000)).onRequestFinished(higherPriorityReq);
// verify lowerPriorityReq goes last
inOrder.verify(mMockListener, timeout(10000)).onRequestFinished(lowerPriorityReq);
queue.stop();
}
/** Asserts that requests with same cache key are processed in order. */
@Test
public void add_dedupeByCacheKey() throws Exception {
// Enqueue 2 requests with the same cache key. The first request takes 20ms. Assert that the
// second request is only handled after the first one has been parsed and delivered.
MockRequest req1 = new MockRequest();
MockRequest req2 = new MockRequest();
Answer<NetworkResponse> delayAnswer =
new Answer<NetworkResponse>() {
@Override
public NetworkResponse answer(InvocationOnMock invocationOnMock)
throws Throwable {
Thread.sleep(20);
return mock(NetworkResponse.class);
}
};
// delay only for first
when(mMockNetwork.performRequest(req1)).thenAnswer(delayAnswer);
when(mMockNetwork.performRequest(req2)).thenReturn(mock(NetworkResponse.class));
RequestQueue queue = new RequestQueue(new NoCache(), mMockNetwork, 3, mDelivery);
queue.addRequestFinishedListener(mMockListener);
queue.add(req1);
queue.add(req2);
queue.start();
InOrder inOrder = inOrder(mMockListener);
// verify req1 goes through first
inOrder.verify(mMockListener, timeout(10000)).onRequestFinished(req1);
// verify req2 goes last
inOrder.verify(mMockListener, timeout(10000)).onRequestFinished(req2);
queue.stop();
}
/** Verify RequestFinishedListeners are informed when requests are canceled. */
@Test
public void add_requestFinishedListenerCanceled() throws Exception {
MockRequest request = new MockRequest();
Answer<NetworkResponse> delayAnswer =
new Answer<NetworkResponse>() {
@Override
public NetworkResponse answer(InvocationOnMock invocationOnMock)
throws Throwable {
Thread.sleep(200);
return mock(NetworkResponse.class);
}
};
RequestQueue queue = new RequestQueue(new NoCache(), mMockNetwork, 1, mDelivery);
when(mMockNetwork.performRequest(request)).thenAnswer(delayAnswer);
queue.addRequestFinishedListener(mMockListener);
queue.start();
queue.add(request);
request.cancel();
verify(mMockListener, timeout(10000)).onRequestFinished(request);
queue.stop();
}
/** Verify RequestFinishedListeners are informed when requests are successfully delivered. */
@Test
public void add_requestFinishedListenerSuccess() throws Exception {
MockRequest request = new MockRequest();
RequestQueue queue = new RequestQueue(new NoCache(), mMockNetwork, 1, mDelivery);
queue.addRequestFinishedListener(mMockListener);
queue.addRequestFinishedListener(mMockListener2);
queue.start();
queue.add(request);
verify(mMockListener, timeout(10000)).onRequestFinished(request);
verify(mMockListener2, timeout(10000)).onRequestFinished(request);
queue.stop();
}
/** Verify RequestFinishedListeners are informed when request errors. */
@Test
public void add_requestFinishedListenerError() throws Exception {
MockRequest request = new MockRequest();
RequestQueue queue = new RequestQueue(new NoCache(), mMockNetwork, 1, mDelivery);
when(mMockNetwork.performRequest(request)).thenThrow(new VolleyError());
queue.addRequestFinishedListener(mMockListener);
queue.start();
queue.add(request);
verify(mMockListener, timeout(10000)).onRequestFinished(request);
queue.stop();
}
}