Chromium Code Reviews| Index: net/quic/quic_stream_factory_test.cc |
| diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc |
| index 8d54574807d7934bfb301ddb36e277fac8f7eeeb..4d71b545d04328e3744833858415e14e0ab8bc8e 100644 |
| --- a/net/quic/quic_stream_factory_test.cc |
| +++ b/net/quic/quic_stream_factory_test.cc |
| @@ -2648,6 +2648,107 @@ TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorMigrationDisabled) { |
| EXPECT_TRUE(socket_data.AllWriteDataConsumed()); |
| } |
| +TEST_P(QuicStreamFactoryTest, ServerMigration) { |
| + Initialize(); |
| + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); |
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); |
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); |
| + |
| + std::unique_ptr<QuicEncryptedPacket> request_packet( |
| + ConstructGetRequestPacket(1, kClientDataStreamId1, true, true)); |
| + MockWrite writes1[] = {MockWrite(SYNCHRONOUS, request_packet->data(), |
| + request_packet->length(), 1)}; |
| + MockRead reads1[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; |
| + SequencedSocketData socket_data1(reads1, arraysize(reads1), writes1, |
| + arraysize(writes1)); |
| + socket_factory_.AddSocketDataProvider(&socket_data1); |
| + |
| + // Create request and QuicHttpStream. |
| + QuicStreamRequest request(factory_.get()); |
| + EXPECT_EQ(ERR_IO_PENDING, |
| + request.Request(host_port_pair_, privacy_mode_, |
| + /*cert_verify_flags=*/0, url_, "GET", net_log_, |
| + callback_.callback())); |
| + EXPECT_EQ(OK, callback_.WaitForResult()); |
| + std::unique_ptr<QuicHttpStream> stream = request.CreateStream(); |
| + EXPECT_TRUE(stream.get()); |
| + |
| + // Cause QUIC stream to be created. This causes session to be created and |
| + // migrate to using a new socket to the server's alternate address. |
|
Ryan Hamilton
2016/07/06 19:29:37
I don't think this comment is correct since there
Jana
2016/07/12 22:34:10
Yes, that's right -- leftover text from previous i
|
| + HttpRequestInfo request_info; |
| + request_info.method = "GET"; |
| + request_info.url = GURL("https://www.example.org/"); |
| + EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY, |
| + net_log_, CompletionCallback())); |
| + |
| + // Ensure that session is alive and active. |
| + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); |
| + EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); |
| + EXPECT_TRUE(HasActiveSession(host_port_pair_)); |
| + |
| + // Send GET request on stream. |
| + HttpResponseInfo response; |
| + HttpRequestHeaders request_headers; |
| + EXPECT_EQ(OK, stream->SendRequest(request_headers, &response, |
| + callback_.callback())); |
| + |
| + IPEndPoint ip; |
| + session->GetDefaultSocket()->GetPeerAddress(&ip); |
| + DVLOG(1) << "Socket connected to: " << ip.address().ToString() << " " |
| + << ip.port(); |
| + |
| + // Set up second socket data provider that is used after |
| + // migration. The request is rewritten to this new socket, and the |
| + // response to the request is read on this new socket. |
| + std::unique_ptr<QuicEncryptedPacket> ping( |
| + client_maker_.MakePingPacket(2, /*include_version=*/true)); |
| + std::unique_ptr<QuicEncryptedPacket> client_rst( |
| + client_maker_.MakeAckAndRstPacket(3, false, kClientDataStreamId1, |
| + QUIC_STREAM_CANCELLED, 1, 1, 1, true)); |
| + MockWrite writes2[] = { |
| + MockWrite(SYNCHRONOUS, ping->data(), ping->length(), 0), |
| + MockWrite(SYNCHRONOUS, client_rst->data(), client_rst->length(), 3)}; |
| + std::unique_ptr<QuicEncryptedPacket> response_headers_packet( |
| + ConstructOkResponsePacket(1, kClientDataStreamId1, false, false)); |
| + MockRead reads2[] = {MockRead(ASYNC, response_headers_packet->data(), |
| + response_headers_packet->length(), 1), |
| + MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2)}; |
| + SequencedSocketData socket_data2(reads2, arraysize(reads2), writes2, |
| + arraysize(writes2)); |
| + socket_factory_.AddSocketDataProvider(&socket_data2); |
| + |
| + const uint8_t kTestIpAddress[] = {1, 2, 3, 4}; |
| + const uint16_t kTestPort = 123; |
| + factory_->MigrateSessionToNewSocket( |
| + session, IPEndPoint(IPAddress(kTestIpAddress), kTestPort), |
| + NetworkChangeNotifier::kInvalidNetworkHandle, net_log_, nullptr); |
| + |
| + session->GetDefaultSocket()->GetPeerAddress(&ip); |
| + DVLOG(1) << "Socket migrated to: " << ip.address().ToString() << " " |
| + << ip.port(); |
| + |
| + // The session should be alive and active. |
| + EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session)); |
| + EXPECT_TRUE(HasActiveSession(host_port_pair_)); |
| + EXPECT_EQ(1u, session->GetNumActiveStreams()); |
| + |
| + // Run the message loop so that data queued in the new socket is read by the |
| + // packet reader. |
| + base::RunLoop().RunUntilIdle(); |
| + |
| + // Verify that response headers on the migrated socket were delivered to the |
| + // stream. |
| + EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback())); |
| + EXPECT_EQ(200, response.headers->response_code()); |
| + |
| + stream.reset(); |
| + |
| + EXPECT_TRUE(socket_data1.AllReadDataConsumed()); |
| + EXPECT_TRUE(socket_data1.AllWriteDataConsumed()); |
| + EXPECT_TRUE(socket_data2.AllReadDataConsumed()); |
| + EXPECT_TRUE(socket_data2.AllWriteDataConsumed()); |
| +} |
|
Ryan Hamilton
2016/07/06 19:29:37
This seems like a test which might be a better fit
Jana
2016/07/12 22:34:10
I think the test would basically end up testing th
|
| + |
| TEST_P(QuicStreamFactoryTest, OnSSLConfigChanged) { |
| Initialize(); |
| ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); |