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