blob: 2421cc7148a6d36f5972f0fe17eec19ce63037f9 [file] [log] [blame]
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +00001/*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
pbos@webrtc.orgf5d4cb12013-05-17 13:44:48 +000011#include "testing/gmock/include/gmock/gmock.h"
12#include "testing/gtest/include/gtest/gtest.h"
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000013
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +000014#include "webrtc/base/scoped_ptr.h"
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010015#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
sprange2d83d62016-02-19 09:03:26 -080016#include "webrtc/system_wrappers/include/metrics.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010017#include "webrtc/system_wrappers/include/tick_util.h"
sprange2d83d62016-02-19 09:03:26 -080018#include "webrtc/test/histogram.h"
Peter Boström7623ce42015-12-09 12:13:30 +010019#include "webrtc/video/call_stats.h"
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000020
21using ::testing::_;
22using ::testing::AnyNumber;
23using ::testing::Return;
24
25namespace webrtc {
26
fischman@webrtc.orgaea96d32013-02-19 22:09:36 +000027class MockStatsObserver : public CallStatsObserver {
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000028 public:
29 MockStatsObserver() {}
30 virtual ~MockStatsObserver() {}
31
stefan2328a942015-08-07 04:27:51 -070032 MOCK_METHOD2(OnRttUpdate, void(int64_t, int64_t));
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000033};
34
35class CallStatsTest : public ::testing::Test {
Peter Boströmd3c94472015-12-09 11:20:58 +010036 public:
37 CallStatsTest() : fake_clock_(12345) {}
38
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000039 protected:
Peter Boströmd3c94472015-12-09 11:20:58 +010040 virtual void SetUp() { call_stats_.reset(new CallStats(&fake_clock_)); }
41 SimulatedClock fake_clock_;
kwiberg@webrtc.org00b8f6b2015-02-26 14:34:55 +000042 rtc::scoped_ptr<CallStats> call_stats_;
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000043};
44
45TEST_F(CallStatsTest, AddAndTriggerCallback) {
46 MockStatsObserver stats_observer;
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +000047 RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000048 call_stats_->RegisterStatsObserver(&stats_observer);
Peter Boströmd3c94472015-12-09 11:20:58 +010049 fake_clock_.AdvanceTimeMilliseconds(1000);
sprange2d83d62016-02-19 09:03:26 -080050 EXPECT_EQ(-1, rtcp_rtt_stats->LastProcessedRtt());
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000051
pkasting@chromium.org16825b12015-01-12 21:51:21 +000052 const int64_t kRtt = 25;
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +000053 rtcp_rtt_stats->OnRttUpdate(kRtt);
stefan2328a942015-08-07 04:27:51 -070054 EXPECT_CALL(stats_observer, OnRttUpdate(kRtt, kRtt)).Times(1);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000055 call_stats_->Process();
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +000056 EXPECT_EQ(kRtt, rtcp_rtt_stats->LastProcessedRtt());
57
pkasting@chromium.org16825b12015-01-12 21:51:21 +000058 const int64_t kRttTimeOutMs = 1500 + 10;
Peter Boströmd3c94472015-12-09 11:20:58 +010059 fake_clock_.AdvanceTimeMilliseconds(kRttTimeOutMs);
stefan2328a942015-08-07 04:27:51 -070060 EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(0);
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +000061 call_stats_->Process();
sprange2d83d62016-02-19 09:03:26 -080062 EXPECT_EQ(-1, rtcp_rtt_stats->LastProcessedRtt());
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000063
64 call_stats_->DeregisterStatsObserver(&stats_observer);
65}
66
67TEST_F(CallStatsTest, ProcessTime) {
68 MockStatsObserver stats_observer;
69 call_stats_->RegisterStatsObserver(&stats_observer);
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +000070 RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
71 rtcp_rtt_stats->OnRttUpdate(100);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000072
73 // Time isn't updated yet.
stefan2328a942015-08-07 04:27:51 -070074 EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(0);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000075 call_stats_->Process();
76
77 // Advance clock and verify we get an update.
Peter Boströmd3c94472015-12-09 11:20:58 +010078 fake_clock_.AdvanceTimeMilliseconds(1000);
stefan2328a942015-08-07 04:27:51 -070079 EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(1);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000080 call_stats_->Process();
81
82 // Advance clock just too little to get an update.
Peter Boströmd3c94472015-12-09 11:20:58 +010083 fake_clock_.AdvanceTimeMilliseconds(999);
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +000084 rtcp_rtt_stats->OnRttUpdate(100);
stefan2328a942015-08-07 04:27:51 -070085 EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(0);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000086 call_stats_->Process();
87
88 // Advance enough to trigger a new update.
Peter Boströmd3c94472015-12-09 11:20:58 +010089 fake_clock_.AdvanceTimeMilliseconds(1);
stefan2328a942015-08-07 04:27:51 -070090 EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(1);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000091 call_stats_->Process();
92
93 call_stats_->DeregisterStatsObserver(&stats_observer);
94}
95
96// Verify all observers get correct estimates and observers can be added and
97// removed.
98TEST_F(CallStatsTest, MultipleObservers) {
99 MockStatsObserver stats_observer_1;
100 call_stats_->RegisterStatsObserver(&stats_observer_1);
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000101 // Add the second observer twice, there should still be only one report to the
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000102 // observer.
103 MockStatsObserver stats_observer_2;
104 call_stats_->RegisterStatsObserver(&stats_observer_2);
105 call_stats_->RegisterStatsObserver(&stats_observer_2);
106
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +0000107 RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000108 const int64_t kRtt = 100;
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000109 rtcp_rtt_stats->OnRttUpdate(kRtt);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000110
111 // Verify both observers are updated.
Peter Boströmd3c94472015-12-09 11:20:58 +0100112 fake_clock_.AdvanceTimeMilliseconds(1000);
stefan2328a942015-08-07 04:27:51 -0700113 EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt)).Times(1);
114 EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt)).Times(1);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000115 call_stats_->Process();
116
117 // Deregister the second observer and verify update is only sent to the first
118 // observer.
119 call_stats_->DeregisterStatsObserver(&stats_observer_2);
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000120 rtcp_rtt_stats->OnRttUpdate(kRtt);
Peter Boströmd3c94472015-12-09 11:20:58 +0100121 fake_clock_.AdvanceTimeMilliseconds(1000);
stefan2328a942015-08-07 04:27:51 -0700122 EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt)).Times(1);
123 EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt)).Times(0);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000124 call_stats_->Process();
125
126 // Deregister the first observer.
127 call_stats_->DeregisterStatsObserver(&stats_observer_1);
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000128 rtcp_rtt_stats->OnRttUpdate(kRtt);
Peter Boströmd3c94472015-12-09 11:20:58 +0100129 fake_clock_.AdvanceTimeMilliseconds(1000);
stefan2328a942015-08-07 04:27:51 -0700130 EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt)).Times(0);
131 EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt)).Times(0);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000132 call_stats_->Process();
133}
134
135// Verify increasing and decreasing rtt triggers callbacks with correct values.
136TEST_F(CallStatsTest, ChangeRtt) {
137 MockStatsObserver stats_observer;
138 call_stats_->RegisterStatsObserver(&stats_observer);
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +0000139 RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000140
141 // Advance clock to be ready for an update.
Peter Boströmd3c94472015-12-09 11:20:58 +0100142 fake_clock_.AdvanceTimeMilliseconds(1000);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000143
144 // Set a first value and verify the callback is triggered.
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000145 const int64_t kFirstRtt = 100;
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000146 rtcp_rtt_stats->OnRttUpdate(kFirstRtt);
stefan2328a942015-08-07 04:27:51 -0700147 EXPECT_CALL(stats_observer, OnRttUpdate(kFirstRtt, kFirstRtt)).Times(1);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000148 call_stats_->Process();
149
150 // Increase rtt and verify the new value is reported.
Peter Boströmd3c94472015-12-09 11:20:58 +0100151 fake_clock_.AdvanceTimeMilliseconds(1000);
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000152 const int64_t kHighRtt = kFirstRtt + 20;
stefan2328a942015-08-07 04:27:51 -0700153 const int64_t kAvgRtt1 = 103;
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000154 rtcp_rtt_stats->OnRttUpdate(kHighRtt);
stefan2328a942015-08-07 04:27:51 -0700155 EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt1, kHighRtt)).Times(1);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000156 call_stats_->Process();
157
158 // Increase time enough for a new update, but not too much to make the
159 // rtt invalid. Report a lower rtt and verify the old/high value still is sent
160 // in the callback.
Peter Boströmd3c94472015-12-09 11:20:58 +0100161 fake_clock_.AdvanceTimeMilliseconds(1000);
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000162 const int64_t kLowRtt = kFirstRtt - 20;
stefan2328a942015-08-07 04:27:51 -0700163 const int64_t kAvgRtt2 = 102;
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000164 rtcp_rtt_stats->OnRttUpdate(kLowRtt);
stefan2328a942015-08-07 04:27:51 -0700165 EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt2, kHighRtt)).Times(1);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000166 call_stats_->Process();
167
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +0000168 // Advance time to make the high report invalid, the lower rtt should now be
169 // in the callback.
Peter Boströmd3c94472015-12-09 11:20:58 +0100170 fake_clock_.AdvanceTimeMilliseconds(1000);
stefan2328a942015-08-07 04:27:51 -0700171 const int64_t kAvgRtt3 = 95;
172 EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt3, kLowRtt)).Times(1);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000173 call_stats_->Process();
174
175 call_stats_->DeregisterStatsObserver(&stats_observer);
176}
177
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000178TEST_F(CallStatsTest, LastProcessedRtt) {
179 MockStatsObserver stats_observer;
180 call_stats_->RegisterStatsObserver(&stats_observer);
181 RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
Peter Boströmd3c94472015-12-09 11:20:58 +0100182 fake_clock_.AdvanceTimeMilliseconds(1000);
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000183
184 // Set a first values and verify that LastProcessedRtt initially returns the
185 // average rtt.
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000186 const int64_t kRttLow = 10;
187 const int64_t kRttHigh = 30;
188 const int64_t kAvgRtt = 20;
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000189 rtcp_rtt_stats->OnRttUpdate(kRttLow);
190 rtcp_rtt_stats->OnRttUpdate(kRttHigh);
stefan2328a942015-08-07 04:27:51 -0700191 EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt, kRttHigh)).Times(1);
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000192 call_stats_->Process();
193 EXPECT_EQ(kAvgRtt, rtcp_rtt_stats->LastProcessedRtt());
194
195 // Update values and verify LastProcessedRtt.
Peter Boströmd3c94472015-12-09 11:20:58 +0100196 fake_clock_.AdvanceTimeMilliseconds(1000);
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000197 rtcp_rtt_stats->OnRttUpdate(kRttLow);
198 rtcp_rtt_stats->OnRttUpdate(kRttHigh);
stefan2328a942015-08-07 04:27:51 -0700199 EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt, kRttHigh)).Times(1);
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000200 call_stats_->Process();
201 EXPECT_EQ(kAvgRtt, rtcp_rtt_stats->LastProcessedRtt());
202
203 call_stats_->DeregisterStatsObserver(&stats_observer);
204}
205
sprange2d83d62016-02-19 09:03:26 -0800206TEST_F(CallStatsTest, ProducesHistogramMetrics) {
207 const int64_t kRtt = 123;
208 RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
209 rtcp_rtt_stats->OnRttUpdate(kRtt);
210 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
211 rtcp_rtt_stats->OnRttUpdate(kRtt);
212 call_stats_->Process();
213 call_stats_.reset();
214
215 EXPECT_EQ(1, test::NumHistogramSamples(
216 "WebRTC.Video.AverageRoundTripTimeInMilliseconds"));
217 EXPECT_EQ(kRtt, test::LastHistogramSample(
218 "WebRTC.Video.AverageRoundTripTimeInMilliseconds"));
219}
220
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000221} // namespace webrtc