Chromium Code Reviews| 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 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
| 12 #include "base/test/histogram_tester.h" | 12 #include "base/test/histogram_tester.h" |
| 13 #include "base/test/scoped_feature_list.h" | 13 #include "base/test/scoped_feature_list.h" |
| 14 #include "base/test/scoped_mock_time_message_loop_task_runner.h" | |
| 14 #include "base/threading/platform_thread.h" | 15 #include "base/threading/platform_thread.h" |
| 15 #include "net/base/test_proxy_delegate.h" | 16 #include "net/base/test_proxy_delegate.h" |
| 16 #include "net/dns/mock_host_resolver.h" | 17 #include "net/dns/mock_host_resolver.h" |
| 17 #include "net/http/http_basic_stream.h" | 18 #include "net/http/http_basic_stream.h" |
| 18 #include "net/http/http_stream_factory_impl_request.h" | 19 #include "net/http/http_stream_factory_impl_request.h" |
| 19 #include "net/http/http_stream_factory_test_util.h" | 20 #include "net/http/http_stream_factory_test_util.h" |
| 20 #include "net/log/net_log_with_source.h" | 21 #include "net/log/net_log_with_source.h" |
| 21 #include "net/proxy/mock_proxy_resolver.h" | 22 #include "net/proxy/mock_proxy_resolver.h" |
| 22 #include "net/proxy/proxy_config_service_fixed.h" | 23 #include "net/proxy/proxy_config_service_fixed.h" |
| 23 #include "net/proxy/proxy_info.h" | 24 #include "net/proxy/proxy_info.h" |
| (...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 879 | 880 |
| 880 // Wait until OnStreamFailedCallback is executed on the alternative job. | 881 // Wait until OnStreamFailedCallback is executed on the alternative job. |
| 881 // Request shouldn't be notified as the main job is still pending status. | 882 // Request shouldn't be notified as the main job is still pending status. |
| 882 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 883 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
| 883 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); | 884 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1); |
| 884 | 885 |
| 885 base::RunLoop().RunUntilIdle(); | 886 base::RunLoop().RunUntilIdle(); |
| 886 } | 887 } |
| 887 | 888 |
| 888 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) { | 889 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCP) { |
| 890 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; | |
| 889 HangingResolver* resolver = new HangingResolver(); | 891 HangingResolver* resolver = new HangingResolver(); |
| 890 session_deps_.host_resolver.reset(resolver); | 892 session_deps_.host_resolver.reset(resolver); |
| 891 | 893 |
| 892 HttpRequestInfo request_info; | 894 HttpRequestInfo request_info; |
| 893 request_info.method = "GET"; | 895 request_info.method = "GET"; |
| 894 request_info.url = GURL("https://www.google.com"); | 896 request_info.url = GURL("https://www.google.com"); |
| 895 | 897 |
| 896 Initialize(request_info, false, false); | 898 Initialize(request_info, false, false); |
| 897 | 899 |
| 898 // Enable delayed TCP and set time delay for waiting job. | 900 // Enable delayed TCP and set time delay for waiting job. |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 912 request_.reset( | 914 request_.reset( |
| 913 job_controller_->Start(request_info, &request_delegate_, nullptr, | 915 job_controller_->Start(request_info, &request_delegate_, nullptr, |
| 914 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 916 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| 915 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | 917 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| 916 EXPECT_TRUE(job_controller_->main_job()); | 918 EXPECT_TRUE(job_controller_->main_job()); |
| 917 EXPECT_TRUE(job_controller_->alternative_job()); | 919 EXPECT_TRUE(job_controller_->alternative_job()); |
| 918 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | 920 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
| 919 | 921 |
| 920 // The alternative job stalls as host resolution hangs when creating the QUIC | 922 // The alternative job stalls as host resolution hangs when creating the QUIC |
| 921 // request and controller should resume the main job after delay. | 923 // request and controller should resume the main job after delay. |
| 922 base::RunLoop run_loop; | 924 EXPECT_TRUE(test_task_runner->HasPendingTask()); |
| 925 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | |
| 923 EXPECT_CALL(*job_factory_.main_job(), Resume()) | 926 EXPECT_CALL(*job_factory_.main_job(), Resume()) |
| 924 .Times(1) | 927 .Times(1) |
| 925 .WillOnce(testing::DoAll( | 928 .WillOnce(testing::Invoke(testing::CreateFunctor( |
| 926 testing::Invoke(testing::CreateFunctor( | 929 &JobControllerPeer::VerifyWaitingTimeForMainJob, job_controller_, |
| 927 &JobControllerPeer::VerifyWaitingTimeForMainJob, job_controller_, | 930 base::TimeDelta::FromMicroseconds(15)))); |
|
Ryan Hamilton
2017/02/15 23:37:57
You could probably drop the Invoke() part of this
Zhongyi Shi
2017/02/16 00:19:44
Done.
| |
| 928 base::TimeDelta::FromMicroseconds(15))), | 931 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); |
| 929 testing::Invoke([&run_loop]() { run_loop.Quit(); }))); | |
| 930 | |
| 931 // Wait for the main job to be resumed. | |
| 932 run_loop.Run(); | |
| 933 | 932 |
| 934 EXPECT_TRUE(job_controller_->main_job()); | 933 EXPECT_TRUE(job_controller_->main_job()); |
| 935 EXPECT_TRUE(job_controller_->alternative_job()); | 934 EXPECT_TRUE(job_controller_->alternative_job()); |
| 936 | 935 |
| 937 // |alternative_job| fails but should not report status to Request. | 936 // |alternative_job| fails but should not report status to Request. |
| 938 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 937 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
| 939 | 938 |
| 940 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); | 939 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); |
| 941 // OnStreamFailed will not resume the main job again since it's been resumed | 940 // OnStreamFailed will post a task to resume the main job immediately but |
| 942 // already. | 941 // won't call Resume() on the main job since it's been resumed already. |
| 943 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); | 942 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); |
| 944 | |
| 945 job_controller_->OnStreamFailed(job_factory_.alternative_job(), | 943 job_controller_->OnStreamFailed(job_factory_.alternative_job(), |
| 946 ERR_NETWORK_CHANGED, SSLConfig()); | 944 ERR_NETWORK_CHANGED, SSLConfig()); |
| 945 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | |
| 946 test_task_runner->RunUntilIdle(); | |
| 947 } | |
| 948 | |
| 949 // Test that main job is blocked for kMaxDelayTimeForMainJob(3s) if | |
| 950 // http_server_properties cached an inappropriate large srtt for the server, | |
| 951 // which would potentially delay the main job for a extremely long time in | |
| 952 // delayed tcp case. | |
| 953 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPWithLargeSrtt) { | |
| 954 // Overrides the main thread's message loop with a mock tick clock so that we | |
| 955 // could verify the main job is resumed with appropriate delay. | |
| 956 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; | |
| 957 // The max delay time should be in sync with .cc file. | |
| 958 base::TimeDelta kMaxDelayTimeForMainJob = base::TimeDelta::FromSeconds(3); | |
| 959 HangingResolver* resolver = new HangingResolver(); | |
| 960 session_deps_.host_resolver.reset(resolver); | |
| 961 | |
| 962 HttpRequestInfo request_info; | |
| 963 request_info.method = "GET"; | |
| 964 request_info.url = GURL("https://www.google.com"); | |
| 965 | |
| 966 Initialize(request_info, false, false); | |
| 967 | |
| 968 // Enable delayed TCP and set a extremely large time delay for waiting job. | |
| 969 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); | |
| 970 test::QuicStreamFactoryPeer::SetDelayTcpRace(quic_stream_factory, true); | |
| 971 quic_stream_factory->set_require_confirmation(false); | |
| 972 ServerNetworkStats stats1; | |
| 973 stats1.srtt = base::TimeDelta::FromSeconds(100); | |
| 974 session_->http_server_properties()->SetServerNetworkStats( | |
| 975 url::SchemeHostPort(GURL("https://www.google.com")), stats1); | |
| 976 | |
| 977 // Set a SPDY alternative service for the server. | |
| 978 url::SchemeHostPort server(request_info.url); | |
| 979 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | |
| 980 SetAlternativeService(request_info, alternative_service); | |
| 981 | |
| 982 request_.reset( | |
| 983 job_controller_->Start(request_info, &request_delegate_, nullptr, | |
| 984 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | |
| 985 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | |
| 986 EXPECT_TRUE(job_controller_->main_job()); | |
| 987 EXPECT_TRUE(job_controller_->alternative_job()); | |
| 988 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | |
| 989 | |
| 990 // The alternative job stalls as host resolution hangs when creating the QUIC | |
| 991 // request and controller should resume the main job after delay. | |
| 992 EXPECT_TRUE(test_task_runner->HasPendingTask()); | |
| 993 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | |
| 994 | |
| 995 EXPECT_CALL(*job_factory_.main_job(), Resume()) | |
| 996 .Times(1) | |
| 997 .WillOnce(testing::Invoke(testing::CreateFunctor( | |
| 998 &JobControllerPeer::VerifyWaitingTimeForMainJob, job_controller_, | |
| 999 kMaxDelayTimeForMainJob))); | |
| 1000 // Move forward the task runner with kMaxDelayTimeForMainJob and verify the | |
| 1001 // main job is resumed. | |
| 1002 test_task_runner->FastForwardBy(kMaxDelayTimeForMainJob); | |
| 1003 | |
| 1004 EXPECT_FALSE(test_task_runner->HasPendingTask()); | |
| 947 } | 1005 } |
| 948 | 1006 |
| 949 TEST_F(HttpStreamFactoryImplJobControllerTest, | 1007 TEST_F(HttpStreamFactoryImplJobControllerTest, |
| 950 ResumeMainJobImmediatelyOnStreamFailed) { | 1008 ResumeMainJobImmediatelyOnStreamFailed) { |
| 1009 // Overrides the main thread's message loop with a mock tick clock so that we | |
| 1010 // could verify the main job is resumed with appropriate delay. | |
| 1011 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner; | |
| 1012 | |
| 951 HangingResolver* resolver = new HangingResolver(); | 1013 HangingResolver* resolver = new HangingResolver(); |
| 952 session_deps_.host_resolver.reset(resolver); | 1014 session_deps_.host_resolver.reset(resolver); |
| 953 | 1015 |
| 954 HttpRequestInfo request_info; | 1016 HttpRequestInfo request_info; |
| 955 request_info.method = "GET"; | 1017 request_info.method = "GET"; |
| 956 request_info.url = GURL("https://www.google.com"); | 1018 request_info.url = GURL("https://www.google.com"); |
| 957 | 1019 |
| 958 Initialize(request_info, false, false); | 1020 Initialize(request_info, false, false); |
| 959 | 1021 |
| 960 // Enable delayed TCP and set time delay for waiting job. | 1022 // Enable delayed TCP and set time delay for waiting job. |
| 961 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); | 1023 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); |
| 962 test::QuicStreamFactoryPeer::SetDelayTcpRace(quic_stream_factory, true); | 1024 test::QuicStreamFactoryPeer::SetDelayTcpRace(quic_stream_factory, true); |
| 963 quic_stream_factory->set_require_confirmation(false); | 1025 quic_stream_factory->set_require_confirmation(false); |
| 964 ServerNetworkStats stats1; | 1026 ServerNetworkStats stats1; |
| 965 stats1.srtt = base::TimeDelta::FromMicroseconds(10); | 1027 stats1.srtt = base::TimeDelta::FromMicroseconds(10); |
| 966 session_->http_server_properties()->SetServerNetworkStats( | 1028 session_->http_server_properties()->SetServerNetworkStats( |
| 967 url::SchemeHostPort(GURL("https://www.google.com")), stats1); | 1029 url::SchemeHostPort(GURL("https://www.google.com")), stats1); |
| 968 | 1030 |
| 969 // Set a SPDY alternative service for the server. | 1031 // Set a SPDY alternative service for the server. |
| 970 url::SchemeHostPort server(request_info.url); | 1032 url::SchemeHostPort server(request_info.url); |
| 971 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); | 1033 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
| 972 SetAlternativeService(request_info, alternative_service); | 1034 SetAlternativeService(request_info, alternative_service); |
| 973 | 1035 |
| 1036 // The alternative job stalls as host resolution hangs when creating the QUIC | |
| 1037 // request and controller should resume the main job with delay. | |
| 1038 // OnStreamFailed should resume the main job immediately. | |
| 974 request_.reset( | 1039 request_.reset( |
| 975 job_controller_->Start(request_info, &request_delegate_, nullptr, | 1040 job_controller_->Start(request_info, &request_delegate_, nullptr, |
| 976 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, | 1041 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, |
| 977 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); | 1042 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); |
| 978 EXPECT_TRUE(job_controller_->main_job()); | 1043 EXPECT_TRUE(job_controller_->main_job()); |
| 979 EXPECT_TRUE(job_controller_->alternative_job()); | 1044 EXPECT_TRUE(job_controller_->alternative_job()); |
| 980 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); | 1045 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); |
| 981 | 1046 |
| 1047 EXPECT_TRUE(test_task_runner->HasPendingTask()); | |
| 1048 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | |
| 1049 | |
| 982 // |alternative_job| fails but should not report status to Request. | 1050 // |alternative_job| fails but should not report status to Request. |
| 983 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); | 1051 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); |
| 984 | 1052 job_controller_->OnStreamFailed(job_factory_.alternative_job(), |
| 985 // The alternative job stalls as host resolution hangs when creating the QUIC | 1053 ERR_NETWORK_CHANGED, SSLConfig()); |
| 986 // request and controller should resume the main job with delay. | 1054 EXPECT_EQ(2u, test_task_runner->GetPendingTaskCount()); |
| 987 // OnStreamFailed should resume the main job immediately. | 1055 // Verify the main job will be resumed immediately. |
| 988 EXPECT_CALL(*job_factory_.main_job(), Resume()) | 1056 EXPECT_CALL(*job_factory_.main_job(), Resume()) |
| 989 .Times(1) | 1057 .Times(1) |
| 990 .WillOnce(Invoke(testing::CreateFunctor( | 1058 .WillOnce(Invoke(testing::CreateFunctor( |
| 991 &JobControllerPeer::VerifyWaitingTimeForMainJob, job_controller_, | 1059 &JobControllerPeer::VerifyWaitingTimeForMainJob, job_controller_, |
| 992 base::TimeDelta::FromMicroseconds(0)))); | 1060 base::TimeDelta::FromMicroseconds(0)))); |
| 993 | 1061 |
| 994 job_controller_->OnStreamFailed(job_factory_.alternative_job(), | 1062 // Execute tasks that have no remaining delay. Tasks with nonzero delay will |
| 995 ERR_NETWORK_CHANGED, SSLConfig()); | 1063 // remain queued. |
| 1064 test_task_runner->RunUntilIdle(); | |
| 996 | 1065 |
| 997 base::RunLoop().RunUntilIdle(); | 1066 // Verify there should another task to resume main job with delay but should |
| 1067 // not call Resume() on the main job as main job has been resumed. | |
| 1068 EXPECT_TRUE(test_task_runner->HasPendingTask()); | |
| 1069 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount()); | |
| 1070 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); | |
| 1071 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15)); | |
| 1072 EXPECT_FALSE(test_task_runner->HasPendingTask()); | |
| 998 } | 1073 } |
| 999 // Verifies that the alternative proxy server job is not created if the URL | 1074 // Verifies that the alternative proxy server job is not created if the URL |
| 1000 // scheme is HTTPS. | 1075 // scheme is HTTPS. |
| 1001 TEST_F(HttpStreamFactoryImplJobControllerTest, HttpsURL) { | 1076 TEST_F(HttpStreamFactoryImplJobControllerTest, HttpsURL) { |
| 1002 // Using hanging resolver will cause the alternative job to hang indefinitely. | 1077 // Using hanging resolver will cause the alternative job to hang indefinitely. |
| 1003 HangingResolver* resolver = new HangingResolver(); | 1078 HangingResolver* resolver = new HangingResolver(); |
| 1004 session_deps_.host_resolver.reset(resolver); | 1079 session_deps_.host_resolver.reset(resolver); |
| 1005 | 1080 |
| 1006 HttpRequestInfo request_info; | 1081 HttpRequestInfo request_info; |
| 1007 request_info.method = "GET"; | 1082 request_info.method = "GET"; |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1297 Preconnect(kNumPreconects); | 1372 Preconnect(kNumPreconects); |
| 1298 // If experiment is enabled, only 1 stream is requested. | 1373 // If experiment is enabled, only 1 stream is requested. |
| 1299 EXPECT_EQ( | 1374 EXPECT_EQ( |
| 1300 (int)actual_num_connects, | 1375 (int)actual_num_connects, |
| 1301 HttpStreamFactoryImplJobPeer::GetNumStreams(job_controller_->main_job())); | 1376 HttpStreamFactoryImplJobPeer::GetNumStreams(job_controller_->main_job())); |
| 1302 base::RunLoop().RunUntilIdle(); | 1377 base::RunLoop().RunUntilIdle(); |
| 1303 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); | 1378 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); |
| 1304 } | 1379 } |
| 1305 | 1380 |
| 1306 } // namespace net | 1381 } // namespace net |
| OLD | NEW |