Replace random delay test case with a competing flow case in QuartcBidiTest. This test case runs for 15 seconds normally, then introduces a competing flow that transfers a burst of 50 kb of data in each direction. Per-packet random delay isn't very realistic. A burst of competing traffic is a much more realistic scenario for testing how well the Quartc transport responds to an unpredictable change in delay. For example, the user might make an HTTP request and load a web page while streaming media. A couple of ideas for future competing flow tests include persistent competition or multiple small bursts that occur throughout the test. gfe-relnote: n/a (test only) PiperOrigin-RevId: 246586456 Change-Id: I50d090135e2193c17c7249904a4a996be43f3f00
diff --git a/quic/quartc/test/quartc_bidi_test.cc b/quic/quartc/test/quartc_bidi_test.cc index 3d0e30a..816653a 100644 --- a/quic/quartc/test/quartc_bidi_test.cc +++ b/quic/quartc/test/quartc_bidi_test.cc
@@ -11,15 +11,30 @@ #include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h" #include "net/third_party/quiche/src/quic/quartc/test/bidi_test_runner.h" #include "net/third_party/quiche/src/quic/quartc/test/quic_trace_interceptor.h" -#include "net/third_party/quiche/src/quic/quartc/test/random_delay_link.h" #include "net/third_party/quiche/src/quic/quartc/test/random_packet_filter.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" +#include "net/third_party/quiche/src/quic/test_tools/simulator/link.h" +#include "net/third_party/quiche/src/quic/test_tools/simulator/quic_endpoint.h" #include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" +#include "net/third_party/quiche/src/quic/test_tools/simulator/switch.h" namespace quic { namespace test { namespace { +class CompetingTransferAlarmDelegate : public quic::QuicAlarm::Delegate { + public: + CompetingTransferAlarmDelegate(quic::simulator::QuicEndpoint* endpoint, + QuicByteCount bytes) + : endpoint_(endpoint), bytes_(bytes) {} + + void OnAlarm() override { endpoint_->AddBytesToTransfer(bytes_); } + + private: + quic::simulator::QuicEndpoint* const endpoint_; + const QuicByteCount bytes_; +}; + class QuartcBidiTest : public QuicTest { protected: QuartcBidiTest() { @@ -36,21 +51,58 @@ QuicTime::Delta propagation_delay, QuicByteCount queue_length, int loss_percent) { + // Endpoints which serve as the transports for client and server. client_transport_ = QuicMakeUnique<simulator::SimulatedQuartcPacketTransport>( &simulator_, "client_transport", "server_transport", queue_length); server_transport_ = QuicMakeUnique<simulator::SimulatedQuartcPacketTransport>( &simulator_, "server_transport", "client_transport", queue_length); + + // Filters on each of the endpoints facilitate random packet loss. client_filter_ = QuicMakeUnique<simulator::RandomPacketFilter>( &simulator_, "client_filter", client_transport_.get()); server_filter_ = QuicMakeUnique<simulator::RandomPacketFilter>( &simulator_, "server_filter", server_transport_.get()); - client_server_link_ = QuicMakeUnique<simulator::SymmetricRandomDelayLink>( - client_filter_.get(), server_filter_.get(), bandwidth, - propagation_delay); client_filter_->set_loss_percent(loss_percent); server_filter_->set_loss_percent(loss_percent); + + // Each endpoint connects directly to a switch. + client_switch_ = QuicMakeUnique<simulator::Switch>( + &simulator_, "client_switch", /*port_count=*/8, 2 * queue_length); + server_switch_ = QuicMakeUnique<simulator::Switch>( + &simulator_, "server_switch", /*port_count=*/8, 2 * queue_length); + + // Links to the switch have significantly higher bandwdith than the + // bottleneck and insignificant propagation delay. + client_link_ = QuicMakeUnique<simulator::SymmetricLink>( + client_filter_.get(), client_switch_->port(1), 10 * bandwidth, + QuicTime::Delta::FromMicroseconds(1)); + server_link_ = QuicMakeUnique<simulator::SymmetricLink>( + server_filter_.get(), server_switch_->port(1), 10 * bandwidth, + QuicTime::Delta::FromMicroseconds(1)); + + // The bottleneck link connects the two switches with the bandwidth and + // propagation delay specified by the test case. + bottleneck_link_ = QuicMakeUnique<simulator::SymmetricLink>( + client_switch_->port(2), server_switch_->port(2), bandwidth, + propagation_delay); + } + + void SetupCompetingEndpoints(QuicBandwidth bandwidth) { + competing_client_ = absl::make_unique<quic::simulator::QuicEndpoint>( + &simulator_, "competing_client", "competing_server", + quic::Perspective::IS_CLIENT, quic::test::TestConnectionId(3)); + competing_server_ = absl::make_unique<quic::simulator::QuicEndpoint>( + &simulator_, "competing_server", "competing_client", + quic::Perspective::IS_SERVER, quic::test::TestConnectionId(3)); + + competing_client_link_ = absl::make_unique<quic::simulator::SymmetricLink>( + competing_client_.get(), client_switch_->port(3), 10 * bandwidth, + QuicTime::Delta::FromMicroseconds(1)); + competing_server_link_ = absl::make_unique<quic::simulator::SymmetricLink>( + competing_server_.get(), server_switch_->port(3), 10 * bandwidth, + QuicTime::Delta::FromMicroseconds(1)); } simulator::Simulator simulator_; @@ -60,7 +112,16 @@ std::unique_ptr<simulator::SimulatedQuartcPacketTransport> server_transport_; std::unique_ptr<simulator::RandomPacketFilter> client_filter_; std::unique_ptr<simulator::RandomPacketFilter> server_filter_; - std::unique_ptr<simulator::SymmetricRandomDelayLink> client_server_link_; + std::unique_ptr<simulator::Switch> client_switch_; + std::unique_ptr<simulator::Switch> server_switch_; + std::unique_ptr<simulator::SymmetricLink> client_link_; + std::unique_ptr<simulator::SymmetricLink> server_link_; + std::unique_ptr<simulator::SymmetricLink> bottleneck_link_; + + std::unique_ptr<simulator::QuicEndpoint> competing_client_; + std::unique_ptr<simulator::QuicEndpoint> competing_server_; + std::unique_ptr<simulator::SymmetricLink> competing_client_link_; + std::unique_ptr<simulator::SymmetricLink> competing_server_link_; std::unique_ptr<QuicTraceInterceptor> client_trace_interceptor_; std::unique_ptr<QuicTraceInterceptor> server_trace_interceptor_; @@ -88,14 +149,27 @@ EXPECT_TRUE(runner.RunTest(QuicTime::Delta::FromSeconds(30))); } -TEST_F(QuartcBidiTest, 300kbps200ms25msRandom2PercentLoss) { - CreateTransports(QuicBandwidth::FromKBitsPerSecond(300), - QuicTime::Delta::FromMilliseconds(200), - 10 * kDefaultMaxPacketSize, /*loss_percent=*/2); - client_server_link_->set_median_random_delay( - QuicTime::Delta::FromMilliseconds(25)); - BidiTestRunner runner(&simulator_, client_transport_.get(), - server_transport_.get()); +TEST_F(QuartcBidiTest, 300kbps200ms2PercentLossCompetingBurst) { + QuicBandwidth bandwidth = QuicBandwidth::FromKBitsPerSecond(300); + CreateTransports(bandwidth, QuicTime::Delta::FromMilliseconds(200), + 10 * quic::kDefaultMaxPacketSize, /*loss_percent=*/2); + SetupCompetingEndpoints(bandwidth); + + QuicTime competing_burst_time = + simulator_.GetClock()->Now() + QuicTime::Delta::FromSeconds(15); + std::unique_ptr<quic::QuicAlarm> competing_client_burst_alarm_ = + absl::WrapUnique(simulator_.GetAlarmFactory()->CreateAlarm( + new CompetingTransferAlarmDelegate(competing_client_.get(), + /*bytes=*/50 * 1024))); + std::unique_ptr<quic::QuicAlarm> competing_server_burst_alarm_ = + absl::WrapUnique(simulator_.GetAlarmFactory()->CreateAlarm( + new CompetingTransferAlarmDelegate(competing_server_.get(), + /*bytes=*/50 * 1024))); + competing_client_burst_alarm_->Set(competing_burst_time); + competing_server_burst_alarm_->Set(competing_burst_time); + + quic::test::BidiTestRunner runner(&simulator_, client_transport_.get(), + server_transport_.get()); runner.set_client_interceptor(client_trace_interceptor_.get()); runner.set_server_interceptor(server_trace_interceptor_.get()); EXPECT_TRUE(runner.RunTest(QuicTime::Delta::FromSeconds(30)));