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

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: remove invoke methods on Resume() expectations 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());
923 EXPECT_CALL(*job_factory_.main_job(), Resume()) 925 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
924 .Times(1) 926 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
925 .WillOnce(testing::DoAll( 927 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15));
926 testing::Invoke(testing::CreateFunctor( 928 EXPECT_FALSE(test_task_runner->HasPendingTask());
927 &JobControllerPeer::VerifyWaitingTimeForMainJob, job_controller_,
Ryan Hamilton 2017/02/16 00:30:58 Do we need this method any more? If not, feel free
Zhongyi Shi 2017/02/16 00:33:38 Not any more! I'll do a clean up CL to change thos
Ryan Hamilton 2017/02/16 00:39:26 \o/
928 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 929
934 EXPECT_TRUE(job_controller_->main_job()); 930 EXPECT_TRUE(job_controller_->main_job());
935 EXPECT_TRUE(job_controller_->alternative_job()); 931 EXPECT_TRUE(job_controller_->alternative_job());
936 932
937 // |alternative_job| fails but should not report status to Request. 933 // |alternative_job| fails but should not report status to Request.
938 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); 934 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
939 935
940 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_)); 936 EXPECT_FALSE(JobControllerPeer::main_job_is_blocked(job_controller_));
941 // OnStreamFailed will not resume the main job again since it's been resumed 937 // OnStreamFailed will post a task to resume the main job immediately but
942 // already. 938 // won't call Resume() on the main job since it's been resumed already.
943 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0); 939 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
944
945 job_controller_->OnStreamFailed(job_factory_.alternative_job(), 940 job_controller_->OnStreamFailed(job_factory_.alternative_job(),
946 ERR_NETWORK_CHANGED, SSLConfig()); 941 ERR_NETWORK_CHANGED, SSLConfig());
942 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
943 test_task_runner->RunUntilIdle();
944 }
945
946 // Test that main job is blocked for kMaxDelayTimeForMainJob(3s) if
947 // http_server_properties cached an inappropriate large srtt for the server,
948 // which would potentially delay the main job for a extremely long time in
949 // delayed tcp case.
950 TEST_F(HttpStreamFactoryImplJobControllerTest, DelayedTCPWithLargeSrtt) {
951 // Overrides the main thread's message loop with a mock tick clock so that we
952 // could verify the main job is resumed with appropriate delay.
953 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner;
954 // The max delay time should be in sync with .cc file.
955 base::TimeDelta kMaxDelayTimeForMainJob = base::TimeDelta::FromSeconds(3);
956 HangingResolver* resolver = new HangingResolver();
957 session_deps_.host_resolver.reset(resolver);
958
959 HttpRequestInfo request_info;
960 request_info.method = "GET";
961 request_info.url = GURL("https://www.google.com");
962
963 Initialize(request_info, false, false);
964
965 // Enable delayed TCP and set a extremely large time delay for waiting job.
966 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory();
967 test::QuicStreamFactoryPeer::SetDelayTcpRace(quic_stream_factory, true);
968 quic_stream_factory->set_require_confirmation(false);
969 ServerNetworkStats stats1;
970 stats1.srtt = base::TimeDelta::FromSeconds(100);
971 session_->http_server_properties()->SetServerNetworkStats(
972 url::SchemeHostPort(GURL("https://www.google.com")), stats1);
973
974 // Set a SPDY alternative service for the server.
975 url::SchemeHostPort server(request_info.url);
976 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
977 SetAlternativeService(request_info, alternative_service);
978
979 request_.reset(
980 job_controller_->Start(request_info, &request_delegate_, nullptr,
981 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM,
982 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
983 EXPECT_TRUE(job_controller_->main_job());
984 EXPECT_TRUE(job_controller_->alternative_job());
985 EXPECT_TRUE(job_controller_->main_job()->is_waiting());
986
987 // The alternative job stalls as host resolution hangs when creating the QUIC
988 // request and controller should resume the main job after delay.
989 EXPECT_TRUE(test_task_runner->HasPendingTask());
990 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
991
992 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
993 // Move forward the task runner with kMaxDelayTimeForMainJob and verify the
994 // main job is resumed.
995 test_task_runner->FastForwardBy(kMaxDelayTimeForMainJob);
996 EXPECT_FALSE(test_task_runner->HasPendingTask());
947 } 997 }
948 998
949 TEST_F(HttpStreamFactoryImplJobControllerTest, 999 TEST_F(HttpStreamFactoryImplJobControllerTest,
950 ResumeMainJobImmediatelyOnStreamFailed) { 1000 ResumeMainJobImmediatelyOnStreamFailed) {
1001 // Overrides the main thread's message loop with a mock tick clock so that we
1002 // could verify the main job is resumed with appropriate delay.
1003 base::ScopedMockTimeMessageLoopTaskRunner test_task_runner;
1004
951 HangingResolver* resolver = new HangingResolver(); 1005 HangingResolver* resolver = new HangingResolver();
952 session_deps_.host_resolver.reset(resolver); 1006 session_deps_.host_resolver.reset(resolver);
953 1007
954 HttpRequestInfo request_info; 1008 HttpRequestInfo request_info;
955 request_info.method = "GET"; 1009 request_info.method = "GET";
956 request_info.url = GURL("https://www.google.com"); 1010 request_info.url = GURL("https://www.google.com");
957 1011
958 Initialize(request_info, false, false); 1012 Initialize(request_info, false, false);
959 1013
960 // Enable delayed TCP and set time delay for waiting job. 1014 // Enable delayed TCP and set time delay for waiting job.
961 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory(); 1015 QuicStreamFactory* quic_stream_factory = session_->quic_stream_factory();
962 test::QuicStreamFactoryPeer::SetDelayTcpRace(quic_stream_factory, true); 1016 test::QuicStreamFactoryPeer::SetDelayTcpRace(quic_stream_factory, true);
963 quic_stream_factory->set_require_confirmation(false); 1017 quic_stream_factory->set_require_confirmation(false);
964 ServerNetworkStats stats1; 1018 ServerNetworkStats stats1;
965 stats1.srtt = base::TimeDelta::FromMicroseconds(10); 1019 stats1.srtt = base::TimeDelta::FromMicroseconds(10);
966 session_->http_server_properties()->SetServerNetworkStats( 1020 session_->http_server_properties()->SetServerNetworkStats(
967 url::SchemeHostPort(GURL("https://www.google.com")), stats1); 1021 url::SchemeHostPort(GURL("https://www.google.com")), stats1);
968 1022
969 // Set a SPDY alternative service for the server. 1023 // Set a SPDY alternative service for the server.
970 url::SchemeHostPort server(request_info.url); 1024 url::SchemeHostPort server(request_info.url);
971 AlternativeService alternative_service(kProtoQUIC, server.host(), 443); 1025 AlternativeService alternative_service(kProtoQUIC, server.host(), 443);
972 SetAlternativeService(request_info, alternative_service); 1026 SetAlternativeService(request_info, alternative_service);
973 1027
1028 // The alternative job stalls as host resolution hangs when creating the QUIC
1029 // request and controller should resume the main job with delay.
1030 // OnStreamFailed should resume the main job immediately.
974 request_.reset( 1031 request_.reset(
975 job_controller_->Start(request_info, &request_delegate_, nullptr, 1032 job_controller_->Start(request_info, &request_delegate_, nullptr,
976 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM, 1033 NetLogWithSource(), HttpStreamRequest::HTTP_STREAM,
977 DEFAULT_PRIORITY, SSLConfig(), SSLConfig())); 1034 DEFAULT_PRIORITY, SSLConfig(), SSLConfig()));
978 EXPECT_TRUE(job_controller_->main_job()); 1035 EXPECT_TRUE(job_controller_->main_job());
979 EXPECT_TRUE(job_controller_->alternative_job()); 1036 EXPECT_TRUE(job_controller_->alternative_job());
980 EXPECT_TRUE(job_controller_->main_job()->is_waiting()); 1037 EXPECT_TRUE(job_controller_->main_job()->is_waiting());
981 1038
1039 EXPECT_TRUE(test_task_runner->HasPendingTask());
1040 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
1041
982 // |alternative_job| fails but should not report status to Request. 1042 // |alternative_job| fails but should not report status to Request.
983 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0); 1043 EXPECT_CALL(request_delegate_, OnStreamFailed(_, _)).Times(0);
984
985 // The alternative job stalls as host resolution hangs when creating the QUIC
986 // request and controller should resume the main job with delay.
987 // OnStreamFailed should resume the main job immediately.
988 EXPECT_CALL(*job_factory_.main_job(), Resume())
989 .Times(1)
990 .WillOnce(Invoke(testing::CreateFunctor(
991 &JobControllerPeer::VerifyWaitingTimeForMainJob, job_controller_,
992 base::TimeDelta::FromMicroseconds(0))));
993
994 job_controller_->OnStreamFailed(job_factory_.alternative_job(), 1044 job_controller_->OnStreamFailed(job_factory_.alternative_job(),
995 ERR_NETWORK_CHANGED, SSLConfig()); 1045 ERR_NETWORK_CHANGED, SSLConfig());
1046 EXPECT_EQ(2u, test_task_runner->GetPendingTaskCount());
996 1047
997 base::RunLoop().RunUntilIdle(); 1048 // Verify the main job will be resumed immediately.
1049 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(1);
1050 // Execute tasks that have no remaining delay. Tasks with nonzero delay will
1051 // remain queued.
1052 test_task_runner->RunUntilIdle();
1053
1054 // Verify there is another task to resume main job with delay but should
1055 // not call Resume() on the main job as main job has been resumed.
1056 EXPECT_TRUE(test_task_runner->HasPendingTask());
1057 EXPECT_EQ(1u, test_task_runner->GetPendingTaskCount());
1058 EXPECT_CALL(*job_factory_.main_job(), Resume()).Times(0);
1059 test_task_runner->FastForwardBy(base::TimeDelta::FromMicroseconds(15));
1060 EXPECT_FALSE(test_task_runner->HasPendingTask());
998 } 1061 }
1062
999 // Verifies that the alternative proxy server job is not created if the URL 1063 // Verifies that the alternative proxy server job is not created if the URL
1000 // scheme is HTTPS. 1064 // scheme is HTTPS.
1001 TEST_F(HttpStreamFactoryImplJobControllerTest, HttpsURL) { 1065 TEST_F(HttpStreamFactoryImplJobControllerTest, HttpsURL) {
1002 // Using hanging resolver will cause the alternative job to hang indefinitely. 1066 // Using hanging resolver will cause the alternative job to hang indefinitely.
1003 HangingResolver* resolver = new HangingResolver(); 1067 HangingResolver* resolver = new HangingResolver();
1004 session_deps_.host_resolver.reset(resolver); 1068 session_deps_.host_resolver.reset(resolver);
1005 1069
1006 HttpRequestInfo request_info; 1070 HttpRequestInfo request_info;
1007 request_info.method = "GET"; 1071 request_info.method = "GET";
1008 request_info.url = GURL("https://mail.example.org/"); 1072 request_info.url = GURL("https://mail.example.org/");
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 Preconnect(kNumPreconects); 1361 Preconnect(kNumPreconects);
1298 // If experiment is enabled, only 1 stream is requested. 1362 // If experiment is enabled, only 1 stream is requested.
1299 EXPECT_EQ( 1363 EXPECT_EQ(
1300 (int)actual_num_connects, 1364 (int)actual_num_connects,
1301 HttpStreamFactoryImplJobPeer::GetNumStreams(job_controller_->main_job())); 1365 HttpStreamFactoryImplJobPeer::GetNumStreams(job_controller_->main_job()));
1302 base::RunLoop().RunUntilIdle(); 1366 base::RunLoop().RunUntilIdle();
1303 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_)); 1367 EXPECT_TRUE(HttpStreamFactoryImplPeer::IsJobControllerDeleted(factory_));
1304 } 1368 }
1305 1369
1306 } // namespace net 1370 } // 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