Added the following experiments:
1) Testing different PTO values (2, 3 and 5) for path degradation. (cl/766276642)
2) Enabling multi-port connection creation on 1 RTO in PTO_MODE with and without migration. (cl/772554253)
3) Added the test in the `end_to_end_test` when both kMPR1 and kMPQM are passed in the client connection options.
PiperOrigin-RevId: 774884978
diff --git a/quiche/quic/core/http/end_to_end_test.cc b/quiche/quic/core/http/end_to_end_test.cc
index ec8d3a4..87420ca 100644
--- a/quiche/quic/core/http/end_to_end_test.cc
+++ b/quiche/quic/core/http/end_to_end_test.cc
@@ -6071,6 +6071,69 @@
stream->Reset(QuicRstStreamErrorCode::QUIC_STREAM_NO_ERROR);
}
+TEST_P(EndToEndTest, ClientMultiPortMigrationOnPathDegradingOnRTO) {
+ client_config_.SetClientConnectionOptions(QuicTagVector{kMPQC, kMPR1, kMPQM});
+ ASSERT_TRUE(Initialize());
+ if (!version_.HasIetfQuicFrames()) {
+ return;
+ }
+ client_.reset(EndToEndTest::CreateQuicClient(nullptr));
+ ASSERT_TRUE(client_->client()->WaitForHandshakeConfirmed());
+
+ QuicConnection* client_connection = GetClientConnection();
+ QuicSpdyClientStream* stream = client_->GetOrCreateStream();
+ ASSERT_TRUE(stream);
+
+ // Increase the probing frequency to speed up this test.
+ client_connection->SetMultiPortProbingInterval(
+ QuicTime::Delta::FromMilliseconds(100));
+
+ SendSynchronousFooRequestAndCheckResponse();
+
+ // If no multiport connection is established, induce the client to validate an
+ // alternative path.
+ server_writer_->set_fake_packet_loss_percentage(100);
+ EXPECT_TRUE(client_->WaitUntil(1000, [&]() {
+ return client_connection->multi_port_stats()
+ ->num_multi_port_paths_created == 1;
+ }));
+ server_writer_->set_fake_packet_loss_percentage(0);
+
+ // Verify that the probing is triggered after multiport connection is
+ // established.
+ EXPECT_TRUE(client_->WaitUntil(1000, [&]() {
+ return 1u == client_connection->GetStats().num_path_response_received;
+ }));
+
+ auto original_self_addr = client_connection->self_address();
+ // Trigger client side path degrading
+ client_connection->OnPathDegradingDetected();
+ // Verify that the client address has changed due to migration.
+ EXPECT_NE(original_self_addr, client_connection->self_address());
+
+ // Send another request to trigger connection id retirement.
+ SendSynchronousFooRequestAndCheckResponse();
+ EXPECT_EQ(1u, client_connection->GetStats().num_retire_connection_id_sent);
+
+ // Verify new alternate path is created.
+ WaitForNewConnectionIds();
+ // Send another request to make sure the server will have a chance to
+ // establish new multiport connection on RTO.
+ SendSynchronousFooRequestAndCheckResponse();
+ // Simulate another RTO and verify that the probing on RTO is triggered again.
+ server_writer_->set_fake_packet_loss_percentage(100);
+ // Verify that a new multiport connection is established on RTO.
+ EXPECT_TRUE(client_->WaitUntil(2000, [&]() {
+ return client_connection->multi_port_stats()
+ ->num_multi_port_paths_created == 2;
+ }));
+ server_writer_->set_fake_packet_loss_percentage(0);
+ auto new_alt_path = QuicConnectionPeer::GetAlternativePath(client_connection);
+ EXPECT_NE(client_connection->self_address(), new_alt_path->self_address);
+
+ stream->Reset(QuicRstStreamErrorCode::QUIC_STREAM_NO_ERROR);
+}
+
TEST_P(EndToEndTest, SimpleServerPreferredAddressTest) {
use_preferred_address_ = true;
ASSERT_TRUE(Initialize());