Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(308)

Side by Side Diff: net/proxy/dhcp_proxy_script_fetcher_win_unittest.cc

Issue 7189016: Do GetAdaptersAddresses on a worker thread. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix handling of cancellation. Add regression test. Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/proxy/dhcp_proxy_script_fetcher_win.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/dhcp_proxy_script_fetcher_win.h" 5 #include "net/proxy/dhcp_proxy_script_fetcher_win.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/message_loop.h" 9 #include "base/message_loop.h"
10 #include "base/perftimer.h" 10 #include "base/perftimer.h"
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 bool did_finish_; 256 bool did_finish_;
257 int result_; 257 int result_;
258 string16 pac_script_; 258 string16 pac_script_;
259 int fetch_delay_ms_; 259 int fetch_delay_ms_;
260 CompletionCallback* client_callback_; 260 CompletionCallback* client_callback_;
261 base::OneShotTimer<DummyDhcpProxyScriptAdapterFetcher> timer_; 261 base::OneShotTimer<DummyDhcpProxyScriptAdapterFetcher> timer_;
262 }; 262 };
263 263
264 class MockDhcpProxyScriptFetcherWin : public DhcpProxyScriptFetcherWin { 264 class MockDhcpProxyScriptFetcherWin : public DhcpProxyScriptFetcherWin {
265 public: 265 public:
266 class MockWorkerThread : public WorkerThread {
267 public:
268 MockWorkerThread() : worker_finished_event_(true, false) {
269 }
270
271 virtual ~MockWorkerThread() {
272 }
273
274 void Init(const base::WeakPtr<DhcpProxyScriptFetcherWin>& owner) {
275 WorkerThread::Init(owner);
276 }
277
278 virtual bool ImplGetCandidateAdapterNames(
279 std::set<std::string>* adapter_names) OVERRIDE {
280 adapter_names->insert(
281 mock_adapter_names_.begin(), mock_adapter_names_.end());
282 return true;
283 }
284
285 virtual void OnThreadDone() OVERRIDE {
286 WorkerThread::OnThreadDone();
287 worker_finished_event_.Signal();
288 }
289
290 std::vector<std::string> mock_adapter_names_;
291 base::WaitableEvent worker_finished_event_;
292 };
293
266 MockDhcpProxyScriptFetcherWin() 294 MockDhcpProxyScriptFetcherWin()
267 : DhcpProxyScriptFetcherWin(new TestURLRequestContext()) { 295 : DhcpProxyScriptFetcherWin(new TestURLRequestContext()),
296 num_fetchers_created_(0) {
268 ResetTestState(); 297 ResetTestState();
269 } 298 }
270 299
271 // Adds a fetcher object to the queue of fetchers used by 300 // Adds a fetcher object to the queue of fetchers used by
272 // |ImplCreateAdapterFetcher()|, and its name to the list of adapters 301 // |ImplCreateAdapterFetcher()|, and its name to the list of adapters
273 // returned by ImplGetCandidateAdapterNames. 302 // returned by ImplGetCandidateAdapterNames.
274 void PushBackAdapter(const std::string& adapter_name, 303 void PushBackAdapter(const std::string& adapter_name,
275 DhcpProxyScriptAdapterFetcher* fetcher) { 304 DhcpProxyScriptAdapterFetcher* fetcher) {
276 adapter_names_.push_back(adapter_name); 305 worker_thread_->mock_adapter_names_.push_back(adapter_name);
277 adapter_fetchers_.push_back(fetcher); 306 adapter_fetchers_.push_back(fetcher);
278 } 307 }
279 308
280 void ConfigureAndPushBackAdapter(const std::string& adapter_name, 309 void ConfigureAndPushBackAdapter(const std::string& adapter_name,
281 bool did_finish, 310 bool did_finish,
282 int result, 311 int result,
283 string16 pac_script, 312 string16 pac_script,
284 int fetch_delay_ms) { 313 int fetch_delay_ms) {
285 scoped_ptr<DummyDhcpProxyScriptAdapterFetcher> adapter_fetcher( 314 scoped_ptr<DummyDhcpProxyScriptAdapterFetcher> adapter_fetcher(
286 new DummyDhcpProxyScriptAdapterFetcher()); 315 new DummyDhcpProxyScriptAdapterFetcher());
287 adapter_fetcher->Configure(did_finish, result, pac_script, fetch_delay_ms); 316 adapter_fetcher->Configure(did_finish, result, pac_script, fetch_delay_ms);
288 PushBackAdapter(adapter_name, adapter_fetcher.release()); 317 PushBackAdapter(adapter_name, adapter_fetcher.release());
289 } 318 }
290 319
291 DhcpProxyScriptAdapterFetcher* ImplCreateAdapterFetcher() OVERRIDE { 320 DhcpProxyScriptAdapterFetcher* ImplCreateAdapterFetcher() OVERRIDE {
321 ++num_fetchers_created_;
292 return adapter_fetchers_[next_adapter_fetcher_index_++]; 322 return adapter_fetchers_[next_adapter_fetcher_index_++];
293 } 323 }
294 324
295 bool ImplGetCandidateAdapterNames( 325 virtual WorkerThread* ImplCreateWorkerThread(
296 std::set<std::string>* adapter_names) OVERRIDE { 326 const base::WeakPtr<DhcpProxyScriptFetcherWin>& owner) OVERRIDE {
297 adapter_names->insert(adapter_names_.begin(), adapter_names_.end()); 327 DCHECK(worker_thread_);
298 return true; 328 worker_thread_->Init(owner);
329 return worker_thread_.get();
299 } 330 }
300 331
301 int ImplGetMaxWaitMs() OVERRIDE { 332 int ImplGetMaxWaitMs() OVERRIDE {
302 return max_wait_ms_; 333 return max_wait_ms_;
303 } 334 }
304 335
305 void ResetTestState() { 336 void ResetTestState() {
306 next_adapter_fetcher_index_ = 0; 337 next_adapter_fetcher_index_ = 0;
338 num_fetchers_created_ = 0;
307 adapter_fetchers_.clear(); 339 adapter_fetchers_.clear();
308 // String pointers contained herein will have been freed during test. 340 worker_thread_ = new MockWorkerThread();
309 adapter_names_.clear();
310 max_wait_ms_ = TestTimeouts::tiny_timeout_ms(); 341 max_wait_ms_ = TestTimeouts::tiny_timeout_ms();
311 } 342 }
312 343
313 bool HasPendingFetchers() { 344 bool HasPendingFetchers() {
314 return num_pending_fetchers() > 0; 345 return num_pending_fetchers() > 0;
315 } 346 }
316 347
317 int next_adapter_fetcher_index_; 348 int next_adapter_fetcher_index_;
318 349
319 // Ownership is not here; it gets transferred to the implementation 350 // Ownership is not here; it gets transferred to the implementation
320 // class via ImplCreateAdapterFetcher. 351 // class via ImplCreateAdapterFetcher.
321 std::vector<DhcpProxyScriptAdapterFetcher*> adapter_fetchers_; 352 std::vector<DhcpProxyScriptAdapterFetcher*> adapter_fetchers_;
322 353
323 std::vector<std::string> adapter_names_; 354 scoped_refptr<MockWorkerThread> worker_thread_;
324 355
325 int max_wait_ms_; 356 int max_wait_ms_;
357 int num_fetchers_created_;
326 }; 358 };
327 359
328 class FetcherClient { 360 class FetcherClient {
329 public: 361 public:
330 FetcherClient() 362 FetcherClient()
331 : finished_(false), 363 : finished_(false),
332 result_(ERR_UNEXPECTED), 364 result_(ERR_UNEXPECTED),
333 ALLOW_THIS_IN_INITIALIZER_LIST( 365 ALLOW_THIS_IN_INITIALIZER_LIST(
334 completion_callback_(this, &FetcherClient::OnCompletion)) { 366 completion_callback_(this, &FetcherClient::OnCompletion)) {
335 } 367 }
336 368
337 void RunTest() { 369 void RunTest() {
338 int result = fetcher_.Fetch(&pac_text_, &completion_callback_); 370 int result = fetcher_.Fetch(&pac_text_, &completion_callback_);
339 ASSERT_EQ(ERR_IO_PENDING, result); 371 ASSERT_EQ(ERR_IO_PENDING, result);
340 } 372 }
341 373
342 void RunImmediateReturnTest() {
343 int result = fetcher_.Fetch(&pac_text_, &completion_callback_);
344 ASSERT_EQ(ERR_PAC_NOT_IN_DHCP, result);
345 }
346
347 void RunMessageLoopUntilComplete() { 374 void RunMessageLoopUntilComplete() {
348 while (!finished_) { 375 while (!finished_) {
349 MessageLoop::current()->RunAllPending(); 376 MessageLoop::current()->RunAllPending();
350 } 377 }
351 MessageLoop::current()->RunAllPending(); 378 MessageLoop::current()->RunAllPending();
352 } 379 }
353 380
381 void RunMessageLoopUntilWorkerDone() {
382 DCHECK(fetcher_.worker_thread_.get());
383 while (!fetcher_.worker_thread_->worker_finished_event_.TimedWait(
384 base::TimeDelta::FromMilliseconds(10))) {
385 MessageLoop::current()->RunAllPending();
386 }
387 }
388
354 void OnCompletion(int result) { 389 void OnCompletion(int result) {
355 finished_ = true; 390 finished_ = true;
356 result_ = result; 391 result_ = result;
357 } 392 }
358 393
359 void ResetTestState() { 394 void ResetTestState() {
360 finished_ = false; 395 finished_ = false;
361 result_ = ERR_UNEXPECTED; 396 result_ = ERR_UNEXPECTED;
362 pac_text_ = L""; 397 pac_text_ = L"";
363 fetcher_.ResetTestState(); 398 fetcher_.ResetTestState();
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 ASSERT_EQ(ERR_PAC_NOT_IN_DHCP, client->result_); 505 ASSERT_EQ(ERR_PAC_NOT_IN_DHCP, client->result_);
471 ASSERT_EQ(L"", client->pac_text_); 506 ASSERT_EQ(L"", client->pac_text_);
472 } 507 }
473 508
474 TEST(DhcpProxyScriptFetcherWin, FailureCaseNoURLConfigured) { 509 TEST(DhcpProxyScriptFetcherWin, FailureCaseNoURLConfigured) {
475 FetcherClient client; 510 FetcherClient client;
476 TestFailureCaseNoURLConfigured(&client); 511 TestFailureCaseNoURLConfigured(&client);
477 } 512 }
478 513
479 void TestFailureCaseNoDhcpAdapters(FetcherClient* client) { 514 void TestFailureCaseNoDhcpAdapters(FetcherClient* client) {
480 client->RunImmediateReturnTest(); 515 client->RunTest();
481 // In case there are any pending messages that get us in a bad state 516 client->RunMessageLoopUntilComplete();
482 // (there shouldn't be). 517 ASSERT_EQ(ERR_PAC_NOT_IN_DHCP, client->result_);
483 MessageLoop::current()->RunAllPending(); 518 ASSERT_EQ(L"", client->pac_text_);
519 ASSERT_EQ(0, client->fetcher_.num_fetchers_created_);
484 } 520 }
485 521
486 TEST(DhcpProxyScriptFetcherWin, FailureCaseNoDhcpAdapters) { 522 TEST(DhcpProxyScriptFetcherWin, FailureCaseNoDhcpAdapters) {
487 FetcherClient client; 523 FetcherClient client;
488 TestFailureCaseNoDhcpAdapters(&client); 524 TestFailureCaseNoDhcpAdapters(&client);
489 } 525 }
490 526
491 void TestShortCircuitLessPreferredAdapters(FetcherClient* client) { 527 void TestShortCircuitLessPreferredAdapters(FetcherClient* client) {
492 // Here we have a bunch of adapters; the first reports no PAC in DHCP, 528 // Here we have a bunch of adapters; the first reports no PAC in DHCP,
493 // the second responds quickly with a PAC file, the rest take a long 529 // the second responds quickly with a PAC file, the rest take a long
(...skipping 21 matching lines...) Expand all
515 ASSERT_GT(base::TimeDelta::FromMilliseconds( 551 ASSERT_GT(base::TimeDelta::FromMilliseconds(
516 client->fetcher_.max_wait_ms_ - (client->fetcher_.max_wait_ms_ / 10)), 552 client->fetcher_.max_wait_ms_ - (client->fetcher_.max_wait_ms_ / 10)),
517 timer.Elapsed()); 553 timer.Elapsed());
518 } 554 }
519 555
520 TEST(DhcpProxyScriptFetcherWin, ShortCircuitLessPreferredAdapters) { 556 TEST(DhcpProxyScriptFetcherWin, ShortCircuitLessPreferredAdapters) {
521 FetcherClient client; 557 FetcherClient client;
522 TestShortCircuitLessPreferredAdapters(&client); 558 TestShortCircuitLessPreferredAdapters(&client);
523 } 559 }
524 560
561 void TestImmediateCancel(FetcherClient* client) {
562 scoped_ptr<DummyDhcpProxyScriptAdapterFetcher> adapter_fetcher(
563 new DummyDhcpProxyScriptAdapterFetcher());
564 adapter_fetcher->Configure(true, OK, L"bingo", 1);
565 client->fetcher_.PushBackAdapter("a", adapter_fetcher.release());
566 client->RunTest();
567 client->fetcher_.Cancel();
568 client->RunMessageLoopUntilWorkerDone();
569 ASSERT_EQ(0, client->fetcher_.num_fetchers_created_);
570 }
571
572 // Regression test to check that when we cancel immediately, no
573 // adapter fetchers get created.
574 TEST(DhcpProxyScriptFetcherWin, ImmediateCancel) {
575 FetcherClient client;
576 TestImmediateCancel(&client);
577 }
578
525 TEST(DhcpProxyScriptFetcherWin, ReuseFetcher) { 579 TEST(DhcpProxyScriptFetcherWin, ReuseFetcher) {
526 FetcherClient client; 580 FetcherClient client;
527 581
528 // The ProxyScriptFetcher interface stipulates that only a single 582 // The ProxyScriptFetcher interface stipulates that only a single
529 // |Fetch()| may be in flight at once, but allows reuse, so test 583 // |Fetch()| may be in flight at once, but allows reuse, so test
530 // that the state transitions correctly from done to start in all 584 // that the state transitions correctly from done to start in all
531 // cases we're testing. 585 // cases we're testing.
532 586
533 typedef void (*FetcherClientTestFunction)(FetcherClient*); 587 typedef void (*FetcherClientTestFunction)(FetcherClient*);
534 typedef std::vector<FetcherClientTestFunction> TestVector; 588 typedef std::vector<FetcherClientTestFunction> TestVector;
535 TestVector test_functions; 589 TestVector test_functions;
536 test_functions.push_back(TestNormalCaseURLConfiguredOneAdapter); 590 test_functions.push_back(TestNormalCaseURLConfiguredOneAdapter);
537 test_functions.push_back(TestNormalCaseURLConfiguredMultipleAdapters); 591 test_functions.push_back(TestNormalCaseURLConfiguredMultipleAdapters);
538 test_functions.push_back( 592 test_functions.push_back(
539 TestNormalCaseURLConfiguredMultipleAdaptersWithTimeout); 593 TestNormalCaseURLConfiguredMultipleAdaptersWithTimeout);
540 test_functions.push_back( 594 test_functions.push_back(
541 TestFailureCaseURLConfiguredMultipleAdaptersWithTimeout); 595 TestFailureCaseURLConfiguredMultipleAdaptersWithTimeout);
542 test_functions.push_back(TestFailureCaseNoURLConfigured); 596 test_functions.push_back(TestFailureCaseNoURLConfigured);
543 test_functions.push_back(TestFailureCaseNoDhcpAdapters); 597 test_functions.push_back(TestFailureCaseNoDhcpAdapters);
544 test_functions.push_back(TestShortCircuitLessPreferredAdapters); 598 test_functions.push_back(TestShortCircuitLessPreferredAdapters);
599 test_functions.push_back(TestImmediateCancel);
545 600
546 std::random_shuffle(test_functions.begin(), 601 std::random_shuffle(test_functions.begin(),
547 test_functions.end(), 602 test_functions.end(),
548 base::RandGenerator); 603 base::RandGenerator);
549 for (TestVector::const_iterator it = test_functions.begin(); 604 for (TestVector::const_iterator it = test_functions.begin();
550 it != test_functions.end(); 605 it != test_functions.end();
551 ++it) { 606 ++it) {
552 (*it)(&client); 607 (*it)(&client);
553 client.ResetTestState(); 608 client.ResetTestState();
554 } 609 }
555 610
556 // Re-do the first test to make sure the last test that was run did 611 // Re-do the first test to make sure the last test that was run did
557 // not leave things in a bad state. 612 // not leave things in a bad state.
558 (*test_functions.begin())(&client); 613 (*test_functions.begin())(&client);
559 } 614 }
560 615
561 } // namespace 616 } // namespace
562 617
563 } // namespace net 618 } // namespace net
OLDNEW
« no previous file with comments | « net/proxy/dhcp_proxy_script_fetcher_win.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698