1e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org/*
2e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org *
4e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org *  Use of this source code is governed by a BSD-style license
5e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org *  that can be found in the LICENSE file in the root of the source
6e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org *  tree. An additional intellectual property rights grant can be found
7e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org *  in the file PATENTS.  All contributing project authors may
8e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org */
10e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
11281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "testing/gmock/include/gmock/gmock.h"
12281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "testing/gtest/include/gtest/gtest.h"
13e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
14e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
15e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org#include "webrtc/system_wrappers/interface/scoped_ptr.h"
16e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org#include "webrtc/system_wrappers/interface/tick_util.h"
17e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org#include "webrtc/video_engine/call_stats.h"
18e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
19e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.orgusing ::testing::_;
20e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.orgusing ::testing::AnyNumber;
21e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.orgusing ::testing::Return;
22e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
23e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.orgnamespace webrtc {
24e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
250329e591cd17957836fd295ae9b31f7d3a73e5e8fischman@webrtc.orgclass MockStatsObserver : public CallStatsObserver {
26e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org public:
27e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  MockStatsObserver() {}
28e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  virtual ~MockStatsObserver() {}
29e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
30e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  MOCK_METHOD1(OnRttUpdate, void(uint32_t));
31e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org};
32e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
33e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.orgclass CallStatsTest : public ::testing::Test {
34e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org protected:
35e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  virtual void SetUp() {
36e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org    TickTime::UseFakeClock(12345);
37e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org    call_stats_.reset(new CallStats());
38e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  }
39e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  scoped_ptr<CallStats> call_stats_;
40e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org};
41e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
42e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.orgTEST_F(CallStatsTest, AddAndTriggerCallback) {
43e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  MockStatsObserver stats_observer;
44c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
45e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->RegisterStatsObserver(&stats_observer);
46e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  TickTime::AdvanceFakeClock(1000);
47c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  EXPECT_EQ(0U, rtcp_rtt_stats->LastProcessedRtt());
48e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
49c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  const uint32_t kRtt = 25;
50c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  rtcp_rtt_stats->OnRttUpdate(kRtt);
51c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  EXPECT_CALL(stats_observer, OnRttUpdate(kRtt))
52e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org      .Times(1);
53e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->Process();
54c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  EXPECT_EQ(kRtt, rtcp_rtt_stats->LastProcessedRtt());
55c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org
56c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  const int kRttTimeOutMs = 1500 + 10;
57c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  TickTime::AdvanceFakeClock(kRttTimeOutMs);
58c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  EXPECT_CALL(stats_observer, OnRttUpdate(_))
59c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org      .Times(0);
60c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  call_stats_->Process();
61c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  EXPECT_EQ(0U, rtcp_rtt_stats->LastProcessedRtt());
62e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
63e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->DeregisterStatsObserver(&stats_observer);
64e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org}
65e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
66e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.orgTEST_F(CallStatsTest, ProcessTime) {
67e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  MockStatsObserver stats_observer;
68e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->RegisterStatsObserver(&stats_observer);
69c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
70c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  rtcp_rtt_stats->OnRttUpdate(100);
71e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
72e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  // Time isn't updated yet.
73e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  EXPECT_CALL(stats_observer, OnRttUpdate(_))
74e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org      .Times(0);
75e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->Process();
76e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
77e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  // Advance clock and verify we get an update.
78e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  TickTime::AdvanceFakeClock(1000);
79e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  EXPECT_CALL(stats_observer, OnRttUpdate(_))
80e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org      .Times(1);
81e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->Process();
82e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
83e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  // Advance clock just too little to get an update.
84e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  TickTime::AdvanceFakeClock(999);
85c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  rtcp_rtt_stats->OnRttUpdate(100);
86e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  EXPECT_CALL(stats_observer, OnRttUpdate(_))
87e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org      .Times(0);
88e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->Process();
89e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
90e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  // Advance enough to trigger a new update.
91e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  TickTime::AdvanceFakeClock(1);
92e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  EXPECT_CALL(stats_observer, OnRttUpdate(_))
93e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org      .Times(1);
94e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->Process();
95e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
96e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->DeregisterStatsObserver(&stats_observer);
97e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org}
98e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
99e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org// Verify all observers get correct estimates and observers can be added and
100e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org// removed.
101e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.orgTEST_F(CallStatsTest, MultipleObservers) {
102e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  MockStatsObserver stats_observer_1;
103e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->RegisterStatsObserver(&stats_observer_1);
104e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  // Add the secondobserver twice, there should still be only one report to the
105e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  // observer.
106e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  MockStatsObserver stats_observer_2;
107e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->RegisterStatsObserver(&stats_observer_2);
108e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->RegisterStatsObserver(&stats_observer_2);
109e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
110c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
111e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  uint32_t rtt = 100;
112c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  rtcp_rtt_stats->OnRttUpdate(rtt);
113e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
114e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  // Verify both observers are updated.
115e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  TickTime::AdvanceFakeClock(1000);
116e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  EXPECT_CALL(stats_observer_1, OnRttUpdate(rtt))
117e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org      .Times(1);
118e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  EXPECT_CALL(stats_observer_2, OnRttUpdate(rtt))
119e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org      .Times(1);
120e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->Process();
121e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
122e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  // Deregister the second observer and verify update is only sent to the first
123e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  // observer.
124e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->DeregisterStatsObserver(&stats_observer_2);
125c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  rtcp_rtt_stats->OnRttUpdate(rtt);
126e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  TickTime::AdvanceFakeClock(1000);
127e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  EXPECT_CALL(stats_observer_1, OnRttUpdate(rtt))
128e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org      .Times(1);
129e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  EXPECT_CALL(stats_observer_2, OnRttUpdate(rtt))
130e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org      .Times(0);
131e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->Process();
132e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
133e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  // Deregister the first observer.
134e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->DeregisterStatsObserver(&stats_observer_1);
135c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  rtcp_rtt_stats->OnRttUpdate(rtt);
136e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  TickTime::AdvanceFakeClock(1000);
137e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  EXPECT_CALL(stats_observer_1, OnRttUpdate(rtt))
138e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org      .Times(0);
139e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  EXPECT_CALL(stats_observer_2, OnRttUpdate(rtt))
140e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org      .Times(0);
141e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->Process();
142e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org}
143e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
144e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org// Verify increasing and decreasing rtt triggers callbacks with correct values.
145e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.orgTEST_F(CallStatsTest, ChangeRtt) {
146e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  MockStatsObserver stats_observer;
147e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->RegisterStatsObserver(&stats_observer);
148c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
149e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
150e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  // Advance clock to be ready for an update.
151e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  TickTime::AdvanceFakeClock(1000);
152e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
153e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  // Set a first value and verify the callback is triggered.
154e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  const uint32_t first_rtt = 100;
155c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  rtcp_rtt_stats->OnRttUpdate(first_rtt);
156e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  EXPECT_CALL(stats_observer, OnRttUpdate(first_rtt))
157e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org      .Times(1);
158e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->Process();
159e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
160e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  // Increase rtt and verify the new value is reported.
161e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  TickTime::AdvanceFakeClock(1000);
162e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  const uint32_t high_rtt = first_rtt + 20;
163c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  rtcp_rtt_stats->OnRttUpdate(high_rtt);
164e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  EXPECT_CALL(stats_observer, OnRttUpdate(high_rtt))
165e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org      .Times(1);
166e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->Process();
167e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
168e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  // Increase time enough for a new update, but not too much to make the
169e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  // rtt invalid. Report a lower rtt and verify the old/high value still is sent
170e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  // in the callback.
171e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  TickTime::AdvanceFakeClock(1000);
172e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  const uint32_t low_rtt = first_rtt - 20;
173c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  rtcp_rtt_stats->OnRttUpdate(low_rtt);
174e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  EXPECT_CALL(stats_observer, OnRttUpdate(high_rtt))
175e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org      .Times(1);
176e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->Process();
177e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
178c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  // Advance time to make the high report invalid, the lower rtt should now be
179c4af4cf7814bb773d838aefa476c196e5f1bc360asapersson@webrtc.org  // in the callback.
180e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  TickTime::AdvanceFakeClock(1000);
181e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  EXPECT_CALL(stats_observer, OnRttUpdate(low_rtt))
182e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org      .Times(1);
183e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->Process();
184e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
185e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org  call_stats_->DeregisterStatsObserver(&stats_observer);
186e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org}
187e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org
188e296783ae1fd7fa8a52582c8bb63a570e625532amflodman@webrtc.org}  // namespace webrtc
189