blob: 825dd6d06517c1f088af7448208d99ef352ebf19 [file] [log] [blame]
Mirko Bonadei248fdb12022-10-13 13:06:081/*
2 * Copyright 2022 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10#include "call/simulated_network.h"
11
12#include <algorithm>
13#include <map>
14#include <optional>
15#include <set>
16#include <vector>
17
18#include "absl/algorithm/container.h"
19#include "api/test/simulated_network.h"
20#include "api/units/data_rate.h"
21#include "api/units/time_delta.h"
22#include "test/gmock.h"
23#include "test/gtest.h"
24
25namespace webrtc {
26namespace {
27
28using ::testing::ElementsAre;
29
30PacketInFlightInfo PacketWithSize(size_t size) {
31 return PacketInFlightInfo(/*size=*/size, /*send_time_us=*/0, /*packet_id=*/1);
32}
33
34TEST(SimulatedNetworkTest, NextDeliveryTimeIsUnknownOnEmptyNetwork) {
35 SimulatedNetwork network = SimulatedNetwork({});
36 EXPECT_EQ(network.NextDeliveryTimeUs(), absl::nullopt);
37}
38
39TEST(SimulatedNetworkTest, EnqueueFirstPacketOnNetworkWithInfiniteCapacity) {
40 // A packet of 1 kB that gets enqueued on a network with infinite capacity
41 // should be ready to exit the network immediately.
42 SimulatedNetwork network = SimulatedNetwork({});
43 ASSERT_TRUE(network.EnqueuePacket(PacketWithSize(1'000)));
44
45 EXPECT_EQ(network.NextDeliveryTimeUs(), 0);
46}
47
48TEST(SimulatedNetworkTest, EnqueueFirstPacketOnNetworkWithLimitedCapacity) {
49 // A packet of 125 bytes that gets enqueued on a network with 1 kbps capacity
50 // should be ready to exit the network in 1 second.
51 SimulatedNetwork network = SimulatedNetwork({.link_capacity_kbps = 1});
52 ASSERT_TRUE(network.EnqueuePacket(PacketWithSize(125)));
53
54 EXPECT_EQ(network.NextDeliveryTimeUs(), TimeDelta::Seconds(1).us());
55}
56
57TEST(SimulatedNetworkTest,
58 EnqueuePacketsButNextDeliveryIsBasedOnFirstEnqueuedPacket) {
59 // A packet of 125 bytes that gets enqueued on a network with 1 kbps capacity
60 // should be ready to exit the network in 1 second.
61 SimulatedNetwork network = SimulatedNetwork({.link_capacity_kbps = 1});
62 ASSERT_TRUE(network.EnqueuePacket(
63 PacketInFlightInfo(/*size=*/125, /*send_time_us=*/0, /*packet_id=*/1)));
64 EXPECT_EQ(network.NextDeliveryTimeUs(), TimeDelta::Seconds(1).us());
65
66 // Enqueuing another packet after 100 us doesn't change the next delivery
67 // time.
68 ASSERT_TRUE(network.EnqueuePacket(
69 PacketInFlightInfo(/*size=*/125, /*send_time_us=*/100, /*packet_id=*/2)));
70 EXPECT_EQ(network.NextDeliveryTimeUs(), TimeDelta::Seconds(1).us());
71
72 // Enqueuing another packet after 2 seconds doesn't change the next delivery
73 // time since the first packet has not left the network yet.
74 ASSERT_TRUE(network.EnqueuePacket(PacketInFlightInfo(
75 /*size=*/125, /*send_time_us=*/TimeDelta::Seconds(2).us(),
76 /*packet_id=*/3)));
77 EXPECT_EQ(network.NextDeliveryTimeUs(), TimeDelta::Seconds(1).us());
78}
79
80TEST(SimulatedNetworkTest, EnqueueFailsWhenQueueLengthIsReached) {
81 SimulatedNetwork network =
82 SimulatedNetwork({.queue_length_packets = 1, .link_capacity_kbps = 1});
83 ASSERT_TRUE(network.EnqueuePacket(
84 PacketInFlightInfo(/*size=*/125, /*send_time_us=*/0, /*packet_id=*/1)));
85
86 // Until there is 1 packet in the queue, no other packets can be enqueued,
87 // the only way to make space for new packets is calling
88 // DequeueDeliverablePackets at a time greater than or equal to
89 // NextDeliveryTimeUs.
90 EXPECT_FALSE(network.EnqueuePacket(
91 PacketInFlightInfo(/*size=*/125,
92 /*send_time_us=*/TimeDelta::Seconds(0.5).us(),
93 /*packet_id=*/2)));
94
95 // Even if the send_time_us is after NextDeliveryTimeUs, it is still not
96 // possible to enqueue a new packet since the client didn't deque any packet
97 // from the queue (in this case the client is introducing unbounded delay but
98 // the network cannot do anything about it).
99 EXPECT_FALSE(network.EnqueuePacket(
100 PacketInFlightInfo(/*size=*/125,
101 /*send_time_us=*/TimeDelta::Seconds(2).us(),
102 /*packet_id=*/3)));
103}
104
105TEST(SimulatedNetworkTest, PacketOverhead) {
106 // A packet of 125 bytes that gets enqueued on a network with 1 kbps capacity
107 // should be ready to exit the network in 1 second, but since there is an
108 // overhead per packet of 125 bytes, it will exit the network after 2 seconds.
109 SimulatedNetwork network =
110 SimulatedNetwork({.link_capacity_kbps = 1, .packet_overhead = 125});
111 ASSERT_TRUE(network.EnqueuePacket(PacketWithSize(125)));
112
113 EXPECT_EQ(network.NextDeliveryTimeUs(), TimeDelta::Seconds(2).us());
114}
115
116TEST(SimulatedNetworkTest,
117 DequeueDeliverablePacketsLeavesPacketsInCapacityLink) {
118 // A packet of 125 bytes that gets enqueued on a network with 1 kbps capacity
119 // should be ready to exit the network in 1 second.
120 SimulatedNetwork network = SimulatedNetwork({.link_capacity_kbps = 1});
121 ASSERT_TRUE(network.EnqueuePacket(
122 PacketInFlightInfo(/*size=*/125, /*send_time_us=*/0, /*packet_id=*/1)));
123 // Enqueue another packet of 125 bytes (this one should exit after 2 seconds).
124 ASSERT_TRUE(network.EnqueuePacket(
125 PacketInFlightInfo(/*size=*/125,
126 /*send_time_us=*/TimeDelta::Seconds(1).us(),
127 /*packet_id=*/2)));
128
129 // The first packet will exit after 1 second, so that is the next delivery
130 // time.
131 EXPECT_EQ(network.NextDeliveryTimeUs(), TimeDelta::Seconds(1).us());
132
133 // After 1 seconds, we collect the delivered packets...
134 std::vector<PacketDeliveryInfo> delivered_packets =
135 network.DequeueDeliverablePackets(
136 /*receive_time_us=*/TimeDelta::Seconds(1).us());
137 ASSERT_EQ(delivered_packets.size(), 1ul);
138 EXPECT_EQ(delivered_packets[0].packet_id, 1ul);
139 EXPECT_EQ(delivered_packets[0].receive_time_us, TimeDelta::Seconds(1).us());
140
141 // ... And after the first enqueued packet has left the network, the next
142 // delivery time reflects the delivery time of the next packet.
143 EXPECT_EQ(network.NextDeliveryTimeUs(), TimeDelta::Seconds(2).us());
144}
145
146TEST(SimulatedNetworkTest,
147 DequeueDeliverablePacketsAppliesConfigChangesToCapacityLink) {
148 // A packet of 125 bytes that gets enqueued on a network with 1 kbps capacity
149 // should be ready to exit the network in 1 second.
150 SimulatedNetwork network = SimulatedNetwork({.link_capacity_kbps = 1});
151 const PacketInFlightInfo packet_1 =
152 PacketInFlightInfo(/*size=*/125, /*send_time_us=*/0, /*packet_id=*/1);
153 ASSERT_TRUE(network.EnqueuePacket(packet_1));
154
155 // Enqueue another packet of 125 bytes with send time 1 second so this should
156 // exit after 2 seconds.
157 PacketInFlightInfo packet_2 =
158 PacketInFlightInfo(/*size=*/125,
159 /*send_time_us=*/TimeDelta::Seconds(1).us(),
160 /*packet_id=*/2);
161 ASSERT_TRUE(network.EnqueuePacket(packet_2));
162
163 // The first packet will exit after 1 second, so that is the next delivery
164 // time.
165 EXPECT_EQ(network.NextDeliveryTimeUs(), TimeDelta::Seconds(1).us());
166
167 // Since the link capacity changes from 1 kbps to 10 kbps, packets will take
168 // 100 ms each to leave the network.
169 network.SetConfig({.link_capacity_kbps = 10});
170
171 // The next delivery time doesn't change (it will be updated, if needed at
172 // DequeueDeliverablePackets time).
173 EXPECT_EQ(network.NextDeliveryTimeUs(), TimeDelta::Seconds(1).us());
174
175 // Getting the first enqueued packet after 100 ms.
176 std::vector<PacketDeliveryInfo> delivered_packets =
177 network.DequeueDeliverablePackets(
178 /*receive_time_us=*/TimeDelta::Millis(100).us());
179 ASSERT_EQ(delivered_packets.size(), 1ul);
180 EXPECT_THAT(delivered_packets,
181 ElementsAre(PacketDeliveryInfo(
182 /*source=*/packet_1,
183 /*receive_time_us=*/TimeDelta::Millis(100).us())));
184
185 // Getting the second enqueued packet that cannot be delivered before its send
186 // time, hence it will be delivered after 1.1 seconds.
187 EXPECT_EQ(network.NextDeliveryTimeUs(), TimeDelta::Millis(1100).us());
188 delivered_packets = network.DequeueDeliverablePackets(
189 /*receive_time_us=*/TimeDelta::Millis(1100).us());
190 ASSERT_EQ(delivered_packets.size(), 1ul);
191 EXPECT_THAT(delivered_packets,
192 ElementsAre(PacketDeliveryInfo(
193 /*source=*/packet_2,
194 /*receive_time_us=*/TimeDelta::Millis(1100).us())));
195}
196
197TEST(SimulatedNetworkTest, NetworkEmptyAfterLastPacketDequeued) {
198 // A packet of 125 bytes that gets enqueued on a network with 1 kbps capacity
199 // should be ready to exit the network in 1 second.
200 SimulatedNetwork network = SimulatedNetwork({.link_capacity_kbps = 1});
201 ASSERT_TRUE(network.EnqueuePacket(PacketWithSize(125)));
202
203 // Collecting all the delivered packets ...
204 std::vector<PacketDeliveryInfo> delivered_packets =
205 network.DequeueDeliverablePackets(
206 /*receive_time_us=*/TimeDelta::Seconds(1).us());
207 EXPECT_EQ(delivered_packets.size(), 1ul);
208
209 // ... leaves the network empty.
210 EXPECT_EQ(network.NextDeliveryTimeUs(), absl::nullopt);
211}
212
213TEST(SimulatedNetworkTest, DequeueDeliverablePacketsOnLateCall) {
214 // A packet of 125 bytes that gets enqueued on a network with 1 kbps capacity
215 // should be ready to exit the network in 1 second.
216 SimulatedNetwork network = SimulatedNetwork({.link_capacity_kbps = 1});
217 ASSERT_TRUE(network.EnqueuePacket(
218 PacketInFlightInfo(/*size=*/125, /*send_time_us=*/0, /*packet_id=*/1)));
219
220 // Enqueue another packet of 125 bytes with send time 1 second so this should
221 // exit after 2 seconds.
222 ASSERT_TRUE(network.EnqueuePacket(
223 PacketInFlightInfo(/*size=*/125,
224 /*send_time_us=*/TimeDelta::Seconds(1).us(),
225 /*packet_id=*/2)));
226
227 // Collecting delivered packets after 3 seconds will result in the delivery of
228 // both the enqueued packets.
229 std::vector<PacketDeliveryInfo> delivered_packets =
230 network.DequeueDeliverablePackets(
231 /*receive_time_us=*/TimeDelta::Seconds(3).us());
232 EXPECT_EQ(delivered_packets.size(), 2ul);
233}
234
235TEST(SimulatedNetworkTest,
236 DequeueDeliverablePacketsOnEarlyCallReturnsNoPackets) {
237 // A packet of 125 bytes that gets enqueued on a network with 1 kbps capacity
238 // should be ready to exit the network in 1 second.
239 SimulatedNetwork network = SimulatedNetwork({.link_capacity_kbps = 1});
240 ASSERT_TRUE(network.EnqueuePacket(PacketWithSize(125)));
241
242 // Collecting delivered packets after 0.5 seconds will result in the delivery
243 // of 0 packets.
244 std::vector<PacketDeliveryInfo> delivered_packets =
245 network.DequeueDeliverablePackets(
246 /*receive_time_us=*/TimeDelta::Seconds(0.5).us());
247 EXPECT_EQ(delivered_packets.size(), 0ul);
248
249 // Since the first enqueued packet was supposed to exit after 1 second.
250 EXPECT_EQ(network.NextDeliveryTimeUs(), TimeDelta::Seconds(1).us());
251}
252
253TEST(SimulatedNetworkTest, QueueDelayMsWithoutStandardDeviation) {
254 // A packet of 125 bytes that gets enqueued on a network with 1 kbps capacity
255 // should be ready to exit the network in 1 second.
256 SimulatedNetwork network =
257 SimulatedNetwork({.queue_delay_ms = 100, .link_capacity_kbps = 1});
258 ASSERT_TRUE(network.EnqueuePacket(PacketWithSize(125)));
259 // The next delivery time is still 1 second even if there are 100 ms of
260 // extra delay but this will be applied at DequeueDeliverablePackets time.
261 ASSERT_EQ(network.NextDeliveryTimeUs(), TimeDelta::Seconds(1).us());
262
263 // Since all packets are delayed by 100 ms, after 1 second, no packets will
264 // exit the network.
265 std::vector<PacketDeliveryInfo> delivered_packets =
266 network.DequeueDeliverablePackets(
267 /*receive_time_us=*/TimeDelta::Seconds(1).us());
268 EXPECT_EQ(delivered_packets.size(), 0ul);
269
270 // And the updated next delivery time takes into account the extra delay of
271 // 100 ms so the first packet in the network will be delivered after 1.1
272 // seconds.
273 EXPECT_EQ(network.NextDeliveryTimeUs(), TimeDelta::Millis(1100).us());
274 delivered_packets = network.DequeueDeliverablePackets(
275 /*receive_time_us=*/TimeDelta::Millis(1100).us());
276 EXPECT_EQ(delivered_packets.size(), 1ul);
277}
278
279TEST(SimulatedNetworkTest,
280 QueueDelayMsWithStandardDeviationAndReorderNotAllowed) {
281 SimulatedNetwork network =
282 SimulatedNetwork({.queue_delay_ms = 100,
283 .delay_standard_deviation_ms = 90,
284 .link_capacity_kbps = 1,
285 .allow_reordering = false});
286 // A packet of 125 bytes that gets enqueued on a network with 1 kbps capacity
287 // should be ready to exit the network in 1 second.
288 ASSERT_TRUE(network.EnqueuePacket(
289 PacketInFlightInfo(/*size=*/125, /*send_time_us=*/0, /*packet_id=*/1)));
290
291 // But 3 more packets of size 1 byte are enqueued at the same time.
292 ASSERT_TRUE(network.EnqueuePacket(
293 PacketInFlightInfo(/*size=*/1, /*send_time_us=*/0, /*packet_id=*/2)));
294 ASSERT_TRUE(network.EnqueuePacket(
295 PacketInFlightInfo(/*size=*/1, /*send_time_us=*/0, /*packet_id=*/3)));
296 ASSERT_TRUE(network.EnqueuePacket(
297 PacketInFlightInfo(/*size=*/1, /*send_time_us=*/0, /*packet_id=*/4)));
298
299 // After 5 seconds all of them exit the network.
300 std::vector<PacketDeliveryInfo> delivered_packets =
301 network.DequeueDeliverablePackets(
302 /*receive_time_us=*/TimeDelta::Seconds(5).us());
303 ASSERT_EQ(delivered_packets.size(), 4ul);
304
305 // And they are still in order even if the delay was applied.
306 EXPECT_EQ(delivered_packets[0].packet_id, 1ul);
307 EXPECT_EQ(delivered_packets[1].packet_id, 2ul);
308 EXPECT_GE(delivered_packets[1].receive_time_us,
309 delivered_packets[0].receive_time_us);
310 EXPECT_EQ(delivered_packets[2].packet_id, 3ul);
311 EXPECT_GE(delivered_packets[2].receive_time_us,
312 delivered_packets[1].receive_time_us);
313 EXPECT_EQ(delivered_packets[3].packet_id, 4ul);
314 EXPECT_GE(delivered_packets[3].receive_time_us,
315 delivered_packets[2].receive_time_us);
316}
317
318TEST(SimulatedNetworkTest, QueueDelayMsWithStandardDeviationAndReorderAllowed) {
319 SimulatedNetwork network =
320 SimulatedNetwork({.queue_delay_ms = 100,
321 .delay_standard_deviation_ms = 90,
322 .link_capacity_kbps = 1,
323 .allow_reordering = true},
324 /*random_seed=*/1);
325 // A packet of 125 bytes that gets enqueued on a network with 1 kbps capacity
326 // should be ready to exit the network in 1 second.
327 ASSERT_TRUE(network.EnqueuePacket(
328 PacketInFlightInfo(/*size=*/125, /*send_time_us=*/0, /*packet_id=*/1)));
329
330 // But 3 more packets of size 1 byte are enqueued at the same time.
331 ASSERT_TRUE(network.EnqueuePacket(
332 PacketInFlightInfo(/*size=*/1, /*send_time_us=*/0, /*packet_id=*/2)));
333 ASSERT_TRUE(network.EnqueuePacket(
334 PacketInFlightInfo(/*size=*/1, /*send_time_us=*/0, /*packet_id=*/3)));
335 ASSERT_TRUE(network.EnqueuePacket(
336 PacketInFlightInfo(/*size=*/1, /*send_time_us=*/0, /*packet_id=*/4)));
337
338 // After 5 seconds all of them exit the network.
339 std::vector<PacketDeliveryInfo> delivered_packets =
340 network.DequeueDeliverablePackets(
341 /*receive_time_us=*/TimeDelta::Seconds(5).us());
342 ASSERT_EQ(delivered_packets.size(), 4ul);
343
344 // And they have been reordered accorting to the applied extra delay.
345 EXPECT_EQ(delivered_packets[0].packet_id, 3ul);
346 EXPECT_EQ(delivered_packets[1].packet_id, 1ul);
347 EXPECT_GE(delivered_packets[1].receive_time_us,
348 delivered_packets[0].receive_time_us);
349 EXPECT_EQ(delivered_packets[2].packet_id, 2ul);
350 EXPECT_GE(delivered_packets[2].receive_time_us,
351 delivered_packets[1].receive_time_us);
352 EXPECT_EQ(delivered_packets[3].packet_id, 4ul);
353 EXPECT_GE(delivered_packets[3].receive_time_us,
354 delivered_packets[2].receive_time_us);
355}
356
357TEST(SimulatedNetworkTest, PacketLoss) {
358 // On a network with 50% probablility of packet loss ...
359 SimulatedNetwork network = SimulatedNetwork({.loss_percent = 50});
360
361 // Enqueueing 8 packets ...
362 for (int i = 0; i < 8; i++) {
363 ASSERT_TRUE(network.EnqueuePacket(PacketInFlightInfo(
364 /*size=*/1, /*send_time_us=*/0, /*packet_id=*/i + 1)));
365 }
366
367 std::vector<PacketDeliveryInfo> delivered_packets =
368 network.DequeueDeliverablePackets(
369 /*receive_time_us=*/TimeDelta::Seconds(5).us());
370 EXPECT_EQ(delivered_packets.size(), 8ul);
371
372 // Results in the loss of 4 of them.
373 int lost_packets = 0;
374 for (const auto& packet : delivered_packets) {
375 if (packet.receive_time_us == PacketDeliveryInfo::kNotReceived) {
376 lost_packets++;
377 }
378 }
379 EXPECT_EQ(lost_packets, 4);
380}
381
382TEST(SimulatedNetworkTest, PacketLossBurst) {
383 // On a network with 50% probablility of packet loss and an average burst loss
384 // length of 100 ...
385 SimulatedNetwork network = SimulatedNetwork(
386 {.loss_percent = 50, .avg_burst_loss_length = 100}, /*random_seed=*/1);
387
388 // Enqueueing 20 packets ...
389 for (int i = 0; i < 20; i++) {
390 ASSERT_TRUE(network.EnqueuePacket(PacketInFlightInfo(
391 /*size=*/1, /*send_time_us=*/0, /*packet_id=*/i + 1)));
392 }
393
394 std::vector<PacketDeliveryInfo> delivered_packets =
395 network.DequeueDeliverablePackets(
396 /*receive_time_us=*/TimeDelta::Seconds(5).us());
397 EXPECT_EQ(delivered_packets.size(), 20ul);
398
399 // Results in a burst of lost packets after the first packet lost.
400 // With the current random seed, the first 12 are not lost, while the
401 // last 8 are.
402 int current_packet = 0;
403 for (const auto& packet : delivered_packets) {
404 if (current_packet < 12) {
405 EXPECT_NE(packet.receive_time_us, PacketDeliveryInfo::kNotReceived);
406 current_packet++;
407 } else {
408 EXPECT_EQ(packet.receive_time_us, PacketDeliveryInfo::kNotReceived);
409 current_packet++;
410 }
411 }
412}
413
414TEST(SimulatedNetworkTest, PauseTransmissionUntil) {
415 // 3 packets of 125 bytes that gets enqueued on a network with 1 kbps capacity
416 // should be ready to exit the network after 1, 2 and 3 seconds respectively.
417 SimulatedNetwork network = SimulatedNetwork({.link_capacity_kbps = 1});
418 ASSERT_TRUE(network.EnqueuePacket(
419 PacketInFlightInfo(/*size=*/125, /*send_time_us=*/0, /*packet_id=*/1)));
420 ASSERT_TRUE(network.EnqueuePacket(
421 PacketInFlightInfo(/*size=*/125, /*send_time_us=*/0, /*packet_id=*/2)));
422 ASSERT_TRUE(network.EnqueuePacket(
423 PacketInFlightInfo(/*size=*/125, /*send_time_us=*/0, /*packet_id=*/3)));
424 ASSERT_EQ(network.NextDeliveryTimeUs(), TimeDelta::Seconds(1).us());
425
426 // The network gets paused for 5 seconds, which means that the first packet
427 // can exit after 5 seconds instead of 1 second.
428 network.PauseTransmissionUntil(TimeDelta::Seconds(5).us());
429
430 // No packets after 1 second.
431 std::vector<PacketDeliveryInfo> delivered_packets =
432 network.DequeueDeliverablePackets(
433 /*receive_time_us=*/TimeDelta::Seconds(1).us());
434 EXPECT_EQ(delivered_packets.size(), 0ul);
435 EXPECT_EQ(network.NextDeliveryTimeUs(), TimeDelta::Seconds(5).us());
436
437 // The first packet exits after 5 seconds.
438 delivered_packets = network.DequeueDeliverablePackets(
439 /*receive_time_us=*/TimeDelta::Seconds(5).us());
440 EXPECT_EQ(delivered_packets.size(), 1ul);
441
442 // After the first packet is exited, the next delivery time reflects the
443 // delivery time of the next packet which accounts for the network pause.
444 EXPECT_EQ(network.NextDeliveryTimeUs(), TimeDelta::Seconds(6).us());
445
446 // And 2 seconds after the exit of the first enqueued packet, the following 2
447 // packets are also delivered.
448 delivered_packets = network.DequeueDeliverablePackets(
449 /*receive_time_us=*/TimeDelta::Seconds(7).us());
450 EXPECT_EQ(delivered_packets.size(), 2ul);
451}
452
453TEST(SimulatedNetworkTest, CongestedNetworkRespectsLinkCapacity) {
454 SimulatedNetwork network = SimulatedNetwork({.link_capacity_kbps = 1});
455 for (size_t i = 0; i < 1'000; ++i) {
456 ASSERT_TRUE(network.EnqueuePacket(
457 PacketInFlightInfo(/*size=*/125, /*send_time_us=*/0, /*packet_id=*/i)));
458 }
459 PacketDeliveryInfo last_delivered_packet{
460 PacketInFlightInfo(/*size=*/0, /*send_time_us=*/0, /*packet_id=*/0), 0};
461 while (network.NextDeliveryTimeUs().has_value()) {
462 std::vector<PacketDeliveryInfo> delivered_packets =
463 network.DequeueDeliverablePackets(
464 /*receive_time_us=*/network.NextDeliveryTimeUs().value());
465 if (!delivered_packets.empty()) {
466 last_delivered_packet = delivered_packets.back();
467 }
468 }
469 // 1000 packets of 1000 bits each will take 1000 seconds to exit a 1 kpbs
470 // network.
471 EXPECT_EQ(last_delivered_packet.receive_time_us,
472 TimeDelta::Seconds(1000).us());
473 EXPECT_EQ(last_delivered_packet.packet_id, 999ul);
474}
475
476TEST(SimulatedNetworkTest, EnqueuePacketWithSubSecondNonMonotonicBehaviour) {
477 // On multi-core systems, different threads can experience sub-millisecond non
478 // monothonic behaviour when running on different cores. This test checks that
479 // when a non monotonic packet enqueue, the network continues to work and the
480 // out of order packet is sent anyway.
481 SimulatedNetwork network = SimulatedNetwork({.link_capacity_kbps = 1});
482 ASSERT_TRUE(network.EnqueuePacket(PacketInFlightInfo(
483 /*size=*/125, /*send_time_us=*/TimeDelta::Seconds(1).us(),
484 /*packet_id=*/0)));
485 ASSERT_TRUE(network.EnqueuePacket(PacketInFlightInfo(
486 /*size=*/125, /*send_time_us=*/TimeDelta::Seconds(1).us() - 1,
487 /*packet_id=*/1)));
488
489 std::vector<PacketDeliveryInfo> delivered_packets =
490 network.DequeueDeliverablePackets(
491 /*receive_time_us=*/TimeDelta::Seconds(2).us());
492 ASSERT_EQ(delivered_packets.size(), 1ul);
493 EXPECT_EQ(delivered_packets[0].packet_id, 0ul);
494 EXPECT_EQ(delivered_packets[0].receive_time_us, TimeDelta::Seconds(2).us());
495
496 delivered_packets = network.DequeueDeliverablePackets(
497 /*receive_time_us=*/TimeDelta::Seconds(3).us());
498 ASSERT_EQ(delivered_packets.size(), 1ul);
499 EXPECT_EQ(delivered_packets[0].packet_id, 1ul);
500 EXPECT_EQ(delivered_packets[0].receive_time_us, TimeDelta::Seconds(3).us());
501}
502
503// TODO(bugs.webrtc.org/14525): Re-enable when the DCHECK will be uncommented
504// and the non-monotonic events on real time clock tests is solved/understood.
505// TEST(SimulatedNetworkDeathTest, EnqueuePacketExpectMonotonicSendTime) {
506// SimulatedNetwork network = SimulatedNetwork({.link_capacity_kbps = 1});
507// ASSERT_TRUE(network.EnqueuePacket(PacketInFlightInfo(
508// /*size=*/125, /*send_time_us=*/2'000'000, /*packet_id=*/0)));
509// EXPECT_DEATH_IF_SUPPORTED(network.EnqueuePacket(PacketInFlightInfo(
510// /*size=*/125, /*send_time_us=*/900'000, /*packet_id=*/1)), "");
511// }
512} // namespace
513} // namespace webrtc