OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2017 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 | |
11 #include "webrtc/call/rtcp_demuxer.h" | |
12 | |
13 #include <memory> | |
14 | |
15 #include "webrtc/base/arraysize.h" | |
16 #include "webrtc/base/basictypes.h" | |
17 #include "webrtc/base/checks.h" | |
18 #include "webrtc/base/ptr_util.h" | |
19 #include "webrtc/call/rtcp_packet_sink_interface.h" | |
20 #include "webrtc/common_types.h" | |
21 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/bye.h" | |
22 #include "webrtc/test/gmock.h" | |
23 #include "webrtc/test/gtest.h" | |
24 | |
25 namespace webrtc { | |
26 | |
27 namespace { | |
28 | |
29 using ::testing::_; | |
30 using ::testing::AtLeast; | |
31 using ::testing::ElementsAreArray; | |
32 using ::testing::InSequence; | |
33 using ::testing::NiceMock; | |
34 | |
35 class MockRtcpPacketSink : public RtcpPacketSinkInterface { | |
36 public: | |
37 MOCK_METHOD1(OnRtcpPacket, void(rtc::ArrayView<const uint8_t>)); | |
38 }; | |
39 | |
40 // Produces a packet buffer representing an RTCP packet with a given SSRC, | |
41 // as it would look when sent over the wire. | |
42 // |distinguishing_string| allows different RTCP packets with the same SSRC | |
43 // to be distinguished. How this is set into the actual packet is | |
44 // unimportant, and depends on which RTCP message we choose to use. | |
45 rtc::Buffer CreateRtcpPacket(uint32_t ssrc, | |
46 const std::string& distinguishing_string = "") { | |
47 rtcp::Bye packet; | |
48 packet.SetSenderSsrc(ssrc); | |
49 if (distinguishing_string != "") { | |
50 // Actual way we use |distinguishing_string| is unimportant, so long | |
51 // as it ends up in the packet. | |
52 packet.SetReason(distinguishing_string); | |
53 } | |
54 return packet.Build(); | |
55 } | |
56 | |
57 } // namespace | |
58 | |
59 TEST(RtcpDemuxerTest, OnRtcpPacketCalledOnCorrectSinkBySsrc) { | |
60 RtcpDemuxer demuxer; | |
61 | |
62 constexpr uint32_t ssrcs[] = {101, 202, 303}; | |
63 MockRtcpPacketSink sinks[arraysize(ssrcs)]; | |
64 for (size_t i = 0; i < arraysize(ssrcs); i++) { | |
65 demuxer.AddSink(ssrcs[i], &sinks[i]); | |
66 } | |
67 | |
68 for (size_t i = 0; i < arraysize(ssrcs); i++) { | |
69 auto packet = CreateRtcpPacket(ssrcs[i]); | |
70 EXPECT_CALL(sinks[i], | |
71 OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))) | |
72 .Times(1); | |
73 demuxer.OnRtcpPacket(packet); | |
74 } | |
75 | |
76 // Test tear-down | |
77 for (const auto& sink : sinks) { | |
78 demuxer.RemoveSink(&sink); | |
79 } | |
80 } | |
81 | |
82 TEST(RtcpDemuxerTest, OnRtcpPacketCalledOnResolvedRsidSink) { | |
83 RtcpDemuxer demuxer; | |
84 | |
85 // Set up some RSID sinks. | |
86 const std::string rsids[] = {"a", "b", "c"}; | |
87 MockRtcpPacketSink sinks[arraysize(rsids)]; | |
88 for (size_t i = 0; i < arraysize(rsids); i++) { | |
89 demuxer.AddSink(rsids[i], &sinks[i]); | |
90 } | |
91 | |
92 // Only resolve one of the sinks. | |
93 constexpr size_t resolved_sink_index = 0; | |
94 constexpr uint32_t ssrc = 345; | |
95 demuxer.OnRsidResolved(rsids[resolved_sink_index], ssrc); | |
96 | |
97 // The resolved sink gets notifications of RTCP messages with its SSRC. | |
98 auto packet = CreateRtcpPacket(ssrc); | |
99 EXPECT_CALL(sinks[resolved_sink_index], | |
100 OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))) | |
101 .Times(1); | |
102 | |
103 // RTCP received; expected calls triggered. | |
104 demuxer.OnRtcpPacket(packet); | |
105 | |
106 // Test tear-down | |
107 for (const auto& sink : sinks) { | |
108 demuxer.RemoveSink(&sink); | |
109 } | |
110 } | |
111 | |
112 TEST(RtcpDemuxerTest, | |
113 SingleCallbackAfterResolutionOfAnRsidToAlreadyRegisteredSsrc) { | |
114 RtcpDemuxer demuxer; | |
115 | |
116 // Associate a sink with an SSRC. | |
117 MockRtcpPacketSink sink; | |
118 constexpr uint32_t ssrc = 999; | |
119 demuxer.AddSink(ssrc, &sink); | |
120 | |
121 // Associate the same sink with an RSID. | |
122 const std::string rsid = "r"; | |
123 demuxer.AddSink(rsid, &sink); | |
124 | |
125 // Resolve the RSID to the aforementioned SSRC. | |
126 demuxer.OnRsidResolved(rsid, ssrc); | |
127 | |
128 // OnRtcpPacket still called only a single time for messages with this SSRC. | |
129 auto packet = CreateRtcpPacket(ssrc); | |
130 EXPECT_CALL(sink, | |
131 OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))) | |
132 .Times(1); | |
133 demuxer.OnRtcpPacket(packet); | |
134 | |
135 // Test tear-down | |
136 demuxer.RemoveSink(&sink); | |
137 } | |
138 | |
139 TEST(RtcpDemuxerTest, OnRtcpPacketCalledOnAllBroadcastSinksForAllRtcpPackets) { | |
140 RtcpDemuxer demuxer; | |
141 | |
142 MockRtcpPacketSink sinks[3]; | |
143 for (MockRtcpPacketSink& sink : sinks) { | |
144 demuxer.AddBroadcastSink(&sink); | |
145 } | |
146 | |
147 constexpr uint32_t ssrc = 747; | |
148 auto packet = CreateRtcpPacket(ssrc); | |
149 | |
150 for (MockRtcpPacketSink& sink : sinks) { | |
151 EXPECT_CALL(sink, | |
152 OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))) | |
153 .Times(1); | |
154 } | |
155 | |
156 // RTCP received; expected calls triggered. | |
157 demuxer.OnRtcpPacket(packet); | |
158 | |
159 // Test tear-down | |
160 for (const auto& sink : sinks) { | |
161 demuxer.RemoveBroadcastSink(&sink); | |
162 } | |
163 } | |
164 | |
165 TEST(RtcpDemuxerTest, PacketsDeliveredInRightOrderToNonBroadcastSink) { | |
166 RtcpDemuxer demuxer; | |
167 | |
168 constexpr uint32_t ssrc = 101; | |
169 MockRtcpPacketSink sink; | |
170 demuxer.AddSink(ssrc, &sink); | |
171 | |
172 std::vector<rtc::Buffer> packets; | |
173 for (size_t i = 0; i < 5; i++) { | |
174 packets.push_back(CreateRtcpPacket(ssrc, std::to_string(i))); | |
175 } | |
176 | |
177 InSequence sequence; | |
178 for (const auto& packet : packets) { | |
179 EXPECT_CALL(sink, | |
180 OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))) | |
181 .Times(1); | |
182 } | |
183 | |
184 for (const auto& packet : packets) { | |
185 demuxer.OnRtcpPacket(packet); | |
186 } | |
187 | |
188 // Test tear-down | |
189 demuxer.RemoveSink(&sink); | |
190 } | |
191 | |
192 TEST(RtcpDemuxerTest, PacketsDeliveredInRightOrderToBroadcastSink) { | |
193 RtcpDemuxer demuxer; | |
194 | |
195 MockRtcpPacketSink sink; | |
196 demuxer.AddBroadcastSink(&sink); | |
197 | |
198 std::vector<rtc::Buffer> packets; | |
199 for (size_t i = 0; i < 5; i++) { | |
200 constexpr uint32_t ssrc = 101; | |
201 packets.push_back(CreateRtcpPacket(ssrc, std::to_string(i))); | |
202 } | |
203 | |
204 InSequence sequence; | |
205 for (const auto& packet : packets) { | |
206 EXPECT_CALL(sink, | |
207 OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))) | |
208 .Times(1); | |
209 } | |
210 | |
211 for (const auto& packet : packets) { | |
212 demuxer.OnRtcpPacket(packet); | |
213 } | |
214 | |
215 // Test tear-down | |
216 demuxer.RemoveBroadcastSink(&sink); | |
217 } | |
218 | |
219 TEST(RtcpDemuxerTest, MultipleSinksMappedToSameSsrc) { | |
220 RtcpDemuxer demuxer; | |
221 | |
222 MockRtcpPacketSink sinks[3]; | |
223 constexpr uint32_t ssrc = 404; | |
224 for (auto& sink : sinks) { | |
225 demuxer.AddSink(ssrc, &sink); | |
226 } | |
227 | |
228 // Reception of an RTCP packet associated with the shared SSRC triggers the | |
229 // callback on all of the sinks associated with it. | |
230 auto packet = CreateRtcpPacket(ssrc); | |
231 for (auto& sink : sinks) { | |
232 EXPECT_CALL(sink, | |
233 OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))); | |
234 } | |
235 demuxer.OnRtcpPacket(packet); | |
236 | |
237 // Test tear-down | |
238 for (const auto& sink : sinks) { | |
239 demuxer.RemoveSink(&sink); | |
240 } | |
241 } | |
242 | |
243 TEST(RtcpDemuxerTest, SinkMappedToMultipleSsrcs) { | |
244 RtcpDemuxer demuxer; | |
245 | |
246 constexpr uint32_t ssrcs[] = {404, 505, 606}; | |
247 MockRtcpPacketSink sink; | |
248 for (uint32_t ssrc : ssrcs) { | |
249 demuxer.AddSink(ssrc, &sink); | |
250 } | |
251 | |
252 // The sink which is associated with multiple SSRCs gets the callback | |
253 // triggered for each of those SSRCs. | |
254 for (uint32_t ssrc : ssrcs) { | |
255 auto packet = CreateRtcpPacket(ssrc); | |
256 EXPECT_CALL(sink, | |
257 OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))); | |
258 demuxer.OnRtcpPacket(packet); | |
259 } | |
260 | |
261 // Test tear-down | |
262 demuxer.RemoveSink(&sink); | |
263 } | |
264 | |
265 TEST(RtcpDemuxerTest, MultipleRsidsOnSameSink) { | |
266 RtcpDemuxer demuxer; | |
267 | |
268 // Sink associated with multiple sinks. | |
269 MockRtcpPacketSink sink; | |
270 const std::string rsids[] = {"a", "b", "c"}; | |
271 for (const auto& rsid : rsids) { | |
272 demuxer.AddSink(rsid, &sink); | |
273 } | |
274 | |
275 // RSIDs resolved to SSRCs. | |
276 uint32_t ssrcs[arraysize(rsids)]; | |
277 for (size_t i = 0; i < arraysize(rsids); i++) { | |
278 ssrcs[i] = 1000 + static_cast<uint32_t>(i); | |
279 demuxer.OnRsidResolved(rsids[i], ssrcs[i]); | |
280 } | |
281 | |
282 // Set up packets to match those RSIDs/SSRCs. | |
283 std::vector<rtc::Buffer> packets; | |
284 for (size_t i = 0; i < arraysize(rsids); i++) { | |
285 packets.push_back(CreateRtcpPacket(ssrcs[i])); | |
286 } | |
287 | |
288 // The sink expects to receive all of the packets. | |
289 for (const auto& packet : packets) { | |
290 EXPECT_CALL(sink, | |
291 OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))) | |
292 .Times(1); | |
293 } | |
294 | |
295 // Packet demuxed correctly; OnRtcpPacket() triggered on sink. | |
296 for (const auto& packet : packets) { | |
297 demuxer.OnRtcpPacket(packet); | |
298 } | |
299 | |
300 // Test tear-down | |
301 demuxer.RemoveSink(&sink); | |
302 } | |
303 | |
304 TEST(RtcpDemuxerTest, RsidUsedByMultipleSinks) { | |
305 RtcpDemuxer demuxer; | |
306 | |
307 MockRtcpPacketSink sinks[3]; | |
308 const std::string shared_rsid = "a"; | |
309 | |
310 for (MockRtcpPacketSink& sink : sinks) { | |
311 demuxer.AddSink(shared_rsid, &sink); | |
312 } | |
313 | |
314 constexpr uint32_t shared_ssrc = 888; | |
315 demuxer.OnRsidResolved(shared_rsid, shared_ssrc); | |
316 | |
317 auto packet = CreateRtcpPacket(shared_ssrc); | |
318 | |
319 for (MockRtcpPacketSink& sink : sinks) { | |
320 EXPECT_CALL(sink, | |
321 OnRtcpPacket(ElementsAreArray(packet.cbegin(), packet.cend()))) | |
322 .Times(1); | |
323 } | |
324 | |
325 demuxer.OnRtcpPacket(packet); | |
326 | |
327 // Test tear-down | |
328 for (MockRtcpPacketSink& sink : sinks) { | |
329 demuxer.RemoveSink(&sink); | |
330 } | |
331 } | |
332 | |
333 TEST(RtcpDemuxerTest, NoCallbackOnSsrcSinkRemovedBeforeFirstPacket) { | |
334 RtcpDemuxer demuxer; | |
335 | |
336 constexpr uint32_t ssrc = 404; | |
337 MockRtcpPacketSink sink; | |
338 demuxer.AddSink(ssrc, &sink); | |
339 | |
340 demuxer.RemoveSink(&sink); | |
341 | |
342 // The removed sink does not get callbacks. | |
343 auto packet = CreateRtcpPacket(ssrc); | |
344 EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called. | |
345 demuxer.OnRtcpPacket(packet); | |
346 } | |
347 | |
348 TEST(RtcpDemuxerTest, NoCallbackOnSsrcSinkRemovedAfterFirstPacket) { | |
349 RtcpDemuxer demuxer; | |
350 | |
351 constexpr uint32_t ssrc = 404; | |
352 NiceMock<MockRtcpPacketSink> sink; | |
353 demuxer.AddSink(ssrc, &sink); | |
354 | |
355 auto before_packet = CreateRtcpPacket(ssrc); | |
356 demuxer.OnRtcpPacket(before_packet); | |
357 | |
358 demuxer.RemoveSink(&sink); | |
359 | |
360 // The removed sink does not get callbacks. | |
361 auto after_packet = CreateRtcpPacket(ssrc); | |
362 EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called. | |
363 demuxer.OnRtcpPacket(after_packet); | |
364 } | |
365 | |
366 TEST(RtcpDemuxerTest, NoCallbackOnRsidSinkRemovedBeforeRsidResolution) { | |
367 RtcpDemuxer demuxer; | |
368 | |
369 const std::string rsid = "a"; | |
370 constexpr uint32_t ssrc = 404; | |
371 MockRtcpPacketSink sink; | |
372 demuxer.AddSink(rsid, &sink); | |
373 | |
374 // Removal before resolution. | |
375 demuxer.RemoveSink(&sink); | |
376 demuxer.OnRsidResolved(rsid, ssrc); | |
377 | |
378 // The removed sink does not get callbacks. | |
379 auto packet = CreateRtcpPacket(ssrc); | |
380 EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called. | |
381 demuxer.OnRtcpPacket(packet); | |
382 } | |
383 | |
384 TEST(RtcpDemuxerTest, NoCallbackOnRsidSinkRemovedAfterRsidResolution) { | |
385 RtcpDemuxer demuxer; | |
386 | |
387 const std::string rsid = "a"; | |
388 constexpr uint32_t ssrc = 404; | |
389 MockRtcpPacketSink sink; | |
390 demuxer.AddSink(rsid, &sink); | |
391 | |
392 // Removal after resolution. | |
393 demuxer.OnRsidResolved(rsid, ssrc); | |
394 demuxer.RemoveSink(&sink); | |
395 | |
396 // The removed sink does not get callbacks. | |
397 auto packet = CreateRtcpPacket(ssrc); | |
398 EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called. | |
399 demuxer.OnRtcpPacket(packet); | |
400 } | |
401 | |
402 TEST(RtcpDemuxerTest, NoCallbackOnBroadcastSinkRemovedBeforeFirstPacket) { | |
403 RtcpDemuxer demuxer; | |
404 | |
405 MockRtcpPacketSink sink; | |
406 demuxer.AddBroadcastSink(&sink); | |
407 | |
408 demuxer.RemoveBroadcastSink(&sink); | |
409 | |
410 // The removed sink does not get callbacks. | |
411 constexpr uint32_t ssrc = 404; | |
412 auto packet = CreateRtcpPacket(ssrc); | |
413 EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called. | |
414 demuxer.OnRtcpPacket(packet); | |
415 } | |
416 | |
417 TEST(RtcpDemuxerTest, NoCallbackOnBroadcastSinkRemovedAfterFirstPacket) { | |
418 RtcpDemuxer demuxer; | |
419 | |
420 NiceMock<MockRtcpPacketSink> sink; | |
421 demuxer.AddBroadcastSink(&sink); | |
422 | |
423 constexpr uint32_t ssrc = 404; | |
424 auto before_packet = CreateRtcpPacket(ssrc); | |
425 demuxer.OnRtcpPacket(before_packet); | |
426 | |
427 demuxer.RemoveBroadcastSink(&sink); | |
428 | |
429 // The removed sink does not get callbacks. | |
430 auto after_packet = CreateRtcpPacket(ssrc); | |
431 EXPECT_CALL(sink, OnRtcpPacket(_)).Times(0); // Not called. | |
432 demuxer.OnRtcpPacket(after_packet); | |
433 } | |
434 | |
435 // The RSID to SSRC mapping should be one-to-one. If we end up receiving | |
436 // two (or more) packets with the same SSRC, but different RSIDs, we guarantee | |
437 // remembering the first one; no guarantees are made about further associations. | |
438 TEST(RtcpDemuxerTest, FirstRsolutionOfRsidNotForgotten) { | |
439 RtcpDemuxer demuxer; | |
440 MockRtcpPacketSink sink; | |
441 | |
442 const std::string rsid = "a"; | |
443 demuxer.AddSink(rsid, &sink); | |
444 | |
445 constexpr uint32_t ssrc_a = 111; // First resolution - guaranteed effective. | |
446 demuxer.OnRsidResolved(rsid, ssrc_a); | |
447 | |
448 constexpr uint32_t ssrc_b = 222; // Second resolution - no guarantees. | |
449 demuxer.OnRsidResolved(rsid, ssrc_b); | |
450 | |
451 auto packet_a = CreateRtcpPacket(ssrc_a); | |
452 EXPECT_CALL( | |
453 sink, OnRtcpPacket(ElementsAreArray(packet_a.cbegin(), packet_a.cend()))) | |
454 .Times(1); | |
455 demuxer.OnRtcpPacket(packet_a); | |
456 | |
457 auto packet_b = CreateRtcpPacket(ssrc_b); | |
458 EXPECT_CALL( | |
459 sink, OnRtcpPacket(ElementsAreArray(packet_b.cbegin(), packet_b.cend()))) | |
460 .Times(AtLeast(0)); | |
461 demuxer.OnRtcpPacket(packet_b); | |
462 | |
463 // Test tear-down | |
464 demuxer.RemoveSink(&sink); | |
465 } | |
466 | |
467 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | |
468 TEST(RtcpDemuxerTest, RepeatedSsrcToSinkAssociationsDisallowed) { | |
469 RtcpDemuxer demuxer; | |
470 MockRtcpPacketSink sink; | |
471 | |
472 constexpr uint32_t ssrc = 101; | |
473 demuxer.AddSink(ssrc, &sink); | |
474 EXPECT_DEATH(demuxer.AddSink(ssrc, &sink), ""); | |
475 | |
476 // Test tear-down | |
477 demuxer.RemoveSink(&sink); | |
478 } | |
479 | |
480 TEST(RtcpDemuxerTest, RepeatedRsidToSinkAssociationsDisallowed) { | |
481 RtcpDemuxer demuxer; | |
482 MockRtcpPacketSink sink; | |
483 | |
484 const std::string rsid = "z"; | |
485 demuxer.AddSink(rsid, &sink); | |
486 EXPECT_DEATH(demuxer.AddSink(rsid, &sink), ""); | |
487 | |
488 // Test tear-down | |
489 demuxer.RemoveSink(&sink); | |
490 } | |
491 | |
492 TEST(RtcpDemuxerTest, RepeatedBroadcastSinkRegistrationDisallowed) { | |
493 RtcpDemuxer demuxer; | |
494 MockRtcpPacketSink sink; | |
495 | |
496 demuxer.AddBroadcastSink(&sink); | |
497 EXPECT_DEATH(demuxer.AddBroadcastSink(&sink), ""); | |
498 | |
499 // Test tear-down | |
500 demuxer.RemoveBroadcastSink(&sink); | |
501 } | |
502 | |
503 TEST(RtcpDemuxerTest, SsrcSinkCannotAlsoBeRegisteredAsBroadcast) { | |
504 RtcpDemuxer demuxer; | |
505 MockRtcpPacketSink sink; | |
506 | |
507 constexpr uint32_t ssrc = 101; | |
508 demuxer.AddSink(ssrc, &sink); | |
509 EXPECT_DEATH(demuxer.AddBroadcastSink(&sink), ""); | |
510 | |
511 // Test tear-down | |
512 demuxer.RemoveSink(&sink); | |
513 } | |
514 | |
515 TEST(RtcpDemuxerTest, RsidSinkCannotAlsoBeRegisteredAsBroadcast) { | |
516 RtcpDemuxer demuxer; | |
517 MockRtcpPacketSink sink; | |
518 | |
519 const std::string rsid = "z"; | |
520 demuxer.AddSink(rsid, &sink); | |
521 EXPECT_DEATH(demuxer.AddBroadcastSink(&sink), ""); | |
522 | |
523 // Test tear-down | |
524 demuxer.RemoveSink(&sink); | |
525 } | |
526 | |
527 TEST(RtcpDemuxerTest, BroadcastSinkCannotAlsoBeRegisteredAsSsrcSink) { | |
528 RtcpDemuxer demuxer; | |
529 MockRtcpPacketSink sink; | |
530 | |
531 demuxer.AddBroadcastSink(&sink); | |
532 constexpr uint32_t ssrc = 101; | |
533 EXPECT_DEATH(demuxer.AddSink(ssrc, &sink), ""); | |
534 | |
535 // Test tear-down | |
536 demuxer.RemoveBroadcastSink(&sink); | |
537 } | |
538 | |
539 TEST(RtcpDemuxerTest, BroadcastSinkCannotAlsoBeRegisteredAsRsidSink) { | |
540 RtcpDemuxer demuxer; | |
541 MockRtcpPacketSink sink; | |
542 | |
543 demuxer.AddBroadcastSink(&sink); | |
544 const std::string rsid = "j"; | |
545 EXPECT_DEATH(demuxer.AddSink(rsid, &sink), ""); | |
546 | |
547 // Test tear-down | |
548 demuxer.RemoveBroadcastSink(&sink); | |
549 } | |
550 | |
551 TEST(RtcpDemuxerTest, MayNotCallRemoveSinkOnNeverAddedSink) { | |
552 RtcpDemuxer demuxer; | |
553 MockRtcpPacketSink sink; | |
554 | |
555 EXPECT_DEATH(demuxer.RemoveSink(&sink), ""); | |
556 } | |
557 | |
558 TEST(RtcpDemuxerTest, MayNotCallRemoveBroadcastSinkOnNeverAddedSink) { | |
559 RtcpDemuxer demuxer; | |
560 MockRtcpPacketSink sink; | |
561 | |
562 EXPECT_DEATH(demuxer.RemoveBroadcastSink(&sink), ""); | |
563 } | |
564 | |
565 TEST(RtcpDemuxerTest, RsidMustBeNonEmpty) { | |
566 RtcpDemuxer demuxer; | |
567 MockRtcpPacketSink sink; | |
568 EXPECT_DEATH(demuxer.AddSink("", &sink), ""); | |
569 } | |
570 | |
571 TEST(RtcpDemuxerTest, RsidMustBeAlphaNumeric) { | |
572 RtcpDemuxer demuxer; | |
573 MockRtcpPacketSink sink; | |
574 EXPECT_DEATH(demuxer.AddSink("a_3", &sink), ""); | |
575 } | |
576 | |
577 TEST(RtcpDemuxerTest, RsidMustNotExceedMaximumLength) { | |
578 RtcpDemuxer demuxer; | |
579 MockRtcpPacketSink sink; | |
580 std::string rsid(StreamId::kMaxSize + 1, 'a'); | |
581 EXPECT_DEATH(demuxer.AddSink(rsid, &sink), ""); | |
582 } | |
583 #endif | |
584 } // namespace webrtc | |
OLD | NEW |