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/rtp_demuxer.h" | |
12 | |
13 #include <memory> | |
14 | |
15 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h" | |
danilchap
2017/05/24 17:14:02
put it inbetween webrtc/base and webrtc/test (alph
eladalon
2017/05/25 08:00:05
I will explain my reasoning, and if you still pref
danilchap
2017/05/29 08:59:53
I'm not sure why introduce own convention when the
eladalon
2017/05/30 14:23:37
Done.
| |
16 | |
17 #include "webrtc/base/arraysize.h" | |
18 #include "webrtc/base/checks.h" | |
19 #include "webrtc/test/gmock.h" | |
20 #include "webrtc/test/gtest.h" | |
21 | |
22 namespace webrtc { | |
23 | |
24 namespace { | |
25 | |
26 class MockRtpPacketSink : public RtpPacketSinkInterface { | |
27 public: | |
28 MOCK_METHOD1(OnRtpPacket, void(const RtpPacketReceived&)); | |
29 }; | |
30 | |
31 constexpr uint32_t kSsrcs[] = {101, 202, 303}; | |
32 | |
33 MATCHER_P(RtpPacketReceivedSsrcMatcher, other, "") { | |
34 return arg.Ssrc() == other.Ssrc(); | |
35 } | |
36 | |
37 std::unique_ptr<RtpPacketReceived> GetRtpPacketReceived(uint32_t ssrc) { | |
danilchap
2017/05/24 17:14:02
may be call it Create...
eladalon
2017/05/25 08:00:05
Done.
| |
38 std::unique_ptr<RtpPacketReceived> packet(new RtpPacketReceived()); | |
danilchap
2017/05/24 17:14:02
may be to avoid mentioning RtpPacketReceived twice
eladalon
2017/05/25 08:00:05
Thank you for bringing this utility function to my
danilchap
2017/05/29 08:59:53
The way I see it, MakeUnique tells 'nothing odd go
eladalon
2017/05/30 14:23:37
Thanks for explaining your rationale for preferrin
nisse-webrtc
2017/05/30 14:53:23
MakeUnique was added recently, and I think the int
| |
39 packet->SetSsrc(ssrc); | |
40 return packet; | |
41 } | |
42 | |
43 class RtpDemuxerTest : public ::testing::Test { | |
44 protected: | |
45 RtpDemuxerTest() { | |
46 for (size_t i = 0; i < kNumOfSinks; i++) { | |
47 demuxer.AddSink(kSsrcs[i], &sinks[i]); | |
48 } | |
49 } | |
50 | |
51 virtual ~RtpDemuxerTest() { | |
danilchap
2017/05/24 17:14:02
override instead of virtual
eladalon
2017/05/25 08:00:05
Done.
| |
52 for (size_t i = 0; i < kNumOfSinks; i++) { | |
53 EXPECT_EQ(demuxer.RemoveSink(&sinks[i]), 1u); | |
54 } | |
55 } | |
56 | |
57 RtpDemuxer demuxer; | |
58 static constexpr size_t kNumOfSinks = 3; | |
danilchap
2017/05/24 17:14:02
prefer constants above constructor.
https://google
eladalon
2017/05/25 08:00:05
I thought you were okay with putting it here?
htt
danilchap
2017/05/29 08:59:53
One of the worries: in your tests you rely on fact
| |
59 MockRtpPacketSink sinks[kNumOfSinks]; | |
60 }; | |
61 | |
62 TEST_F(RtpDemuxerTest, OnRtpPacketCalledOnCorrectSink) { | |
63 for (size_t i = 0; i < kNumOfSinks; i++) { | |
64 auto packet = GetRtpPacketReceived(kSsrcs[i]); | |
65 EXPECT_CALL(sinks[i], OnRtpPacket(RtpPacketReceivedSsrcMatcher(*packet))); | |
danilchap
2017/05/24 17:14:02
which line you think would be faster to understand
eladalon
2017/05/25 08:00:05
I see what you mean. Sure, let's go with SsrcSameA
| |
66 demuxer.OnRtpPacket(*packet); | |
67 testing::Mock::VerifyAndClearExpectations(&sinks[i]); | |
68 } | |
69 } | |
70 | |
71 TEST_F(RtpDemuxerTest, MultipleSinksMappedToSameSsrc) { | |
72 // |sinks| associated with different SSRCs each. Add a few additional sinks | |
73 // that are all associated with one new, distinct SSRC. | |
74 constexpr size_t kNumOfSameSsrcSinks = 3; | |
75 MockRtpPacketSink same_ssrc_sinks[kNumOfSameSsrcSinks]; | |
76 constexpr uint32_t kSharedSsrc = 404; | |
77 for (size_t i = 0; i < kNumOfSameSsrcSinks; i++) { | |
78 demuxer.AddSink(kSharedSsrc, &same_ssrc_sinks[i]); | |
79 } | |
80 | |
81 // Reception of an RTP packet associated with the shared SSRC triggers the | |
82 // callback on all of the interfaces associated with it. | |
83 auto packet = GetRtpPacketReceived(kSharedSsrc); | |
84 for (size_t i = 0; i < kNumOfSameSsrcSinks; i++) { | |
85 EXPECT_CALL(same_ssrc_sinks[i], | |
86 OnRtpPacket(RtpPacketReceivedSsrcMatcher(*packet))); | |
87 } | |
88 demuxer.OnRtpPacket(*packet); | |
89 | |
90 // Test-specific tear-down | |
91 for (size_t i = 0; i < kNumOfSameSsrcSinks; i++) { | |
92 EXPECT_EQ(demuxer.RemoveSink(&same_ssrc_sinks[i]), 1u); | |
93 } | |
94 } | |
95 | |
96 TEST_F(RtpDemuxerTest, SinkMappedToMultipleSsrcs) { | |
97 // |sinks| associated with different SSRCs each. We set one of them to also | |
98 // be mapped to additional SSRCs. | |
99 constexpr uint32_t kSsrcsOfMultiSsrcSink[] = {404, 505, 606}; | |
100 MockRtpPacketSink multi_ssrc_sink; | |
101 for (uint32_t ssrc : kSsrcsOfMultiSsrcSink) { | |
102 demuxer.AddSink(ssrc, &multi_ssrc_sink); | |
103 } | |
104 | |
105 // The sink which is associated with multiple SSRCs gets the callback | |
106 // triggered for each of those SSRCs. | |
107 for (uint32_t ssrc : kSsrcsOfMultiSsrcSink) { | |
108 auto packet = GetRtpPacketReceived(ssrc); | |
109 EXPECT_CALL(multi_ssrc_sink, | |
110 OnRtpPacket(RtpPacketReceivedSsrcMatcher(*packet))); | |
111 demuxer.OnRtpPacket(*packet); | |
112 testing::Mock::VerifyAndClearExpectations(&multi_ssrc_sink); | |
113 } | |
114 | |
115 // Test-specific tear-down | |
116 EXPECT_EQ(demuxer.RemoveSink(&multi_ssrc_sink), | |
117 arraysize(kSsrcsOfMultiSsrcSink)); | |
118 } | |
119 | |
120 TEST_F(RtpDemuxerTest, SinkRemovalSanity) { | |
danilchap
2017/05/24 17:14:02
prefer to name test describing what it is tesing,
eladalon
2017/05/25 08:00:05
Good point. I've gone with "OnRtpPacketNotCalledOn
| |
121 // |sinks| associated with different SSRCs each. We set one of them to also | |
122 // be mapped to additional SSRCs. | |
123 constexpr uint32_t kSsrcsOfMultiSsrcSink[] = {404, 505, 606}; | |
124 MockRtpPacketSink multi_ssrc_sink; | |
125 for (uint32_t ssrc : kSsrcsOfMultiSsrcSink) { | |
126 demuxer.AddSink(ssrc, &multi_ssrc_sink); | |
127 } | |
128 | |
129 // Remove the sink. | |
130 EXPECT_EQ(demuxer.RemoveSink(&multi_ssrc_sink), | |
131 arraysize(kSsrcsOfMultiSsrcSink)); | |
132 | |
133 // The removed sink does not get callbacks triggered for any of the SSRCs | |
134 // with which it was previously associated. | |
danilchap
2017/05/24 17:14:03
check it with StrictMock<MockRtpPacketSink>
or wit
eladalon
2017/05/25 08:00:05
I'm not sure why this would be needed. If you move
danilchap
2017/05/29 08:59:53
I tried to move RemoveSink after the loop - test s
eladalon
2017/05/30 14:23:37
Sorry, I mistook a warning for an error. Thank you
| |
135 for (uint32_t ssrc : kSsrcsOfMultiSsrcSink) { | |
136 auto packet = GetRtpPacketReceived(ssrc); | |
137 demuxer.OnRtpPacket(*packet); | |
138 } | |
139 } | |
140 | |
141 #if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) | |
142 TEST_F(RtpDemuxerTest, RepeatedAssociationsForbidden) { | |
143 // Set-up already associated sinks[0] with kSsrcs[0]. Repeating the | |
144 // association is an error. | |
145 EXPECT_DEATH(demuxer.AddSink(kSsrcs[0], &sinks[0]), ""); | |
146 } | |
147 | |
148 TEST_F(RtpDemuxerTest, SinksMustBeRemovedBeforeDestruction) { | |
149 std::unique_ptr<RtpDemuxer> bad_demuxer(new RtpDemuxer()); | |
150 MockRtpPacketSink sink; | |
151 constexpr uint32_t ssrc = 111; | |
152 bad_demuxer->AddSink(ssrc, &sink); | |
153 EXPECT_DEATH(bad_demuxer.reset(), ""); | |
154 EXPECT_EQ(bad_demuxer->RemoveSink(&sink), 1u); | |
155 } | |
156 #endif | |
157 | |
158 } // namespace | |
159 } // namespace webrtc | |
OLD | NEW |