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.
4
5#include "base/memory/ref_counted.h"
6#include "base/memory/scoped_ptr.h"
7#include "base/test/simple_test_tick_clock.h"
8#include "base/time/tick_clock.h"
9#include "media/cast/cast_environment.h"
10#include "media/cast/logging/logging_defines.h"
11#include "media/cast/net/rtcp/receiver_rtcp_event_subscriber.h"
12#include "media/cast/test/fake_single_thread_task_runner.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15namespace media {
16namespace cast {
17
18namespace {
19
20const size_t kMaxEventEntries = 10u;
21const int64 kDelayMs = 20L;
22
23}  // namespace
24
25class ReceiverRtcpEventSubscriberTest : public ::testing::Test {
26 protected:
27  ReceiverRtcpEventSubscriberTest()
28      : testing_clock_(new base::SimpleTestTickClock()),
29        task_runner_(new test::FakeSingleThreadTaskRunner(testing_clock_)),
30        cast_environment_(new CastEnvironment(
31            scoped_ptr<base::TickClock>(testing_clock_).Pass(),
32            task_runner_,
33            task_runner_,
34            task_runner_)) {}
35
36  virtual ~ReceiverRtcpEventSubscriberTest() {}
37
38  virtual void TearDown() OVERRIDE {
39    if (event_subscriber_) {
40      cast_environment_->Logging()->RemoveRawEventSubscriber(
41          event_subscriber_.get());
42    }
43  }
44
45  void Init(EventMediaType type) {
46    event_subscriber_.reset(
47        new ReceiverRtcpEventSubscriber(kMaxEventEntries, type));
48    cast_environment_->Logging()->AddRawEventSubscriber(
49        event_subscriber_.get());
50  }
51
52  void InsertEvents() {
53    // Video events
54    cast_environment_->Logging()->InsertFrameEventWithDelay(
55        testing_clock_->NowTicks(), FRAME_PLAYOUT, VIDEO_EVENT,
56        /*rtp_timestamp*/ 100u, /*frame_id*/ 2u,
57        base::TimeDelta::FromMilliseconds(kDelayMs));
58    cast_environment_->Logging()->InsertFrameEvent(
59        testing_clock_->NowTicks(), FRAME_DECODED, VIDEO_EVENT,
60        /*rtp_timestamp*/ 200u, /*frame_id*/ 1u);
61    cast_environment_->Logging()->InsertPacketEvent(
62        testing_clock_->NowTicks(), PACKET_RECEIVED, VIDEO_EVENT,
63        /*rtp_timestamp */ 200u, /*frame_id*/ 2u, /*packet_id*/ 1u,
64        /*max_packet_id*/ 10u, /*size*/ 1024u);
65
66    // Audio events
67    cast_environment_->Logging()->InsertFrameEventWithDelay(
68        testing_clock_->NowTicks(), FRAME_PLAYOUT, AUDIO_EVENT,
69        /*rtp_timestamp*/ 300u, /*frame_id*/ 4u,
70        base::TimeDelta::FromMilliseconds(kDelayMs));
71    cast_environment_->Logging()->InsertFrameEvent(
72        testing_clock_->NowTicks(), FRAME_DECODED, AUDIO_EVENT,
73        /*rtp_timestamp*/ 400u, /*frame_id*/ 3u);
74    cast_environment_->Logging()->InsertPacketEvent(
75        testing_clock_->NowTicks(), PACKET_RECEIVED, AUDIO_EVENT,
76        /*rtp_timestamp */ 400u, /*frame_id*/ 5u, /*packet_id*/ 1u,
77        /*max_packet_id*/ 10u, /*size*/ 128u);
78
79    // Unrelated events
80    cast_environment_->Logging()->InsertFrameEvent(testing_clock_->NowTicks(),
81                                                   FRAME_CAPTURE_END,
82                                                   VIDEO_EVENT,
83                                                   /*rtp_timestamp*/ 100u,
84                                                   /*frame_id*/ 1u);
85    cast_environment_->Logging()->InsertFrameEvent(testing_clock_->NowTicks(),
86                                                   FRAME_CAPTURE_END,
87                                                   AUDIO_EVENT,
88                                                   /*rtp_timestamp*/ 100u,
89                                                   /*frame_id*/ 1u);
90  }
91
92  base::SimpleTestTickClock* testing_clock_;  // Owned by CastEnvironment.
93  scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_;
94  scoped_refptr<CastEnvironment> cast_environment_;
95  scoped_ptr<ReceiverRtcpEventSubscriber> event_subscriber_;
96};
97
98TEST_F(ReceiverRtcpEventSubscriberTest, LogVideoEvents) {
99  Init(VIDEO_EVENT);
100
101  InsertEvents();
102  ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events;
103  event_subscriber_->GetRtcpEventsAndReset(&rtcp_events);
104  EXPECT_EQ(3u, rtcp_events.size());
105}
106
107TEST_F(ReceiverRtcpEventSubscriberTest, LogAudioEvents) {
108  Init(AUDIO_EVENT);
109
110  InsertEvents();
111  ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events;
112  event_subscriber_->GetRtcpEventsAndReset(&rtcp_events);
113  EXPECT_EQ(3u, rtcp_events.size());
114}
115
116TEST_F(ReceiverRtcpEventSubscriberTest, DropEventsWhenSizeExceeded) {
117  Init(VIDEO_EVENT);
118
119  for (uint32 i = 1u; i <= 10u; ++i) {
120    cast_environment_->Logging()->InsertFrameEvent(
121        testing_clock_->NowTicks(), FRAME_DECODED, VIDEO_EVENT,
122        /*rtp_timestamp*/ i * 10, /*frame_id*/ i);
123  }
124
125  ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events;
126  event_subscriber_->GetRtcpEventsAndReset(&rtcp_events);
127  EXPECT_EQ(10u, rtcp_events.size());
128}
129
130}  // namespace cast
131}  // namespace media
132