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

Side by Side Diff: net/quic/quic_stream_factory_test.cc

Issue 1327923002: Migrates QUIC sessions to a new network when old network is (about to be) disconnected. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@home
Patch Set: Naming fixes. Created 5 years 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/quic/quic_stream_factory.h" 5 #include "net/quic/quic_stream_factory.h"
6 6
7 #include "base/run_loop.h" 7 #include "base/run_loop.h"
8 #include "base/strings/string_util.h" 8 #include "base/strings/string_util.h"
9 #include "base/thread_task_runner_handle.h" 9 #include "base/thread_task_runner_handle.h"
10 #include "net/base/test_data_directory.h" 10 #include "net/base/test_data_directory.h"
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 class MockQuicServerInfoFactory : public QuicServerInfoFactory { 109 class MockQuicServerInfoFactory : public QuicServerInfoFactory {
110 public: 110 public:
111 MockQuicServerInfoFactory() {} 111 MockQuicServerInfoFactory() {}
112 ~MockQuicServerInfoFactory() override {} 112 ~MockQuicServerInfoFactory() override {}
113 113
114 QuicServerInfo* GetForServer(const QuicServerId& server_id) override { 114 QuicServerInfo* GetForServer(const QuicServerId& server_id) override {
115 return new MockQuicServerInfo(server_id); 115 return new MockQuicServerInfo(server_id);
116 } 116 }
117 }; 117 };
118 118
119 class MockNetworkChangeNotifier : public NetworkChangeNotifier {
120 public:
121 MockNetworkChangeNotifier() : force_network_handles_supported_(false) {}
122
123 ConnectionType GetCurrentConnectionType() const override {
124 return CONNECTION_UNKNOWN;
125 }
126
127 void ForceNetworkHandlesSupported() {
128 force_network_handles_supported_ = true;
129 }
130
131 bool AreNetworkHandlesCurrentlySupported() const override {
132 return force_network_handles_supported_;
133 }
134
135 void SetConnectedNetworksList(NetworkList network_list) {
136 connected_networks_ = network_list;
137 }
138
139 void GetCurrentConnectedNetworks(NetworkList* network_list) const override {
140 network_list->clear();
141 *network_list = connected_networks_;
142 }
143
144 private:
145 bool force_network_handles_supported_;
146 NetworkChangeNotifier::NetworkList connected_networks_;
147 };
148
149 // Class to replace existing NetworkChangeNotifier singleton with a
150 // MockNetworkChangeNotifier for a test. To use, simply create a
151 // ScopedMockNetworkChangeNotifier object in the test.
152 class ScopedMockNetworkChangeNotifier {
153 public:
154 ScopedMockNetworkChangeNotifier()
155 : mock_network_change_notifier_(nullptr),
156 disable_network_change_notifier_for_tests_(nullptr) {
157 // Disable existing NetworkChangeNotifier first, then create mock.
158 disable_network_change_notifier_for_tests_ =
159 new NetworkChangeNotifier::DisableForTest();
160 mock_network_change_notifier_ = new MockNetworkChangeNotifier();
Ryan Hamilton 2015/12/18 22:00:19 I think you can initialize these in the initialize
Jana 2015/12/21 23:10:19 Done.
161 }
162
163 ~ScopedMockNetworkChangeNotifier() {
164 delete mock_network_change_notifier_;
165 delete disable_network_change_notifier_for_tests_;
Ryan Hamilton 2015/12/18 22:00:19 Can you use a scoped_ptr<> instead of needing to e
Jana 2015/12/21 23:10:19 Done.
166 }
167
168 MockNetworkChangeNotifier* mock_network_change_notifier() {
169 return mock_network_change_notifier_;
170 }
171
172 private:
173 MockNetworkChangeNotifier* mock_network_change_notifier_;
174 NetworkChangeNotifier::DisableForTest*
175 disable_network_change_notifier_for_tests_;
176 };
177
119 class QuicStreamFactoryTest : public ::testing::TestWithParam<TestParams> { 178 class QuicStreamFactoryTest : public ::testing::TestWithParam<TestParams> {
120 protected: 179 protected:
121 QuicStreamFactoryTest() 180 QuicStreamFactoryTest()
122 : random_generator_(0), 181 : random_generator_(0),
123 clock_(new MockClock()), 182 clock_(new MockClock()),
124 runner_(new TestTaskRunner(clock_)), 183 runner_(new TestTaskRunner(clock_)),
125 maker_(GetParam().version, 0, clock_, kDefaultServerHostName), 184 maker_(GetParam().version, 0, clock_, kDefaultServerHostName),
126 cert_verifier_(CertVerifier::CreateDefault()), 185 cert_verifier_(CertVerifier::CreateDefault()),
127 channel_id_service_( 186 channel_id_service_(
128 new ChannelIDService(new DefaultChannelIDStore(nullptr), 187 new ChannelIDService(new DefaultChannelIDStore(nullptr),
(...skipping 12 matching lines...) Expand all
141 prefer_aes_(false), 200 prefer_aes_(false),
142 max_number_of_lossy_connections_(0), 201 max_number_of_lossy_connections_(0),
143 packet_loss_threshold_(1.0f), 202 packet_loss_threshold_(1.0f),
144 max_disabled_reasons_(3), 203 max_disabled_reasons_(3),
145 threshold_timeouts_with_open_streams_(2), 204 threshold_timeouts_with_open_streams_(2),
146 threshold_public_resets_post_handshake_(2), 205 threshold_public_resets_post_handshake_(2),
147 receive_buffer_size_(0), 206 receive_buffer_size_(0),
148 delay_tcp_race_(false), 207 delay_tcp_race_(false),
149 store_server_configs_in_properties_(false), 208 store_server_configs_in_properties_(false),
150 close_sessions_on_ip_change_(false), 209 close_sessions_on_ip_change_(false),
151 idle_connection_timeout_seconds_(kIdleConnectionTimeoutSeconds) { 210 idle_connection_timeout_seconds_(kIdleConnectionTimeoutSeconds),
211 migrate_sessions_on_network_change_(false) {
152 clock_->AdvanceTime(QuicTime::Delta::FromSeconds(1)); 212 clock_->AdvanceTime(QuicTime::Delta::FromSeconds(1));
153 } 213 }
154 214
155 void Initialize() { 215 void Initialize() {
156 factory_.reset(new QuicStreamFactory( 216 factory_.reset(new QuicStreamFactory(
157 &host_resolver_, &socket_factory_, http_server_properties_.GetWeakPtr(), 217 &host_resolver_, &socket_factory_, http_server_properties_.GetWeakPtr(),
158 cert_verifier_.get(), nullptr, channel_id_service_.get(), 218 cert_verifier_.get(), nullptr, channel_id_service_.get(),
159 &transport_security_state_, cert_transparency_verifier_.get(), 219 &transport_security_state_, cert_transparency_verifier_.get(),
160 /*SocketPerformanceWatcherFactory*/ nullptr, 220 /*SocketPerformanceWatcherFactory*/ nullptr,
161 &crypto_client_stream_factory_, &random_generator_, clock_, 221 &crypto_client_stream_factory_, &random_generator_, clock_,
162 kDefaultMaxPacketSize, std::string(), 222 kDefaultMaxPacketSize, std::string(),
163 SupportedVersions(GetParam().version), enable_port_selection_, 223 SupportedVersions(GetParam().version), enable_port_selection_,
164 always_require_handshake_confirmation_, disable_connection_pooling_, 224 always_require_handshake_confirmation_, disable_connection_pooling_,
165 load_server_info_timeout_srtt_multiplier_, enable_connection_racing_, 225 load_server_info_timeout_srtt_multiplier_, enable_connection_racing_,
166 enable_non_blocking_io_, disable_disk_cache_, prefer_aes_, 226 enable_non_blocking_io_, disable_disk_cache_, prefer_aes_,
167 max_number_of_lossy_connections_, packet_loss_threshold_, 227 max_number_of_lossy_connections_, packet_loss_threshold_,
168 max_disabled_reasons_, threshold_timeouts_with_open_streams_, 228 max_disabled_reasons_, threshold_timeouts_with_open_streams_,
169 threshold_public_resets_post_handshake_, receive_buffer_size_, 229 threshold_public_resets_post_handshake_, receive_buffer_size_,
170 delay_tcp_race_, store_server_configs_in_properties_, 230 delay_tcp_race_, store_server_configs_in_properties_,
171 close_sessions_on_ip_change_, idle_connection_timeout_seconds_, 231 close_sessions_on_ip_change_, idle_connection_timeout_seconds_,
172 QuicTagVector())); 232 migrate_sessions_on_network_change_, QuicTagVector()));
173 factory_->set_require_confirmation(false); 233 factory_->set_require_confirmation(false);
174 factory_->set_quic_server_info_factory(new MockQuicServerInfoFactory()); 234 factory_->set_quic_server_info_factory(new MockQuicServerInfoFactory());
175 } 235 }
176 236
177 bool HasActiveSession(const HostPortPair& host_port_pair) { 237 bool HasActiveSession(const HostPortPair& host_port_pair) {
178 return QuicStreamFactoryPeer::HasActiveSession(factory_.get(), 238 return QuicStreamFactoryPeer::HasActiveSession(factory_.get(),
179 host_port_pair); 239 host_port_pair);
180 } 240 }
181 241
182 scoped_ptr<QuicHttpStream> CreateFromSession( 242 scoped_ptr<QuicHttpStream> CreateFromSession(
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 return verify_details; 327 return verify_details;
268 } 328 }
269 329
270 void NotifyIPAddressChanged() { 330 void NotifyIPAddressChanged() {
271 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests(); 331 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
272 // For thread safety, the NCN queues tasks to do the actual notifications, 332 // For thread safety, the NCN queues tasks to do the actual notifications,
273 // so we need to spin the message loop so the notification is delivered. 333 // so we need to spin the message loop so the notification is delivered.
274 base::MessageLoop::current()->RunUntilIdle(); 334 base::MessageLoop::current()->RunUntilIdle();
275 } 335 }
276 336
337 void NotifySpecificNetworkChange(
338 NetworkChangeNotifier::NetworkChangeType type,
339 NetworkChangeNotifier::NetworkHandle network) {
340 NetworkChangeNotifier::NotifyObserversOfSpecificNetworkChangeForTests(
341 type, network);
342 // For thread safety, the NCN queues tasks to do the actual notifications,
Ryan Hamilton 2015/12/18 22:00:19 I'd remove the first part of this (about thread sa
Jana 2015/12/21 23:10:19 I'm following the same pattern as is done with del
343 // so we need to spin the message loop so the notification is delivered.
344 base::MessageLoop::current()->RunUntilIdle();
345 }
346
277 MockHostResolver host_resolver_; 347 MockHostResolver host_resolver_;
278 DeterministicMockClientSocketFactory socket_factory_; 348 DeterministicMockClientSocketFactory socket_factory_;
279 MockCryptoClientStreamFactory crypto_client_stream_factory_; 349 MockCryptoClientStreamFactory crypto_client_stream_factory_;
280 MockRandom random_generator_; 350 MockRandom random_generator_;
281 MockClock* clock_; // Owned by factory_. 351 MockClock* clock_; // Owned by factory_.
282 scoped_refptr<TestTaskRunner> runner_; 352 scoped_refptr<TestTaskRunner> runner_;
283 QuicTestPacketMaker maker_; 353 QuicTestPacketMaker maker_;
284 HttpServerPropertiesImpl http_server_properties_; 354 HttpServerPropertiesImpl http_server_properties_;
285 scoped_ptr<CertVerifier> cert_verifier_; 355 scoped_ptr<CertVerifier> cert_verifier_;
286 scoped_ptr<ChannelIDService> channel_id_service_; 356 scoped_ptr<ChannelIDService> channel_id_service_;
(...skipping 17 matching lines...) Expand all
304 int max_number_of_lossy_connections_; 374 int max_number_of_lossy_connections_;
305 double packet_loss_threshold_; 375 double packet_loss_threshold_;
306 int max_disabled_reasons_; 376 int max_disabled_reasons_;
307 int threshold_timeouts_with_open_streams_; 377 int threshold_timeouts_with_open_streams_;
308 int threshold_public_resets_post_handshake_; 378 int threshold_public_resets_post_handshake_;
309 int receive_buffer_size_; 379 int receive_buffer_size_;
310 bool delay_tcp_race_; 380 bool delay_tcp_race_;
311 bool store_server_configs_in_properties_; 381 bool store_server_configs_in_properties_;
312 bool close_sessions_on_ip_change_; 382 bool close_sessions_on_ip_change_;
313 int idle_connection_timeout_seconds_; 383 int idle_connection_timeout_seconds_;
384 bool migrate_sessions_on_network_change_;
314 }; 385 };
315 386
316 INSTANTIATE_TEST_CASE_P(Version, 387 INSTANTIATE_TEST_CASE_P(Version,
317 QuicStreamFactoryTest, 388 QuicStreamFactoryTest,
318 ::testing::ValuesIn(GetTestParams())); 389 ::testing::ValuesIn(GetTestParams()));
319 390
320 TEST_P(QuicStreamFactoryTest, Create) { 391 TEST_P(QuicStreamFactoryTest, Create) {
321 Initialize(); 392 Initialize();
322 393
323 MockRead reads[] = { 394 MockRead reads[] = {
(...skipping 962 matching lines...) Expand 10 before | Expand all | Expand 10 after
1286 EXPECT_EQ(OK, callback_.WaitForResult()); 1357 EXPECT_EQ(OK, callback_.WaitForResult());
1287 stream = request2.ReleaseStream(); 1358 stream = request2.ReleaseStream();
1288 stream.reset(); // Will reset stream 3. 1359 stream.reset(); // Will reset stream 3.
1289 1360
1290 EXPECT_TRUE(socket_data.AllReadDataConsumed()); 1361 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1291 EXPECT_TRUE(socket_data.AllWriteDataConsumed()); 1362 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1292 EXPECT_TRUE(socket_data2.AllReadDataConsumed()); 1363 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1293 EXPECT_TRUE(socket_data2.AllWriteDataConsumed()); 1364 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
1294 } 1365 }
1295 1366
1367 TEST_P(QuicStreamFactoryTest, OnNetworkChange) {
Ryan Hamilton 2015/12/18 22:00:19 Does this test all of the various combinations? Ac
Jana 2015/12/21 23:10:19 No it doesn't. I had meant to add them before send
1368 ScopedMockNetworkChangeNotifier scoped_mock_ncn;
1369 MockNetworkChangeNotifier* mock_ncn =
1370 scoped_mock_ncn.mock_network_change_notifier();
1371 mock_ncn->ForceNetworkHandlesSupported();
1372 NetworkChangeNotifier::NetworkList connected_networks = {1, 2};
1373 mock_ncn->SetConnectedNetworksList(connected_networks);
1374
1375 migrate_sessions_on_network_change_ = true;
1376 Initialize();
1377
1378 // Set up first socket data provider
1379 MockRead reads[] = {
1380 MockRead(ASYNC, OK, 0) // EOF
1381 };
1382
1383 DeterministicSocketData socket_data(reads, arraysize(reads), nullptr, 0);
1384 socket_data.StopAfter(1);
1385 socket_factory_.AddSocketDataProvider(&socket_data);
1386
1387 // Set up second socket data provider that is used after migration.
1388 MockRead reads1[] = {
1389 MockRead(ASYNC, OK, 0) // EOF
1390 };
1391 scoped_ptr<QuicEncryptedPacket> ping(
1392 maker_.MakePingPacket(1, /*include_version=*/true));
1393 MockWrite writes1[] = {
1394 MockWrite(ASYNC, ping->data(), ping->length(), 1),
1395 };
1396 DeterministicSocketData socket_data1(reads1, arraysize(reads1), writes1,
1397 arraysize(writes1));
1398 socket_data1.StopAfter(1);
1399 socket_factory_.AddSocketDataProvider(&socket_data1);
1400
1401 // Create request and QuicHttpStream.
1402 QuicStreamRequest request(factory_.get());
1403 EXPECT_EQ(ERR_IO_PENDING,
1404 request.Request(host_port_pair_, privacy_mode_,
1405 /*cert_verify_flags=*/0, host_port_pair_.host(),
1406 "GET", net_log_, callback_.callback()));
1407
1408 EXPECT_EQ(OK, callback_.WaitForResult());
1409 scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
1410 EXPECT_TRUE(stream.get());
1411
1412 // Cause QUIC stream to be created.
1413 HttpRequestInfo request_info;
1414 EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
1415 net_log_, CompletionCallback()));
1416
1417 // Ensure that session is alive and active.
1418 QuicChromiumClientSession* session =
1419 QuicStreamFactoryPeer::GetActiveSession(factory_.get(), host_port_pair_);
1420 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
1421 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1422
1423 // Cause connection migration to happen. This should cause a PING frame
1424 // to be emitted.
1425 NotifySpecificNetworkChange(NetworkChangeNotifier::SOON_TO_DISCONNECT, 1);
1426
1427 // The session should now be marked as going away. Ensure that
1428 // while it is still alive, it is no longer active.
1429 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
1430 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1431 EXPECT_EQ(1u, session->GetNumActiveStreams());
1432
1433 // Create a new request for the same destination and verify that a
1434 // new session is created.
1435 MockRead reads2[] = {
1436 MockRead(ASYNC, OK, 0) // EOF
1437 };
1438 DeterministicSocketData socket_data2(reads2, arraysize(reads2), nullptr, 0);
1439 socket_data2.StopAfter(1);
1440 socket_factory_.AddSocketDataProvider(&socket_data2);
1441 QuicStreamRequest request2(factory_.get());
1442 EXPECT_EQ(ERR_IO_PENDING,
1443 request2.Request(host_port_pair_, privacy_mode_,
1444 /*cert_verify_flags=*/0, host_port_pair_.host(),
1445 "GET", net_log_, callback_.callback()));
1446 EXPECT_EQ(OK, callback_.WaitForResult());
1447 scoped_ptr<QuicHttpStream> stream2 = request2.ReleaseStream();
1448 EXPECT_TRUE(stream2.get());
1449
1450 EXPECT_TRUE(
1451 QuicStreamFactoryPeer::HasActiveSession(factory_.get(), host_port_pair_));
1452 EXPECT_NE(session, QuicStreamFactoryPeer::GetActiveSession(factory_.get(),
1453 host_port_pair_));
1454 EXPECT_EQ(true,
1455 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
1456
1457 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1458 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1459 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
1460 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
1461 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1462 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
1463 }
1464
1296 TEST_P(QuicStreamFactoryTest, OnSSLConfigChanged) { 1465 TEST_P(QuicStreamFactoryTest, OnSSLConfigChanged) {
1297 Initialize(); 1466 Initialize();
1298 MockRead reads[] = { 1467 MockRead reads[] = {
1299 MockRead(ASYNC, 0, 0) // EOF 1468 MockRead(ASYNC, 0, 0) // EOF
1300 }; 1469 };
1301 scoped_ptr<QuicEncryptedPacket> rst(ConstructRstPacket()); 1470 scoped_ptr<QuicEncryptedPacket> rst(ConstructRstPacket());
1302 std::vector<MockWrite> writes; 1471 std::vector<MockWrite> writes;
1303 writes.push_back(MockWrite(ASYNC, rst->data(), rst->length(), 1)); 1472 writes.push_back(MockWrite(ASYNC, rst->data(), rst->length(), 1));
1304 DeterministicSocketData socket_data(reads, arraysize(reads), 1473 DeterministicSocketData socket_data(reads, arraysize(reads),
1305 writes.empty() ? nullptr : &writes[0], 1474 writes.empty() ? nullptr : &writes[0],
(...skipping 1426 matching lines...) Expand 10 before | Expand all | Expand 10 after
2732 EXPECT_EQ(1u, observer.executed_count()); 2901 EXPECT_EQ(1u, observer.executed_count());
2733 2902
2734 scoped_ptr<QuicHttpStream> stream = request.ReleaseStream(); 2903 scoped_ptr<QuicHttpStream> stream = request.ReleaseStream();
2735 EXPECT_TRUE(stream.get()); 2904 EXPECT_TRUE(stream.get());
2736 EXPECT_TRUE(socket_data.AllReadDataConsumed()); 2905 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2737 EXPECT_TRUE(socket_data.AllWriteDataConsumed()); 2906 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2738 } 2907 }
2739 2908
2740 } // namespace test 2909 } // namespace test
2741 } // namespace net 2910 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698