1 /*
2 * Copyright (c) 2016 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 "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
12
13 #include "rtc_base/random.h"
14 #include "test/gmock.h"
15 #include "test/gtest.h"
16 #include "test/rtcp_packet_parser.h"
17
18 using ::testing::ElementsAre;
19 using ::testing::ElementsAreArray;
20 using ::testing::make_tuple;
21 using ::testing::SizeIs;
22 using webrtc::rtcp::ExtendedReports;
23 using webrtc::rtcp::ReceiveTimeInfo;
24 using webrtc::rtcp::Rrtr;
25
26 namespace webrtc {
27 namespace {
28 constexpr uint32_t kSenderSsrc = 0x12345678;
29 constexpr uint8_t kEmptyPacket[] = {0x80, 207, 0x00, 0x01,
30 0x12, 0x34, 0x56, 0x78};
31 } // namespace
32
33 class RtcpPacketExtendedReportsTest : public ::testing::Test {
34 public:
RtcpPacketExtendedReportsTest()35 RtcpPacketExtendedReportsTest() : random_(0x123456789) {}
36
37 protected:
38 template <typename T>
Rand()39 T Rand() {
40 return random_.Rand<T>();
41 }
42
43 private:
44 Random random_;
45 };
46
47 template <>
Rand()48 ReceiveTimeInfo RtcpPacketExtendedReportsTest::Rand<ReceiveTimeInfo>() {
49 uint32_t ssrc = Rand<uint32_t>();
50 uint32_t last_rr = Rand<uint32_t>();
51 uint32_t delay_since_last_rr = Rand<uint32_t>();
52 return ReceiveTimeInfo(ssrc, last_rr, delay_since_last_rr);
53 }
54
55 template <>
Rand()56 NtpTime RtcpPacketExtendedReportsTest::Rand<NtpTime>() {
57 uint32_t secs = Rand<uint32_t>();
58 uint32_t frac = Rand<uint32_t>();
59 return NtpTime(secs, frac);
60 }
61
62 template <>
Rand()63 Rrtr RtcpPacketExtendedReportsTest::Rand<Rrtr>() {
64 Rrtr rrtr;
65 rrtr.SetNtp(Rand<NtpTime>());
66 return rrtr;
67 }
68
TEST_F(RtcpPacketExtendedReportsTest,CreateWithoutReportBlocks)69 TEST_F(RtcpPacketExtendedReportsTest, CreateWithoutReportBlocks) {
70 ExtendedReports xr;
71 xr.SetSenderSsrc(kSenderSsrc);
72
73 rtc::Buffer packet = xr.Build();
74
75 EXPECT_THAT(make_tuple(packet.data(), packet.size()),
76 ElementsAreArray(kEmptyPacket));
77 }
78
TEST_F(RtcpPacketExtendedReportsTest,ParseWithoutReportBlocks)79 TEST_F(RtcpPacketExtendedReportsTest, ParseWithoutReportBlocks) {
80 ExtendedReports parsed;
81 EXPECT_TRUE(test::ParseSinglePacket(kEmptyPacket, &parsed));
82 EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
83 EXPECT_FALSE(parsed.rrtr());
84 EXPECT_FALSE(parsed.dlrr());
85 }
86
TEST_F(RtcpPacketExtendedReportsTest,CreateAndParseWithRrtrBlock)87 TEST_F(RtcpPacketExtendedReportsTest, CreateAndParseWithRrtrBlock) {
88 const Rrtr kRrtr = Rand<Rrtr>();
89 ExtendedReports xr;
90 xr.SetSenderSsrc(kSenderSsrc);
91 xr.SetRrtr(kRrtr);
92 rtc::Buffer packet = xr.Build();
93
94 ExtendedReports mparsed;
95 EXPECT_TRUE(test::ParseSinglePacket(packet, &mparsed));
96 const ExtendedReports& parsed = mparsed;
97
98 EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
99 EXPECT_EQ(kRrtr, parsed.rrtr());
100 }
101
TEST_F(RtcpPacketExtendedReportsTest,CreateAndParseWithDlrrWithOneSubBlock)102 TEST_F(RtcpPacketExtendedReportsTest, CreateAndParseWithDlrrWithOneSubBlock) {
103 const ReceiveTimeInfo kTimeInfo = Rand<ReceiveTimeInfo>();
104 ExtendedReports xr;
105 xr.SetSenderSsrc(kSenderSsrc);
106 xr.AddDlrrItem(kTimeInfo);
107
108 rtc::Buffer packet = xr.Build();
109
110 ExtendedReports mparsed;
111 EXPECT_TRUE(test::ParseSinglePacket(packet, &mparsed));
112 const ExtendedReports& parsed = mparsed;
113
114 EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
115 EXPECT_THAT(parsed.dlrr().sub_blocks(), ElementsAre(kTimeInfo));
116 }
117
TEST_F(RtcpPacketExtendedReportsTest,CreateAndParseWithDlrrWithTwoSubBlocks)118 TEST_F(RtcpPacketExtendedReportsTest, CreateAndParseWithDlrrWithTwoSubBlocks) {
119 const ReceiveTimeInfo kTimeInfo1 = Rand<ReceiveTimeInfo>();
120 const ReceiveTimeInfo kTimeInfo2 = Rand<ReceiveTimeInfo>();
121 ExtendedReports xr;
122 xr.SetSenderSsrc(kSenderSsrc);
123 xr.AddDlrrItem(kTimeInfo1);
124 xr.AddDlrrItem(kTimeInfo2);
125
126 rtc::Buffer packet = xr.Build();
127
128 ExtendedReports mparsed;
129 EXPECT_TRUE(test::ParseSinglePacket(packet, &mparsed));
130 const ExtendedReports& parsed = mparsed;
131
132 EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
133 EXPECT_THAT(parsed.dlrr().sub_blocks(), ElementsAre(kTimeInfo1, kTimeInfo2));
134 }
135
TEST_F(RtcpPacketExtendedReportsTest,CreateLimitsTheNumberOfDlrrSubBlocks)136 TEST_F(RtcpPacketExtendedReportsTest, CreateLimitsTheNumberOfDlrrSubBlocks) {
137 const ReceiveTimeInfo kTimeInfo = Rand<ReceiveTimeInfo>();
138 ExtendedReports xr;
139
140 for (size_t i = 0; i < ExtendedReports::kMaxNumberOfDlrrItems; ++i)
141 EXPECT_TRUE(xr.AddDlrrItem(kTimeInfo));
142 EXPECT_FALSE(xr.AddDlrrItem(kTimeInfo));
143
144 EXPECT_THAT(xr.dlrr().sub_blocks(),
145 SizeIs(ExtendedReports::kMaxNumberOfDlrrItems));
146 }
147
TEST_F(RtcpPacketExtendedReportsTest,CreateAndParseWithMaximumReportBlocks)148 TEST_F(RtcpPacketExtendedReportsTest, CreateAndParseWithMaximumReportBlocks) {
149 const Rrtr kRrtr = Rand<Rrtr>();
150
151 ExtendedReports xr;
152 xr.SetSenderSsrc(kSenderSsrc);
153 xr.SetRrtr(kRrtr);
154 for (size_t i = 0; i < ExtendedReports::kMaxNumberOfDlrrItems; ++i)
155 xr.AddDlrrItem(Rand<ReceiveTimeInfo>());
156
157 rtc::Buffer packet = xr.Build();
158
159 ExtendedReports mparsed;
160 EXPECT_TRUE(test::ParseSinglePacket(packet, &mparsed));
161 const ExtendedReports& parsed = mparsed;
162
163 EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc());
164 EXPECT_EQ(kRrtr, parsed.rrtr());
165 EXPECT_THAT(parsed.dlrr().sub_blocks(),
166 ElementsAreArray(xr.dlrr().sub_blocks()));
167 }
168
169 } // namespace webrtc
170