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/bind.h"
6#include "base/callback_helpers.h"
7#include "base/logging.h"
8#include "base/memory/scoped_ptr.h"
9#include "base/time/time.h"
10#include "chromecast/media/cma/base/buffering_controller.h"
11#include "chromecast/media/cma/base/buffering_state.h"
12#include "testing/gmock/include/gmock/gmock.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15namespace chromecast {
16namespace media {
17
18namespace {
19
20class MockBufferingControllerClient {
21 public:
22  MockBufferingControllerClient();
23  ~MockBufferingControllerClient();
24
25  MOCK_METHOD1(OnBufferingNotification, void(bool is_buffering));
26
27 private:
28  DISALLOW_COPY_AND_ASSIGN(MockBufferingControllerClient);
29};
30
31MockBufferingControllerClient::MockBufferingControllerClient() {
32}
33
34MockBufferingControllerClient::~MockBufferingControllerClient() {
35}
36
37}  // namespace
38
39class BufferingControllerTest : public testing::Test {
40 public:
41  BufferingControllerTest();
42  virtual ~BufferingControllerTest();
43
44 protected:
45  scoped_ptr<BufferingController> buffering_controller_;
46
47  MockBufferingControllerClient client_;
48
49  // Buffer level under the low level threshold.
50  base::TimeDelta d1_;
51
52  // Buffer level between the low and the high level.
53  base::TimeDelta d2_;
54
55  // Buffer level above the high level.
56  base::TimeDelta d3_;
57
58 private:
59  DISALLOW_COPY_AND_ASSIGN(BufferingControllerTest);
60};
61
62BufferingControllerTest::BufferingControllerTest() {
63  base::TimeDelta low_level_threshold(
64      base::TimeDelta::FromMilliseconds(2000));
65  base::TimeDelta high_level_threshold(
66      base::TimeDelta::FromMilliseconds(6000));
67
68  d1_ = low_level_threshold - base::TimeDelta::FromMilliseconds(50);
69  d2_ = (low_level_threshold + high_level_threshold) / 2;
70  d3_ = high_level_threshold + base::TimeDelta::FromMilliseconds(50);
71
72  scoped_refptr<BufferingConfig> buffering_config(
73      new BufferingConfig(low_level_threshold, high_level_threshold));
74  buffering_controller_.reset(new BufferingController(
75      buffering_config,
76      base::Bind(&MockBufferingControllerClient::OnBufferingNotification,
77                 base::Unretained(&client_))));
78}
79
80BufferingControllerTest::~BufferingControllerTest() {
81}
82
83TEST_F(BufferingControllerTest, OneStream_Typical) {
84  EXPECT_CALL(client_, OnBufferingNotification(true)).Times(1);
85  scoped_refptr<BufferingState> buffering_state =
86      buffering_controller_->AddStream();
87  buffering_state->SetMediaTime(base::TimeDelta());
88
89  // Simulate pre-buffering.
90  buffering_state->SetBufferedTime(d2_);
91  EXPECT_EQ(buffering_state->GetState(), BufferingState::kMediumLevel);
92
93  EXPECT_CALL(client_, OnBufferingNotification(false)).Times(1);
94  buffering_state->SetBufferedTime(d3_);
95  EXPECT_EQ(buffering_state->GetState(), BufferingState::kHighLevel);
96
97  // Simulate some fluctuations of the buffering level.
98  buffering_state->SetBufferedTime(d2_);
99  EXPECT_EQ(buffering_state->GetState(), BufferingState::kMediumLevel);
100
101  // Simulate an underrun.
102  EXPECT_CALL(client_, OnBufferingNotification(true)).Times(1);
103  buffering_state->SetBufferedTime(d1_);
104  EXPECT_EQ(buffering_state->GetState(), BufferingState::kLowLevel);
105
106  EXPECT_CALL(client_, OnBufferingNotification(false)).Times(1);
107  buffering_state->SetBufferedTime(d3_);
108  EXPECT_EQ(buffering_state->GetState(), BufferingState::kHighLevel);
109
110  // Simulate the end of stream.
111  buffering_state->NotifyEos();
112  EXPECT_EQ(buffering_state->GetState(), BufferingState::kEosReached);
113
114  buffering_state->SetBufferedTime(d2_);
115  EXPECT_EQ(buffering_state->GetState(), BufferingState::kEosReached);
116
117  buffering_state->SetBufferedTime(d1_);
118  EXPECT_EQ(buffering_state->GetState(), BufferingState::kEosReached);
119}
120
121TEST_F(BufferingControllerTest, OneStream_LeaveBufferingOnEos) {
122  EXPECT_CALL(client_, OnBufferingNotification(true)).Times(1);
123  scoped_refptr<BufferingState> buffering_state =
124      buffering_controller_->AddStream();
125  buffering_state->SetMediaTime(base::TimeDelta());
126
127  EXPECT_CALL(client_, OnBufferingNotification(false)).Times(1);
128  buffering_state->NotifyEos();
129  EXPECT_EQ(buffering_state->GetState(), BufferingState::kEosReached);
130}
131
132}  // namespace media
133}  // namespace chromecast
134