| OLD | NEW |
| 1 // Copyright (c) 2016 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2016 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/http/http_stream_factory_impl_job_controller.h" | 5 #include "net/http/http_stream_factory_impl_job_controller.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
| 10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| 11 #include "base/test/histogram_tester.h" | 11 #include "base/test/histogram_tester.h" |
| 12 #include "base/test/scoped_mock_time_message_loop_task_runner.h" |
| 12 #include "base/threading/platform_thread.h" | 13 #include "base/threading/platform_thread.h" |
| 13 #include "net/base/test_proxy_delegate.h" | 14 #include "net/base/test_proxy_delegate.h" |
| 14 #include "net/dns/mock_host_resolver.h" | 15 #include "net/dns/mock_host_resolver.h" |
| 15 #include "net/http/http_basic_stream.h" | 16 #include "net/http/http_basic_stream.h" |
| 16 #include "net/http/http_stream_factory_impl_request.h" | 17 #include "net/http/http_stream_factory_impl_request.h" |
| 17 #include "net/http/http_stream_factory_test_util.h" | 18 #include "net/http/http_stream_factory_test_util.h" |
| 18 #include "net/log/net_log_with_source.h" | 19 #include "net/log/net_log_with_source.h" |
| 19 #include "net/proxy/mock_proxy_resolver.h" | 20 #include "net/proxy/mock_proxy_resolver.h" |
| 20 #include "net/proxy/proxy_config_service_fixed.h" | 21 #include "net/proxy/proxy_config_service_fixed.h" |
| 21 #include "net/proxy/proxy_info.h" | 22 #include "net/proxy/proxy_info.h" |
| (...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 806 | 807 |
| 807 // Wait until OnStreamFailedCallback is executed on the alternative job. | 808 // Wait until OnStreamFailedCallback is executed on the alternative job. |
| 808 // Request shouldn't be notified as the main job is still pending status. | 809 // Request shouldn't be notified as the main job is still pending status. |
| 809 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 810 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
| 810 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); | 811 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
| 811 | 812 |
| 812 base::RunLoop().RunUntilIdle(); | 813 base::RunLoop().RunUntilIdle(); |
| 813 } | 814 } |
| 814 | 815 |
| 815 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) { | 816 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) { |
| 817 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; |
| 816 HangingResolver* resolver = new HangingResolver(); | 818 HangingResolver* resolver = new HangingResolver(); |
| 817 session_deps_.host_resolver.reset(resolver); | 819 session_deps_.host_resolver.reset(resolver); |
| 818 | 820 |
| 819 Initialize(false); | 821 Initialize(false); |
| 820 | 822 |
| 821 // Enable delayed TCP and set time delay for waiting job. | 823 // Enable delayed TCP and set time delay for waiting job. |
| 822 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); | 824 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); |
| 823 test::QuicStreamFactoryPeer::SetDelayTcpRace(quic_stream_factory, true); | 825 test::QuicStreamFactoryPeer::SetDelayTcpRace(quic_stream_factory, true); |
| 824 quic_stream_factory->set_require_confirmation(false); | 826 quic_stream_factory->set_require_confirmation(false); |
| 825 ServerNetworkStats stats1; | 827 ServerNetworkStats stats1; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 839 request_.reset( | 841 request_.reset( |
| 840 job_controller_->Start(request_info, &request_delegate_, nullptr, | 842 job_controller_->Start(request_info, &request_delegate_, nullptr, |
| 841 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 843 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| 842 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | 844 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| 843 EXPECT_TRUE(job_controller_->main_job()); | 845 EXPECT_TRUE(job_controller_->main_job()); |
| 844 EXPECT_TRUE(job_controller_->alternative_job()); | 846 EXPECT_TRUE(job_controller_->alternative_job()); |
| 845 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | 847 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
| 846 | 848 |
| 847 // The alternative job stalls as host resolution hangs when creating the QUIC | 849 // The alternative job stalls as host resolution hangs when creating the QUIC |
| 848 // request and controller should resume the main job after delay. | 850 // request and controller should resume the main job after delay. |
| 849 base::RunLoop run_loop; | 851 EXPECT_TRUE(test_task_runner->HasPendingTask()); |
| 850 EXPECT_CALL(*job_factory_.main_job(), Resume()) | 852 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
| 851 .Times(1) | 853 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
| 852 .WillOnce(testing::DoAll( | 854 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); |
| 853 testing::Invoke(testing::CreateFunctor( | 855 EXPECT_FALSE(test_task_runner->HasPendingTask()); |
| 854 &JobControllerPeer::VerifyWaitingTimeForMainJob, job_controller_, | |
| 855 base::TimeDelta::FromMicroseconds(15))), | |
| 856 testing::Invoke([&run_loop]() { run_loop.Quit(); }))); | |
| 857 | |
| 858 // Wait for the main job to be resumed. | |
| 859 run_loop.Run(); | |
| 860 | 856 |
| 861 EXPECT_TRUE(job_controller_->main_job()); | 857 EXPECT_TRUE(job_controller_->main_job()); |
| 862 EXPECT_TRUE(job_controller_->alternative_job()); | 858 EXPECT_TRUE(job_controller_->alternative_job()); |
| 863 | 859 |
| 864 // |alternative_job| fails but should not report status to Request. | 860 // |alternative_job| fails but should not report status to Request. |
| 865 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 861 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
| 866 | 862 |
| 867 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); | 863 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
| 868 // OnStreamFailed will not resume the main job again since it's been resumed | 864 // OnStreamFailed will post a task to resume the main job immediately but |
| 869 // already. | 865 // won't call Resume() on the main job since it's been resumed already. |
| 870 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); | 866 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); |
| 871 | |
| 872 job_controller_->OnStreamFailed(job_factory_.alternative_job(), | 867 job_controller_->OnStreamFailed(job_factory_.alternative_job(), |
| 873 ERR_NETWORK_CHANGED, SSLConfig()); | 868 ERR_NETWORK_CHANGED, SSLConfig()); |
| 869 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
| 870 test_task_runner->RunUntilIdle(); |
| 871 } |
| 872 |
| 873 // Test that main job is blocked for kMaxDelayTimeForMainJob(3s) if |
| 874 // http_server_properties cached an inappropriate large srtt for the server, |
| 875 // which would potentially delay the main job for a extremely long time in |
| 876 // delayed tcp case. |
| 877 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPWithLargeSrtt) { |
| 878 // Overrides the main thread's message loop with a mock tick clock so that we |
| 879 // could verify the main job is resumed with appropriate delay. |
| 880 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; |
| 881 // The max delay time should be in sync with .cc file. |
| 882 base::TimeDelta kMaxDelayTimeForMainJob = base::TimeDelta::FromSeconds(3); |
| 883 HangingResolver* resolver = new HangingResolver(); |
| 884 session_deps_.host_resolver.reset(resolver); |
| 885 |
| 886 HttpRequestInfo request_info; |
| 887 request_info.method = "GET"; |
| 888 request_info.url = GURL("https://www.google.com"); |
| 889 |
| 890 Initialize(false); |
| 891 |
| 892 // Enable delayed TCP and set a extremely large time delay for waiting job. |
| 893 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); |
| 894 test::QuicStreamFactoryPeer::SetDelayTcpRace(quic_stream_factory, true); |
| 895 quic_stream_factory->set_require_confirmation(false); |
| 896 ServerNetworkStats stats1; |
| 897 stats1.srtt = base::TimeDelta::FromSeconds(100); |
| 898 session_->http_server_properties()->SetServerNetworkStats( |
| 899 url::SchemeHostPort(GURL("https://www.google.com")), stats1); |
| 900 |
| 901 // Set a SPDY alternative service for the server. |
| 902 url::SchemeHostPort server(request_info.url); |
| 903 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 904 SetAlternativeService(request_info, alternative_service); |
| 905 |
| 906 request_.reset( |
| 907 job_controller_->Start(request_info, &request_delegate_, nullptr, |
| 908 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| 909 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| 910 EXPECT_TRUE(job_controller_->main_job()); |
| 911 EXPECT_TRUE(job_controller_->alternative_job()); |
| 912 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
| 913 |
| 914 // The alternative job stalls as host resolution hangs when creating the QUIC |
| 915 // request and controller should resume the main job after delay. |
| 916 EXPECT_TRUE(test_task_runner->HasPendingTask()); |
| 917 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
| 918 |
| 919 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
| 920 // Move forward the task runner with kMaxDelayTimeForMainJob and verify the |
| 921 // main job is resumed. |
| 922 test_task_runner->FastForwardBy(kMaxDelayTimeForMainJob); |
| 923 EXPECT_FALSE(test_task_runner->HasPendingTask()); |
| 874 } | 924 } |
| 875 | 925 |
| 876 TEST_F(HttpStreamFactoryImplJobControllerTest, | 926 TEST_F(HttpStreamFactoryImplJobControllerTest, |
| 877 ResumeMainJobImmediatelyOnStreamFailed) { | 927 ResumeMainJobImmediatelyOnStreamFailed) { |
| 928 // Overrides the main thread's message loop with a mock tick clock so that we |
| 929 // could verify the main job is resumed with appropriate delay. |
| 930 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; |
| 931 |
| 878 HangingResolver* resolver = new HangingResolver(); | 932 HangingResolver* resolver = new HangingResolver(); |
| 879 session_deps_.host_resolver.reset(resolver); | 933 session_deps_.host_resolver.reset(resolver); |
| 880 | 934 |
| 881 HttpRequestInfo request_info; | 935 HttpRequestInfo request_info; |
| 882 request_info.method = "GET"; | 936 request_info.method = "GET"; |
| 883 request_info.url = GURL("https://www.google.com"); | 937 request_info.url = GURL("https://www.google.com"); |
| 884 | 938 |
| 885 Initialize(false); | 939 Initialize(false); |
| 886 | 940 |
| 887 // Enable delayed TCP and set time delay for waiting job. | 941 // Enable delayed TCP and set time delay for waiting job. |
| 888 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); | 942 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); |
| 889 test::QuicStreamFactoryPeer::SetDelayTcpRace(quic_stream_factory, true); | 943 test::QuicStreamFactoryPeer::SetDelayTcpRace(quic_stream_factory, true); |
| 890 quic_stream_factory->set_require_confirmation(false); | 944 quic_stream_factory->set_require_confirmation(false); |
| 891 ServerNetworkStats stats1; | 945 ServerNetworkStats stats1; |
| 892 stats1.srtt = base::TimeDelta::FromMicroseconds(10); | 946 stats1.srtt = base::TimeDelta::FromMicroseconds(10); |
| 893 session_->http_server_properties()->SetServerNetworkStats( | 947 session_->http_server_properties()->SetServerNetworkStats( |
| 894 url::SchemeHostPort(GURL("https://www.google.com")), stats1); | 948 url::SchemeHostPort(GURL("https://www.google.com")), stats1); |
| 895 | 949 |
| 896 // Set a SPDY alternative service for the server. | 950 // Set a SPDY alternative service for the server. |
| 897 url::SchemeHostPort server(request_info.url); | 951 url::SchemeHostPort server(request_info.url); |
| 898 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 952 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 899 SetAlternativeService(request_info, alternative_service); | 953 SetAlternativeService(request_info, alternative_service); |
| 900 | 954 |
| 955 // The alternative job stalls as host resolution hangs when creating the QUIC |
| 956 // request and controller should resume the main job with delay. |
| 957 // OnStreamFailed should resume the main job immediately. |
| 901 request_.reset( | 958 request_.reset( |
| 902 job_controller_->Start(request_info, &request_delegate_, nullptr, | 959 job_controller_->Start(request_info, &request_delegate_, nullptr, |
| 903 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 960 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| 904 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | 961 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| 905 EXPECT_TRUE(job_controller_->main_job()); | 962 EXPECT_TRUE(job_controller_->main_job()); |
| 906 EXPECT_TRUE(job_controller_->alternative_job()); | 963 EXPECT_TRUE(job_controller_->alternative_job()); |
| 907 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | 964 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
| 908 | 965 |
| 966 EXPECT_TRUE(test_task_runner->HasPendingTask()); |
| 967 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
| 968 |
| 909 // |alternative_job| fails but should not report status to Request. | 969 // |alternative_job| fails but should not report status to Request. |
| 910 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 970 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
| 911 | |
| 912 // The alternative job stalls as host resolution hangs when creating the QUIC | |
| 913 // request and controller should resume the main job with delay. | |
| 914 // OnStreamFailed should resume the main job immediately. | |
| 915 EXPECT_CALL(*job_factory_.main_job(), Resume()) | |
| 916 .Times(1) | |
| 917 .WillOnce(Invoke(testing::CreateFunctor( | |
| 918 &JobControllerPeer::VerifyWaitingTimeForMainJob, job_controller_, | |
| 919 base::TimeDelta::FromMicroseconds(0)))); | |
| 920 | |
| 921 job_controller_->OnStreamFailed(job_factory_.alternative_job(), | 971 job_controller_->OnStreamFailed(job_factory_.alternative_job(), |
| 922 ERR_NETWORK_CHANGED, SSLConfig()); | 972 ERR_NETWORK_CHANGED, SSLConfig()); |
| 973 EXPECT_EQ(2u, test_task_runner->GetPendingTaskCount()); |
| 923 | 974 |
| 924 base::RunLoop().RunUntilIdle(); | 975 // Verify the main job will be resumed immediately. |
| 976 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
| 977 // Execute tasks that have no remaining delay. Tasks with nonzero delay will |
| 978 // remain queued. |
| 979 test_task_runner->RunUntilIdle(); |
| 980 |
| 981 // Verify there is another task to resume main job with delay but should |
| 982 // not call Resume() on the main job as main job has been resumed. |
| 983 EXPECT_TRUE(test_task_runner->HasPendingTask()); |
| 984 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); |
| 985 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); |
| 986 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); |
| 987 EXPECT_FALSE(test_task_runner->HasPendingTask()); |
| 925 } | 988 } |
| 989 |
| 926 // Verifies that the alternative proxy server job is not created if the URL | 990 // Verifies that the alternative proxy server job is not created if the URL |
| 927 // scheme is HTTPS. | 991 // scheme is HTTPS. |
| 928 TEST_F(HttpStreamFactoryImplJobControllerTest, HttpsURL) { | 992 TEST_F(HttpStreamFactoryImplJobControllerTest, HttpsURL) { |
| 929 // Using hanging resolver will cause the alternative job to hang indefinitely. | 993 // Using hanging resolver will cause the alternative job to hang indefinitely. |
| 930 HangingResolver* resolver = new HangingResolver(); | 994 HangingResolver* resolver = new HangingResolver(); |
| 931 session_deps_.host_resolver.reset(resolver); | 995 session_deps_.host_resolver.reset(resolver); |
| 932 | 996 |
| 933 Initialize(true); | 997 Initialize(true); |
| 934 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); | 998 EXPECT_TRUE(test_proxy_delegate()->alternative_proxy_server().is_quic()); |
| 935 | 999 |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1126 // Reset the request as it's been successfully served. | 1190 // Reset the request as it's been successfully served. |
| 1127 request_.reset(); | 1191 request_.reset(); |
| 1128 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 1192 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 1129 | 1193 |
| 1130 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage", | 1194 histogram_tester.ExpectUniqueSample("Net.QuicAlternativeProxy.Usage", |
| 1131 2 /* ALTERNATIVE_PROXY_USAGE_LOST_RACE */, | 1195 2 /* ALTERNATIVE_PROXY_USAGE_LOST_RACE */, |
| 1132 1); | 1196 1); |
| 1133 } | 1197 } |
| 1134 | 1198 |
| 1135 } // namespace net | 1199 } // namespace net |
| OLD | NEW |