xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/test_tools/simulator/simulator_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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
3 // found in the LICENSE file.
4 
5 #include "quiche/quic/test_tools/simulator/simulator.h"
6 
7 #include <utility>
8 
9 #include "absl/container/node_hash_map.h"
10 #include "quiche/quic/platform/api/quic_logging.h"
11 #include "quiche/quic/platform/api/quic_test.h"
12 #include "quiche/quic/test_tools/quic_test_utils.h"
13 #include "quiche/quic/test_tools/simulator/alarm_factory.h"
14 #include "quiche/quic/test_tools/simulator/link.h"
15 #include "quiche/quic/test_tools/simulator/packet_filter.h"
16 #include "quiche/quic/test_tools/simulator/queue.h"
17 #include "quiche/quic/test_tools/simulator/switch.h"
18 #include "quiche/quic/test_tools/simulator/traffic_policer.h"
19 
20 using testing::_;
21 using testing::Return;
22 using testing::StrictMock;
23 
24 namespace quic {
25 namespace simulator {
26 
27 // A simple counter that increments its value by 1 every specified period.
28 class Counter : public Actor {
29  public:
Counter(Simulator * simulator,std::string name,QuicTime::Delta period)30   Counter(Simulator* simulator, std::string name, QuicTime::Delta period)
31       : Actor(simulator, name), value_(-1), period_(period) {
32     Schedule(clock_->Now());
33   }
~Counter()34   ~Counter() override {}
35 
get_value() const36   inline int get_value() const { return value_; }
37 
Act()38   void Act() override {
39     ++value_;
40     QUIC_DVLOG(1) << name_ << " has value " << value_ << " at time "
41                   << clock_->Now().ToDebuggingValue();
42     Schedule(clock_->Now() + period_);
43   }
44 
45  private:
46   int value_;
47   QuicTime::Delta period_;
48 };
49 
50 class SimulatorTest : public quic::test::QuicTest {};
51 
52 // Test that the basic event handling works, and that Actors can be created and
53 // destroyed mid-simulation.
TEST_F(SimulatorTest,Counters)54 TEST_F(SimulatorTest, Counters) {
55   Simulator simulator;
56   for (int i = 0; i < 2; ++i) {
57     Counter fast_counter(&simulator, "fast_counter",
58                          QuicTime::Delta::FromSeconds(3));
59     Counter slow_counter(&simulator, "slow_counter",
60                          QuicTime::Delta::FromSeconds(10));
61 
62     simulator.RunUntil(
63         [&slow_counter]() { return slow_counter.get_value() >= 10; });
64 
65     EXPECT_EQ(10, slow_counter.get_value());
66     EXPECT_EQ(10 * 10 / 3, fast_counter.get_value());
67   }
68 }
69 
70 // A port which counts the number of packets received on it, both total and
71 // per-destination.
72 class CounterPort : public UnconstrainedPortInterface {
73  public:
CounterPort()74   CounterPort() { Reset(); }
~CounterPort()75   ~CounterPort() override {}
76 
bytes() const77   inline QuicByteCount bytes() const { return bytes_; }
packets() const78   inline QuicPacketCount packets() const { return packets_; }
79 
AcceptPacket(std::unique_ptr<Packet> packet)80   void AcceptPacket(std::unique_ptr<Packet> packet) override {
81     bytes_ += packet->size;
82     packets_ += 1;
83 
84     per_destination_packet_counter_[packet->destination] += 1;
85   }
86 
Reset()87   void Reset() {
88     bytes_ = 0;
89     packets_ = 0;
90     per_destination_packet_counter_.clear();
91   }
92 
CountPacketsForDestination(std::string destination) const93   QuicPacketCount CountPacketsForDestination(std::string destination) const {
94     auto result_it = per_destination_packet_counter_.find(destination);
95     if (result_it == per_destination_packet_counter_.cend()) {
96       return 0;
97     }
98     return result_it->second;
99   }
100 
101  private:
102   QuicByteCount bytes_;
103   QuicPacketCount packets_;
104 
105   absl::node_hash_map<std::string, QuicPacketCount>
106       per_destination_packet_counter_;
107 };
108 
109 // Sends the packet to the specified destination at the uplink rate.  Provides a
110 // CounterPort as an Rx interface.
111 class LinkSaturator : public Endpoint {
112  public:
LinkSaturator(Simulator * simulator,std::string name,QuicByteCount packet_size,std::string destination)113   LinkSaturator(Simulator* simulator, std::string name,
114                 QuicByteCount packet_size, std::string destination)
115       : Endpoint(simulator, name),
116         packet_size_(packet_size),
117         destination_(std::move(destination)),
118         bytes_transmitted_(0),
119         packets_transmitted_(0) {
120     Schedule(clock_->Now());
121   }
122 
Act()123   void Act() override {
124     if (tx_port_->TimeUntilAvailable().IsZero()) {
125       auto packet = std::make_unique<Packet>();
126       packet->source = name_;
127       packet->destination = destination_;
128       packet->tx_timestamp = clock_->Now();
129       packet->size = packet_size_;
130 
131       tx_port_->AcceptPacket(std::move(packet));
132 
133       bytes_transmitted_ += packet_size_;
134       packets_transmitted_ += 1;
135     }
136 
137     Schedule(clock_->Now() + tx_port_->TimeUntilAvailable());
138   }
139 
GetRxPort()140   UnconstrainedPortInterface* GetRxPort() override {
141     return static_cast<UnconstrainedPortInterface*>(&rx_port_);
142   }
143 
SetTxPort(ConstrainedPortInterface * port)144   void SetTxPort(ConstrainedPortInterface* port) override { tx_port_ = port; }
145 
counter()146   CounterPort* counter() { return &rx_port_; }
147 
bytes_transmitted() const148   inline QuicByteCount bytes_transmitted() const { return bytes_transmitted_; }
packets_transmitted() const149   inline QuicPacketCount packets_transmitted() const {
150     return packets_transmitted_;
151   }
152 
Pause()153   void Pause() { Unschedule(); }
Resume()154   void Resume() { Schedule(clock_->Now()); }
155 
156  private:
157   QuicByteCount packet_size_;
158   std::string destination_;
159 
160   ConstrainedPortInterface* tx_port_;
161   CounterPort rx_port_;
162 
163   QuicByteCount bytes_transmitted_;
164   QuicPacketCount packets_transmitted_;
165 };
166 
167 // Saturate a symmetric link and verify that the number of packets sent and
168 // received is correct.
TEST_F(SimulatorTest,DirectLinkSaturation)169 TEST_F(SimulatorTest, DirectLinkSaturation) {
170   Simulator simulator;
171   LinkSaturator saturator_a(&simulator, "Saturator A", 1000, "Saturator B");
172   LinkSaturator saturator_b(&simulator, "Saturator B", 100, "Saturator A");
173   SymmetricLink link(&saturator_a, &saturator_b,
174                      QuicBandwidth::FromKBytesPerSecond(1000),
175                      QuicTime::Delta::FromMilliseconds(100) +
176                          QuicTime::Delta::FromMicroseconds(1));
177 
178   const QuicTime start_time = simulator.GetClock()->Now();
179   const QuicTime after_first_50_ms =
180       start_time + QuicTime::Delta::FromMilliseconds(50);
181   simulator.RunUntil([&simulator, after_first_50_ms]() {
182     return simulator.GetClock()->Now() >= after_first_50_ms;
183   });
184   EXPECT_LE(1000u * 50u, saturator_a.bytes_transmitted());
185   EXPECT_GE(1000u * 51u, saturator_a.bytes_transmitted());
186   EXPECT_LE(1000u * 50u, saturator_b.bytes_transmitted());
187   EXPECT_GE(1000u * 51u, saturator_b.bytes_transmitted());
188   EXPECT_LE(50u, saturator_a.packets_transmitted());
189   EXPECT_GE(51u, saturator_a.packets_transmitted());
190   EXPECT_LE(500u, saturator_b.packets_transmitted());
191   EXPECT_GE(501u, saturator_b.packets_transmitted());
192   EXPECT_EQ(0u, saturator_a.counter()->bytes());
193   EXPECT_EQ(0u, saturator_b.counter()->bytes());
194 
195   simulator.RunUntil([&saturator_a, &saturator_b]() {
196     if (saturator_a.counter()->packets() > 1000 ||
197         saturator_b.counter()->packets() > 100) {
198       ADD_FAILURE() << "The simulation did not arrive at the expected "
199                        "termination contidition. Saturator A counter: "
200                     << saturator_a.counter()->packets()
201                     << ", saturator B counter: "
202                     << saturator_b.counter()->packets();
203       return true;
204     }
205 
206     return saturator_a.counter()->packets() == 1000 &&
207            saturator_b.counter()->packets() == 100;
208   });
209   EXPECT_EQ(201u, saturator_a.packets_transmitted());
210   EXPECT_EQ(2001u, saturator_b.packets_transmitted());
211   EXPECT_EQ(201u * 1000, saturator_a.bytes_transmitted());
212   EXPECT_EQ(2001u * 100, saturator_b.bytes_transmitted());
213 
214   EXPECT_EQ(1000u,
215             saturator_a.counter()->CountPacketsForDestination("Saturator A"));
216   EXPECT_EQ(100u,
217             saturator_b.counter()->CountPacketsForDestination("Saturator B"));
218   EXPECT_EQ(0u,
219             saturator_a.counter()->CountPacketsForDestination("Saturator B"));
220   EXPECT_EQ(0u,
221             saturator_b.counter()->CountPacketsForDestination("Saturator A"));
222 
223   const QuicTime end_time = simulator.GetClock()->Now();
224   const QuicBandwidth observed_bandwidth = QuicBandwidth::FromBytesAndTimeDelta(
225       saturator_a.bytes_transmitted(), end_time - start_time);
226   EXPECT_APPROX_EQ(link.bandwidth(), observed_bandwidth, 0.01f);
227 }
228 
229 // Accepts packets and stores them internally.
230 class PacketAcceptor : public ConstrainedPortInterface {
231  public:
AcceptPacket(std::unique_ptr<Packet> packet)232   void AcceptPacket(std::unique_ptr<Packet> packet) override {
233     packets_.emplace_back(std::move(packet));
234   }
235 
TimeUntilAvailable()236   QuicTime::Delta TimeUntilAvailable() override {
237     return QuicTime::Delta::Zero();
238   }
239 
packets()240   std::vector<std::unique_ptr<Packet>>* packets() { return &packets_; }
241 
242  private:
243   std::vector<std::unique_ptr<Packet>> packets_;
244 };
245 
246 // Ensure the queue behaves correctly with accepting packets.
TEST_F(SimulatorTest,Queue)247 TEST_F(SimulatorTest, Queue) {
248   Simulator simulator;
249   Queue queue(&simulator, "Queue", 1000);
250   PacketAcceptor acceptor;
251   queue.set_tx_port(&acceptor);
252 
253   EXPECT_EQ(0u, queue.bytes_queued());
254   EXPECT_EQ(0u, queue.packets_queued());
255   EXPECT_EQ(0u, acceptor.packets()->size());
256 
257   auto first_packet = std::make_unique<Packet>();
258   first_packet->size = 600;
259   queue.AcceptPacket(std::move(first_packet));
260   EXPECT_EQ(600u, queue.bytes_queued());
261   EXPECT_EQ(1u, queue.packets_queued());
262   EXPECT_EQ(0u, acceptor.packets()->size());
263 
264   // The second packet does not fit and is dropped.
265   auto second_packet = std::make_unique<Packet>();
266   second_packet->size = 500;
267   queue.AcceptPacket(std::move(second_packet));
268   EXPECT_EQ(600u, queue.bytes_queued());
269   EXPECT_EQ(1u, queue.packets_queued());
270   EXPECT_EQ(0u, acceptor.packets()->size());
271 
272   auto third_packet = std::make_unique<Packet>();
273   third_packet->size = 400;
274   queue.AcceptPacket(std::move(third_packet));
275   EXPECT_EQ(1000u, queue.bytes_queued());
276   EXPECT_EQ(2u, queue.packets_queued());
277   EXPECT_EQ(0u, acceptor.packets()->size());
278 
279   // Run until there is nothing scheduled, so that the queue can deplete.
280   simulator.RunUntil([]() { return false; });
281   EXPECT_EQ(0u, queue.bytes_queued());
282   EXPECT_EQ(0u, queue.packets_queued());
283   ASSERT_EQ(2u, acceptor.packets()->size());
284   EXPECT_EQ(600u, acceptor.packets()->at(0)->size);
285   EXPECT_EQ(400u, acceptor.packets()->at(1)->size);
286 }
287 
288 // Simulate a situation where the bottleneck link is 10 times slower than the
289 // uplink, and they are separated by a queue.
TEST_F(SimulatorTest,QueueBottleneck)290 TEST_F(SimulatorTest, QueueBottleneck) {
291   const QuicBandwidth local_bandwidth =
292       QuicBandwidth::FromKBytesPerSecond(1000);
293   const QuicBandwidth bottleneck_bandwidth = 0.1f * local_bandwidth;
294   const QuicTime::Delta local_propagation_delay =
295       QuicTime::Delta::FromMilliseconds(1);
296   const QuicTime::Delta bottleneck_propagation_delay =
297       QuicTime::Delta::FromMilliseconds(20);
298   const QuicByteCount bdp =
299       bottleneck_bandwidth *
300       (local_propagation_delay + bottleneck_propagation_delay);
301 
302   Simulator simulator;
303   LinkSaturator saturator(&simulator, "Saturator", 1000, "Counter");
304   ASSERT_GE(bdp, 1000u);
305   Queue queue(&simulator, "Queue", bdp);
306   CounterPort counter;
307 
308   OneWayLink local_link(&simulator, "Local link", &queue, local_bandwidth,
309                         local_propagation_delay);
310   OneWayLink bottleneck_link(&simulator, "Bottleneck link", &counter,
311                              bottleneck_bandwidth,
312                              bottleneck_propagation_delay);
313   saturator.SetTxPort(&local_link);
314   queue.set_tx_port(&bottleneck_link);
315 
316   static const QuicPacketCount packets_received = 1000;
317   simulator.RunUntil(
318       [&counter]() { return counter.packets() == packets_received; });
319   const double loss_ratio = 1 - static_cast<double>(packets_received) /
320                                     saturator.packets_transmitted();
321   EXPECT_NEAR(loss_ratio, 0.9, 0.001);
322 }
323 
324 // Verify that the queue of exactly one packet allows the transmission to
325 // actually go through.
TEST_F(SimulatorTest,OnePacketQueue)326 TEST_F(SimulatorTest, OnePacketQueue) {
327   const QuicBandwidth local_bandwidth =
328       QuicBandwidth::FromKBytesPerSecond(1000);
329   const QuicBandwidth bottleneck_bandwidth = 0.1f * local_bandwidth;
330   const QuicTime::Delta local_propagation_delay =
331       QuicTime::Delta::FromMilliseconds(1);
332   const QuicTime::Delta bottleneck_propagation_delay =
333       QuicTime::Delta::FromMilliseconds(20);
334 
335   Simulator simulator;
336   LinkSaturator saturator(&simulator, "Saturator", 1000, "Counter");
337   Queue queue(&simulator, "Queue", 1000);
338   CounterPort counter;
339 
340   OneWayLink local_link(&simulator, "Local link", &queue, local_bandwidth,
341                         local_propagation_delay);
342   OneWayLink bottleneck_link(&simulator, "Bottleneck link", &counter,
343                              bottleneck_bandwidth,
344                              bottleneck_propagation_delay);
345   saturator.SetTxPort(&local_link);
346   queue.set_tx_port(&bottleneck_link);
347 
348   static const QuicPacketCount packets_received = 10;
349   // The deadline here is to prevent this tests from looping infinitely in case
350   // the packets never reach the receiver.
351   const QuicTime deadline =
352       simulator.GetClock()->Now() + QuicTime::Delta::FromSeconds(10);
353   simulator.RunUntil([&simulator, &counter, deadline]() {
354     return counter.packets() == packets_received ||
355            simulator.GetClock()->Now() > deadline;
356   });
357   ASSERT_EQ(packets_received, counter.packets());
358 }
359 
360 // Simulate a network where three endpoints are connected to a switch and they
361 // are sending traffic in circle (1 -> 2, 2 -> 3, 3 -> 1).
TEST_F(SimulatorTest,SwitchedNetwork)362 TEST_F(SimulatorTest, SwitchedNetwork) {
363   const QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(10000);
364   const QuicTime::Delta base_propagation_delay =
365       QuicTime::Delta::FromMilliseconds(50);
366 
367   Simulator simulator;
368   LinkSaturator saturator1(&simulator, "Saturator 1", 1000, "Saturator 2");
369   LinkSaturator saturator2(&simulator, "Saturator 2", 1000, "Saturator 3");
370   LinkSaturator saturator3(&simulator, "Saturator 3", 1000, "Saturator 1");
371   Switch network_switch(&simulator, "Switch", 8,
372                         bandwidth * base_propagation_delay * 10);
373 
374   // For determinicity, make it so that the first packet will arrive from
375   // Saturator 1, then from Saturator 2, and then from Saturator 3.
376   SymmetricLink link1(&saturator1, network_switch.port(1), bandwidth,
377                       base_propagation_delay);
378   SymmetricLink link2(&saturator2, network_switch.port(2), bandwidth,
379                       base_propagation_delay * 2);
380   SymmetricLink link3(&saturator3, network_switch.port(3), bandwidth,
381                       base_propagation_delay * 3);
382 
383   const QuicTime start_time = simulator.GetClock()->Now();
384   static const QuicPacketCount bytes_received = 64 * 1000;
385   simulator.RunUntil([&saturator1]() {
386     return saturator1.counter()->bytes() >= bytes_received;
387   });
388   const QuicTime end_time = simulator.GetClock()->Now();
389 
390   const QuicBandwidth observed_bandwidth = QuicBandwidth::FromBytesAndTimeDelta(
391       bytes_received, end_time - start_time);
392   const double bandwidth_ratio =
393       static_cast<double>(observed_bandwidth.ToBitsPerSecond()) /
394       bandwidth.ToBitsPerSecond();
395   EXPECT_NEAR(1, bandwidth_ratio, 0.1);
396 
397   const double normalized_received_packets_for_saturator_2 =
398       static_cast<double>(saturator2.counter()->packets()) /
399       saturator1.counter()->packets();
400   const double normalized_received_packets_for_saturator_3 =
401       static_cast<double>(saturator3.counter()->packets()) /
402       saturator1.counter()->packets();
403   EXPECT_NEAR(1, normalized_received_packets_for_saturator_2, 0.1);
404   EXPECT_NEAR(1, normalized_received_packets_for_saturator_3, 0.1);
405 
406   // Since Saturator 1 has its packet arrive first into the switch, switch will
407   // always know how to route traffic to it.
408   EXPECT_EQ(0u,
409             saturator2.counter()->CountPacketsForDestination("Saturator 1"));
410   EXPECT_EQ(0u,
411             saturator3.counter()->CountPacketsForDestination("Saturator 1"));
412 
413   // Packets from the other saturators will be broadcast at least once.
414   EXPECT_EQ(1u,
415             saturator1.counter()->CountPacketsForDestination("Saturator 2"));
416   EXPECT_EQ(1u,
417             saturator3.counter()->CountPacketsForDestination("Saturator 2"));
418   EXPECT_EQ(1u,
419             saturator1.counter()->CountPacketsForDestination("Saturator 3"));
420   EXPECT_EQ(1u,
421             saturator2.counter()->CountPacketsForDestination("Saturator 3"));
422 }
423 
424 // Toggle an alarm on and off at the specified interval.  Assumes that alarm is
425 // initially set and unsets it almost immediately after the object is
426 // instantiated.
427 class AlarmToggler : public Actor {
428  public:
AlarmToggler(Simulator * simulator,std::string name,QuicAlarm * alarm,QuicTime::Delta interval)429   AlarmToggler(Simulator* simulator, std::string name, QuicAlarm* alarm,
430                QuicTime::Delta interval)
431       : Actor(simulator, name),
432         alarm_(alarm),
433         interval_(interval),
434         deadline_(alarm->deadline()),
435         times_set_(0),
436         times_cancelled_(0) {
437     EXPECT_TRUE(alarm->IsSet());
438     EXPECT_GE(alarm->deadline(), clock_->Now());
439     Schedule(clock_->Now());
440   }
441 
Act()442   void Act() override {
443     if (deadline_ <= clock_->Now()) {
444       return;
445     }
446 
447     if (alarm_->IsSet()) {
448       alarm_->Cancel();
449       times_cancelled_++;
450     } else {
451       alarm_->Set(deadline_);
452       times_set_++;
453     }
454 
455     Schedule(clock_->Now() + interval_);
456   }
457 
times_set()458   inline int times_set() { return times_set_; }
times_cancelled()459   inline int times_cancelled() { return times_cancelled_; }
460 
461  private:
462   QuicAlarm* alarm_;
463   QuicTime::Delta interval_;
464   QuicTime deadline_;
465 
466   // Counts the number of times the alarm was set.
467   int times_set_;
468   // Counts the number of times the alarm was cancelled.
469   int times_cancelled_;
470 };
471 
472 // Counts the number of times an alarm has fired.
473 class CounterDelegate : public QuicAlarm::DelegateWithoutContext {
474  public:
CounterDelegate(size_t * counter)475   explicit CounterDelegate(size_t* counter) : counter_(counter) {}
476 
OnAlarm()477   void OnAlarm() override { *counter_ += 1; }
478 
479  private:
480   size_t* counter_;
481 };
482 
483 // Verifies that the alarms work correctly, even when they are repeatedly
484 // toggled.
TEST_F(SimulatorTest,Alarms)485 TEST_F(SimulatorTest, Alarms) {
486   Simulator simulator;
487   QuicAlarmFactory* alarm_factory = simulator.GetAlarmFactory();
488 
489   size_t fast_alarm_counter = 0;
490   size_t slow_alarm_counter = 0;
491   std::unique_ptr<QuicAlarm> alarm_fast(
492       alarm_factory->CreateAlarm(new CounterDelegate(&fast_alarm_counter)));
493   std::unique_ptr<QuicAlarm> alarm_slow(
494       alarm_factory->CreateAlarm(new CounterDelegate(&slow_alarm_counter)));
495 
496   const QuicTime start_time = simulator.GetClock()->Now();
497   alarm_fast->Set(start_time + QuicTime::Delta::FromMilliseconds(100));
498   alarm_slow->Set(start_time + QuicTime::Delta::FromMilliseconds(750));
499   AlarmToggler toggler(&simulator, "Toggler", alarm_slow.get(),
500                        QuicTime::Delta::FromMilliseconds(100));
501 
502   const QuicTime end_time =
503       start_time + QuicTime::Delta::FromMilliseconds(1000);
504   EXPECT_FALSE(simulator.RunUntil([&simulator, end_time]() {
505     return simulator.GetClock()->Now() >= end_time;
506   }));
507   EXPECT_EQ(1u, slow_alarm_counter);
508   EXPECT_EQ(1u, fast_alarm_counter);
509 
510   EXPECT_EQ(4, toggler.times_set());
511   EXPECT_EQ(4, toggler.times_cancelled());
512 }
513 
514 // Verifies that a cancelled alarm is never fired.
TEST_F(SimulatorTest,AlarmCancelling)515 TEST_F(SimulatorTest, AlarmCancelling) {
516   Simulator simulator;
517   QuicAlarmFactory* alarm_factory = simulator.GetAlarmFactory();
518 
519   size_t alarm_counter = 0;
520   std::unique_ptr<QuicAlarm> alarm(
521       alarm_factory->CreateAlarm(new CounterDelegate(&alarm_counter)));
522 
523   const QuicTime start_time = simulator.GetClock()->Now();
524   const QuicTime alarm_at = start_time + QuicTime::Delta::FromMilliseconds(300);
525   const QuicTime end_time = start_time + QuicTime::Delta::FromMilliseconds(400);
526 
527   alarm->Set(alarm_at);
528   alarm->Cancel();
529   EXPECT_FALSE(alarm->IsSet());
530 
531   EXPECT_FALSE(simulator.RunUntil([&simulator, end_time]() {
532     return simulator.GetClock()->Now() >= end_time;
533   }));
534 
535   EXPECT_FALSE(alarm->IsSet());
536   EXPECT_EQ(0u, alarm_counter);
537 }
538 
539 // Verifies that alarms can be scheduled into the past.
TEST_F(SimulatorTest,AlarmInPast)540 TEST_F(SimulatorTest, AlarmInPast) {
541   Simulator simulator;
542   QuicAlarmFactory* alarm_factory = simulator.GetAlarmFactory();
543 
544   size_t alarm_counter = 0;
545   std::unique_ptr<QuicAlarm> alarm(
546       alarm_factory->CreateAlarm(new CounterDelegate(&alarm_counter)));
547 
548   const QuicTime start_time = simulator.GetClock()->Now();
549   simulator.RunFor(QuicTime::Delta::FromMilliseconds(400));
550 
551   alarm->Set(start_time);
552   simulator.RunFor(QuicTime::Delta::FromMilliseconds(1));
553   EXPECT_FALSE(alarm->IsSet());
554   EXPECT_EQ(1u, alarm_counter);
555 }
556 
557 // Tests Simulator::RunUntilOrTimeout() interface.
TEST_F(SimulatorTest,RunUntilOrTimeout)558 TEST_F(SimulatorTest, RunUntilOrTimeout) {
559   Simulator simulator;
560   bool simulation_result;
561 
562   // Count the number of seconds since the beginning of the simulation.
563   Counter counter(&simulator, "counter", QuicTime::Delta::FromSeconds(1));
564 
565   // Ensure that the counter reaches the value of 10 given a 20 second deadline.
566   simulation_result = simulator.RunUntilOrTimeout(
567       [&counter]() { return counter.get_value() == 10; },
568       QuicTime::Delta::FromSeconds(20));
569   ASSERT_TRUE(simulation_result);
570 
571   // Ensure that the counter will not reach the value of 100 given that the
572   // starting value is 10 and the deadline is 20 seconds.
573   simulation_result = simulator.RunUntilOrTimeout(
574       [&counter]() { return counter.get_value() == 100; },
575       QuicTime::Delta::FromSeconds(20));
576   ASSERT_FALSE(simulation_result);
577 }
578 
579 // Tests Simulator::RunFor() interface.
TEST_F(SimulatorTest,RunFor)580 TEST_F(SimulatorTest, RunFor) {
581   Simulator simulator;
582 
583   Counter counter(&simulator, "counter", QuicTime::Delta::FromSeconds(3));
584 
585   simulator.RunFor(QuicTime::Delta::FromSeconds(100));
586 
587   EXPECT_EQ(33, counter.get_value());
588 }
589 
590 class MockPacketFilter : public PacketFilter {
591  public:
MockPacketFilter(Simulator * simulator,std::string name,Endpoint * endpoint)592   MockPacketFilter(Simulator* simulator, std::string name, Endpoint* endpoint)
593       : PacketFilter(simulator, name, endpoint) {}
594   MOCK_METHOD(bool, FilterPacket, (const Packet&), (override));
595 };
596 
597 // Set up two trivial packet filters, one allowing any packets, and one dropping
598 // all of them.
TEST_F(SimulatorTest,PacketFilter)599 TEST_F(SimulatorTest, PacketFilter) {
600   const QuicBandwidth bandwidth =
601       QuicBandwidth::FromBytesPerSecond(1024 * 1024);
602   const QuicTime::Delta base_propagation_delay =
603       QuicTime::Delta::FromMilliseconds(5);
604 
605   Simulator simulator;
606   LinkSaturator saturator_a(&simulator, "Saturator A", 1000, "Saturator B");
607   LinkSaturator saturator_b(&simulator, "Saturator B", 1000, "Saturator A");
608 
609   // Attach packets to the switch to create a delay between the point at which
610   // the packet is generated and the point at which it is filtered.  Note that
611   // if the saturators were connected directly, the link would be always
612   // available for the endpoint which has all of its packets dropped, resulting
613   // in saturator looping infinitely.
614   Switch network_switch(&simulator, "Switch", 8,
615                         bandwidth * base_propagation_delay * 10);
616   StrictMock<MockPacketFilter> a_to_b_filter(&simulator, "A -> B filter",
617                                              network_switch.port(1));
618   StrictMock<MockPacketFilter> b_to_a_filter(&simulator, "B -> A filter",
619                                              network_switch.port(2));
620   SymmetricLink link_a(&a_to_b_filter, &saturator_b, bandwidth,
621                        base_propagation_delay);
622   SymmetricLink link_b(&b_to_a_filter, &saturator_a, bandwidth,
623                        base_propagation_delay);
624 
625   // Allow packets from A to B, but not from B to A.
626   EXPECT_CALL(a_to_b_filter, FilterPacket(_)).WillRepeatedly(Return(true));
627   EXPECT_CALL(b_to_a_filter, FilterPacket(_)).WillRepeatedly(Return(false));
628 
629   // Run the simulation for a while, and expect that only B will receive any
630   // packets.
631   simulator.RunFor(QuicTime::Delta::FromSeconds(10));
632   EXPECT_GE(saturator_b.counter()->packets(), 1u);
633   EXPECT_EQ(saturator_a.counter()->packets(), 0u);
634 }
635 
636 // Set up a traffic policer in one direction that throttles at 25% of link
637 // bandwidth, and put two link saturators at each endpoint.
TEST_F(SimulatorTest,TrafficPolicer)638 TEST_F(SimulatorTest, TrafficPolicer) {
639   const QuicBandwidth bandwidth =
640       QuicBandwidth::FromBytesPerSecond(1024 * 1024);
641   const QuicTime::Delta base_propagation_delay =
642       QuicTime::Delta::FromMilliseconds(5);
643   const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
644 
645   Simulator simulator;
646   LinkSaturator saturator1(&simulator, "Saturator 1", 1000, "Saturator 2");
647   LinkSaturator saturator2(&simulator, "Saturator 2", 1000, "Saturator 1");
648   Switch network_switch(&simulator, "Switch", 8,
649                         bandwidth * base_propagation_delay * 10);
650 
651   static const QuicByteCount initial_burst = 1000 * 10;
652   static const QuicByteCount max_bucket_size = 1000 * 100;
653   static const QuicBandwidth target_bandwidth = bandwidth * 0.25;
654   TrafficPolicer policer(&simulator, "Policer", initial_burst, max_bucket_size,
655                          target_bandwidth, network_switch.port(2));
656 
657   SymmetricLink link1(&saturator1, network_switch.port(1), bandwidth,
658                       base_propagation_delay);
659   SymmetricLink link2(&saturator2, &policer, bandwidth, base_propagation_delay);
660 
661   // Ensure the initial burst passes without being dropped at all.
662   bool simulator_result = simulator.RunUntilOrTimeout(
663       [&saturator1]() {
664         return saturator1.bytes_transmitted() == initial_burst;
665       },
666       timeout);
667   ASSERT_TRUE(simulator_result);
668   saturator1.Pause();
669   simulator_result = simulator.RunUntilOrTimeout(
670       [&saturator2]() {
671         return saturator2.counter()->bytes() == initial_burst;
672       },
673       timeout);
674   ASSERT_TRUE(simulator_result);
675   saturator1.Resume();
676 
677   // Run for some time so that the initial burst is not visible.
678   const QuicTime::Delta simulation_time = QuicTime::Delta::FromSeconds(10);
679   simulator.RunFor(simulation_time);
680 
681   // Ensure we've transmitted the amount of data we expected.
682   for (auto* saturator : {&saturator1, &saturator2}) {
683     EXPECT_APPROX_EQ(bandwidth * simulation_time,
684                      saturator->bytes_transmitted(), 0.01f);
685   }
686 
687   // Check that only one direction is throttled.
688   EXPECT_APPROX_EQ(saturator1.bytes_transmitted() / 4,
689                    saturator2.counter()->bytes(), 0.1f);
690   EXPECT_APPROX_EQ(saturator2.bytes_transmitted(),
691                    saturator1.counter()->bytes(), 0.1f);
692 }
693 
694 // Ensure that a larger burst is allowed when the policed saturator exits
695 // quiescence.
TEST_F(SimulatorTest,TrafficPolicerBurst)696 TEST_F(SimulatorTest, TrafficPolicerBurst) {
697   const QuicBandwidth bandwidth =
698       QuicBandwidth::FromBytesPerSecond(1024 * 1024);
699   const QuicTime::Delta base_propagation_delay =
700       QuicTime::Delta::FromMilliseconds(5);
701   const QuicTime::Delta timeout = QuicTime::Delta::FromSeconds(10);
702 
703   Simulator simulator;
704   LinkSaturator saturator1(&simulator, "Saturator 1", 1000, "Saturator 2");
705   LinkSaturator saturator2(&simulator, "Saturator 2", 1000, "Saturator 1");
706   Switch network_switch(&simulator, "Switch", 8,
707                         bandwidth * base_propagation_delay * 10);
708 
709   const QuicByteCount initial_burst = 1000 * 10;
710   const QuicByteCount max_bucket_size = 1000 * 100;
711   const QuicBandwidth target_bandwidth = bandwidth * 0.25;
712   TrafficPolicer policer(&simulator, "Policer", initial_burst, max_bucket_size,
713                          target_bandwidth, network_switch.port(2));
714 
715   SymmetricLink link1(&saturator1, network_switch.port(1), bandwidth,
716                       base_propagation_delay);
717   SymmetricLink link2(&saturator2, &policer, bandwidth, base_propagation_delay);
718 
719   // Ensure at least one packet is sent on each side.
720   bool simulator_result = simulator.RunUntilOrTimeout(
721       [&saturator1, &saturator2]() {
722         return saturator1.packets_transmitted() > 0 &&
723                saturator2.packets_transmitted() > 0;
724       },
725       timeout);
726   ASSERT_TRUE(simulator_result);
727 
728   // Wait until the bucket fills up.
729   saturator1.Pause();
730   saturator2.Pause();
731   simulator.RunFor(1.5f * target_bandwidth.TransferTime(max_bucket_size));
732 
733   // Send a burst.
734   saturator1.Resume();
735   simulator.RunFor(bandwidth.TransferTime(max_bucket_size));
736   saturator1.Pause();
737   simulator.RunFor(2 * base_propagation_delay);
738 
739   // Expect the burst to pass without losses.
740   EXPECT_APPROX_EQ(saturator1.bytes_transmitted(),
741                    saturator2.counter()->bytes(), 0.1f);
742 
743   // Expect subsequent traffic to be policed.
744   saturator1.Resume();
745   simulator.RunFor(QuicTime::Delta::FromSeconds(10));
746   EXPECT_APPROX_EQ(saturator1.bytes_transmitted() / 4,
747                    saturator2.counter()->bytes(), 0.1f);
748 }
749 
750 // Test that the packet aggregation support in queues work.
TEST_F(SimulatorTest,PacketAggregation)751 TEST_F(SimulatorTest, PacketAggregation) {
752   // Model network where the delays are dominated by transfer delay.
753   const QuicBandwidth bandwidth = QuicBandwidth::FromBytesPerSecond(1000);
754   const QuicTime::Delta base_propagation_delay =
755       QuicTime::Delta::FromMicroseconds(1);
756   const QuicByteCount aggregation_threshold = 1000;
757   const QuicTime::Delta aggregation_timeout = QuicTime::Delta::FromSeconds(30);
758 
759   Simulator simulator;
760   LinkSaturator saturator1(&simulator, "Saturator 1", 10, "Saturator 2");
761   LinkSaturator saturator2(&simulator, "Saturator 2", 10, "Saturator 1");
762   Switch network_switch(&simulator, "Switch", 8, 10 * aggregation_threshold);
763 
764   // Make links with asymmetric propagation delay so that Saturator 2 only
765   // receives packets addressed to it.
766   SymmetricLink link1(&saturator1, network_switch.port(1), bandwidth,
767                       base_propagation_delay);
768   SymmetricLink link2(&saturator2, network_switch.port(2), bandwidth,
769                       2 * base_propagation_delay);
770 
771   // Enable aggregation in 1 -> 2 direction.
772   Queue* queue = network_switch.port_queue(2);
773   queue->EnableAggregation(aggregation_threshold, aggregation_timeout);
774 
775   // Enable aggregation in 2 -> 1 direction in a way that all packets are larger
776   // than the threshold, so that aggregation is effectively a no-op.
777   network_switch.port_queue(1)->EnableAggregation(5, aggregation_timeout);
778 
779   // Fill up the aggregation buffer up to 90% (900 bytes).
780   simulator.RunFor(0.9 * bandwidth.TransferTime(aggregation_threshold));
781   EXPECT_EQ(0u, saturator2.counter()->bytes());
782 
783   // Stop sending, ensure that given a timespan much shorter than timeout, the
784   // packets remain in the queue.
785   saturator1.Pause();
786   saturator2.Pause();
787   simulator.RunFor(QuicTime::Delta::FromSeconds(10));
788   EXPECT_EQ(0u, saturator2.counter()->bytes());
789   EXPECT_EQ(900u, queue->bytes_queued());
790 
791   // Ensure that all packets have reached the saturator not affected by
792   // aggregation.  Here, 10 extra bytes account for a misrouted packet in the
793   // beginning.
794   EXPECT_EQ(910u, saturator1.counter()->bytes());
795 
796   // Send 500 more bytes.  Since the aggregation threshold is 1000 bytes, and
797   // queue already has 900 bytes, 1000 bytes will be send and 400 will be in the
798   // queue.
799   saturator1.Resume();
800   simulator.RunFor(0.5 * bandwidth.TransferTime(aggregation_threshold));
801   saturator1.Pause();
802   simulator.RunFor(QuicTime::Delta::FromSeconds(10));
803   EXPECT_EQ(1000u, saturator2.counter()->bytes());
804   EXPECT_EQ(400u, queue->bytes_queued());
805 
806   // Actually time out, and cause all of the data to be received.
807   simulator.RunFor(aggregation_timeout);
808   EXPECT_EQ(1400u, saturator2.counter()->bytes());
809   EXPECT_EQ(0u, queue->bytes_queued());
810 
811   // Run saturator for a longer time, to ensure that the logic to cancel and
812   // reset alarms works correctly.
813   saturator1.Resume();
814   simulator.RunFor(5.5 * bandwidth.TransferTime(aggregation_threshold));
815   saturator1.Pause();
816   simulator.RunFor(QuicTime::Delta::FromSeconds(10));
817   EXPECT_EQ(6400u, saturator2.counter()->bytes());
818   EXPECT_EQ(500u, queue->bytes_queued());
819 
820   // Time out again.
821   simulator.RunFor(aggregation_timeout);
822   EXPECT_EQ(6900u, saturator2.counter()->bytes());
823   EXPECT_EQ(0u, queue->bytes_queued());
824 }
825 
826 }  // namespace simulator
827 }  // namespace quic
828