Chromium Code Reviews| 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( |
| 283 GURL("http://request0"), &results0, &callback0, NULL, log0.bound()); | 283 GURL("http://request0"), &results0, callback0.callback(), NULL, log0.bound ()); |
|
James Hawkins
2011/12/17 23:50:55
80 cols.
James Hawkins
2011/12/18 00:05:47
Done.
| |
| 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( |
| 306 GURL("http://request1"), &results1, &callback1, NULL, BoundNetLog()); | 306 GURL("http://request1"), &results1, callback1.callback(), NULL, BoundNetLo g()); |
| 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( |
| 312 GURL("http://request2"), &results2, &callback2, NULL, BoundNetLog()); | 312 GURL("http://request2"), &results2, callback2.callback(), NULL, BoundNetLo g()); |
| 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( |
| 318 GURL("http://request3"), &results3, &callback3, NULL, BoundNetLog()); | 318 GURL("http://request3"), &results3, callback3.callback(), NULL, BoundNetLo g()); |
| 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( |
| 376 GURL("http://request0"), &results0, &callback0, &request0, log0.bound()); | 376 GURL("http://request0"), &results0, 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( |
| 385 GURL("http://request1"), &results1, &callback1, NULL, log1.bound()); | 385 GURL("http://request1"), &results1, 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( |
| 393 GURL("http://request2"), &results2, &callback2, &request2, log2.bound()); | 393 GURL("http://request2"), &results2, 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( |
| 469 GURL("http://request0"), &results0, &callback0, &request0, BoundNetLog()); | 469 GURL("http://request0"), &results0, callback0.callback(), &request0, Bound NetLog()); |
| 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( |
| 480 GURL("http://request1"), &results1, &callback1, NULL, BoundNetLog()); | 480 GURL("http://request1"), &results1, callback1.callback(), NULL, BoundNetLo g()); |
| 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( |
| 487 GURL("http://request2"), &results2, &callback2, &request2, BoundNetLog()); | 487 GURL("http://request2"), &results2, callback2.callback(), &request2, Bound NetLog()); |
| 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( |
| 493 GURL("http://request3"), &results3, &callback3, NULL, BoundNetLog()); | 493 GURL("http://request3"), &results3, callback3.callback(), NULL, BoundNetLo g()); |
| 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( |
| 546 GURL("http://request0"), &results0, &callback0, NULL, BoundNetLog()); | 546 GURL("http://request0"), &results0, callback0.callback(), NULL, BoundNetLo g()); |
| 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( |
| 552 GURL("http://request1"), &results1, &callback1, NULL, BoundNetLog()); | 552 GURL("http://request1"), &results1, callback1.callback(), NULL, BoundNetLo g()); |
| 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( |
| 558 GURL("http://request2"), &results2, &callback2, NULL, BoundNetLog()); | 558 GURL("http://request2"), &results2, callback2.callback(), NULL, BoundNetLo g()); |
| 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 |