OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/proxy_resolver_v8_tracing.h" | 5 #include "net/proxy/proxy_resolver_v8_tracing.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 MockCachingHostResolver host_resolver; | 580 MockCachingHostResolver host_resolver; |
581 MockBindings mock_bindings(&host_resolver); | 581 MockBindings mock_bindings(&host_resolver); |
582 | 582 |
583 host_resolver.rules()->AddSimulatedFailure("*"); | 583 host_resolver.rules()->AddSimulatedFailure("*"); |
584 | 584 |
585 scoped_ptr<ProxyResolverV8Tracing> resolver = | 585 scoped_ptr<ProxyResolverV8Tracing> resolver = |
586 CreateResolver(mock_bindings.CreateBindings(), "dns.js"); | 586 CreateResolver(mock_bindings.CreateBindings(), "dns.js"); |
587 | 587 |
588 const size_t kNumRequests = 5; | 588 const size_t kNumRequests = 5; |
589 ProxyInfo proxy_info[kNumRequests]; | 589 ProxyInfo proxy_info[kNumRequests]; |
590 ProxyResolver::RequestHandle request[kNumRequests]; | 590 scoped_ptr<ProxyResolver::Request> request[kNumRequests]; |
591 | 591 |
592 for (size_t i = 0; i < kNumRequests; ++i) { | 592 for (size_t i = 0; i < kNumRequests; ++i) { |
593 resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info[i], | 593 resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info[i], |
594 base::Bind(&CrashCallback), &request[i], | 594 base::Bind(&CrashCallback), &request[i], |
595 mock_bindings.CreateBindings()); | 595 mock_bindings.CreateBindings()); |
596 } | 596 } |
597 | 597 |
598 for (size_t i = 0; i < kNumRequests; ++i) { | 598 for (size_t i = 0; i < kNumRequests; ++i) { |
599 resolver->CancelRequest(request[i]); | 599 request[i].reset(); |
600 } | 600 } |
601 } | 601 } |
602 | 602 |
603 // Note the execution order for this test can vary. Since multiple | 603 // Note the execution order for this test can vary. Since multiple |
604 // threads are involved, the cancellation may be received a different | 604 // threads are involved, the cancellation may be received a different |
605 // times. | 605 // times. |
606 TEST_F(ProxyResolverV8TracingTest, CancelSome) { | 606 TEST_F(ProxyResolverV8TracingTest, CancelSome) { |
607 MockCachingHostResolver host_resolver; | 607 MockCachingHostResolver host_resolver; |
608 MockBindings mock_bindings(&host_resolver); | 608 MockBindings mock_bindings(&host_resolver); |
609 | 609 |
610 host_resolver.rules()->AddSimulatedFailure("*"); | 610 host_resolver.rules()->AddSimulatedFailure("*"); |
611 | 611 |
612 scoped_ptr<ProxyResolverV8Tracing> resolver = | 612 scoped_ptr<ProxyResolverV8Tracing> resolver = |
613 CreateResolver(mock_bindings.CreateBindings(), "dns.js"); | 613 CreateResolver(mock_bindings.CreateBindings(), "dns.js"); |
614 | 614 |
615 ProxyInfo proxy_info1; | 615 ProxyInfo proxy_info1; |
616 ProxyInfo proxy_info2; | 616 ProxyInfo proxy_info2; |
617 ProxyResolver::RequestHandle request1; | 617 scoped_ptr<ProxyResolver::Request> request1; |
618 ProxyResolver::RequestHandle request2; | 618 scoped_ptr<ProxyResolver::Request> request2; |
619 TestCompletionCallback callback; | 619 TestCompletionCallback callback; |
620 | 620 |
621 resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info1, | 621 resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info1, |
622 base::Bind(&CrashCallback), &request1, | 622 base::Bind(&CrashCallback), &request1, |
623 mock_bindings.CreateBindings()); | 623 mock_bindings.CreateBindings()); |
624 resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info2, | 624 resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info2, |
625 callback.callback(), &request2, | 625 callback.callback(), &request2, |
626 mock_bindings.CreateBindings()); | 626 mock_bindings.CreateBindings()); |
627 | 627 |
628 resolver->CancelRequest(request1); | 628 request1.reset(); |
629 | 629 |
630 EXPECT_EQ(OK, callback.WaitForResult()); | 630 EXPECT_EQ(OK, callback.WaitForResult()); |
631 } | 631 } |
632 | 632 |
633 // Cancel a request after it has finished running on the worker thread, and has | 633 // Cancel a request after it has finished running on the worker thread, and has |
634 // posted a task the completion task back to origin thread. | 634 // posted a task the completion task back to origin thread. |
635 TEST_F(ProxyResolverV8TracingTest, CancelWhilePendingCompletionTask) { | 635 TEST_F(ProxyResolverV8TracingTest, CancelWhilePendingCompletionTask) { |
636 MockCachingHostResolver host_resolver; | 636 MockCachingHostResolver host_resolver; |
637 MockBindings mock_bindings(&host_resolver); | 637 MockBindings mock_bindings(&host_resolver); |
638 | 638 |
639 host_resolver.rules()->AddSimulatedFailure("*"); | 639 host_resolver.rules()->AddSimulatedFailure("*"); |
640 | 640 |
641 scoped_ptr<ProxyResolverV8Tracing> resolver = | 641 scoped_ptr<ProxyResolverV8Tracing> resolver = |
642 CreateResolver(mock_bindings.CreateBindings(), "error.js"); | 642 CreateResolver(mock_bindings.CreateBindings(), "error.js"); |
643 | 643 |
644 ProxyInfo proxy_info1; | 644 ProxyInfo proxy_info1; |
645 ProxyInfo proxy_info2; | 645 ProxyInfo proxy_info2; |
646 ProxyResolver::RequestHandle request1; | 646 scoped_ptr<ProxyResolver::Request> request1; |
647 ProxyResolver::RequestHandle request2; | 647 scoped_ptr<ProxyResolver::Request> request2; |
648 TestCompletionCallback callback; | 648 TestCompletionCallback callback; |
649 | 649 |
650 resolver->GetProxyForURL(GURL("http://throw-an-error/"), &proxy_info1, | 650 resolver->GetProxyForURL(GURL("http://throw-an-error/"), &proxy_info1, |
651 base::Bind(&CrashCallback), &request1, | 651 base::Bind(&CrashCallback), &request1, |
652 mock_bindings.CreateBindings()); | 652 mock_bindings.CreateBindings()); |
653 | 653 |
654 // Wait until the first request has finished running on the worker thread. | 654 // Wait until the first request has finished running on the worker thread. |
655 // Cancel the first request, while it is running its completion task on | 655 // Cancel the first request, while it is running its completion task on |
656 // the origin thread. | 656 // the origin thread. Reset deletes Request opject which cancels the request. |
657 mock_bindings.RunOnError(base::Bind(&ProxyResolverV8Tracing::CancelRequest, | 657 mock_bindings.RunOnError( |
658 base::Unretained(resolver.get()), | 658 base::Bind(&scoped_ptr<ProxyResolver::Request>::reset, |
659 request1)); | 659 base::Unretained(&request1), nullptr)); |
660 | 660 |
661 // Start another request, to make sure it is able to complete. | 661 // Start another request, to make sure it is able to complete. |
662 resolver->GetProxyForURL(GURL("http://i-have-no-idea-what-im-doing/"), | 662 resolver->GetProxyForURL(GURL("http://i-have-no-idea-what-im-doing/"), |
663 &proxy_info2, callback.callback(), &request2, | 663 &proxy_info2, callback.callback(), &request2, |
664 mock_bindings.CreateBindings()); | 664 mock_bindings.CreateBindings()); |
665 | 665 |
666 EXPECT_EQ(OK, callback.WaitForResult()); | 666 EXPECT_EQ(OK, callback.WaitForResult()); |
667 | 667 |
668 EXPECT_EQ("i-approve-this-message:42", proxy_info2.proxy_server().ToURI()); | 668 EXPECT_EQ("i-approve-this-message:42", proxy_info2.proxy_server().ToURI()); |
669 } | 669 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 // when the request has an outstanding DNS request in flight. | 739 // when the request has an outstanding DNS request in flight. |
740 TEST_F(ProxyResolverV8TracingTest, CancelWhileOutstandingNonBlockingDns) { | 740 TEST_F(ProxyResolverV8TracingTest, CancelWhileOutstandingNonBlockingDns) { |
741 BlockableHostResolver host_resolver; | 741 BlockableHostResolver host_resolver; |
742 MockBindings mock_bindings(&host_resolver); | 742 MockBindings mock_bindings(&host_resolver); |
743 | 743 |
744 scoped_ptr<ProxyResolverV8Tracing> resolver = | 744 scoped_ptr<ProxyResolverV8Tracing> resolver = |
745 CreateResolver(mock_bindings.CreateBindings(), "dns.js"); | 745 CreateResolver(mock_bindings.CreateBindings(), "dns.js"); |
746 | 746 |
747 ProxyInfo proxy_info1; | 747 ProxyInfo proxy_info1; |
748 ProxyInfo proxy_info2; | 748 ProxyInfo proxy_info2; |
749 ProxyResolver::RequestHandle request1; | 749 scoped_ptr<ProxyResolver::Request> request1; |
750 ProxyResolver::RequestHandle request2; | 750 scoped_ptr<ProxyResolver::Request> request2; |
751 | 751 |
752 resolver->GetProxyForURL(GURL("http://foo/req1"), &proxy_info1, | 752 resolver->GetProxyForURL(GURL("http://foo/req1"), &proxy_info1, |
753 base::Bind(&CrashCallback), &request1, | 753 base::Bind(&CrashCallback), &request1, |
754 mock_bindings.CreateBindings()); | 754 mock_bindings.CreateBindings()); |
755 | 755 |
756 host_resolver.WaitUntilRequestIsReceived(); | 756 host_resolver.WaitUntilRequestIsReceived(); |
757 | 757 |
758 resolver->GetProxyForURL(GURL("http://foo/req2"), &proxy_info2, | 758 resolver->GetProxyForURL(GURL("http://foo/req2"), &proxy_info2, |
759 base::Bind(&CrashCallback), &request2, | 759 base::Bind(&CrashCallback), &request2, |
760 mock_bindings.CreateBindings()); | 760 mock_bindings.CreateBindings()); |
761 | 761 |
762 host_resolver.WaitUntilRequestIsReceived(); | 762 host_resolver.WaitUntilRequestIsReceived(); |
763 | 763 |
764 resolver->CancelRequest(request1); | 764 request1.reset(); |
765 resolver->CancelRequest(request2); | 765 request2.reset(); |
766 | 766 |
767 EXPECT_EQ(2, host_resolver.num_cancelled_requests()); | 767 EXPECT_EQ(2, host_resolver.num_cancelled_requests()); |
768 | 768 |
769 // After leaving this scope, the ProxyResolver is destroyed. | 769 // After leaving this scope, the ProxyResolver is destroyed. |
770 // This should not cause any problems, as the outstanding work | 770 // This should not cause any problems, as the outstanding work |
771 // should have been cancelled. | 771 // should have been cancelled. |
772 } | 772 } |
773 | 773 |
774 void CancelRequestAndPause(ProxyResolverV8Tracing* resolver, | 774 void CancelRequestAndPause(scoped_ptr<ProxyResolver::Request>* request) { |
775 ProxyResolver::RequestHandle request) { | 775 request->reset(); |
776 resolver->CancelRequest(request); | |
777 | 776 |
778 // Sleep for a little bit. This makes it more likely for the worker | 777 // Sleep for a little bit. This makes it more likely for the worker |
779 // thread to have returned from its call, and serves as a regression | 778 // thread to have returned from its call, and serves as a regression |
780 // test for http://crbug.com/173373. | 779 // test for http://crbug.com/173373. |
781 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(30)); | 780 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(30)); |
782 } | 781 } |
783 | 782 |
784 // In non-blocking mode, the worker thread actually does block for | 783 // In non-blocking mode, the worker thread actually does block for |
785 // a short time to see if the result is in the DNS cache. Test | 784 // a short time to see if the result is in the DNS cache. Test |
786 // cancellation while the worker thread is waiting on this event. | 785 // cancellation while the worker thread is waiting on this event. |
787 TEST_F(ProxyResolverV8TracingTest, CancelWhileBlockedInNonBlockingDns) { | 786 TEST_F(ProxyResolverV8TracingTest, CancelWhileBlockedInNonBlockingDns) { |
788 BlockableHostResolver host_resolver; | 787 BlockableHostResolver host_resolver; |
789 MockBindings mock_bindings(&host_resolver); | 788 MockBindings mock_bindings(&host_resolver); |
790 | 789 |
791 scoped_ptr<ProxyResolverV8Tracing> resolver = | 790 scoped_ptr<ProxyResolverV8Tracing> resolver = |
792 CreateResolver(mock_bindings.CreateBindings(), "dns.js"); | 791 CreateResolver(mock_bindings.CreateBindings(), "dns.js"); |
793 | 792 |
794 ProxyInfo proxy_info; | 793 ProxyInfo proxy_info; |
795 ProxyResolver::RequestHandle request; | 794 scoped_ptr<ProxyResolver::Request> request; |
796 | 795 |
797 resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info, | 796 resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info, |
798 base::Bind(&CrashCallback), &request, | 797 base::Bind(&CrashCallback), &request, |
799 mock_bindings.CreateBindings()); | 798 mock_bindings.CreateBindings()); |
800 | 799 |
801 host_resolver.SetAction( | 800 host_resolver.SetAction(base::Bind(CancelRequestAndPause, &request)); |
802 base::Bind(CancelRequestAndPause, resolver.get(), request)); | |
803 | 801 |
804 host_resolver.WaitUntilRequestIsReceived(); | 802 host_resolver.WaitUntilRequestIsReceived(); |
805 } | 803 } |
806 | 804 |
807 // Cancel the request while there is a pending DNS request, however before | 805 // Cancel the request while there is a pending DNS request, however before |
808 // the request is sent to the host resolver. | 806 // the request is sent to the host resolver. |
809 TEST_F(ProxyResolverV8TracingTest, CancelWhileBlockedInNonBlockingDns2) { | 807 TEST_F(ProxyResolverV8TracingTest, CancelWhileBlockedInNonBlockingDns2) { |
810 MockCachingHostResolver host_resolver; | 808 MockCachingHostResolver host_resolver; |
811 MockBindings mock_bindings(&host_resolver); | 809 MockBindings mock_bindings(&host_resolver); |
812 | 810 |
813 scoped_ptr<ProxyResolverV8Tracing> resolver = | 811 scoped_ptr<ProxyResolverV8Tracing> resolver = |
814 CreateResolver(mock_bindings.CreateBindings(), "dns.js"); | 812 CreateResolver(mock_bindings.CreateBindings(), "dns.js"); |
815 | 813 |
816 ProxyInfo proxy_info; | 814 ProxyInfo proxy_info; |
817 ProxyResolver::RequestHandle request; | 815 scoped_ptr<ProxyResolver::Request> request; |
818 | 816 |
819 resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info, | 817 resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info, |
820 base::Bind(&CrashCallback), &request, | 818 base::Bind(&CrashCallback), &request, |
821 mock_bindings.CreateBindings()); | 819 mock_bindings.CreateBindings()); |
822 | 820 |
823 // Wait a bit, so the DNS task has hopefully been posted. The test will | 821 // Wait a bit, so the DNS task has hopefully been posted. The test will |
824 // work whatever the delay is here, but it is most useful if the delay | 822 // work whatever the delay is here, but it is most useful if the delay |
825 // is large enough to allow a task to be posted back. | 823 // is large enough to allow a task to be posted back. |
826 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10)); | 824 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10)); |
827 resolver->CancelRequest(request); | 825 request.reset(); |
828 | 826 |
829 EXPECT_EQ(0u, host_resolver.num_resolve()); | 827 EXPECT_EQ(0u, host_resolver.num_resolve()); |
830 } | 828 } |
831 | 829 |
832 TEST_F(ProxyResolverV8TracingTest, | 830 TEST_F(ProxyResolverV8TracingTest, |
833 CancelCreateResolverWhileOutstandingBlockingDns) { | 831 CancelCreateResolverWhileOutstandingBlockingDns) { |
834 BlockableHostResolver host_resolver; | 832 BlockableHostResolver host_resolver; |
835 MockBindings mock_bindings(&host_resolver); | 833 MockBindings mock_bindings(&host_resolver); |
836 | 834 |
837 scoped_ptr<ProxyResolverV8TracingFactory> factory( | 835 scoped_ptr<ProxyResolverV8TracingFactory> factory( |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 proxy_uri.substr(0, proxy_uri.find(':') + 1)); | 1013 proxy_uri.substr(0, proxy_uri.find(':') + 1)); |
1016 } else { | 1014 } else { |
1017 NOTREACHED(); | 1015 NOTREACHED(); |
1018 } | 1016 } |
1019 } | 1017 } |
1020 } | 1018 } |
1021 | 1019 |
1022 } // namespace | 1020 } // namespace |
1023 | 1021 |
1024 } // namespace net | 1022 } // namespace net |
OLD | NEW |