OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/proxy/multi_threaded_proxy_resolver.h" | 5 #include "net/proxy/multi_threaded_proxy_resolver.h" |
6 | 6 |
7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 // - returns a single-item proxy list with the query's host. | 28 // - returns a single-item proxy list with the query's host. |
29 class MockProxyResolver : public ProxyResolver { | 29 class MockProxyResolver : public ProxyResolver { |
30 public: | 30 public: |
31 MockProxyResolver() | 31 MockProxyResolver() |
32 : ProxyResolver(true /*expects_pac_bytes*/), | 32 : ProxyResolver(true /*expects_pac_bytes*/), |
33 wrong_loop_(MessageLoop::current()), | 33 wrong_loop_(MessageLoop::current()), |
34 request_count_(0), | 34 request_count_(0), |
35 purge_count_(0), | 35 purge_count_(0), |
36 resolve_latency_ms_(0) {} | 36 resolve_latency_ms_(0) {} |
37 | 37 |
38 // ProxyResolver implementation: | 38 // ProxyResolver implementation. |
39 virtual int GetProxyForURL(const GURL& query_url, | 39 virtual int GetProxyForURL(const GURL& query_url, |
40 ProxyInfo* results, | 40 ProxyInfo* results, |
41 OldCompletionCallback* callback, | 41 const CompletionCallback& callback, |
42 RequestHandle* request, | 42 RequestHandle* request, |
43 const BoundNetLog& net_log) OVERRIDE { | 43 const BoundNetLog& net_log) OVERRIDE { |
44 if (resolve_latency_ms_) | 44 if (resolve_latency_ms_) |
45 base::PlatformThread::Sleep(resolve_latency_ms_); | 45 base::PlatformThread::Sleep(resolve_latency_ms_); |
46 | 46 |
47 CheckIsOnWorkerThread(); | 47 CheckIsOnWorkerThread(); |
48 | 48 |
49 EXPECT_TRUE(callback == NULL); | 49 EXPECT_TRUE(callback.is_null()); |
50 EXPECT_TRUE(request == NULL); | 50 EXPECT_TRUE(request == NULL); |
51 | 51 |
52 // Write something into |net_log| (doesn't really have any meaning.) | 52 // Write something into |net_log| (doesn't really have any meaning.) |
53 net_log.BeginEvent(NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE, NULL); | 53 net_log.BeginEvent(NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE, NULL); |
54 | 54 |
55 results->UseNamedProxy(query_url.host()); | 55 results->UseNamedProxy(query_url.host()); |
56 | 56 |
57 // Return a success code which represents the request's order. | 57 // Return a success code which represents the request's order. |
58 return request_count_++; | 58 return request_count_++; |
59 } | 59 } |
(...skipping 12 matching lines...) Expand all Loading... |
72 NOTREACHED(); | 72 NOTREACHED(); |
73 return LOAD_STATE_IDLE; | 73 return LOAD_STATE_IDLE; |
74 } | 74 } |
75 | 75 |
76 virtual void CancelSetPacScript() OVERRIDE { | 76 virtual void CancelSetPacScript() OVERRIDE { |
77 NOTREACHED(); | 77 NOTREACHED(); |
78 } | 78 } |
79 | 79 |
80 virtual int SetPacScript( | 80 virtual int SetPacScript( |
81 const scoped_refptr<ProxyResolverScriptData>& script_data, | 81 const scoped_refptr<ProxyResolverScriptData>& script_data, |
82 OldCompletionCallback* callback) OVERRIDE { | 82 const CompletionCallback& callback) OVERRIDE { |
83 CheckIsOnWorkerThread(); | 83 CheckIsOnWorkerThread(); |
84 last_script_data_ = script_data; | 84 last_script_data_ = script_data; |
85 return OK; | 85 return OK; |
86 } | 86 } |
87 | 87 |
88 virtual void PurgeMemory() OVERRIDE { | 88 virtual void PurgeMemory() OVERRIDE { |
89 CheckIsOnWorkerThread(); | 89 CheckIsOnWorkerThread(); |
90 ++purge_count_; | 90 ++purge_count_; |
91 } | 91 } |
92 | 92 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 blocked_.Reset(); | 141 blocked_.Reset(); |
142 unblocked_.Signal(); | 142 unblocked_.Signal(); |
143 } | 143 } |
144 | 144 |
145 void WaitUntilBlocked() { | 145 void WaitUntilBlocked() { |
146 blocked_.Wait(); | 146 blocked_.Wait(); |
147 } | 147 } |
148 | 148 |
149 virtual int GetProxyForURL(const GURL& query_url, | 149 virtual int GetProxyForURL(const GURL& query_url, |
150 ProxyInfo* results, | 150 ProxyInfo* results, |
151 OldCompletionCallback* callback, | 151 const CompletionCallback& callback, |
152 RequestHandle* request, | 152 RequestHandle* request, |
153 const BoundNetLog& net_log) OVERRIDE { | 153 const BoundNetLog& net_log) OVERRIDE { |
154 if (should_block_) { | 154 if (should_block_) { |
155 blocked_.Signal(); | 155 blocked_.Signal(); |
156 unblocked_.Wait(); | 156 unblocked_.Wait(); |
157 } | 157 } |
158 | 158 |
159 return MockProxyResolver::GetProxyForURL( | 159 return MockProxyResolver::GetProxyForURL( |
160 query_url, results, callback, request, net_log); | 160 query_url, results, callback, request, net_log); |
161 } | 161 } |
162 | 162 |
163 private: | 163 private: |
164 bool should_block_; | 164 bool should_block_; |
165 base::WaitableEvent unblocked_; | 165 base::WaitableEvent unblocked_; |
166 base::WaitableEvent blocked_; | 166 base::WaitableEvent blocked_; |
167 }; | 167 }; |
168 | 168 |
169 // ForwardingProxyResolver forwards all requests to |impl|. | 169 // ForwardingProxyResolver forwards all requests to |impl|. |
170 class ForwardingProxyResolver : public ProxyResolver { | 170 class ForwardingProxyResolver : public ProxyResolver { |
171 public: | 171 public: |
172 explicit ForwardingProxyResolver(ProxyResolver* impl) | 172 explicit ForwardingProxyResolver(ProxyResolver* impl) |
173 : ProxyResolver(impl->expects_pac_bytes()), | 173 : ProxyResolver(impl->expects_pac_bytes()), |
174 impl_(impl) {} | 174 impl_(impl) {} |
175 | 175 |
176 virtual int GetProxyForURL(const GURL& query_url, | 176 virtual int GetProxyForURL(const GURL& query_url, |
177 ProxyInfo* results, | 177 ProxyInfo* results, |
178 OldCompletionCallback* callback, | 178 const CompletionCallback& callback, |
179 RequestHandle* request, | 179 RequestHandle* request, |
180 const BoundNetLog& net_log) OVERRIDE { | 180 const BoundNetLog& net_log) OVERRIDE { |
181 return impl_->GetProxyForURL( | 181 return impl_->GetProxyForURL( |
182 query_url, results, callback, request, net_log); | 182 query_url, results, callback, request, net_log); |
183 } | 183 } |
184 | 184 |
185 virtual void CancelRequest(RequestHandle request) OVERRIDE { | 185 virtual void CancelRequest(RequestHandle request) OVERRIDE { |
186 impl_->CancelRequest(request); | 186 impl_->CancelRequest(request); |
187 } | 187 } |
188 | 188 |
189 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE { | 189 virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE { |
190 NOTREACHED(); | 190 NOTREACHED(); |
191 return LOAD_STATE_IDLE; | 191 return LOAD_STATE_IDLE; |
192 } | 192 } |
193 | 193 |
194 virtual LoadState GetLoadStateThreadSafe( | 194 virtual LoadState GetLoadStateThreadSafe( |
195 RequestHandle request) const OVERRIDE { | 195 RequestHandle request) const OVERRIDE { |
196 NOTREACHED(); | 196 NOTREACHED(); |
197 return LOAD_STATE_IDLE; | 197 return LOAD_STATE_IDLE; |
198 } | 198 } |
199 | 199 |
200 virtual void CancelSetPacScript() OVERRIDE { | 200 virtual void CancelSetPacScript() OVERRIDE { |
201 impl_->CancelSetPacScript(); | 201 impl_->CancelSetPacScript(); |
202 } | 202 } |
203 | 203 |
204 virtual int SetPacScript( | 204 virtual int SetPacScript( |
205 const scoped_refptr<ProxyResolverScriptData>& script_data, | 205 const scoped_refptr<ProxyResolverScriptData>& script_data, |
206 OldCompletionCallback* callback) OVERRIDE { | 206 const CompletionCallback& callback) OVERRIDE { |
207 return impl_->SetPacScript(script_data, callback); | 207 return impl_->SetPacScript(script_data, callback); |
208 } | 208 } |
209 | 209 |
210 virtual void PurgeMemory() OVERRIDE { | 210 virtual void PurgeMemory() OVERRIDE { |
211 impl_->PurgeMemory(); | 211 impl_->PurgeMemory(); |
212 } | 212 } |
213 | 213 |
214 private: | 214 private: |
215 ProxyResolver* impl_; | 215 ProxyResolver* impl_; |
216 }; | 216 }; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 scoped_ptr<MockProxyResolver> mock(new MockProxyResolver); | 259 scoped_ptr<MockProxyResolver> mock(new MockProxyResolver); |
260 MultiThreadedProxyResolver resolver( | 260 MultiThreadedProxyResolver resolver( |
261 new ForwardingProxyResolverFactory(mock.get()), kNumThreads); | 261 new ForwardingProxyResolverFactory(mock.get()), kNumThreads); |
262 | 262 |
263 int rv; | 263 int rv; |
264 | 264 |
265 EXPECT_TRUE(resolver.expects_pac_bytes()); | 265 EXPECT_TRUE(resolver.expects_pac_bytes()); |
266 | 266 |
267 // Call SetPacScriptByData() -- verify that it reaches the synchronous | 267 // Call SetPacScriptByData() -- verify that it reaches the synchronous |
268 // resolver. | 268 // resolver. |
269 TestOldCompletionCallback set_script_callback; | 269 TestCompletionCallback set_script_callback; |
270 rv = resolver.SetPacScript( | 270 rv = resolver.SetPacScript( |
271 ProxyResolverScriptData::FromUTF8("pac script bytes"), | 271 ProxyResolverScriptData::FromUTF8("pac script bytes"), |
272 &set_script_callback); | 272 set_script_callback.callback()); |
273 EXPECT_EQ(ERR_IO_PENDING, rv); | 273 EXPECT_EQ(ERR_IO_PENDING, rv); |
274 EXPECT_EQ(OK, set_script_callback.WaitForResult()); | 274 EXPECT_EQ(OK, set_script_callback.WaitForResult()); |
275 EXPECT_EQ(ASCIIToUTF16("pac script bytes"), | 275 EXPECT_EQ(ASCIIToUTF16("pac script bytes"), |
276 mock->last_script_data()->utf16()); | 276 mock->last_script_data()->utf16()); |
277 | 277 |
278 // Start request 0. | 278 // Start request 0. |
279 TestOldCompletionCallback callback0; | 279 TestCompletionCallback callback0; |
280 CapturingBoundNetLog log0(CapturingNetLog::kUnbounded); | 280 CapturingBoundNetLog log0(CapturingNetLog::kUnbounded); |
281 ProxyInfo results0; | 281 ProxyInfo results0; |
282 rv = resolver.GetProxyForURL( | 282 rv = resolver.GetProxyForURL(GURL("http://request0"), &results0, |
283 GURL("http://request0"), &results0, &callback0, NULL, log0.bound()); | 283 callback0.callback(), NULL, log0.bound()); |
284 EXPECT_EQ(ERR_IO_PENDING, rv); | 284 EXPECT_EQ(ERR_IO_PENDING, rv); |
285 | 285 |
286 // Wait for request 0 to finish. | 286 // Wait for request 0 to finish. |
287 rv = callback0.WaitForResult(); | 287 rv = callback0.WaitForResult(); |
288 EXPECT_EQ(0, rv); | 288 EXPECT_EQ(0, rv); |
289 EXPECT_EQ("PROXY request0:80", results0.ToPacString()); | 289 EXPECT_EQ("PROXY request0:80", results0.ToPacString()); |
290 | 290 |
291 // The mock proxy resolver should have written 1 log entry. And | 291 // The mock proxy resolver should have written 1 log entry. And |
292 // on completion, this should have been copied into |log0|. | 292 // on completion, this should have been copied into |log0|. |
293 // We also have 1 log entry that was emitted by the | 293 // We also have 1 log entry that was emitted by the |
294 // MultiThreadedProxyResolver. | 294 // MultiThreadedProxyResolver. |
295 net::CapturingNetLog::EntryList entries0; | 295 net::CapturingNetLog::EntryList entries0; |
296 log0.GetEntries(&entries0); | 296 log0.GetEntries(&entries0); |
297 | 297 |
298 ASSERT_EQ(2u, entries0.size()); | 298 ASSERT_EQ(2u, entries0.size()); |
299 EXPECT_EQ(NetLog::TYPE_SUBMITTED_TO_RESOLVER_THREAD, entries0[0].type); | 299 EXPECT_EQ(NetLog::TYPE_SUBMITTED_TO_RESOLVER_THREAD, entries0[0].type); |
300 | 300 |
301 // Start 3 more requests (request1 to request3). | 301 // Start 3 more requests (request1 to request3). |
302 | 302 |
303 TestOldCompletionCallback callback1; | 303 TestCompletionCallback callback1; |
304 ProxyInfo results1; | 304 ProxyInfo results1; |
305 rv = resolver.GetProxyForURL( | 305 rv = resolver.GetProxyForURL(GURL("http://request1"), &results1, |
306 GURL("http://request1"), &results1, &callback1, NULL, BoundNetLog()); | 306 callback1.callback(), NULL, BoundNetLog()); |
307 EXPECT_EQ(ERR_IO_PENDING, rv); | 307 EXPECT_EQ(ERR_IO_PENDING, rv); |
308 | 308 |
309 TestOldCompletionCallback callback2; | 309 TestCompletionCallback callback2; |
310 ProxyInfo results2; | 310 ProxyInfo results2; |
311 rv = resolver.GetProxyForURL( | 311 rv = resolver.GetProxyForURL(GURL("http://request2"), &results2, |
312 GURL("http://request2"), &results2, &callback2, NULL, BoundNetLog()); | 312 callback2.callback(), NULL, BoundNetLog()); |
313 EXPECT_EQ(ERR_IO_PENDING, rv); | 313 EXPECT_EQ(ERR_IO_PENDING, rv); |
314 | 314 |
315 TestOldCompletionCallback callback3; | 315 TestCompletionCallback callback3; |
316 ProxyInfo results3; | 316 ProxyInfo results3; |
317 rv = resolver.GetProxyForURL( | 317 rv = resolver.GetProxyForURL(GURL("http://request3"), &results3, |
318 GURL("http://request3"), &results3, &callback3, NULL, BoundNetLog()); | 318 callback3.callback(), NULL, BoundNetLog()); |
319 EXPECT_EQ(ERR_IO_PENDING, rv); | 319 EXPECT_EQ(ERR_IO_PENDING, rv); |
320 | 320 |
321 // Wait for the requests to finish (they must finish in the order they were | 321 // Wait for the requests to finish (they must finish in the order they were |
322 // started, which is what we check for from their magic return value) | 322 // started, which is what we check for from their magic return value) |
323 | 323 |
324 rv = callback1.WaitForResult(); | 324 rv = callback1.WaitForResult(); |
325 EXPECT_EQ(1, rv); | 325 EXPECT_EQ(1, rv); |
326 EXPECT_EQ("PROXY request1:80", results1.ToPacString()); | 326 EXPECT_EQ("PROXY request1:80", results1.ToPacString()); |
327 | 327 |
328 rv = callback2.WaitForResult(); | 328 rv = callback2.WaitForResult(); |
329 EXPECT_EQ(2, rv); | 329 EXPECT_EQ(2, rv); |
330 EXPECT_EQ("PROXY request2:80", results2.ToPacString()); | 330 EXPECT_EQ("PROXY request2:80", results2.ToPacString()); |
331 | 331 |
332 rv = callback3.WaitForResult(); | 332 rv = callback3.WaitForResult(); |
333 EXPECT_EQ(3, rv); | 333 EXPECT_EQ(3, rv); |
334 EXPECT_EQ("PROXY request3:80", results3.ToPacString()); | 334 EXPECT_EQ("PROXY request3:80", results3.ToPacString()); |
335 | 335 |
336 // Ensure that PurgeMemory() reaches the wrapped resolver and happens on the | 336 // Ensure that PurgeMemory() reaches the wrapped resolver and happens on the |
337 // right thread. | 337 // right thread. |
338 EXPECT_EQ(0, mock->purge_count()); | 338 EXPECT_EQ(0, mock->purge_count()); |
339 resolver.PurgeMemory(); | 339 resolver.PurgeMemory(); |
340 // There is no way to get a callback directly when PurgeMemory() completes, so | 340 // There is no way to get a callback directly when PurgeMemory() completes, so |
341 // we queue up a dummy request after the PurgeMemory() call and wait until it | 341 // we queue up a dummy request after the PurgeMemory() call and wait until it |
342 // finishes to ensure PurgeMemory() has had a chance to run. | 342 // finishes to ensure PurgeMemory() has had a chance to run. |
343 TestOldCompletionCallback dummy_callback; | 343 TestCompletionCallback dummy_callback; |
344 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("dummy"), | 344 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("dummy"), |
345 &dummy_callback); | 345 dummy_callback.callback()); |
346 EXPECT_EQ(OK, dummy_callback.WaitForResult()); | 346 EXPECT_EQ(OK, dummy_callback.WaitForResult()); |
347 EXPECT_EQ(1, mock->purge_count()); | 347 EXPECT_EQ(1, mock->purge_count()); |
348 } | 348 } |
349 | 349 |
350 // Tests that the NetLog is updated to include the time the request was waiting | 350 // Tests that the NetLog is updated to include the time the request was waiting |
351 // to be scheduled to a thread. | 351 // to be scheduled to a thread. |
352 TEST(MultiThreadedProxyResolverTest, | 352 TEST(MultiThreadedProxyResolverTest, |
353 SingleThread_UpdatesNetLogWithThreadWait) { | 353 SingleThread_UpdatesNetLogWithThreadWait) { |
354 const size_t kNumThreads = 1u; | 354 const size_t kNumThreads = 1u; |
355 scoped_ptr<BlockableProxyResolver> mock(new BlockableProxyResolver); | 355 scoped_ptr<BlockableProxyResolver> mock(new BlockableProxyResolver); |
356 MultiThreadedProxyResolver resolver( | 356 MultiThreadedProxyResolver resolver( |
357 new ForwardingProxyResolverFactory(mock.get()), kNumThreads); | 357 new ForwardingProxyResolverFactory(mock.get()), kNumThreads); |
358 | 358 |
359 int rv; | 359 int rv; |
360 | 360 |
361 // Initialize the resolver. | 361 // Initialize the resolver. |
362 TestOldCompletionCallback init_callback; | 362 TestCompletionCallback init_callback; |
363 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("foo"), | 363 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("foo"), |
364 &init_callback); | 364 init_callback.callback()); |
365 EXPECT_EQ(OK, init_callback.WaitForResult()); | 365 EXPECT_EQ(OK, init_callback.WaitForResult()); |
366 | 366 |
367 // Block the proxy resolver, so no request can complete. | 367 // Block the proxy resolver, so no request can complete. |
368 mock->Block(); | 368 mock->Block(); |
369 | 369 |
370 // Start request 0. | 370 // Start request 0. |
371 ProxyResolver::RequestHandle request0; | 371 ProxyResolver::RequestHandle request0; |
372 TestOldCompletionCallback callback0; | 372 TestCompletionCallback callback0; |
373 ProxyInfo results0; | 373 ProxyInfo results0; |
374 CapturingBoundNetLog log0(CapturingNetLog::kUnbounded); | 374 CapturingBoundNetLog log0(CapturingNetLog::kUnbounded); |
375 rv = resolver.GetProxyForURL( | 375 rv = resolver.GetProxyForURL(GURL("http://request0"), &results0, |
376 GURL("http://request0"), &results0, &callback0, &request0, log0.bound()); | 376 callback0.callback(), &request0, log0.bound()); |
377 EXPECT_EQ(ERR_IO_PENDING, rv); | 377 EXPECT_EQ(ERR_IO_PENDING, rv); |
378 | 378 |
379 // Start 2 more requests (request1 and request2). | 379 // Start 2 more requests (request1 and request2). |
380 | 380 |
381 TestOldCompletionCallback callback1; | 381 TestCompletionCallback callback1; |
382 ProxyInfo results1; | 382 ProxyInfo results1; |
383 CapturingBoundNetLog log1(CapturingNetLog::kUnbounded); | 383 CapturingBoundNetLog log1(CapturingNetLog::kUnbounded); |
384 rv = resolver.GetProxyForURL( | 384 rv = resolver.GetProxyForURL(GURL("http://request1"), &results1, |
385 GURL("http://request1"), &results1, &callback1, NULL, log1.bound()); | 385 callback1.callback(), NULL, log1.bound()); |
386 EXPECT_EQ(ERR_IO_PENDING, rv); | 386 EXPECT_EQ(ERR_IO_PENDING, rv); |
387 | 387 |
388 ProxyResolver::RequestHandle request2; | 388 ProxyResolver::RequestHandle request2; |
389 TestOldCompletionCallback callback2; | 389 TestCompletionCallback callback2; |
390 ProxyInfo results2; | 390 ProxyInfo results2; |
391 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded); | 391 CapturingBoundNetLog log2(CapturingNetLog::kUnbounded); |
392 rv = resolver.GetProxyForURL( | 392 rv = resolver.GetProxyForURL(GURL("http://request2"), &results2, |
393 GURL("http://request2"), &results2, &callback2, &request2, log2.bound()); | 393 callback2.callback(), &request2, log2.bound()); |
394 EXPECT_EQ(ERR_IO_PENDING, rv); | 394 EXPECT_EQ(ERR_IO_PENDING, rv); |
395 | 395 |
396 // Unblock the worker thread so the requests can continue running. | 396 // Unblock the worker thread so the requests can continue running. |
397 mock->WaitUntilBlocked(); | 397 mock->WaitUntilBlocked(); |
398 mock->Unblock(); | 398 mock->Unblock(); |
399 | 399 |
400 // Check that request 0 completed as expected. | 400 // Check that request 0 completed as expected. |
401 // The NetLog has 1 entry that came from the MultiThreadedProxyResolver, and | 401 // The NetLog has 1 entry that came from the MultiThreadedProxyResolver, and |
402 // 1 entry from the mock proxy resolver. | 402 // 1 entry from the mock proxy resolver. |
403 EXPECT_EQ(0, callback0.WaitForResult()); | 403 EXPECT_EQ(0, callback0.WaitForResult()); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 TEST(MultiThreadedProxyResolverTest, SingleThread_CancelRequest) { | 446 TEST(MultiThreadedProxyResolverTest, SingleThread_CancelRequest) { |
447 const size_t kNumThreads = 1u; | 447 const size_t kNumThreads = 1u; |
448 scoped_ptr<BlockableProxyResolver> mock(new BlockableProxyResolver); | 448 scoped_ptr<BlockableProxyResolver> mock(new BlockableProxyResolver); |
449 MultiThreadedProxyResolver resolver( | 449 MultiThreadedProxyResolver resolver( |
450 new ForwardingProxyResolverFactory(mock.get()), | 450 new ForwardingProxyResolverFactory(mock.get()), |
451 kNumThreads); | 451 kNumThreads); |
452 | 452 |
453 int rv; | 453 int rv; |
454 | 454 |
455 // Initialize the resolver. | 455 // Initialize the resolver. |
456 TestOldCompletionCallback init_callback; | 456 TestCompletionCallback init_callback; |
457 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("foo"), | 457 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("foo"), |
458 &init_callback); | 458 init_callback.callback()); |
459 EXPECT_EQ(OK, init_callback.WaitForResult()); | 459 EXPECT_EQ(OK, init_callback.WaitForResult()); |
460 | 460 |
461 // Block the proxy resolver, so no request can complete. | 461 // Block the proxy resolver, so no request can complete. |
462 mock->Block(); | 462 mock->Block(); |
463 | 463 |
464 // Start request 0. | 464 // Start request 0. |
465 ProxyResolver::RequestHandle request0; | 465 ProxyResolver::RequestHandle request0; |
466 TestOldCompletionCallback callback0; | 466 TestCompletionCallback callback0; |
467 ProxyInfo results0; | 467 ProxyInfo results0; |
468 rv = resolver.GetProxyForURL( | 468 rv = resolver.GetProxyForURL(GURL("http://request0"), &results0, |
469 GURL("http://request0"), &results0, &callback0, &request0, BoundNetLog()); | 469 callback0.callback(), &request0, BoundNetLog()); |
470 EXPECT_EQ(ERR_IO_PENDING, rv); | 470 EXPECT_EQ(ERR_IO_PENDING, rv); |
471 | 471 |
472 // Wait until requests 0 reaches the worker thread. | 472 // Wait until requests 0 reaches the worker thread. |
473 mock->WaitUntilBlocked(); | 473 mock->WaitUntilBlocked(); |
474 | 474 |
475 // Start 3 more requests (request1 : request3). | 475 // Start 3 more requests (request1 : request3). |
476 | 476 |
477 TestOldCompletionCallback callback1; | 477 TestCompletionCallback callback1; |
478 ProxyInfo results1; | 478 ProxyInfo results1; |
479 rv = resolver.GetProxyForURL( | 479 rv = resolver.GetProxyForURL(GURL("http://request1"), &results1, |
480 GURL("http://request1"), &results1, &callback1, NULL, BoundNetLog()); | 480 callback1.callback(), NULL, BoundNetLog()); |
481 EXPECT_EQ(ERR_IO_PENDING, rv); | 481 EXPECT_EQ(ERR_IO_PENDING, rv); |
482 | 482 |
483 ProxyResolver::RequestHandle request2; | 483 ProxyResolver::RequestHandle request2; |
484 TestOldCompletionCallback callback2; | 484 TestCompletionCallback callback2; |
485 ProxyInfo results2; | 485 ProxyInfo results2; |
486 rv = resolver.GetProxyForURL( | 486 rv = resolver.GetProxyForURL(GURL("http://request2"), &results2, |
487 GURL("http://request2"), &results2, &callback2, &request2, BoundNetLog()); | 487 callback2.callback(), &request2, BoundNetLog()); |
488 EXPECT_EQ(ERR_IO_PENDING, rv); | 488 EXPECT_EQ(ERR_IO_PENDING, rv); |
489 | 489 |
490 TestOldCompletionCallback callback3; | 490 TestCompletionCallback callback3; |
491 ProxyInfo results3; | 491 ProxyInfo results3; |
492 rv = resolver.GetProxyForURL( | 492 rv = resolver.GetProxyForURL(GURL("http://request3"), &results3, |
493 GURL("http://request3"), &results3, &callback3, NULL, BoundNetLog()); | 493 callback3.callback(), NULL, BoundNetLog()); |
494 EXPECT_EQ(ERR_IO_PENDING, rv); | 494 EXPECT_EQ(ERR_IO_PENDING, rv); |
495 | 495 |
496 // Cancel request0 (inprogress) and request2 (pending). | 496 // Cancel request0 (inprogress) and request2 (pending). |
497 resolver.CancelRequest(request0); | 497 resolver.CancelRequest(request0); |
498 resolver.CancelRequest(request2); | 498 resolver.CancelRequest(request2); |
499 | 499 |
500 // Unblock the worker thread so the requests can continue running. | 500 // Unblock the worker thread so the requests can continue running. |
501 mock->Unblock(); | 501 mock->Unblock(); |
502 | 502 |
503 // Wait for requests 1 and 3 to finish. | 503 // Wait for requests 1 and 3 to finish. |
(...skipping 19 matching lines...) Expand all Loading... |
523 TEST(MultiThreadedProxyResolverTest, SingleThread_CancelRequestByDeleting) { | 523 TEST(MultiThreadedProxyResolverTest, SingleThread_CancelRequestByDeleting) { |
524 const size_t kNumThreads = 1u; | 524 const size_t kNumThreads = 1u; |
525 scoped_ptr<BlockableProxyResolver> mock(new BlockableProxyResolver); | 525 scoped_ptr<BlockableProxyResolver> mock(new BlockableProxyResolver); |
526 scoped_ptr<MultiThreadedProxyResolver> resolver( | 526 scoped_ptr<MultiThreadedProxyResolver> resolver( |
527 new MultiThreadedProxyResolver( | 527 new MultiThreadedProxyResolver( |
528 new ForwardingProxyResolverFactory(mock.get()), kNumThreads)); | 528 new ForwardingProxyResolverFactory(mock.get()), kNumThreads)); |
529 | 529 |
530 int rv; | 530 int rv; |
531 | 531 |
532 // Initialize the resolver. | 532 // Initialize the resolver. |
533 TestOldCompletionCallback init_callback; | 533 TestCompletionCallback init_callback; |
534 rv = resolver->SetPacScript(ProxyResolverScriptData::FromUTF8("foo"), | 534 rv = resolver->SetPacScript(ProxyResolverScriptData::FromUTF8("foo"), |
535 &init_callback); | 535 init_callback.callback()); |
536 EXPECT_EQ(OK, init_callback.WaitForResult()); | 536 EXPECT_EQ(OK, init_callback.WaitForResult()); |
537 | 537 |
538 // Block the proxy resolver, so no request can complete. | 538 // Block the proxy resolver, so no request can complete. |
539 mock->Block(); | 539 mock->Block(); |
540 | 540 |
541 // Start 3 requests. | 541 // Start 3 requests. |
542 | 542 |
543 TestOldCompletionCallback callback0; | 543 TestCompletionCallback callback0; |
544 ProxyInfo results0; | 544 ProxyInfo results0; |
545 rv = resolver->GetProxyForURL( | 545 rv = resolver->GetProxyForURL(GURL("http://request0"), &results0, |
546 GURL("http://request0"), &results0, &callback0, NULL, BoundNetLog()); | 546 callback0.callback(), NULL, BoundNetLog()); |
547 EXPECT_EQ(ERR_IO_PENDING, rv); | 547 EXPECT_EQ(ERR_IO_PENDING, rv); |
548 | 548 |
549 TestOldCompletionCallback callback1; | 549 TestCompletionCallback callback1; |
550 ProxyInfo results1; | 550 ProxyInfo results1; |
551 rv = resolver->GetProxyForURL( | 551 rv = resolver->GetProxyForURL(GURL("http://request1"), &results1, |
552 GURL("http://request1"), &results1, &callback1, NULL, BoundNetLog()); | 552 callback1.callback(), NULL, BoundNetLog()); |
553 EXPECT_EQ(ERR_IO_PENDING, rv); | 553 EXPECT_EQ(ERR_IO_PENDING, rv); |
554 | 554 |
555 TestOldCompletionCallback callback2; | 555 TestCompletionCallback callback2; |
556 ProxyInfo results2; | 556 ProxyInfo results2; |
557 rv = resolver->GetProxyForURL( | 557 rv = resolver->GetProxyForURL(GURL("http://request2"), &results2, |
558 GURL("http://request2"), &results2, &callback2, NULL, BoundNetLog()); | 558 callback2.callback(), NULL, BoundNetLog()); |
559 EXPECT_EQ(ERR_IO_PENDING, rv); | 559 EXPECT_EQ(ERR_IO_PENDING, rv); |
560 | 560 |
561 // Wait until request 0 reaches the worker thread. | 561 // Wait until request 0 reaches the worker thread. |
562 mock->WaitUntilBlocked(); | 562 mock->WaitUntilBlocked(); |
563 | 563 |
564 // Add some latency, to improve the chance that when | 564 // Add some latency, to improve the chance that when |
565 // MultiThreadedProxyResolver is deleted below we are still running inside | 565 // MultiThreadedProxyResolver is deleted below we are still running inside |
566 // of the worker thread. The test will pass regardless, so this race doesn't | 566 // of the worker thread. The test will pass regardless, so this race doesn't |
567 // cause flakiness. However the destruction during execution is a more | 567 // cause flakiness. However the destruction during execution is a more |
568 // interesting case to test. | 568 // interesting case to test. |
(...skipping 15 matching lines...) Expand all Loading... |
584 | 584 |
585 // Cancel an outstanding call to SetPacScriptByData(). | 585 // Cancel an outstanding call to SetPacScriptByData(). |
586 TEST(MultiThreadedProxyResolverTest, SingleThread_CancelSetPacScript) { | 586 TEST(MultiThreadedProxyResolverTest, SingleThread_CancelSetPacScript) { |
587 const size_t kNumThreads = 1u; | 587 const size_t kNumThreads = 1u; |
588 scoped_ptr<BlockableProxyResolver> mock(new BlockableProxyResolver); | 588 scoped_ptr<BlockableProxyResolver> mock(new BlockableProxyResolver); |
589 MultiThreadedProxyResolver resolver( | 589 MultiThreadedProxyResolver resolver( |
590 new ForwardingProxyResolverFactory(mock.get()), kNumThreads); | 590 new ForwardingProxyResolverFactory(mock.get()), kNumThreads); |
591 | 591 |
592 int rv; | 592 int rv; |
593 | 593 |
594 TestOldCompletionCallback set_pac_script_callback; | 594 TestCompletionCallback set_pac_script_callback; |
595 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("data"), | 595 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("data"), |
596 &set_pac_script_callback); | 596 set_pac_script_callback.callback()); |
597 EXPECT_EQ(ERR_IO_PENDING, rv); | 597 EXPECT_EQ(ERR_IO_PENDING, rv); |
598 | 598 |
599 // Cancel the SetPacScriptByData request. | 599 // Cancel the SetPacScriptByData request. |
600 resolver.CancelSetPacScript(); | 600 resolver.CancelSetPacScript(); |
601 | 601 |
602 // Start another SetPacScript request | 602 // Start another SetPacScript request |
603 TestOldCompletionCallback set_pac_script_callback2; | 603 TestCompletionCallback set_pac_script_callback2; |
604 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("data2"), | 604 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("data2"), |
605 &set_pac_script_callback2); | 605 set_pac_script_callback2.callback()); |
606 EXPECT_EQ(ERR_IO_PENDING, rv); | 606 EXPECT_EQ(ERR_IO_PENDING, rv); |
607 | 607 |
608 // Wait for the initialization to complete. | 608 // Wait for the initialization to complete. |
609 | 609 |
610 rv = set_pac_script_callback2.WaitForResult(); | 610 rv = set_pac_script_callback2.WaitForResult(); |
611 EXPECT_EQ(0, rv); | 611 EXPECT_EQ(0, rv); |
612 EXPECT_EQ(ASCIIToUTF16("data2"), mock->last_script_data()->utf16()); | 612 EXPECT_EQ(ASCIIToUTF16("data2"), mock->last_script_data()->utf16()); |
613 | 613 |
614 // The first SetPacScript callback should never have been completed. | 614 // The first SetPacScript callback should never have been completed. |
615 EXPECT_FALSE(set_pac_script_callback.have_result()); | 615 EXPECT_FALSE(set_pac_script_callback.have_result()); |
616 } | 616 } |
617 | 617 |
618 // Tests setting the PAC script once, lazily creating new threads, and | 618 // Tests setting the PAC script once, lazily creating new threads, and |
619 // cancelling requests. | 619 // cancelling requests. |
620 TEST(MultiThreadedProxyResolverTest, ThreeThreads_Basic) { | 620 TEST(MultiThreadedProxyResolverTest, ThreeThreads_Basic) { |
621 const size_t kNumThreads = 3u; | 621 const size_t kNumThreads = 3u; |
622 BlockableProxyResolverFactory* factory = new BlockableProxyResolverFactory; | 622 BlockableProxyResolverFactory* factory = new BlockableProxyResolverFactory; |
623 MultiThreadedProxyResolver resolver(factory, kNumThreads); | 623 MultiThreadedProxyResolver resolver(factory, kNumThreads); |
624 | 624 |
625 int rv; | 625 int rv; |
626 | 626 |
627 EXPECT_TRUE(resolver.expects_pac_bytes()); | 627 EXPECT_TRUE(resolver.expects_pac_bytes()); |
628 | 628 |
629 // Call SetPacScriptByData() -- verify that it reaches the synchronous | 629 // Call SetPacScriptByData() -- verify that it reaches the synchronous |
630 // resolver. | 630 // resolver. |
631 TestOldCompletionCallback set_script_callback; | 631 TestCompletionCallback set_script_callback; |
632 rv = resolver.SetPacScript( | 632 rv = resolver.SetPacScript( |
633 ProxyResolverScriptData::FromUTF8("pac script bytes"), | 633 ProxyResolverScriptData::FromUTF8("pac script bytes"), |
634 &set_script_callback); | 634 set_script_callback.callback()); |
635 EXPECT_EQ(ERR_IO_PENDING, rv); | 635 EXPECT_EQ(ERR_IO_PENDING, rv); |
636 EXPECT_EQ(OK, set_script_callback.WaitForResult()); | 636 EXPECT_EQ(OK, set_script_callback.WaitForResult()); |
637 // One thread has been provisioned (i.e. one ProxyResolver was created). | 637 // One thread has been provisioned (i.e. one ProxyResolver was created). |
638 ASSERT_EQ(1u, factory->resolvers().size()); | 638 ASSERT_EQ(1u, factory->resolvers().size()); |
639 EXPECT_EQ(ASCIIToUTF16("pac script bytes"), | 639 EXPECT_EQ(ASCIIToUTF16("pac script bytes"), |
640 factory->resolvers()[0]->last_script_data()->utf16()); | 640 factory->resolvers()[0]->last_script_data()->utf16()); |
641 | 641 |
642 const int kNumRequests = 9; | 642 const int kNumRequests = 9; |
643 TestOldCompletionCallback callback[kNumRequests]; | 643 TestCompletionCallback callback[kNumRequests]; |
644 ProxyInfo results[kNumRequests]; | 644 ProxyInfo results[kNumRequests]; |
645 ProxyResolver::RequestHandle request[kNumRequests]; | 645 ProxyResolver::RequestHandle request[kNumRequests]; |
646 | 646 |
647 // Start request 0 -- this should run on thread 0 as there is nothing else | 647 // Start request 0 -- this should run on thread 0 as there is nothing else |
648 // going on right now. | 648 // going on right now. |
649 rv = resolver.GetProxyForURL( | 649 rv = resolver.GetProxyForURL( |
650 GURL("http://request0"), &results[0], &callback[0], &request[0], | 650 GURL("http://request0"), &results[0], callback[0].callback(), &request[0], |
651 BoundNetLog()); | 651 BoundNetLog()); |
652 EXPECT_EQ(ERR_IO_PENDING, rv); | 652 EXPECT_EQ(ERR_IO_PENDING, rv); |
653 | 653 |
654 // Wait for request 0 to finish. | 654 // Wait for request 0 to finish. |
655 rv = callback[0].WaitForResult(); | 655 rv = callback[0].WaitForResult(); |
656 EXPECT_EQ(0, rv); | 656 EXPECT_EQ(0, rv); |
657 EXPECT_EQ("PROXY request0:80", results[0].ToPacString()); | 657 EXPECT_EQ("PROXY request0:80", results[0].ToPacString()); |
658 ASSERT_EQ(1u, factory->resolvers().size()); | 658 ASSERT_EQ(1u, factory->resolvers().size()); |
659 EXPECT_EQ(1, factory->resolvers()[0]->request_count()); | 659 EXPECT_EQ(1, factory->resolvers()[0]->request_count()); |
660 | 660 |
661 MessageLoop::current()->RunAllPending(); | 661 MessageLoop::current()->RunAllPending(); |
662 | 662 |
663 // We now start 8 requests in parallel -- this will cause the maximum of | 663 // We now start 8 requests in parallel -- this will cause the maximum of |
664 // three threads to be provisioned (an additional two from what we already | 664 // three threads to be provisioned (an additional two from what we already |
665 // have). | 665 // have). |
666 | 666 |
667 for (int i = 1; i < kNumRequests; ++i) { | 667 for (int i = 1; i < kNumRequests; ++i) { |
668 rv = resolver.GetProxyForURL( | 668 rv = resolver.GetProxyForURL( |
669 GURL(base::StringPrintf("http://request%d", i)), &results[i], | 669 GURL(base::StringPrintf("http://request%d", i)), &results[i], |
670 &callback[i], &request[i], BoundNetLog()); | 670 callback[i].callback(), &request[i], BoundNetLog()); |
671 EXPECT_EQ(ERR_IO_PENDING, rv); | 671 EXPECT_EQ(ERR_IO_PENDING, rv); |
672 } | 672 } |
673 | 673 |
674 // We should now have a total of 3 threads, each with its own ProxyResolver | 674 // We should now have a total of 3 threads, each with its own ProxyResolver |
675 // that will get initialized with the same data. (We check this later since | 675 // that will get initialized with the same data. (We check this later since |
676 // the assignment happens on the worker threads and may not have occurred | 676 // the assignment happens on the worker threads and may not have occurred |
677 // yet.) | 677 // yet.) |
678 ASSERT_EQ(3u, factory->resolvers().size()); | 678 ASSERT_EQ(3u, factory->resolvers().size()); |
679 | 679 |
680 // Cancel 3 of the 8 oustanding requests. | 680 // Cancel 3 of the 8 oustanding requests. |
681 resolver.CancelRequest(request[1]); | 681 resolver.CancelRequest(request[1]); |
682 resolver.CancelRequest(request[3]); | 682 resolver.CancelRequest(request[3]); |
683 resolver.CancelRequest(request[6]); | 683 resolver.CancelRequest(request[6]); |
684 | 684 |
685 // Wait for the remaining requests to complete. | 685 // Wait for the remaining requests to complete. |
686 int kNonCancelledRequests[] = {2, 4, 5, 7, 8}; | 686 int kNonCancelledRequests[] = {2, 4, 5, 7, 8}; |
687 for (size_t i = 0; i < arraysize(kNonCancelledRequests); ++i) { | 687 for (size_t i = 0; i < arraysize(kNonCancelledRequests); ++i) { |
688 int request_index = kNonCancelledRequests[i]; | 688 int request_index = kNonCancelledRequests[i]; |
689 EXPECT_GE(callback[request_index].WaitForResult(), 0); | 689 EXPECT_GE(callback[request_index].WaitForResult(), 0); |
690 } | 690 } |
691 | 691 |
692 // Check that the cancelled requests never invoked their callback. | 692 // Check that the cancelled requests never invoked their callback. |
693 EXPECT_FALSE(callback[1].have_result()); | 693 EXPECT_FALSE(callback[1].have_result()); |
694 EXPECT_FALSE(callback[3].have_result()); | 694 EXPECT_FALSE(callback[3].have_result()); |
695 EXPECT_FALSE(callback[6].have_result()); | 695 EXPECT_FALSE(callback[6].have_result()); |
696 | 696 |
697 // We call SetPacScript again, solely to stop the current worker threads. | 697 // We call SetPacScript again, solely to stop the current worker threads. |
698 // (That way we can test to see the values observed by the synchronous | 698 // (That way we can test to see the values observed by the synchronous |
699 // resolvers in a non-racy manner). | 699 // resolvers in a non-racy manner). |
700 TestOldCompletionCallback set_script_callback2; | 700 TestCompletionCallback set_script_callback2; |
701 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("xyz"), | 701 rv = resolver.SetPacScript(ProxyResolverScriptData::FromUTF8("xyz"), |
702 &set_script_callback2); | 702 set_script_callback2.callback()); |
703 EXPECT_EQ(ERR_IO_PENDING, rv); | 703 EXPECT_EQ(ERR_IO_PENDING, rv); |
704 EXPECT_EQ(OK, set_script_callback2.WaitForResult()); | 704 EXPECT_EQ(OK, set_script_callback2.WaitForResult()); |
705 ASSERT_EQ(4u, factory->resolvers().size()); | 705 ASSERT_EQ(4u, factory->resolvers().size()); |
706 | 706 |
707 for (int i = 0; i < 3; ++i) { | 707 for (int i = 0; i < 3; ++i) { |
708 EXPECT_EQ( | 708 EXPECT_EQ( |
709 ASCIIToUTF16("pac script bytes"), | 709 ASCIIToUTF16("pac script bytes"), |
710 factory->resolvers()[i]->last_script_data()->utf16()) << "i=" << i; | 710 factory->resolvers()[i]->last_script_data()->utf16()) << "i=" << i; |
711 } | 711 } |
712 | 712 |
(...skipping 20 matching lines...) Expand all Loading... |
733 TEST(MultiThreadedProxyResolverTest, OneThreadBlocked) { | 733 TEST(MultiThreadedProxyResolverTest, OneThreadBlocked) { |
734 const size_t kNumThreads = 2u; | 734 const size_t kNumThreads = 2u; |
735 BlockableProxyResolverFactory* factory = new BlockableProxyResolverFactory; | 735 BlockableProxyResolverFactory* factory = new BlockableProxyResolverFactory; |
736 MultiThreadedProxyResolver resolver(factory, kNumThreads); | 736 MultiThreadedProxyResolver resolver(factory, kNumThreads); |
737 | 737 |
738 int rv; | 738 int rv; |
739 | 739 |
740 EXPECT_TRUE(resolver.expects_pac_bytes()); | 740 EXPECT_TRUE(resolver.expects_pac_bytes()); |
741 | 741 |
742 // Initialize the resolver. | 742 // Initialize the resolver. |
743 TestOldCompletionCallback set_script_callback; | 743 TestCompletionCallback set_script_callback; |
744 rv = resolver.SetPacScript( | 744 rv = resolver.SetPacScript( |
745 ProxyResolverScriptData::FromUTF8("pac script bytes"), | 745 ProxyResolverScriptData::FromUTF8("pac script bytes"), |
746 &set_script_callback); | 746 set_script_callback.callback()); |
747 EXPECT_EQ(ERR_IO_PENDING, rv); | 747 EXPECT_EQ(ERR_IO_PENDING, rv); |
748 EXPECT_EQ(OK, set_script_callback.WaitForResult()); | 748 EXPECT_EQ(OK, set_script_callback.WaitForResult()); |
749 // One thread has been provisioned (i.e. one ProxyResolver was created). | 749 // One thread has been provisioned (i.e. one ProxyResolver was created). |
750 ASSERT_EQ(1u, factory->resolvers().size()); | 750 ASSERT_EQ(1u, factory->resolvers().size()); |
751 EXPECT_EQ(ASCIIToUTF16("pac script bytes"), | 751 EXPECT_EQ(ASCIIToUTF16("pac script bytes"), |
752 factory->resolvers()[0]->last_script_data()->utf16()); | 752 factory->resolvers()[0]->last_script_data()->utf16()); |
753 | 753 |
754 const int kNumRequests = 4; | 754 const int kNumRequests = 4; |
755 TestOldCompletionCallback callback[kNumRequests]; | 755 TestCompletionCallback callback[kNumRequests]; |
756 ProxyInfo results[kNumRequests]; | 756 ProxyInfo results[kNumRequests]; |
757 ProxyResolver::RequestHandle request[kNumRequests]; | 757 ProxyResolver::RequestHandle request[kNumRequests]; |
758 | 758 |
759 // Start a request that will block the first thread. | 759 // Start a request that will block the first thread. |
760 | 760 |
761 factory->resolvers()[0]->Block(); | 761 factory->resolvers()[0]->Block(); |
762 | 762 |
763 rv = resolver.GetProxyForURL( | 763 rv = resolver.GetProxyForURL( |
764 GURL("http://request0"), &results[0], &callback[0], &request[0], | 764 GURL("http://request0"), &results[0], callback[0].callback(), &request[0], |
765 BoundNetLog()); | 765 BoundNetLog()); |
766 | 766 |
767 EXPECT_EQ(ERR_IO_PENDING, rv); | 767 EXPECT_EQ(ERR_IO_PENDING, rv); |
768 factory->resolvers()[0]->WaitUntilBlocked(); | 768 factory->resolvers()[0]->WaitUntilBlocked(); |
769 | 769 |
770 // Start 3 more requests -- they should all be serviced by thread #2 | 770 // Start 3 more requests -- they should all be serviced by thread #2 |
771 // since thread #1 is blocked. | 771 // since thread #1 is blocked. |
772 | 772 |
773 for (int i = 1; i < kNumRequests; ++i) { | 773 for (int i = 1; i < kNumRequests; ++i) { |
774 rv = resolver.GetProxyForURL( | 774 rv = resolver.GetProxyForURL( |
775 GURL(base::StringPrintf("http://request%d", i)), | 775 GURL(base::StringPrintf("http://request%d", i)), |
776 &results[i], &callback[i], &request[i], BoundNetLog()); | 776 &results[i], callback[i].callback(), &request[i], BoundNetLog()); |
777 EXPECT_EQ(ERR_IO_PENDING, rv); | 777 EXPECT_EQ(ERR_IO_PENDING, rv); |
778 } | 778 } |
779 | 779 |
780 // Wait for the three requests to complete (they should complete in FIFO | 780 // Wait for the three requests to complete (they should complete in FIFO |
781 // order). | 781 // order). |
782 for (int i = 1; i < kNumRequests; ++i) { | 782 for (int i = 1; i < kNumRequests; ++i) { |
783 EXPECT_EQ(i - 1, callback[i].WaitForResult()); | 783 EXPECT_EQ(i - 1, callback[i].WaitForResult()); |
784 } | 784 } |
785 | 785 |
786 // Unblock the first thread. | 786 // Unblock the first thread. |
787 factory->resolvers()[0]->Unblock(); | 787 factory->resolvers()[0]->Unblock(); |
788 EXPECT_EQ(0, callback[0].WaitForResult()); | 788 EXPECT_EQ(0, callback[0].WaitForResult()); |
789 | 789 |
790 // All in all, the first thread should have seen just 1 request. And the | 790 // All in all, the first thread should have seen just 1 request. And the |
791 // second thread 3 requests. | 791 // second thread 3 requests. |
792 ASSERT_EQ(2u, factory->resolvers().size()); | 792 ASSERT_EQ(2u, factory->resolvers().size()); |
793 EXPECT_EQ(1, factory->resolvers()[0]->request_count()); | 793 EXPECT_EQ(1, factory->resolvers()[0]->request_count()); |
794 EXPECT_EQ(3, factory->resolvers()[1]->request_count()); | 794 EXPECT_EQ(3, factory->resolvers()[1]->request_count()); |
795 } | 795 } |
796 | 796 |
797 } // namespace | 797 } // namespace |
798 | 798 |
799 } // namespace net | 799 } // namespace net |
OLD | NEW |