| /* | 
 |  *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 
 |  * | 
 |  *  Use of this source code is governed by a BSD-style license | 
 |  *  that can be found in the LICENSE file in the root of the source | 
 |  *  tree. An additional intellectual property rights grant can be found | 
 |  *  in the file PATENTS.  All contributing project authors may | 
 |  *  be found in the AUTHORS file in the root of the source tree. | 
 |  */ | 
 |  | 
 | #include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h" | 
 |  | 
 | #include <cstddef> | 
 | #include <cstdint> | 
 | #include <utility> | 
 | #include <vector> | 
 |  | 
 | #include "modules/rtp_rtcp/source/rtcp_packet/report_block.h" | 
 | #include "rtc_base/buffer.h" | 
 | #include "system_wrappers/include/ntp_time.h" | 
 | #include "test/gmock.h" | 
 | #include "test/gtest.h" | 
 | #include "test/rtcp_packet_parser.h" | 
 |  | 
 | using ::testing::ElementsAreArray; | 
 | using ::testing::make_tuple; | 
 | using webrtc::rtcp::ReportBlock; | 
 | using webrtc::rtcp::SenderReport; | 
 |  | 
 | namespace webrtc { | 
 | namespace { | 
 | constexpr uint32_t kSenderSsrc = 0x12345678; | 
 | constexpr uint32_t kRemoteSsrc = 0x23456789; | 
 | const NtpTime kNtp(0x11121418, 0x22242628); | 
 | constexpr uint32_t kRtpTimestamp = 0x33343536; | 
 | constexpr uint32_t kPacketCount = 0x44454647; | 
 | constexpr uint32_t kOctetCount = 0x55565758; | 
 | constexpr uint8_t kPacket[] = {0x80, 200,  0x00, 0x06, 0x12, 0x34, 0x56, | 
 |                                0x78, 0x11, 0x12, 0x14, 0x18, 0x22, 0x24, | 
 |                                0x26, 0x28, 0x33, 0x34, 0x35, 0x36, 0x44, | 
 |                                0x45, 0x46, 0x47, 0x55, 0x56, 0x57, 0x58}; | 
 | }  // namespace | 
 |  | 
 | TEST(RtcpPacketSenderReportTest, CreateWithoutReportBlocks) { | 
 |   SenderReport sr; | 
 |   sr.SetSenderSsrc(kSenderSsrc); | 
 |   sr.SetNtp(kNtp); | 
 |   sr.SetRtpTimestamp(kRtpTimestamp); | 
 |   sr.SetPacketCount(kPacketCount); | 
 |   sr.SetOctetCount(kOctetCount); | 
 |  | 
 |   Buffer raw = sr.Build(); | 
 |   EXPECT_THAT(make_tuple(raw.data(), raw.size()), ElementsAreArray(kPacket)); | 
 | } | 
 |  | 
 | TEST(RtcpPacketSenderReportTest, ParseWithoutReportBlocks) { | 
 |   SenderReport parsed; | 
 |   EXPECT_TRUE(test::ParseSinglePacket(kPacket, &parsed)); | 
 |  | 
 |   EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc()); | 
 |   EXPECT_EQ(kNtp, parsed.ntp()); | 
 |   EXPECT_EQ(kRtpTimestamp, parsed.rtp_timestamp()); | 
 |   EXPECT_EQ(kPacketCount, parsed.sender_packet_count()); | 
 |   EXPECT_EQ(kOctetCount, parsed.sender_octet_count()); | 
 |   EXPECT_TRUE(parsed.report_blocks().empty()); | 
 | } | 
 |  | 
 | TEST(RtcpPacketSenderReportTest, CreateAndParseWithOneReportBlock) { | 
 |   ReportBlock rb; | 
 |   rb.SetMediaSsrc(kRemoteSsrc); | 
 |  | 
 |   SenderReport sr; | 
 |   sr.SetSenderSsrc(kSenderSsrc); | 
 |   EXPECT_TRUE(sr.AddReportBlock(rb)); | 
 |  | 
 |   Buffer raw = sr.Build(); | 
 |   SenderReport parsed; | 
 |   EXPECT_TRUE(test::ParseSinglePacket(raw, &parsed)); | 
 |  | 
 |   EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc()); | 
 |   EXPECT_EQ(1u, parsed.report_blocks().size()); | 
 |   EXPECT_EQ(kRemoteSsrc, parsed.report_blocks()[0].source_ssrc()); | 
 | } | 
 |  | 
 | TEST(RtcpPacketSenderReportTest, CreateAndParseWithTwoReportBlocks) { | 
 |   ReportBlock rb1; | 
 |   rb1.SetMediaSsrc(kRemoteSsrc); | 
 |   ReportBlock rb2; | 
 |   rb2.SetMediaSsrc(kRemoteSsrc + 1); | 
 |  | 
 |   SenderReport sr; | 
 |   sr.SetSenderSsrc(kSenderSsrc); | 
 |   EXPECT_TRUE(sr.AddReportBlock(rb1)); | 
 |   EXPECT_TRUE(sr.AddReportBlock(rb2)); | 
 |  | 
 |   Buffer raw = sr.Build(); | 
 |   SenderReport parsed; | 
 |   EXPECT_TRUE(test::ParseSinglePacket(raw, &parsed)); | 
 |  | 
 |   EXPECT_EQ(kSenderSsrc, parsed.sender_ssrc()); | 
 |   EXPECT_EQ(2u, parsed.report_blocks().size()); | 
 |   EXPECT_EQ(kRemoteSsrc, parsed.report_blocks()[0].source_ssrc()); | 
 |   EXPECT_EQ(kRemoteSsrc + 1, parsed.report_blocks()[1].source_ssrc()); | 
 | } | 
 |  | 
 | TEST(RtcpPacketSenderReportTest, CreateWithTooManyReportBlocks) { | 
 |   SenderReport sr; | 
 |   sr.SetSenderSsrc(kSenderSsrc); | 
 |   ReportBlock rb; | 
 |   for (size_t i = 0; i < SenderReport::kMaxNumberOfReportBlocks; ++i) { | 
 |     rb.SetMediaSsrc(kRemoteSsrc + i); | 
 |     EXPECT_TRUE(sr.AddReportBlock(rb)); | 
 |   } | 
 |   rb.SetMediaSsrc(kRemoteSsrc + SenderReport::kMaxNumberOfReportBlocks); | 
 |   EXPECT_FALSE(sr.AddReportBlock(rb)); | 
 | } | 
 |  | 
 | TEST(RtcpPacketSenderReportTest, SetReportBlocksOverwritesOldBlocks) { | 
 |   SenderReport sr; | 
 |   ReportBlock report_block; | 
 |   // Use jitter field of the report blocks to distinguish them. | 
 |   report_block.SetJitter(1001u); | 
 |   sr.AddReportBlock(report_block); | 
 |   ASSERT_EQ(sr.report_blocks().size(), 1u); | 
 |   ASSERT_EQ(sr.report_blocks()[0].jitter(), 1001u); | 
 |  | 
 |   std::vector<ReportBlock> blocks(3u); | 
 |   blocks[0].SetJitter(2001u); | 
 |   blocks[1].SetJitter(3001u); | 
 |   blocks[2].SetJitter(4001u); | 
 |   EXPECT_TRUE(sr.SetReportBlocks(blocks)); | 
 |   ASSERT_EQ(sr.report_blocks().size(), 3u); | 
 |   EXPECT_EQ(sr.report_blocks()[0].jitter(), 2001u); | 
 |   EXPECT_EQ(sr.report_blocks()[1].jitter(), 3001u); | 
 |   EXPECT_EQ(sr.report_blocks()[2].jitter(), 4001u); | 
 | } | 
 |  | 
 | TEST(RtcpPacketSenderReportTest, SetReportBlocksMaxLimit) { | 
 |   SenderReport sr; | 
 |   std::vector<ReportBlock> max_blocks(SenderReport::kMaxNumberOfReportBlocks); | 
 |   EXPECT_TRUE(sr.SetReportBlocks(std::move(max_blocks))); | 
 |  | 
 |   std::vector<ReportBlock> one_too_many_blocks( | 
 |       SenderReport::kMaxNumberOfReportBlocks + 1); | 
 |   EXPECT_FALSE(sr.SetReportBlocks(std::move(one_too_many_blocks))); | 
 | } | 
 |  | 
 | }  // namespace webrtc |