• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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