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

Side by Side Diff: net/http/http_stream_factory_impl_job_controller_unittest.cc

Issue 2690393005: Cap the delay time for the main job when racing with QUIC for delayed (Closed)
Patch Set: use test task runner with a mock timer to verify ResumeMainJob(s) are invoked at the right time Created 3 years, 10 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
« no previous file with comments | « net/http/http_stream_factory_impl_job_controller.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) 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
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
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
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
OLDNEW
« no previous file with comments | « net/http/http_stream_factory_impl_job_controller.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698