1 // Copyright 2020 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 "cast/streaming/sender_packet_router.h"
6
7 #include <chrono>
8
9 #include "cast/streaming/constants.h"
10 #include "cast/streaming/mock_environment.h"
11 #include "cast/streaming/testing/simple_socket_subscriber.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
14 #include "platform/base/ip_address.h"
15 #include "platform/test/fake_clock.h"
16 #include "platform/test/fake_task_runner.h"
17 #include "util/big_endian.h"
18 #include "util/chrono_helpers.h"
19 #include "util/osp_logging.h"
20
21 using testing::_;
22 using testing::Invoke;
23 using testing::Mock;
24 using testing::Return;
25
26 namespace openscreen {
27 namespace cast {
28 namespace {
29
30 const IPEndpoint kRemoteEndpoint{
31 // Use a random IPv6 address in the range reserved for "documentation
32 // purposes."
33 IPAddress::Parse("2001:db8:0d93:69c2:fd1a:49a6:a7c0:e8a6").value(), 25476};
34
35 const IPEndpoint kUnexpectedEndpoint{
36 IPAddress::Parse("2001:db8:0d93:69c2:fd1a:49a6:a7c0:e8a7").value(), 25476};
37
38 // Limited burst parameters to simplify unit testing.
39 constexpr int kMaxPacketsPerBurst = 3;
40 constexpr auto kBurstInterval = milliseconds(10);
41
42 constexpr Ssrc kAudioReceiverSsrc = 2;
43 constexpr Ssrc kVideoReceiverSsrc = 32;
44
45 const uint8_t kGarbagePacket[] = {
46 0x42, 0x61, 0x16, 0x17, 0x26, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69,
47 0x6e, 0x67, 0x2f, 0x63, 0x61, 0x73, 0x74, 0x2f, 0x63, 0x6f, 0x6d, 0x70,
48 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x72, 0x74, 0x63, 0x70, 0x5f};
49
50 // clang-format off
51 const uint8_t kValidAudioRtcpPacket[] = {
52 0b10000000, // Version=2, Padding=no, ReportCount=0.
53 201, // RTCP Packet type byte.
54 0x00, 0x01, // Length of remainder of packet, in 32-bit words.
55 0x00, 0x00, 0x00, 0x02, // Receiver SSRC.
56 };
57
58 const uint8_t kValidAudioRtpPacket[] = {
59 0b10000000, // Version/Padding byte.
60 96, // Payload type byte.
61 0xbe, 0xef, // Sequence number.
62 9, 8, 7, 6, // RTP timestamp.
63 0, 0, 0, 2, // SSRC.
64 0b10000000, // Is key frame, no extensions.
65 5, // Frame ID.
66 0xa, 0xb, // Packet ID.
67 0xa, 0xc, // Max packet ID.
68 0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8, // Payload.
69 };
70 // clang-format on
71
72 // Returns a copy of an |original| RTCP packet, but with its send-to SSRC
73 // modified to the given |alternate_ssrc|.
MakeRtcpPacketWithAlternateReceiverSsrc(absl::Span<const uint8_t> original,Ssrc alternate_ssrc)74 std::vector<uint8_t> MakeRtcpPacketWithAlternateReceiverSsrc(
75 absl::Span<const uint8_t> original,
76 Ssrc alternate_ssrc) {
77 constexpr int kOffsetToSsrcField = 4;
78 std::vector<uint8_t> out(original.begin(), original.end());
79 OSP_CHECK_GE(out.size(), kOffsetToSsrcField + sizeof(uint32_t));
80 WriteBigEndian(uint32_t{alternate_ssrc}, out.data() + kOffsetToSsrcField);
81 return out;
82 }
83
84 // Serializes the |flag| and |send_time| into the front of |buffer| so the tests
85 // can make unique packets and confirm their identities after passing through
86 // various components.
MakeFakePacketWithFlag(char flag,Clock::time_point send_time,absl::Span<uint8_t> buffer)87 absl::Span<uint8_t> MakeFakePacketWithFlag(char flag,
88 Clock::time_point send_time,
89 absl::Span<uint8_t> buffer) {
90 const Clock::duration::rep ticks = send_time.time_since_epoch().count();
91 const auto packet_size = sizeof(ticks) + sizeof(flag);
92 buffer = buffer.subspan(0, packet_size);
93 OSP_CHECK_EQ(buffer.size(), packet_size);
94 WriteBigEndian(ticks, buffer.data());
95 buffer[sizeof(ticks)] = flag;
96 return buffer;
97 }
98
99 // Same as MakeFakePacketWithFlag(), but for tests that don't use the flag.
MakeFakePacket(Clock::time_point send_time,absl::Span<uint8_t> buffer)100 absl::Span<uint8_t> MakeFakePacket(Clock::time_point send_time,
101 absl::Span<uint8_t> buffer) {
102 return MakeFakePacketWithFlag('?', send_time, buffer);
103 }
104
105 // Returns the flag that was placed in the given |fake_packet|, or '?' if
106 // unknown.
ParseFlag(absl::Span<const uint8_t> fake_packet)107 char ParseFlag(absl::Span<const uint8_t> fake_packet) {
108 constexpr auto kFlagOffset = sizeof(Clock::duration::rep);
109 if (fake_packet.size() == (kFlagOffset + sizeof(char))) {
110 return static_cast<char>(fake_packet[kFlagOffset]);
111 }
112 return '?';
113 }
114
115 // Deserializes and returns the timestamp that was placed in the given |packet|
116 // by MakeFakePacketWithFlag().
ParseTimestamp(absl::Span<const uint8_t> fake_packet)117 Clock::time_point ParseTimestamp(absl::Span<const uint8_t> fake_packet) {
118 Clock::duration::rep ticks = 0;
119 if (fake_packet.size() >= sizeof(ticks)) {
120 ticks = ReadBigEndian<Clock::duration::rep>(fake_packet.data());
121 }
122 return Clock::time_point() + Clock::duration(ticks);
123 }
124
125 // Returns an empty version of |buffer|.
ToEmptyPacketBuffer(Clock::time_point send_time,absl::Span<uint8_t> buffer)126 absl::Span<uint8_t> ToEmptyPacketBuffer(Clock::time_point send_time,
127 absl::Span<uint8_t> buffer) {
128 return buffer.subspan(0, 0);
129 }
130
131 class MockSender : public SenderPacketRouter::Sender {
132 public:
133 MockSender() = default;
134 ~MockSender() override = default;
135
136 MOCK_METHOD(void,
137 OnReceivedRtcpPacket,
138 (Clock::time_point arrival_time,
139 absl::Span<const uint8_t> packet),
140 (override));
141 MOCK_METHOD(absl::Span<uint8_t>,
142 GetRtcpPacketForImmediateSend,
143 (Clock::time_point send_time, absl::Span<uint8_t> buffer),
144 (override));
145 MOCK_METHOD(absl::Span<uint8_t>,
146 GetRtpPacketForImmediateSend,
147 (Clock::time_point send_time, absl::Span<uint8_t> buffer),
148 (override));
149 MOCK_METHOD(Clock::time_point, GetRtpResumeTime, (), (override));
150 };
151
152 class SenderPacketRouterTest : public testing::Test {
153 public:
SenderPacketRouterTest()154 SenderPacketRouterTest()
155 : clock_(Clock::now()),
156 task_runner_(&clock_),
157 env_(&FakeClock::now, &task_runner_),
158 router_(&env_, kMaxPacketsPerBurst, kBurstInterval) {
159 env_.SetSocketSubscriber(&socket_subscriber_);
160 }
161
162 ~SenderPacketRouterTest() override = default;
163
env()164 MockEnvironment* env() { return &env_; }
router()165 SenderPacketRouter* router() { return &router_; }
audio_sender()166 MockSender* audio_sender() { return &audio_sender_; }
video_sender()167 MockSender* video_sender() { return &video_sender_; }
168
SimulatePacketArrivedNow(const IPEndpoint & source,absl::Span<const uint8_t> packet)169 void SimulatePacketArrivedNow(const IPEndpoint& source,
170 absl::Span<const uint8_t> packet) {
171 static_cast<Environment::PacketConsumer*>(&router_)->OnReceivedPacket(
172 source, env_.now(), std::vector<uint8_t>(packet.begin(), packet.end()));
173 }
174
AdvanceClockAndRunTasks(Clock::duration delta)175 void AdvanceClockAndRunTasks(Clock::duration delta) { clock_.Advance(delta); }
RunTasksUntilIdle()176 void RunTasksUntilIdle() { task_runner_.RunTasksUntilIdle(); }
177
178 private:
179 FakeClock clock_;
180 FakeTaskRunner task_runner_;
181 testing::NiceMock<MockEnvironment> env_;
182 SenderPacketRouter router_;
183 testing::NiceMock<MockSender> audio_sender_;
184 testing::NiceMock<MockSender> video_sender_;
185 SimpleSubscriber socket_subscriber_;
186 };
187
188 // Tests that the SenderPacketRouter is correctly configured from the specific
189 // burst parameters that were passed to its constructor. This confirms internal
190 // calculations based on these parameters.
TEST_F(SenderPacketRouterTest,IsConfiguredFromBurstParameters)191 TEST_F(SenderPacketRouterTest, IsConfiguredFromBurstParameters) {
192 EXPECT_EQ(env()->GetMaxPacketSize(), router()->max_packet_size());
193
194 // The following lower-bound/upper-bound values were hand-calculated based on
195 // the arguments that were passed to the SenderPacketRouter constructor, and
196 // assuming a packet size anywhere from 256 bytes to one megabyte.
197 //
198 // The exact value for max_burst_bitrate() is not known here because
199 // Environment::GetMaxPacketSize() depends on the platform and network medium.
200 // To test for an exact value would require duplicating the math in
201 // SenderPacketRouter::ComputeMaxBurstBitrate() here (and then *what* would we
202 // be testing?).
203 EXPECT_LE(614400, router()->max_burst_bitrate());
204 EXPECT_GE(2147483647, router()->max_burst_bitrate());
205 }
206
TEST_F(SenderPacketRouterTest,IgnoresPacketsFromUnexpectedSources)207 TEST_F(SenderPacketRouterTest, IgnoresPacketsFromUnexpectedSources) {
208 env()->set_remote_endpoint(kRemoteEndpoint);
209 router()->OnSenderCreated(kAudioReceiverSsrc, audio_sender());
210 EXPECT_CALL(*audio_sender(), OnReceivedRtcpPacket(_, _)).Times(0);
211 SimulatePacketArrivedNow(kUnexpectedEndpoint,
212 absl::Span<const uint8_t>(kValidAudioRtcpPacket));
213 router()->OnSenderDestroyed(kAudioReceiverSsrc);
214 }
215
TEST_F(SenderPacketRouterTest,IgnoresInboundPacketsContainingGarbage)216 TEST_F(SenderPacketRouterTest, IgnoresInboundPacketsContainingGarbage) {
217 env()->set_remote_endpoint(kRemoteEndpoint);
218 router()->OnSenderCreated(kAudioReceiverSsrc, audio_sender());
219 EXPECT_CALL(*audio_sender(), OnReceivedRtcpPacket(_, _)).Times(0);
220 SimulatePacketArrivedNow(kUnexpectedEndpoint,
221 absl::Span<const uint8_t>(kGarbagePacket));
222 SimulatePacketArrivedNow(kRemoteEndpoint,
223 absl::Span<const uint8_t>(kGarbagePacket));
224 router()->OnSenderDestroyed(kAudioReceiverSsrc);
225 }
226
227 // Note: RTP packets should be ignored since it wouldn't make sense for a
228 // Receiver to stream media to a Sender.
TEST_F(SenderPacketRouterTest,IgnoresInboundRtpPackets)229 TEST_F(SenderPacketRouterTest, IgnoresInboundRtpPackets) {
230 env()->set_remote_endpoint(kRemoteEndpoint);
231 router()->OnSenderCreated(kAudioReceiverSsrc, audio_sender());
232 EXPECT_CALL(*audio_sender(), OnReceivedRtcpPacket(_, _)).Times(0);
233 SimulatePacketArrivedNow(kUnexpectedEndpoint,
234 absl::Span<const uint8_t>(kValidAudioRtpPacket));
235 SimulatePacketArrivedNow(kRemoteEndpoint,
236 absl::Span<const uint8_t>(kValidAudioRtpPacket));
237 router()->OnSenderDestroyed(kAudioReceiverSsrc);
238 }
239
TEST_F(SenderPacketRouterTest,IgnoresInboundRtcpPacketsFromUnknownReceivers)240 TEST_F(SenderPacketRouterTest, IgnoresInboundRtcpPacketsFromUnknownReceivers) {
241 env()->set_remote_endpoint(kRemoteEndpoint);
242 router()->OnSenderCreated(kAudioReceiverSsrc, audio_sender());
243 const std::vector<uint8_t> rtcp_packet_not_for_me =
244 MakeRtcpPacketWithAlternateReceiverSsrc(kValidAudioRtcpPacket,
245 kAudioReceiverSsrc + 1);
246 EXPECT_CALL(*audio_sender(), OnReceivedRtcpPacket(_, _)).Times(0);
247 SimulatePacketArrivedNow(kUnexpectedEndpoint,
248 absl::Span<const uint8_t>(rtcp_packet_not_for_me));
249 SimulatePacketArrivedNow(kRemoteEndpoint,
250 absl::Span<const uint8_t>(rtcp_packet_not_for_me));
251 router()->OnSenderDestroyed(kAudioReceiverSsrc);
252 }
253
254 // Tests that the SenderPacketRouter forwards packets from Receivers to the
255 // appropriate Sender.
TEST_F(SenderPacketRouterTest,RoutesRTCPPacketsFromReceivers)256 TEST_F(SenderPacketRouterTest, RoutesRTCPPacketsFromReceivers) {
257 EXPECT_CALL(*env(), SendPacket(_)).Times(0);
258
259 const absl::Span<const uint8_t> audio_rtcp_packet(kValidAudioRtcpPacket);
260 std::vector<uint8_t> video_rtcp_packet =
261 MakeRtcpPacketWithAlternateReceiverSsrc(audio_rtcp_packet,
262 kVideoReceiverSsrc);
263
264 env()->set_remote_endpoint(kRemoteEndpoint);
265 router()->OnSenderCreated(kAudioReceiverSsrc, audio_sender());
266
267 // It should route a valid audio RTCP packet to the audio Sender, and ignore a
268 // valid video RTCP packet (since the video Sender is not yet known to the
269 // SenderPacketRouter).
270 {
271 Clock::time_point arrival_time{};
272 std::vector<uint8_t> received_packet;
273 EXPECT_CALL(*audio_sender(), OnReceivedRtcpPacket(_, _))
274 .WillOnce(Invoke(
275 [&](Clock::time_point when, absl::Span<const uint8_t> packet) {
276 arrival_time = when;
277 received_packet.assign(packet.begin(), packet.end());
278 }));
279 EXPECT_CALL(*video_sender(), OnReceivedRtcpPacket(_, _)).Times(0);
280
281 const Clock::time_point expected_arrival_time = env()->now();
282 SimulatePacketArrivedNow(kRemoteEndpoint, audio_rtcp_packet);
283 SimulatePacketArrivedNow(kRemoteEndpoint, video_rtcp_packet);
284
285 Mock::VerifyAndClear(audio_sender());
286 EXPECT_EQ(expected_arrival_time, arrival_time);
287 EXPECT_EQ(audio_rtcp_packet, received_packet);
288
289 Mock::VerifyAndClear(video_sender());
290 }
291
292 AdvanceClockAndRunTasks(seconds(1));
293
294 // Register the video Sender with the router. Now, confirm audio RTCP packets
295 // still go to the audio Sender and video RTCP packets go to the video Sender.
296 router()->OnSenderCreated(kVideoReceiverSsrc, video_sender());
297 {
298 Clock::time_point audio_arrival_time{}, video_arrival_time{};
299 std::vector<uint8_t> received_audio_packet, received_video_packet;
300 EXPECT_CALL(*audio_sender(), OnReceivedRtcpPacket(_, _))
301 .WillOnce(Invoke(
302 [&](Clock::time_point when, absl::Span<const uint8_t> packet) {
303 audio_arrival_time = when;
304 received_audio_packet.assign(packet.begin(), packet.end());
305 }));
306 EXPECT_CALL(*video_sender(), OnReceivedRtcpPacket(_, _))
307 .WillOnce(Invoke(
308 [&](Clock::time_point when, absl::Span<const uint8_t> packet) {
309 video_arrival_time = when;
310 received_video_packet.assign(packet.begin(), packet.end());
311 }));
312
313 const Clock::time_point expected_audio_arrival_time = env()->now();
314 SimulatePacketArrivedNow(kRemoteEndpoint, audio_rtcp_packet);
315
316 AdvanceClockAndRunTasks(milliseconds(11));
317
318 const Clock::time_point expected_video_arrival_time = env()->now();
319 SimulatePacketArrivedNow(kRemoteEndpoint, video_rtcp_packet);
320
321 Mock::VerifyAndClear(audio_sender());
322 EXPECT_EQ(expected_audio_arrival_time, audio_arrival_time);
323 EXPECT_EQ(audio_rtcp_packet, received_audio_packet);
324
325 Mock::VerifyAndClear(video_sender());
326 EXPECT_EQ(expected_video_arrival_time, video_arrival_time);
327 EXPECT_EQ(video_rtcp_packet, received_video_packet);
328 }
329
330 router()->OnSenderDestroyed(kAudioReceiverSsrc);
331 router()->OnSenderDestroyed(kVideoReceiverSsrc);
332 }
333
334 // Tests that the SenderPacketRouter schedules periodic RTCP packet sends,
335 // starting once the Sender requests the first RTCP send.
TEST_F(SenderPacketRouterTest,SchedulesPeriodicTransmissionOfRTCPPackets)336 TEST_F(SenderPacketRouterTest, SchedulesPeriodicTransmissionOfRTCPPackets) {
337 env()->set_remote_endpoint(kRemoteEndpoint);
338 router()->OnSenderCreated(kAudioReceiverSsrc, audio_sender());
339
340 constexpr int kNumIterations = 5;
341
342 EXPECT_CALL(*audio_sender(), OnReceivedRtcpPacket(_, _)).Times(0);
343 EXPECT_CALL(*audio_sender(), GetRtcpPacketForImmediateSend(_, _))
344 .Times(kNumIterations)
345 .WillRepeatedly(Invoke(&MakeFakePacket));
346 EXPECT_CALL(*audio_sender(), GetRtpPacketForImmediateSend(_, _)).Times(0);
347 ON_CALL(*audio_sender(), GetRtpResumeTime())
348 .WillByDefault(Return(SenderPacketRouter::kNever));
349
350 // Capture every packet sent for analysis at the end of this test.
351 std::vector<std::vector<uint8_t>> packets_sent;
352 EXPECT_CALL(*env(), SendPacket(_))
353 .WillRepeatedly(Invoke([&](absl::Span<const uint8_t> packet) {
354 packets_sent.emplace_back(packet.begin(), packet.end());
355 }));
356
357 const Clock::time_point first_send_time = env()->now();
358 router()->RequestRtcpSend(kAudioReceiverSsrc);
359 RunTasksUntilIdle(); // The first RTCP packet should be sent immediately.
360 for (int i = 1; i < kNumIterations; ++i) {
361 AdvanceClockAndRunTasks(kRtcpReportInterval);
362 }
363
364 // Ensure each RTCP packet was sent and in-sequence.
365 Mock::VerifyAndClear(env());
366 ASSERT_EQ(kNumIterations, static_cast<int>(packets_sent.size()));
367 for (int i = 0; i < kNumIterations; ++i) {
368 const Clock::time_point expected_send_time =
369 first_send_time + i * kRtcpReportInterval;
370 EXPECT_EQ(expected_send_time, ParseTimestamp(packets_sent[i]));
371 }
372
373 router()->OnSenderDestroyed(kAudioReceiverSsrc);
374 }
375
376 // Tests that the SenderPacketRouter schedules RTP packet bursts from a single
377 // Sender.
TEST_F(SenderPacketRouterTest,SchedulesAndTransmitsRTPBursts)378 TEST_F(SenderPacketRouterTest, SchedulesAndTransmitsRTPBursts) {
379 env()->set_remote_endpoint(kRemoteEndpoint);
380 router()->OnSenderCreated(kVideoReceiverSsrc, video_sender());
381
382 // Capture every packet sent for analysis at the end of this test.
383 std::vector<std::vector<uint8_t>> packets_sent;
384 EXPECT_CALL(*env(), SendPacket(_))
385 .WillRepeatedly(Invoke([&](absl::Span<const uint8_t> packet) {
386 packets_sent.emplace_back(packet.begin(), packet.end());
387 }));
388
389 // Simulate a typical video Sender RTP at-startup sending sequence: First, at
390 // t=0ms, the Sender wants to send its large 10-packet key frame. This will
391 // require four bursts, since only 3 packets can be sent per burst.
392 //
393 // While the first frame is being sent, a smaller 4-packet frame is enqueued,
394 // and the Sender will want to start sending this immediately after the first
395 // frame. Part of this second frame will be sent in the fourth burst, and the
396 // rest in the fifth burst.
397 //
398 // After the fifth burst, the Sender will schedule a "kickstart packet" for
399 // 25ms later. However, when the SenderPacketRouter later asks the Sender for
400 // that packet, the Sender will change its mind and decide not to send
401 // anything.
402 //
403 // At t=100ms, the next frame of video is enqueued in the Sender and it
404 // requests that RTP sending resume for that. This is a small 1-packet frame.
405 const Clock::time_point start_time = env()->now();
406 int num_get_rtp_calls = 0;
407 EXPECT_CALL(*video_sender(), GetRtpPacketForImmediateSend(_, _))
408 .Times(14 + 2)
409 .WillRepeatedly(
410 Invoke([&](Clock::time_point send_time, absl::Span<uint8_t> buffer) {
411 ++num_get_rtp_calls;
412
413 // 14 packets are sent: The first through fourth bursts send three
414 // packets each, and the fifth burst sends two.
415 if (num_get_rtp_calls <= 14) {
416 return MakeFakePacket(send_time, buffer);
417 }
418
419 // 2 "done signals" are then sent: One is at the end of the fifth
420 // burst, one is for a "nothing to send" sixth burst.
421 return ToEmptyPacketBuffer(send_time, buffer);
422 }));
423 const Clock::time_point kickstart_time =
424 start_time + 4 * kBurstInterval + milliseconds(25);
425 int num_get_resume_calls = 0;
426 EXPECT_CALL(*video_sender(), GetRtpResumeTime())
427 .Times(4 + 1 + 1)
428 .WillRepeatedly(Invoke([&] {
429 ++num_get_resume_calls;
430
431 // After each of the first through fourth bursts, the Sender wants to
432 // transmit more right away.
433 if (num_get_resume_calls <= 4) {
434 return env()->now();
435 }
436
437 // After the fifth burst, the Sender requests resuming for kickstart
438 // later.
439 if (num_get_resume_calls == 5) {
440 return kickstart_time;
441 }
442
443 // After the sixth burst, the Sender pauses RTP sending indefinitely.
444 return SenderPacketRouter::kNever;
445 }));
446 router()->RequestRtpSend(kVideoReceiverSsrc);
447 // Execute first burst.
448 RunTasksUntilIdle();
449 // Execute second through fifth bursts.
450 for (int i = 1; i <= 4; ++i) {
451 AdvanceClockAndRunTasks(kBurstInterval);
452 }
453 // Execute the sixth burst at the kickstart time.
454 AdvanceClockAndRunTasks(kickstart_time - env()->now());
455 Mock::VerifyAndClear(video_sender());
456
457 // Now, resume RTP sending for one more 1-packet frame, and then pause RTP
458 // sending again.
459 EXPECT_CALL(*video_sender(), GetRtpPacketForImmediateSend(_, _))
460 .WillOnce(Invoke(&MakeFakePacket)) // Frame 2, only packet.
461 .WillOnce(Invoke(&ToEmptyPacketBuffer)); // Done for now.
462 // After the seventh burst, the Sender pauses RTP sending again.
463 EXPECT_CALL(*video_sender(), GetRtpResumeTime())
464 .WillOnce(Return(SenderPacketRouter::kNever));
465 // Advance to the resume time. Nothing should happen until RequestRtpSend() is
466 // called.
467 const Clock::time_point resume_time = start_time + milliseconds(100);
468 AdvanceClockAndRunTasks(resume_time - env()->now());
469 router()->RequestRtpSend(kVideoReceiverSsrc);
470 // Execute seventh burst.
471 RunTasksUntilIdle();
472 // Run for one more second, but nothing should be happening since sending is
473 // paused.
474 AdvanceClockAndRunTasks(seconds(1));
475 Mock::VerifyAndClear(video_sender());
476
477 // Confirm 15 packets got sent and contain the expected data (which tracks
478 // when they were sent).
479 ASSERT_EQ(15, static_cast<int>(packets_sent.size()));
480 Clock::time_point expected_time;
481 int packet_idx = 0;
482 // First burst through fourth burst.
483 for (int burst_number = 0; burst_number < 4; ++burst_number) {
484 expected_time = start_time + burst_number * kBurstInterval;
485 EXPECT_EQ(expected_time, ParseTimestamp(packets_sent[packet_idx++]));
486 EXPECT_EQ(expected_time, ParseTimestamp(packets_sent[packet_idx++]));
487 EXPECT_EQ(expected_time, ParseTimestamp(packets_sent[packet_idx++]));
488 }
489 // Fifth burst.
490 expected_time += kBurstInterval;
491 EXPECT_EQ(expected_time, ParseTimestamp(packets_sent[packet_idx++]));
492 EXPECT_EQ(expected_time, ParseTimestamp(packets_sent[packet_idx++]));
493 // Seventh burst (sixth burst sent nothing).
494 EXPECT_EQ(resume_time, ParseTimestamp(packets_sent[packet_idx++]));
495
496 router()->OnSenderDestroyed(kVideoReceiverSsrc);
497 }
498
499 // Tests that the SenderPacketRouter schedules packet sends based on transmit
500 // prority: RTCP before RTP, and the audio Sender's packets before the video
501 // Sender's.
TEST_F(SenderPacketRouterTest,SchedulesAndTransmitsAccountingForPriority)502 TEST_F(SenderPacketRouterTest, SchedulesAndTransmitsAccountingForPriority) {
503 env()->set_remote_endpoint(kRemoteEndpoint);
504 ASSERT_LT(ComparePriority(kAudioReceiverSsrc, kVideoReceiverSsrc), 0);
505 router()->OnSenderCreated(kVideoReceiverSsrc, video_sender());
506 router()->OnSenderCreated(kAudioReceiverSsrc, audio_sender());
507
508 // Capture every packet sent for analysis at the end of this test.
509 std::vector<std::vector<uint8_t>> packets_sent;
510 EXPECT_CALL(*env(), SendPacket(_))
511 .WillRepeatedly(Invoke([&](absl::Span<const uint8_t> packet) {
512 packets_sent.emplace_back(packet.begin(), packet.end());
513 }));
514
515 // These indicate how often one packet will be sent from each Sender.
516 constexpr Clock::duration kAudioRtpInterval = milliseconds(10);
517 constexpr Clock::duration kVideoRtpInterval = milliseconds(33);
518
519 // Note: The priority flags used in this test ('0'..'3') indicate
520 // lowest-to-highest priority.
521 EXPECT_CALL(*audio_sender(), GetRtcpPacketForImmediateSend(_, _))
522 .WillRepeatedly(
523 Invoke([](Clock::time_point send_time, absl::Span<uint8_t> buffer) {
524 return MakeFakePacketWithFlag('3', send_time, buffer);
525 }));
526 int num_audio_get_rtp_calls = 0;
527 EXPECT_CALL(*audio_sender(), GetRtpPacketForImmediateSend(_, _))
528 .WillRepeatedly(
529 Invoke([&](Clock::time_point send_time, absl::Span<uint8_t> buffer) {
530 // Alternate between returning a single packet and a "done for now"
531 // signal.
532 ++num_audio_get_rtp_calls;
533 if (num_audio_get_rtp_calls % 2) {
534 return MakeFakePacketWithFlag('1', send_time, buffer);
535 }
536 return buffer.subspan(0, 0);
537 }));
538 EXPECT_CALL(*video_sender(), GetRtcpPacketForImmediateSend(_, _))
539 .WillRepeatedly(
540 Invoke([](Clock::time_point send_time, absl::Span<uint8_t> buffer) {
541 return MakeFakePacketWithFlag('2', send_time, buffer);
542 }));
543 int num_video_get_rtp_calls = 0;
544 EXPECT_CALL(*video_sender(), GetRtpPacketForImmediateSend(_, _))
545 .WillRepeatedly(
546 Invoke([&](Clock::time_point send_time, absl::Span<uint8_t> buffer) {
547 // Alternate between returning a single packet and a "done for now"
548 // signal.
549 ++num_video_get_rtp_calls;
550 if (num_video_get_rtp_calls % 2) {
551 return MakeFakePacketWithFlag('0', send_time, buffer);
552 }
553 return buffer.subspan(0, 0);
554 }));
555 EXPECT_CALL(*audio_sender(), GetRtpResumeTime()).WillRepeatedly(Invoke([&] {
556 return env()->now() + kAudioRtpInterval;
557 }));
558 EXPECT_CALL(*video_sender(), GetRtpResumeTime()).WillRepeatedly(Invoke([&] {
559 return env()->now() + kVideoRtpInterval;
560 }));
561
562 // Request starting both RTCP and RTP sends for both Senders, in a random
563 // order.
564 router()->RequestRtcpSend(kVideoReceiverSsrc);
565 router()->RequestRtpSend(kAudioReceiverSsrc);
566 router()->RequestRtcpSend(kAudioReceiverSsrc);
567 router()->RequestRtpSend(kVideoReceiverSsrc);
568
569 // Run the SenderPacketRouter for 3 seconds.
570 constexpr Clock::duration kSimulationDuration = seconds(3);
571 constexpr Clock::duration kSimulationStepPeriod = milliseconds(1);
572 const Clock::time_point start_time = env()->now();
573 RunTasksUntilIdle();
574 const Clock::time_point end_time = start_time + kSimulationDuration;
575 while (env()->now() <= end_time) {
576 AdvanceClockAndRunTasks(kSimulationStepPeriod);
577 }
578
579 // Examine the packets that were actually sent, and confirm that the priority
580 // ordering was maintained.
581 ASSERT_EQ(384, static_cast<int>(packets_sent.size()));
582 // The very first packet sent should be an audio RTCP packet.
583 EXPECT_EQ('3', ParseFlag(packets_sent[0]));
584 EXPECT_EQ(start_time, ParseTimestamp(packets_sent[0]));
585 // Scan the rest, checking that packets sent in the same burst (i.e., having
586 // the same send timestamp) were sent in priority order.
587 char last_priority_flag = '3';
588 Clock::time_point last_timestamp = start_time;
589 for (int i = 1; i < static_cast<int>(packets_sent.size()) &&
590 !testing::Test::HasFailure();
591 ++i) {
592 const char priority_flag = ParseFlag(packets_sent[i]);
593 const Clock::time_point timestamp = ParseTimestamp(packets_sent[i]);
594 EXPECT_LE(last_timestamp, timestamp) << "packet[" << i << ']';
595 if (timestamp == last_timestamp) {
596 EXPECT_GT(last_priority_flag, priority_flag) << "packet[" << i << ']';
597 }
598 last_priority_flag = priority_flag;
599 last_timestamp = timestamp;
600 }
601
602 router()->OnSenderDestroyed(kVideoReceiverSsrc);
603 router()->OnSenderDestroyed(kAudioReceiverSsrc);
604 }
605
606 } // namespace
607 } // namespace cast
608 } // namespace openscreen
609