Unregister from GCM when the only GCM app is removed
[chromium-blink-merge.git] / media / cast / net / rtcp / rtcp_unittest.cc
blob2ecbd1afd3a55ea27092088829677945107af104
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <stdint.h>
6 #include <vector>
8 #include "base/test/simple_test_tick_clock.h"
9 #include "media/cast/cast_defines.h"
10 #include "media/cast/net/cast_transport_config.h"
11 #include "media/cast/net/pacing/paced_sender.h"
12 #include "media/cast/net/rtcp/rtcp.h"
13 #include "media/cast/test/skewed_tick_clock.h"
14 #include "testing/gmock/include/gmock/gmock.h"
16 namespace media {
17 namespace cast {
19 using testing::_;
21 static const uint32 kSenderSsrc = 0x10203;
22 static const uint32 kReceiverSsrc = 0x40506;
23 static const int kInitialReceiverClockOffsetSeconds = -5;
25 class FakeRtcpTransport : public PacedPacketSender {
26 public:
27 explicit FakeRtcpTransport(base::SimpleTestTickClock* clock)
28 : clock_(clock),
29 packet_delay_(base::TimeDelta::FromMilliseconds(42)),
30 paused_(false) {}
32 void set_rtcp_destination(Rtcp* rtcp) { rtcp_ = rtcp; }
34 base::TimeDelta packet_delay() const { return packet_delay_; }
35 void set_packet_delay(base::TimeDelta delay) { packet_delay_ = delay; }
37 bool SendRtcpPacket(uint32 ssrc, PacketRef packet) override {
38 clock_->Advance(packet_delay_);
39 if (paused_) {
40 packet_queue_.push_back(packet);
41 } else {
42 rtcp_->IncomingRtcpPacket(&packet->data[0], packet->data.size());
44 return true;
47 bool SendPackets(const SendPacketVector& packets) override { return false; }
49 bool ResendPackets(const SendPacketVector& packets,
50 const DedupInfo& dedup_info) override {
51 return false;
54 void CancelSendingPacket(const PacketKey& packet_key) override {}
56 void Pause() {
57 paused_ = true;
60 void Unpause() {
61 paused_ = false;
62 for (size_t i = 0; i < packet_queue_.size(); ++i) {
63 rtcp_->IncomingRtcpPacket(&packet_queue_[i]->data[0],
64 packet_queue_[i]->data.size());
66 packet_queue_.clear();
69 void ReversePacketQueue() {
70 std::reverse(packet_queue_.begin(), packet_queue_.end());
73 private:
74 base::SimpleTestTickClock* const clock_;
75 base::TimeDelta packet_delay_;
76 Rtcp* rtcp_;
77 bool paused_;
78 std::vector<PacketRef> packet_queue_;
80 DISALLOW_COPY_AND_ASSIGN(FakeRtcpTransport);
83 class MockFrameSender {
84 public:
85 MockFrameSender() {}
86 virtual ~MockFrameSender() {}
88 MOCK_METHOD1(OnReceivedCastFeedback,
89 void(const RtcpCastMessage& cast_message));
90 MOCK_METHOD1(OnMeasuredRoundTripTime, void(base::TimeDelta rtt));
92 private:
93 DISALLOW_COPY_AND_ASSIGN(MockFrameSender);
96 class RtcpTest : public ::testing::Test {
97 protected:
98 RtcpTest()
99 : sender_clock_(new base::SimpleTestTickClock()),
100 receiver_clock_(new test::SkewedTickClock(sender_clock_.get())),
101 sender_to_receiver_(sender_clock_.get()),
102 receiver_to_sender_(sender_clock_.get()),
103 rtcp_for_sender_(base::Bind(&MockFrameSender::OnReceivedCastFeedback,
104 base::Unretained(&mock_frame_sender_)),
105 base::Bind(&MockFrameSender::OnMeasuredRoundTripTime,
106 base::Unretained(&mock_frame_sender_)),
107 RtcpLogMessageCallback(),
108 sender_clock_.get(),
109 &sender_to_receiver_,
110 kSenderSsrc,
111 kReceiverSsrc),
112 rtcp_for_receiver_(RtcpCastMessageCallback(),
113 RtcpRttCallback(),
114 RtcpLogMessageCallback(),
115 receiver_clock_.get(),
116 &receiver_to_sender_,
117 kReceiverSsrc,
118 kSenderSsrc) {
119 sender_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks());
120 receiver_clock_->SetSkew(
121 1.0, // No skew.
122 base::TimeDelta::FromSeconds(kInitialReceiverClockOffsetSeconds));
124 sender_to_receiver_.set_rtcp_destination(&rtcp_for_receiver_);
125 receiver_to_sender_.set_rtcp_destination(&rtcp_for_sender_);
128 ~RtcpTest() override {}
130 scoped_ptr<base::SimpleTestTickClock> sender_clock_;
131 scoped_ptr<test::SkewedTickClock> receiver_clock_;
132 FakeRtcpTransport sender_to_receiver_;
133 FakeRtcpTransport receiver_to_sender_;
134 MockFrameSender mock_frame_sender_;
135 Rtcp rtcp_for_sender_;
136 Rtcp rtcp_for_receiver_;
138 DISALLOW_COPY_AND_ASSIGN(RtcpTest);
141 TEST_F(RtcpTest, LipSyncGleanedFromSenderReport) {
142 // Initially, expect no lip-sync info receiver-side without having first
143 // received a RTCP packet.
144 base::TimeTicks reference_time;
145 uint32 rtp_timestamp;
146 ASSERT_FALSE(rtcp_for_receiver_.GetLatestLipSyncTimes(&rtp_timestamp,
147 &reference_time));
149 // Send a Sender Report to the receiver.
150 const base::TimeTicks reference_time_sent = sender_clock_->NowTicks();
151 const uint32 rtp_timestamp_sent = 0xbee5;
152 rtcp_for_sender_.SendRtcpFromRtpSender(
153 reference_time_sent, rtp_timestamp_sent, 1, 1);
155 // Now the receiver should have lip-sync info. Confirm that the lip-sync
156 // reference time is the same as that sent.
157 EXPECT_TRUE(rtcp_for_receiver_.GetLatestLipSyncTimes(&rtp_timestamp,
158 &reference_time));
159 const base::TimeTicks rolled_back_time =
160 (reference_time -
161 // Roll-back relative clock offset:
162 base::TimeDelta::FromSeconds(kInitialReceiverClockOffsetSeconds) -
163 // Roll-back packet transmission time (because RTT is not yet known):
164 sender_to_receiver_.packet_delay());
165 EXPECT_NEAR(0, (reference_time_sent - rolled_back_time).InMicroseconds(), 5);
166 EXPECT_EQ(rtp_timestamp_sent, rtp_timestamp);
169 // TODO(miu): There were a few tests here that didn't actually test anything
170 // except that the code wouldn't crash and a callback method was invoked. We
171 // need to fill-in more testing of RTCP now that much of the refactoring work
172 // has been completed.
174 TEST_F(RtcpTest, RoundTripTimesDeterminedFromReportPingPong) {
175 const int iterations = 12;
176 EXPECT_CALL(mock_frame_sender_, OnMeasuredRoundTripTime(_))
177 .Times(iterations);
179 // Initially, neither side knows the round trip time.
180 ASSERT_EQ(base::TimeDelta(), rtcp_for_sender_.current_round_trip_time());
181 ASSERT_EQ(base::TimeDelta(), rtcp_for_receiver_.current_round_trip_time());
183 // Do a number of ping-pongs, checking how the round trip times are measured
184 // by the sender and receiver.
185 base::TimeDelta expected_rtt_according_to_sender;
186 base::TimeDelta expected_rtt_according_to_receiver;
187 for (int i = 0; i < iterations; ++i) {
188 const base::TimeDelta one_way_trip_time =
189 base::TimeDelta::FromMilliseconds(1 << i);
190 sender_to_receiver_.set_packet_delay(one_way_trip_time);
191 receiver_to_sender_.set_packet_delay(one_way_trip_time);
193 // Sender --> Receiver
194 base::TimeTicks reference_time_sent = sender_clock_->NowTicks();
195 uint32 rtp_timestamp_sent = 0xbee5 + i;
196 rtcp_for_sender_.SendRtcpFromRtpSender(
197 reference_time_sent, rtp_timestamp_sent, 1, 1);
198 EXPECT_EQ(expected_rtt_according_to_sender,
199 rtcp_for_sender_.current_round_trip_time());
200 #ifdef SENDER_PROVIDES_REPORT_BLOCK
201 EXPECT_EQ(expected_rtt_according_to_receiver,
202 rtcp_for_receiver_.current_round_trip_time());
203 #endif
205 // Receiver --> Sender
206 RtpReceiverStatistics stats;
207 rtcp_for_receiver_.SendRtcpFromRtpReceiver(
208 rtcp_for_receiver_.ConvertToNTPAndSave(receiver_clock_->NowTicks()),
209 NULL, base::TimeDelta(), NULL, &stats);
210 expected_rtt_according_to_sender = one_way_trip_time * 2;
211 EXPECT_EQ(expected_rtt_according_to_sender,
212 rtcp_for_sender_.current_round_trip_time());
213 #ifdef SENDER_PROVIDES_REPORT_BLOCK
214 EXPECT_EQ(expected_rtt_according_to_receiver,
215 rtcp_for_receiver_.current_round_trip_time();
216 #endif
218 // In the next iteration of this loop, after the receiver gets the sender
219 // report, it will be measuring a round trip time consisting of two
220 // different one-way trip times.
221 expected_rtt_according_to_receiver =
222 (one_way_trip_time + one_way_trip_time * 2) / 2;
226 TEST_F(RtcpTest, RejectOldRtcpPacket) {
227 EXPECT_CALL(mock_frame_sender_, OnReceivedCastFeedback(_))
228 .Times(1);
230 // This is rejected.
231 RtcpCastMessage cast_message(kSenderSsrc);
232 cast_message.ack_frame_id = 1;
233 receiver_to_sender_.Pause();
234 rtcp_for_receiver_.SendRtcpFromRtpReceiver(
235 rtcp_for_receiver_.ConvertToNTPAndSave(
236 receiver_clock_->NowTicks() - base::TimeDelta::FromSeconds(10)),
237 &cast_message, base::TimeDelta(), NULL, NULL);
239 cast_message.ack_frame_id = 2;
240 rtcp_for_receiver_.SendRtcpFromRtpReceiver(
241 rtcp_for_receiver_.ConvertToNTPAndSave(receiver_clock_->NowTicks()),
242 &cast_message, base::TimeDelta(), NULL, NULL);
244 receiver_to_sender_.ReversePacketQueue();
245 receiver_to_sender_.Unpause();
248 TEST_F(RtcpTest, NegativeTimeTicks) {
249 EXPECT_CALL(mock_frame_sender_, OnReceivedCastFeedback(_))
250 .Times(2);
252 // Send a RRTR with NTP timestamp that translates to a very negative
253 // value for TimeTicks.
254 RtcpCastMessage cast_message(kSenderSsrc);
255 cast_message.ack_frame_id = 2;
256 rtcp_for_receiver_.SendRtcpFromRtpReceiver(
257 rtcp_for_receiver_.ConvertToNTPAndSave(
258 base::TimeTicks() - base::TimeDelta::FromSeconds(5)),
259 &cast_message, base::TimeDelta(), NULL, NULL);
261 cast_message.ack_frame_id = 1;
262 rtcp_for_receiver_.SendRtcpFromRtpReceiver(
263 rtcp_for_receiver_.ConvertToNTPAndSave(base::TimeTicks()),
264 &cast_message, base::TimeDelta(), NULL, NULL);
267 // TODO(miu): Find a better home for this test.
268 TEST(MisplacedCastTest, NtpAndTime) {
269 const int64 kSecondsbetweenYear1900and2010 = INT64_C(40176 * 24 * 60 * 60);
270 const int64 kSecondsbetweenYear1900and2030 = INT64_C(47481 * 24 * 60 * 60);
272 uint32 ntp_seconds_1 = 0;
273 uint32 ntp_fraction_1 = 0;
274 base::TimeTicks input_time = base::TimeTicks::Now();
275 ConvertTimeTicksToNtp(input_time, &ntp_seconds_1, &ntp_fraction_1);
277 // Verify absolute value.
278 EXPECT_GT(ntp_seconds_1, kSecondsbetweenYear1900and2010);
279 EXPECT_LT(ntp_seconds_1, kSecondsbetweenYear1900and2030);
281 base::TimeTicks out_1 = ConvertNtpToTimeTicks(ntp_seconds_1, ntp_fraction_1);
282 EXPECT_EQ(input_time, out_1); // Verify inverse.
284 base::TimeDelta time_delta = base::TimeDelta::FromMilliseconds(1000);
285 input_time += time_delta;
287 uint32 ntp_seconds_2 = 0;
288 uint32 ntp_fraction_2 = 0;
290 ConvertTimeTicksToNtp(input_time, &ntp_seconds_2, &ntp_fraction_2);
291 base::TimeTicks out_2 = ConvertNtpToTimeTicks(ntp_seconds_2, ntp_fraction_2);
292 EXPECT_EQ(input_time, out_2); // Verify inverse.
294 // Verify delta.
295 EXPECT_EQ((out_2 - out_1), time_delta);
296 EXPECT_EQ((ntp_seconds_2 - ntp_seconds_1), UINT32_C(1));
297 EXPECT_NEAR(ntp_fraction_2, ntp_fraction_1, 1);
299 time_delta = base::TimeDelta::FromMilliseconds(500);
300 input_time += time_delta;
302 uint32 ntp_seconds_3 = 0;
303 uint32 ntp_fraction_3 = 0;
305 ConvertTimeTicksToNtp(input_time, &ntp_seconds_3, &ntp_fraction_3);
306 base::TimeTicks out_3 = ConvertNtpToTimeTicks(ntp_seconds_3, ntp_fraction_3);
307 EXPECT_EQ(input_time, out_3); // Verify inverse.
309 // Verify delta.
310 EXPECT_EQ((out_3 - out_2), time_delta);
311 EXPECT_NEAR((ntp_fraction_3 - ntp_fraction_2), 0xffffffff / 2, 1);
314 } // namespace cast
315 } // namespace media