• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.squareup.okhttp;
2 
3 import com.squareup.okhttp.Call.AsyncCall;
4 import java.util.ArrayList;
5 import java.util.Arrays;
6 import java.util.Iterator;
7 import java.util.List;
8 import java.util.concurrent.AbstractExecutorService;
9 import java.util.concurrent.TimeUnit;
10 import org.junit.Before;
11 import org.junit.Test;
12 
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.fail;
15 
16 public final class DispatcherTest {
17   RecordingExecutor executor = new RecordingExecutor();
18   RecordingCallback callback = new RecordingCallback();
19   Dispatcher dispatcher = new Dispatcher(executor);
20   OkHttpClient client = new OkHttpClient().setDispatcher(dispatcher);
21 
setUp()22   @Before public void setUp() throws Exception {
23     dispatcher.setMaxRequests(20);
24     dispatcher.setMaxRequestsPerHost(10);
25   }
26 
maxRequestsZero()27   @Test public void maxRequestsZero() throws Exception {
28     try {
29       dispatcher.setMaxRequests(0);
30       fail();
31     } catch (IllegalArgumentException expected) {
32     }
33   }
34 
maxPerHostZero()35   @Test public void maxPerHostZero() throws Exception {
36     try {
37       dispatcher.setMaxRequestsPerHost(0);
38       fail();
39     } catch (IllegalArgumentException expected) {
40     }
41   }
42 
enqueuedJobsRunImmediately()43   @Test public void enqueuedJobsRunImmediately() throws Exception {
44     client.newCall(newRequest("http://a/1")).enqueue(callback);
45     executor.assertJobs("http://a/1");
46   }
47 
maxRequestsEnforced()48   @Test public void maxRequestsEnforced() throws Exception {
49     dispatcher.setMaxRequests(3);
50     client.newCall(newRequest("http://a/1")).enqueue(callback);
51     client.newCall(newRequest("http://a/2")).enqueue(callback);
52     client.newCall(newRequest("http://b/1")).enqueue(callback);
53     client.newCall(newRequest("http://b/2")).enqueue(callback);
54     executor.assertJobs("http://a/1", "http://a/2", "http://b/1");
55   }
56 
maxPerHostEnforced()57   @Test public void maxPerHostEnforced() throws Exception {
58     dispatcher.setMaxRequestsPerHost(2);
59     client.newCall(newRequest("http://a/1")).enqueue(callback);
60     client.newCall(newRequest("http://a/2")).enqueue(callback);
61     client.newCall(newRequest("http://a/3")).enqueue(callback);
62     executor.assertJobs("http://a/1", "http://a/2");
63   }
64 
increasingMaxRequestsPromotesJobsImmediately()65   @Test public void increasingMaxRequestsPromotesJobsImmediately() throws Exception {
66     dispatcher.setMaxRequests(2);
67     client.newCall(newRequest("http://a/1")).enqueue(callback);
68     client.newCall(newRequest("http://b/1")).enqueue(callback);
69     client.newCall(newRequest("http://c/1")).enqueue(callback);
70     client.newCall(newRequest("http://a/2")).enqueue(callback);
71     client.newCall(newRequest("http://b/2")).enqueue(callback);
72     dispatcher.setMaxRequests(4);
73     executor.assertJobs("http://a/1", "http://b/1", "http://c/1", "http://a/2");
74   }
75 
increasingMaxPerHostPromotesJobsImmediately()76   @Test public void increasingMaxPerHostPromotesJobsImmediately() throws Exception {
77     dispatcher.setMaxRequestsPerHost(2);
78     client.newCall(newRequest("http://a/1")).enqueue(callback);
79     client.newCall(newRequest("http://a/2")).enqueue(callback);
80     client.newCall(newRequest("http://a/3")).enqueue(callback);
81     client.newCall(newRequest("http://a/4")).enqueue(callback);
82     client.newCall(newRequest("http://a/5")).enqueue(callback);
83     dispatcher.setMaxRequestsPerHost(4);
84     executor.assertJobs("http://a/1", "http://a/2", "http://a/3", "http://a/4");
85   }
86 
oldJobFinishesNewJobCanRunDifferentHost()87   @Test public void oldJobFinishesNewJobCanRunDifferentHost() throws Exception {
88     dispatcher.setMaxRequests(1);
89     client.newCall(newRequest("http://a/1")).enqueue(callback);
90     client.newCall(newRequest("http://b/1")).enqueue(callback);
91     executor.finishJob("http://a/1");
92     executor.assertJobs("http://b/1");
93   }
94 
oldJobFinishesNewJobWithSameHostStarts()95   @Test public void oldJobFinishesNewJobWithSameHostStarts() throws Exception {
96     dispatcher.setMaxRequests(2);
97     dispatcher.setMaxRequestsPerHost(1);
98     client.newCall(newRequest("http://a/1")).enqueue(callback);
99     client.newCall(newRequest("http://b/1")).enqueue(callback);
100     client.newCall(newRequest("http://b/2")).enqueue(callback);
101     client.newCall(newRequest("http://a/2")).enqueue(callback);
102     executor.finishJob("http://a/1");
103     executor.assertJobs("http://b/1", "http://a/2");
104   }
105 
oldJobFinishesNewJobCantRunDueToHostLimit()106   @Test public void oldJobFinishesNewJobCantRunDueToHostLimit() throws Exception {
107     dispatcher.setMaxRequestsPerHost(1);
108     client.newCall(newRequest("http://a/1")).enqueue(callback);
109     client.newCall(newRequest("http://b/1")).enqueue(callback);
110     client.newCall(newRequest("http://a/2")).enqueue(callback);
111     executor.finishJob("http://b/1");
112     executor.assertJobs("http://a/1");
113   }
114 
cancelingRunningJobTakesNoEffectUntilJobFinishes()115   @Test public void cancelingRunningJobTakesNoEffectUntilJobFinishes() throws Exception {
116     dispatcher.setMaxRequests(1);
117     client.newCall(newRequest("http://a/1", "tag1")).enqueue(callback);
118     client.newCall(newRequest("http://a/2")).enqueue(callback);
119     dispatcher.cancel("tag1");
120     executor.assertJobs("http://a/1");
121     executor.finishJob("http://a/1");
122     executor.assertJobs("http://a/2");
123   }
124 
125   class RecordingExecutor extends AbstractExecutorService {
126     private List<AsyncCall> calls = new ArrayList<>();
127 
execute(Runnable command)128     @Override public void execute(Runnable command) {
129       calls.add((AsyncCall) command);
130     }
131 
assertJobs(String... expectedUrls)132     public void assertJobs(String... expectedUrls) {
133       List<String> actualUrls = new ArrayList<>();
134       for (AsyncCall call : calls) {
135         actualUrls.add(call.request().urlString());
136       }
137       assertEquals(Arrays.asList(expectedUrls), actualUrls);
138     }
139 
finishJob(String url)140     public void finishJob(String url) {
141       for (Iterator<AsyncCall> i = calls.iterator(); i.hasNext(); ) {
142         AsyncCall call = i.next();
143         if (call.request().urlString().equals(url)) {
144           i.remove();
145           dispatcher.finished(call);
146           return;
147         }
148       }
149       throw new AssertionError("No such job: " + url);
150     }
151 
shutdown()152     @Override public void shutdown() {
153       throw new UnsupportedOperationException();
154     }
155 
shutdownNow()156     @Override public List<Runnable> shutdownNow() {
157       throw new UnsupportedOperationException();
158     }
159 
isShutdown()160     @Override public boolean isShutdown() {
161       throw new UnsupportedOperationException();
162     }
163 
isTerminated()164     @Override public boolean isTerminated() {
165       throw new UnsupportedOperationException();
166     }
167 
awaitTermination(long timeout, TimeUnit unit)168     @Override public boolean awaitTermination(long timeout, TimeUnit unit)
169         throws InterruptedException {
170       throw new UnsupportedOperationException();
171     }
172   }
173 
newRequest(String url)174   private Request newRequest(String url) {
175     return new Request.Builder().url(url).build();
176   }
177 
newRequest(String url, String tag)178   private Request newRequest(String url, String tag) {
179     return new Request.Builder().url(url).tag(tag).build();
180   }
181 }
182