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

Side by Side Diff: net/url_request/url_request_unittest.cc

Issue 2130493002: Implement THROTTLED priority semantics. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@NetworkStreamThrottler
Patch Set: All non-merge updates since stamps. Created 4 years, 1 month 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
« net/base/network_throttle_manager_impl.cc ('K') | « net/net.gypi ('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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <memory> 5 #include <memory>
6 #include <utility> 6 #include <utility>
7 7
8 #include "base/memory/ptr_util.h" 8 #include "base/memory/ptr_util.h"
9 #include "base/run_loop.h" 9 #include "base/run_loop.h"
10 #include "build/build_config.h" 10 #include "build/build_config.h"
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 381
382 // Behavior during blocked stages. During other stages, just 382 // Behavior during blocked stages. During other stages, just
383 // returns OK or NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION. 383 // returns OK or NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION.
384 enum BlockMode { 384 enum BlockMode {
385 SYNCHRONOUS, // No callback, returns specified return values. 385 SYNCHRONOUS, // No callback, returns specified return values.
386 AUTO_CALLBACK, // |this| posts a task to run the callback using the 386 AUTO_CALLBACK, // |this| posts a task to run the callback using the
387 // specified return codes. 387 // specified return codes.
388 USER_CALLBACK, // User takes care of doing a callback. |retval_| and 388 USER_CALLBACK, // User takes care of doing a callback. |retval_| and
389 // |auth_retval_| are ignored. In every blocking stage the 389 // |auth_retval_| are ignored. In every blocking stage the
390 // message loop is quit. 390 // message loop is quit.
391 USER_NOTIFY, // User is notified by a provided callback of the
392 // blocking, and synchronously returns instructions
393 // for handling it.
391 }; 394 };
392 395
396 using NotificationCallback =
397 base::Callback<Error(const CompletionCallback&, const URLRequest*)>;
398
399 using NotificationAuthCallback =
400 base::Callback<NetworkDelegate::AuthRequiredResponse(const AuthCallback&,
401 const URLRequest*)>;
402
393 // Creates a delegate which does not block at all. 403 // Creates a delegate which does not block at all.
394 explicit BlockingNetworkDelegate(BlockMode block_mode); 404 explicit BlockingNetworkDelegate(BlockMode block_mode);
395 405
396 // For users to trigger a callback returning |response|. 406 // For users to trigger a callback returning |response|.
397 // Side-effects: resets |stage_blocked_for_callback_| and stored callbacks. 407 // Side-effects: resets |stage_blocked_for_callback_| and stored callbacks.
398 // Only call if |block_mode_| == USER_CALLBACK. 408 // Only call if |block_mode_| == USER_CALLBACK.
399 void DoCallback(int response); 409 void DoCallback(int response);
400 void DoAuthCallback(NetworkDelegate::AuthRequiredResponse response); 410 void DoAuthCallback(NetworkDelegate::AuthRequiredResponse response);
401 411
402 // Setters. 412 // Setters.
(...skipping 16 matching lines...) Expand all
419 } 429 }
420 430
421 void set_redirect_url(const GURL& url) { 431 void set_redirect_url(const GURL& url) {
422 redirect_url_ = url; 432 redirect_url_ = url;
423 } 433 }
424 434
425 void set_block_on(int block_on) { 435 void set_block_on(int block_on) {
426 block_on_ = block_on; 436 block_on_ = block_on;
427 } 437 }
428 438
439 // Only valid if |block_mode_| == USER_NOTIFY
440 void set_notification_callback(
441 const NotificationCallback& notification_callback) {
442 notification_callback_ = notification_callback;
443 }
444
445 void set_notification_auth_callback(
446 const NotificationAuthCallback& notification_auth_callback) {
447 notification_auth_callback_ = notification_auth_callback;
448 }
449
429 // Allows the user to check in which state did we block. 450 // Allows the user to check in which state did we block.
430 Stage stage_blocked_for_callback() const { 451 Stage stage_blocked_for_callback() const {
431 EXPECT_EQ(USER_CALLBACK, block_mode_); 452 EXPECT_EQ(USER_CALLBACK, block_mode_);
432 return stage_blocked_for_callback_; 453 return stage_blocked_for_callback_;
433 } 454 }
434 455
435 private: 456 private:
436 void RunCallback(int response, const CompletionCallback& callback); 457 void RunCallback(int response, const CompletionCallback& callback);
437 void RunAuthCallback(AuthRequiredResponse response, 458 void RunAuthCallback(AuthRequiredResponse response,
438 const AuthCallback& callback); 459 const AuthCallback& callback);
(...skipping 18 matching lines...) Expand all
457 URLRequest* request, 478 URLRequest* request,
458 const AuthChallengeInfo& auth_info, 479 const AuthChallengeInfo& auth_info,
459 const AuthCallback& callback, 480 const AuthCallback& callback,
460 AuthCredentials* credentials) override; 481 AuthCredentials* credentials) override;
461 482
462 // Resets the callbacks and |stage_blocked_for_callback_|. 483 // Resets the callbacks and |stage_blocked_for_callback_|.
463 void Reset(); 484 void Reset();
464 485
465 // Checks whether we should block in |stage|. If yes, returns an error code 486 // Checks whether we should block in |stage|. If yes, returns an error code
466 // and optionally sets up callback based on |block_mode_|. If no, returns OK. 487 // and optionally sets up callback based on |block_mode_|. If no, returns OK.
467 int MaybeBlockStage(Stage stage, const CompletionCallback& callback); 488 int MaybeBlockStage(Stage stage,
489 const URLRequest* request,
490 const CompletionCallback& callback);
468 491
469 // Configuration parameters, can be adjusted by public methods: 492 // Configuration parameters, can be adjusted by public methods:
470 const BlockMode block_mode_; 493 const BlockMode block_mode_;
471 494
472 // Values returned on blocking stages when mode is SYNCHRONOUS or 495 // Values returned on blocking stages when mode is SYNCHRONOUS or
473 // AUTO_CALLBACK. For USER_CALLBACK these are set automatically to IO_PENDING. 496 // AUTO_CALLBACK. For USER_CALLBACK these are set automatically to IO_PENDING.
474 int retval_; // To be returned in non-auth stages. 497 int retval_; // To be returned in non-auth stages.
475 AuthRequiredResponse auth_retval_; 498 AuthRequiredResponse auth_retval_;
476 499
477 GURL redirect_url_; // Used if non-empty during OnBeforeURLRequest. 500 GURL redirect_url_; // Used if non-empty during OnBeforeURLRequest.
478 int block_on_; // Bit mask: in which stages to block. 501 int block_on_; // Bit mask: in which stages to block.
479 502
480 // |auth_credentials_| will be copied to |*target_auth_credential_| on 503 // |auth_credentials_| will be copied to |*target_auth_credential_| on
481 // callback. 504 // callback.
482 AuthCredentials auth_credentials_; 505 AuthCredentials auth_credentials_;
483 AuthCredentials* target_auth_credentials_; 506 AuthCredentials* target_auth_credentials_;
484 507
485 // Internal variables, not set by not the user: 508 // Internal variables, not set by not the user:
486 // Last blocked stage waiting for user callback (unused if |block_mode_| != 509 // Last blocked stage waiting for user callback (unused if |block_mode_| !=
487 // USER_CALLBACK). 510 // USER_CALLBACK).
488 Stage stage_blocked_for_callback_; 511 Stage stage_blocked_for_callback_;
489 512
490 // Callback objects stored during blocking stages. 513 // Callback objects stored during blocking stages.
491 CompletionCallback callback_; 514 CompletionCallback callback_;
492 AuthCallback auth_callback_; 515 AuthCallback auth_callback_;
493 516
517 // Callback to request user instructions for blocking.
518 NotificationCallback notification_callback_;
519 NotificationAuthCallback notification_auth_callback_;
520
494 base::WeakPtrFactory<BlockingNetworkDelegate> weak_factory_; 521 base::WeakPtrFactory<BlockingNetworkDelegate> weak_factory_;
495 522
496 DISALLOW_COPY_AND_ASSIGN(BlockingNetworkDelegate); 523 DISALLOW_COPY_AND_ASSIGN(BlockingNetworkDelegate);
497 }; 524 };
498 525
499 BlockingNetworkDelegate::BlockingNetworkDelegate(BlockMode block_mode) 526 BlockingNetworkDelegate::BlockingNetworkDelegate(BlockMode block_mode)
500 : block_mode_(block_mode), 527 : block_mode_(block_mode),
501 retval_(OK), 528 retval_(OK),
502 auth_retval_(AUTH_REQUIRED_RESPONSE_NO_ACTION), 529 auth_retval_(AUTH_REQUIRED_RESPONSE_NO_ACTION),
503 block_on_(0), 530 block_on_(0),
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 const CompletionCallback& callback, 570 const CompletionCallback& callback,
544 GURL* new_url) { 571 GURL* new_url) {
545 if (redirect_url_ == request->url()) 572 if (redirect_url_ == request->url())
546 return OK; // We've already seen this request and redirected elsewhere. 573 return OK; // We've already seen this request and redirected elsewhere.
547 574
548 TestNetworkDelegate::OnBeforeURLRequest(request, callback, new_url); 575 TestNetworkDelegate::OnBeforeURLRequest(request, callback, new_url);
549 576
550 if (!redirect_url_.is_empty()) 577 if (!redirect_url_.is_empty())
551 *new_url = redirect_url_; 578 *new_url = redirect_url_;
552 579
553 return MaybeBlockStage(ON_BEFORE_URL_REQUEST, callback); 580 return MaybeBlockStage(ON_BEFORE_URL_REQUEST, request, callback);
554 } 581 }
555 582
556 int BlockingNetworkDelegate::OnBeforeStartTransaction( 583 int BlockingNetworkDelegate::OnBeforeStartTransaction(
557 URLRequest* request, 584 URLRequest* request,
558 const CompletionCallback& callback, 585 const CompletionCallback& callback,
559 HttpRequestHeaders* headers) { 586 HttpRequestHeaders* headers) {
560 TestNetworkDelegate::OnBeforeStartTransaction(request, callback, headers); 587 TestNetworkDelegate::OnBeforeStartTransaction(request, callback, headers);
561 588
562 return MaybeBlockStage(ON_BEFORE_SEND_HEADERS, callback); 589 return MaybeBlockStage(ON_BEFORE_SEND_HEADERS, request, callback);
563 } 590 }
564 591
565 int BlockingNetworkDelegate::OnHeadersReceived( 592 int BlockingNetworkDelegate::OnHeadersReceived(
566 URLRequest* request, 593 URLRequest* request,
567 const CompletionCallback& callback, 594 const CompletionCallback& callback,
568 const HttpResponseHeaders* original_response_headers, 595 const HttpResponseHeaders* original_response_headers,
569 scoped_refptr<HttpResponseHeaders>* override_response_headers, 596 scoped_refptr<HttpResponseHeaders>* override_response_headers,
570 GURL* allowed_unsafe_redirect_url) { 597 GURL* allowed_unsafe_redirect_url) {
571 TestNetworkDelegate::OnHeadersReceived(request, 598 TestNetworkDelegate::OnHeadersReceived(request,
572 callback, 599 callback,
573 original_response_headers, 600 original_response_headers,
574 override_response_headers, 601 override_response_headers,
575 allowed_unsafe_redirect_url); 602 allowed_unsafe_redirect_url);
576 603
577 return MaybeBlockStage(ON_HEADERS_RECEIVED, callback); 604 return MaybeBlockStage(ON_HEADERS_RECEIVED, request, callback);
578 } 605 }
579 606
580 NetworkDelegate::AuthRequiredResponse BlockingNetworkDelegate::OnAuthRequired( 607 NetworkDelegate::AuthRequiredResponse BlockingNetworkDelegate::OnAuthRequired(
581 URLRequest* request, 608 URLRequest* request,
582 const AuthChallengeInfo& auth_info, 609 const AuthChallengeInfo& auth_info,
583 const AuthCallback& callback, 610 const AuthCallback& callback,
584 AuthCredentials* credentials) { 611 AuthCredentials* credentials) {
585 TestNetworkDelegate::OnAuthRequired(request, auth_info, callback, 612 TestNetworkDelegate::OnAuthRequired(request, auth_info, callback,
586 credentials); 613 credentials);
587 // Check that the user has provided callback for the previous blocked stage. 614 // Check that the user has provided callback for the previous blocked stage.
(...skipping 17 matching lines...) Expand all
605 base::Bind(&BlockingNetworkDelegate::RunAuthCallback, 632 base::Bind(&BlockingNetworkDelegate::RunAuthCallback,
606 weak_factory_.GetWeakPtr(), auth_retval_, callback)); 633 weak_factory_.GetWeakPtr(), auth_retval_, callback));
607 return AUTH_REQUIRED_RESPONSE_IO_PENDING; 634 return AUTH_REQUIRED_RESPONSE_IO_PENDING;
608 635
609 case USER_CALLBACK: 636 case USER_CALLBACK:
610 auth_callback_ = callback; 637 auth_callback_ = callback;
611 stage_blocked_for_callback_ = ON_AUTH_REQUIRED; 638 stage_blocked_for_callback_ = ON_AUTH_REQUIRED;
612 base::ThreadTaskRunnerHandle::Get()->PostTask( 639 base::ThreadTaskRunnerHandle::Get()->PostTask(
613 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); 640 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
614 return AUTH_REQUIRED_RESPONSE_IO_PENDING; 641 return AUTH_REQUIRED_RESPONSE_IO_PENDING;
642
643 case USER_NOTIFY:
644 // If the callback returns ERR_IO_PENDING, the user has accepted
645 // responsibility for running the callback in the future.
646 return notification_auth_callback_.Run(callback, request);
615 } 647 }
616 NOTREACHED(); 648 NOTREACHED();
617 return AUTH_REQUIRED_RESPONSE_NO_ACTION; // Dummy value. 649 return AUTH_REQUIRED_RESPONSE_NO_ACTION; // Dummy value.
618 } 650 }
619 651
620 void BlockingNetworkDelegate::Reset() { 652 void BlockingNetworkDelegate::Reset() {
621 EXPECT_NE(NOT_BLOCKED, stage_blocked_for_callback_); 653 EXPECT_NE(NOT_BLOCKED, stage_blocked_for_callback_);
622 stage_blocked_for_callback_ = NOT_BLOCKED; 654 stage_blocked_for_callback_ = NOT_BLOCKED;
623 callback_.Reset(); 655 callback_.Reset();
624 auth_callback_.Reset(); 656 auth_callback_.Reset();
625 } 657 }
626 658
627 int BlockingNetworkDelegate::MaybeBlockStage( 659 int BlockingNetworkDelegate::MaybeBlockStage(
628 BlockingNetworkDelegate::Stage stage, 660 BlockingNetworkDelegate::Stage stage,
661 const URLRequest* request,
629 const CompletionCallback& callback) { 662 const CompletionCallback& callback) {
630 // Check that the user has provided callback for the previous blocked stage. 663 // Check that the user has provided callback for the previous blocked stage.
631 EXPECT_EQ(NOT_BLOCKED, stage_blocked_for_callback_); 664 EXPECT_EQ(NOT_BLOCKED, stage_blocked_for_callback_);
632 665
633 if ((block_on_ & stage) == 0) { 666 if ((block_on_ & stage) == 0) {
634 return OK; 667 return OK;
635 } 668 }
636 669
637 switch (block_mode_) { 670 switch (block_mode_) {
638 case SYNCHRONOUS: 671 case SYNCHRONOUS:
639 EXPECT_NE(OK, retval_); 672 EXPECT_NE(OK, retval_);
640 return retval_; 673 return retval_;
641 674
642 case AUTO_CALLBACK: 675 case AUTO_CALLBACK:
643 base::ThreadTaskRunnerHandle::Get()->PostTask( 676 base::ThreadTaskRunnerHandle::Get()->PostTask(
644 FROM_HERE, base::Bind(&BlockingNetworkDelegate::RunCallback, 677 FROM_HERE, base::Bind(&BlockingNetworkDelegate::RunCallback,
645 weak_factory_.GetWeakPtr(), retval_, callback)); 678 weak_factory_.GetWeakPtr(), retval_, callback));
646 return ERR_IO_PENDING; 679 return ERR_IO_PENDING;
647 680
648 case USER_CALLBACK: 681 case USER_CALLBACK:
649 callback_ = callback; 682 callback_ = callback;
650 stage_blocked_for_callback_ = stage; 683 stage_blocked_for_callback_ = stage;
651 base::ThreadTaskRunnerHandle::Get()->PostTask( 684 base::ThreadTaskRunnerHandle::Get()->PostTask(
652 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure()); 685 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
653 return ERR_IO_PENDING; 686 return ERR_IO_PENDING;
687
688 case USER_NOTIFY:
689 // If the callback returns ERR_IO_PENDING, the user has accepted
690 // responsibility for running the callback in the future.
691 return notification_callback_.Run(callback, request);
654 } 692 }
655 NOTREACHED(); 693 NOTREACHED();
656 return 0; 694 return 0;
657 } 695 }
658 696
659 class TestURLRequestContextWithProxy : public TestURLRequestContext { 697 class TestURLRequestContextWithProxy : public TestURLRequestContext {
660 public: 698 public:
661 // Does not own |delegate|. 699 // Does not own |delegate|.
662 TestURLRequestContextWithProxy(const std::string& proxy, 700 TestURLRequestContextWithProxy(const std::string& proxy,
663 NetworkDelegate* delegate) 701 NetworkDelegate* delegate)
(...skipping 7137 matching lines...) Expand 10 before | Expand all | Expand 10 after
7801 std::unique_ptr<URLRequest> req( 7839 std::unique_ptr<URLRequest> req(
7802 default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d)); 7840 default_context_.CreateRequest(test_url, DEFAULT_PRIORITY, &d));
7803 req->SetLoadFlags(LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION); 7841 req->SetLoadFlags(LOAD_ONLY_FROM_CACHE | LOAD_SKIP_CACHE_VALIDATION);
7804 7842
7805 req->Start(); 7843 req->Start();
7806 base::RunLoop().Run(); 7844 base::RunLoop().Run();
7807 7845
7808 EXPECT_FALSE(req->response_info().network_accessed); 7846 EXPECT_FALSE(req->response_info().network_accessed);
7809 } 7847 }
7810 7848
7811 // Test that a single job with a throttled priority completes 7849 // Test that a single job with a THROTTLED priority completes
7812 // correctly in the absence of contention. 7850 // correctly in the absence of contention.
7813 TEST_F(URLRequestTestHTTP, ThrottledPriority) { 7851 TEST_F(URLRequestTestHTTP, ThrottledPriority) {
7814 ASSERT_TRUE(http_test_server()->Start()); 7852 ASSERT_TRUE(http_test_server()->Start());
7815 7853
7816 TestDelegate d; 7854 TestDelegate d;
7817 GURL test_url(http_test_server()->GetURL("/")); 7855 GURL test_url(http_test_server()->GetURL("/"));
7818 std::unique_ptr<URLRequest> req( 7856 std::unique_ptr<URLRequest> req(
7819 default_context_.CreateRequest(test_url, THROTTLED, &d)); 7857 default_context_.CreateRequest(test_url, THROTTLED, &d));
7820 req->Start(); 7858 req->Start();
7821 base::RunLoop().Run(); 7859 base::RunLoop().Run();
7822 7860
7823 EXPECT_TRUE(req->status().is_success()); 7861 EXPECT_TRUE(req->status().is_success());
7824 } 7862 }
7825 7863
7864 // A class to hold state for responding to USER_NOTIFY callbacks from
7865 // BlockingNetworkDelegate. It also accepts a RunLoop that will be
7866 // signaled via QuitWhenIdle() when any request is blocked.
7867 //
7868 class NotificationCallbackHandler {
7869 public:
7870 // Default constructed object doesn't block anything.
7871 NotificationCallbackHandler() : run_loop_(nullptr) {}
7872
7873 void AddURLRequestToBlockList(const URLRequest* request) {
7874 requests_to_block_.insert(request);
7875 }
7876
7877 Error ShouldBlockRequest(const CompletionCallback& callback,
7878 const URLRequest* request) {
7879 if (requests_to_block_.find(request) == requests_to_block_.end()) {
7880 return OK;
7881 }
7882
7883 DCHECK(blocked_callbacks_.find(request) == blocked_callbacks_.end());
7884 blocked_callbacks_[request] = callback;
7885 if (run_loop_ && blocked_callbacks_.size() == requests_to_block_.size())
7886 run_loop_->QuitWhenIdle();
7887 return ERR_IO_PENDING;
7888 }
7889
7890 // Erases object's memory of blocked callbacks as a side effect.
7891 void GetBlockedCallbacks(
7892 std::map<const URLRequest*, CompletionCallback>* blocked_callbacks) {
7893 blocked_callbacks_.swap(*blocked_callbacks);
7894 }
7895
7896 // Set a RunLoop that, if non-null, will be signaled if any request
7897 // is blocked. It is the callers responsibility to make sure the
7898 // passed object lives past the destruction of this class or
7899 // next call to SetRunLoop().
7900 void SetRunLoop(base::RunLoop* run_loop) { run_loop_ = run_loop; }
7901
7902 private:
7903 std::set<const URLRequest*> requests_to_block_;
7904 std::map<const URLRequest*, CompletionCallback> blocked_callbacks_;
7905
7906 base::RunLoop* run_loop_;
7907
7908 DISALLOW_COPY_AND_ASSIGN(NotificationCallbackHandler);
7909 };
7910
7911 TEST_F(URLRequestTestHTTP, MultiThrottledPriority) {
7912 ASSERT_TRUE(http_test_server()->Start());
7913
7914 base::RunLoop run_until_request_blocked;
7915
7916 NotificationCallbackHandler notification_handler;
7917 notification_handler.SetRunLoop(&run_until_request_blocked);
7918 BlockingNetworkDelegate network_delegate(
7919 BlockingNetworkDelegate::USER_NOTIFY);
7920 network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED);
7921 network_delegate.set_notification_callback(
7922 base::Bind(&NotificationCallbackHandler::ShouldBlockRequest,
7923 // Both objects are owned by this function, and
7924 // |*network_delegate| will be destroyed first, so
7925 // it's safe to pass it an unretained pointer.
7926 base::Unretained(&notification_handler)));
7927
7928 TestURLRequestContext context(true);
7929 context.set_network_delegate(&network_delegate);
7930 context.Init();
7931
7932 // Use different test URLs to make sure all three requests turn into
7933 // HttpNetworkTransacations. Use different URLRequest::Delegates so that
7934 // the requests may be waited on separately.
7935 TestDelegate d1;
7936 std::unique_ptr<URLRequest> req1(context.CreateRequest(
7937 http_test_server()->GetURL("/echoall/l"), THROTTLED, &d1));
7938 notification_handler.AddURLRequestToBlockList(req1.get());
7939
7940 TestDelegate d2;
7941 std::unique_ptr<URLRequest> req2(context.CreateRequest(
7942 http_test_server()->GetURL("/echoall/2"), THROTTLED, &d2));
7943 notification_handler.AddURLRequestToBlockList(req2.get());
7944
7945 TestDelegate d3;
7946 std::unique_ptr<URLRequest> req3(context.CreateRequest(
7947 http_test_server()->GetURL("/echoall/3"), THROTTLED, &d3));
7948 req1->Start();
7949 req2->Start();
7950 req3->Start();
7951 run_until_request_blocked.Run();
7952 notification_handler.SetRunLoop(nullptr);
7953
7954 // The first two requests should be blocked based on the notification
7955 // callback, and their status should have blocked the third request
7956 // through throttling.
7957 EXPECT_TRUE(req1->status().is_io_pending());
7958 EXPECT_TRUE(req2->status().is_io_pending());
7959 EXPECT_TRUE(req3->status().is_io_pending());
7960
7961 std::map<const URLRequest*, CompletionCallback> blocked_callbacks;
7962 notification_handler.GetBlockedCallbacks(&blocked_callbacks);
7963 ASSERT_EQ(2u, blocked_callbacks.size());
7964 ASSERT_TRUE(blocked_callbacks.find(req1.get()) != blocked_callbacks.end());
7965 ASSERT_TRUE(blocked_callbacks.find(req2.get()) != blocked_callbacks.end());
7966
7967 // Unblocking one of the requests blocked on the notification callback
7968 // should let it complete, which should then let the third request
7969 // complete. Unblock the second request, then wait for the third
7970 // request to complete.
7971 // TODO(rdsmith): Find something to wait on other than the third
7972 // requests completion; if there's a bug in throttling, that will
7973 // result in this test hanging rather than failing quickly.
7974 d1.set_quit_on_complete(false);
7975 d2.set_quit_on_complete(false);
7976 d3.set_quit_on_complete(true);
7977 blocked_callbacks[req2.get()].Run(OK);
7978 base::RunLoop().Run();
7979
7980 notification_handler.GetBlockedCallbacks(&blocked_callbacks);
7981 EXPECT_EQ(0u, blocked_callbacks.size());
7982 EXPECT_TRUE(req1->status().is_io_pending());
7983 // req3 is only unblocked after req2 completes, so req2's
7984 // success is guaranteed at this point in the function.
7985 EXPECT_EQ(URLRequestStatus::SUCCESS, req2->status().status());
7986 EXPECT_EQ(URLRequestStatus::SUCCESS, req3->status().status());
7987 }
7988
7989 // Confirm that failing a request unblocks following requests.
7990 TEST_F(URLRequestTestHTTP, ThrottledFailure) {
7991 ASSERT_TRUE(http_test_server()->Start());
7992
7993 base::RunLoop run_until_request_blocked;
7994
7995 NotificationCallbackHandler notification_handler;
7996 notification_handler.SetRunLoop(&run_until_request_blocked);
7997 BlockingNetworkDelegate network_delegate(
7998 BlockingNetworkDelegate::USER_NOTIFY);
7999 network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED);
8000 network_delegate.set_notification_callback(
8001 base::Bind(&NotificationCallbackHandler::ShouldBlockRequest,
8002 // Both objects are owned by this function, and
8003 // |*network_delegate| will be destroyed first, so
8004 // it's safe to pass it an unretained pointer.
8005 base::Unretained(&notification_handler)));
8006
8007 TestURLRequestContext context(true);
8008 context.set_network_delegate(&network_delegate);
8009 context.Init();
8010
8011 // Use different test URLs to make sure all three requests turn into
8012 // HttpNetworkTransacations. Use different URLRequest::Delegates so that
8013 // the requests may be waited on separately.
8014 TestDelegate d1;
8015 std::unique_ptr<URLRequest> req1(context.CreateRequest(
8016 http_test_server()->GetURL("/echoall/l"), THROTTLED, &d1));
8017 notification_handler.AddURLRequestToBlockList(req1.get());
8018
8019 TestDelegate d2;
8020 std::unique_ptr<URLRequest> req2(context.CreateRequest(
8021 http_test_server()->GetURL("/echoall/2"), THROTTLED, &d2));
8022 notification_handler.AddURLRequestToBlockList(req2.get());
8023
8024 TestDelegate d3;
8025 std::unique_ptr<URLRequest> req3(context.CreateRequest(
8026 http_test_server()->GetURL("/echoall/3"), THROTTLED, &d3));
8027 req1->Start();
8028 req2->Start();
8029 req3->Start();
8030 run_until_request_blocked.Run();
8031 notification_handler.SetRunLoop(nullptr);
8032
8033 // The first two requests should be blocked based on the notification
8034 // callback, and their status should have blocked the third request
8035 // through throttling.
8036 EXPECT_TRUE(req1->status().is_io_pending());
8037 EXPECT_TRUE(req2->status().is_io_pending());
8038 EXPECT_TRUE(req3->status().is_io_pending());
8039
8040 std::map<const URLRequest*, CompletionCallback> blocked_callbacks;
8041 notification_handler.GetBlockedCallbacks(&blocked_callbacks);
8042 ASSERT_EQ(2u, blocked_callbacks.size());
8043 ASSERT_TRUE(blocked_callbacks.find(req1.get()) != blocked_callbacks.end());
8044 ASSERT_TRUE(blocked_callbacks.find(req2.get()) != blocked_callbacks.end());
8045
8046 // Confirm canceling one of the outstanding requests allows the
8047 // blocked request to complete.
8048
8049 // TODO(rdsmith): Find something to wait on other than the third
8050 // requests completion; if there's a bug in throttling, that will
8051 // result in this test hanging rather than failing quickly.
8052 d1.set_quit_on_complete(false);
8053 d2.set_quit_on_complete(false);
8054 d3.set_quit_on_complete(true);
8055 req2->Cancel();
8056 base::RunLoop().Run();
8057
8058 notification_handler.GetBlockedCallbacks(&blocked_callbacks);
8059 EXPECT_EQ(0u, blocked_callbacks.size());
8060 EXPECT_TRUE(req1->status().is_io_pending());
8061 EXPECT_EQ(URLRequestStatus::CANCELED, req2->status().status());
8062 EXPECT_EQ(URLRequestStatus::SUCCESS, req3->status().status());
8063 }
8064
8065 TEST_F(URLRequestTestHTTP, ThrottledRepriUnblock) {
8066 ASSERT_TRUE(http_test_server()->Start());
8067
8068 base::RunLoop run_until_request_blocked;
8069
8070 NotificationCallbackHandler notification_handler;
8071 notification_handler.SetRunLoop(&run_until_request_blocked);
8072 BlockingNetworkDelegate network_delegate(
8073 BlockingNetworkDelegate::USER_NOTIFY);
8074 network_delegate.set_block_on(BlockingNetworkDelegate::ON_HEADERS_RECEIVED);
8075 network_delegate.set_notification_callback(
8076 base::Bind(&NotificationCallbackHandler::ShouldBlockRequest,
8077 // Both objects are owned by this function, and
8078 // |*network_delegate| will be destroyed first, so
8079 // it's safe to pass it an unretained pointer.
8080 base::Unretained(&notification_handler)));
8081
8082 TestURLRequestContext context(true);
8083 context.set_network_delegate(&network_delegate);
8084 context.Init();
8085
8086 // Use different test URLs to make sure all three requests turn into
8087 // HttpNetworkTransacations. Use different URLRequest::Delegates so that
8088 // the requests may be waited on separately.
8089 TestDelegate d1;
8090 std::unique_ptr<URLRequest> req1(context.CreateRequest(
8091 http_test_server()->GetURL("/echoall/l"), THROTTLED, &d1));
8092 notification_handler.AddURLRequestToBlockList(req1.get());
8093
8094 TestDelegate d2;
8095 std::unique_ptr<URLRequest> req2(context.CreateRequest(
8096 http_test_server()->GetURL("/echoall/2"), THROTTLED, &d2));
8097 notification_handler.AddURLRequestToBlockList(req2.get());
8098
8099 TestDelegate d3;
8100 std::unique_ptr<URLRequest> req3(context.CreateRequest(
8101 http_test_server()->GetURL("/echoall/3"), THROTTLED, &d3));
8102 req1->Start();
8103 req2->Start();
8104 req3->Start();
8105 run_until_request_blocked.Run();
8106 notification_handler.SetRunLoop(nullptr);
8107
8108 // The first two requests should be blocked based on the notification
8109 // callback, and their status should have blocked the third request
8110 // through throttling.
8111 EXPECT_TRUE(req1->status().is_io_pending());
8112 EXPECT_TRUE(req2->status().is_io_pending());
8113 EXPECT_TRUE(req3->status().is_io_pending());
8114
8115 std::map<const URLRequest*, CompletionCallback> blocked_callbacks;
8116 notification_handler.GetBlockedCallbacks(&blocked_callbacks);
8117 ASSERT_EQ(2u, blocked_callbacks.size());
8118 ASSERT_TRUE(blocked_callbacks.find(req1.get()) != blocked_callbacks.end());
8119 ASSERT_TRUE(blocked_callbacks.find(req2.get()) != blocked_callbacks.end());
8120
8121 // Confirm raising the priority of the third request allows it to complete.
8122
8123 // TODO(rdsmith): Find something to wait on other than the third
8124 // requests completion; if there's a bug in throttling, that will
8125 // result in this test hanging rather than failing quickly.
8126 d1.set_quit_on_complete(false);
8127 d2.set_quit_on_complete(false);
8128 d3.set_quit_on_complete(true);
8129 req3->SetPriority(IDLE);
8130 base::RunLoop().Run();
8131
8132 notification_handler.GetBlockedCallbacks(&blocked_callbacks);
8133 EXPECT_EQ(0u, blocked_callbacks.size());
8134 EXPECT_TRUE(req1->status().is_io_pending());
8135 EXPECT_TRUE(req2->status().is_io_pending());
8136 EXPECT_EQ(URLRequestStatus::SUCCESS, req3->status().status());
8137 }
8138
7826 TEST_F(URLRequestTestHTTP, RawBodyBytesNoContentEncoding) { 8139 TEST_F(URLRequestTestHTTP, RawBodyBytesNoContentEncoding) {
7827 ASSERT_TRUE(http_test_server()->Start()); 8140 ASSERT_TRUE(http_test_server()->Start());
7828 8141
7829 TestDelegate d; 8142 TestDelegate d;
7830 std::unique_ptr<URLRequest> req(default_context().CreateRequest( 8143 std::unique_ptr<URLRequest> req(default_context().CreateRequest(
7831 http_test_server()->GetURL("/simple.html"), DEFAULT_PRIORITY, &d)); 8144 http_test_server()->GetURL("/simple.html"), DEFAULT_PRIORITY, &d));
7832 req->Start(); 8145 req->Start();
7833 base::RunLoop().Run(); 8146 base::RunLoop().Run();
7834 8147
7835 EXPECT_EQ(5, req->GetRawBodyBytes()); 8148 EXPECT_EQ(5, req->GetRawBodyBytes());
(...skipping 2414 matching lines...) Expand 10 before | Expand all | Expand 10 after
10250 AddTestInterceptor()->set_main_intercept_job(std::move(job)); 10563 AddTestInterceptor()->set_main_intercept_job(std::move(job));
10251 10564
10252 req->Start(); 10565 req->Start();
10253 req->Cancel(); 10566 req->Cancel();
10254 base::RunLoop().RunUntilIdle(); 10567 base::RunLoop().RunUntilIdle();
10255 EXPECT_EQ(ERR_ABORTED, d.request_status()); 10568 EXPECT_EQ(ERR_ABORTED, d.request_status());
10256 EXPECT_EQ(0, d.received_redirect_count()); 10569 EXPECT_EQ(0, d.received_redirect_count());
10257 } 10570 }
10258 10571
10259 } // namespace net 10572 } // namespace net
OLDNEW
« net/base/network_throttle_manager_impl.cc ('K') | « net/net.gypi ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698