blob: 6e2e1bca786108d2899353060e11d2b0cb6a45dd [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
kwiberg27f982b2016-03-01 11:52:33 -080011#include <memory>
12
pbos@webrtc.orgf5d4cb12013-05-17 13:44:48 +000013#include "testing/gmock/include/gmock/gmock.h"
14#include "testing/gtest/include/gtest/gtest.h"
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000015
Henrik Kjellanderff761fb2015-11-04 08:31:52 +010016#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
sprange2d83d62016-02-19 09:03:26 -080017#include "webrtc/system_wrappers/include/metrics.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010018#include "webrtc/system_wrappers/include/tick_util.h"
sprange2d83d62016-02-19 09:03:26 -080019#include "webrtc/test/histogram.h"
Peter Boström7623ce42015-12-09 12:13:30 +010020#include "webrtc/video/call_stats.h"
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000021
22using ::testing::_;
23using ::testing::AnyNumber;
24using ::testing::Return;
25
26namespace webrtc {
27
fischman@webrtc.orgaea96d32013-02-19 22:09:36 +000028class MockStatsObserver : public CallStatsObserver {
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000029 public:
30 MockStatsObserver() {}
31 virtual ~MockStatsObserver() {}
32
stefan2328a942015-08-07 04:27:51 -070033 MOCK_METHOD2(OnRttUpdate, void(int64_t, int64_t));
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000034};
35
36class CallStatsTest : public ::testing::Test {
Peter Boströmd3c94472015-12-09 11:20:58 +010037 public:
38 CallStatsTest() : fake_clock_(12345) {}
39
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000040 protected:
Peter Boströmd3c94472015-12-09 11:20:58 +010041 virtual void SetUp() { call_stats_.reset(new CallStats(&fake_clock_)); }
42 SimulatedClock fake_clock_;
kwiberg27f982b2016-03-01 11:52:33 -080043 std::unique_ptr<CallStats> call_stats_;
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000044};
45
46TEST_F(CallStatsTest, AddAndTriggerCallback) {
47 MockStatsObserver stats_observer;
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +000048 RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000049 call_stats_->RegisterStatsObserver(&stats_observer);
Peter Boströmd3c94472015-12-09 11:20:58 +010050 fake_clock_.AdvanceTimeMilliseconds(1000);
sprange2d83d62016-02-19 09:03:26 -080051 EXPECT_EQ(-1, rtcp_rtt_stats->LastProcessedRtt());
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000052
pkasting@chromium.org16825b12015-01-12 21:51:21 +000053 const int64_t kRtt = 25;
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +000054 rtcp_rtt_stats->OnRttUpdate(kRtt);
stefan2328a942015-08-07 04:27:51 -070055 EXPECT_CALL(stats_observer, OnRttUpdate(kRtt, kRtt)).Times(1);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000056 call_stats_->Process();
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +000057 EXPECT_EQ(kRtt, rtcp_rtt_stats->LastProcessedRtt());
58
pkasting@chromium.org16825b12015-01-12 21:51:21 +000059 const int64_t kRttTimeOutMs = 1500 + 10;
Peter Boströmd3c94472015-12-09 11:20:58 +010060 fake_clock_.AdvanceTimeMilliseconds(kRttTimeOutMs);
stefan2328a942015-08-07 04:27:51 -070061 EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(0);
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +000062 call_stats_->Process();
sprange2d83d62016-02-19 09:03:26 -080063 EXPECT_EQ(-1, rtcp_rtt_stats->LastProcessedRtt());
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000064
65 call_stats_->DeregisterStatsObserver(&stats_observer);
66}
67
68TEST_F(CallStatsTest, ProcessTime) {
69 MockStatsObserver stats_observer;
70 call_stats_->RegisterStatsObserver(&stats_observer);
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +000071 RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
72 rtcp_rtt_stats->OnRttUpdate(100);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000073
74 // Time isn't updated yet.
stefan2328a942015-08-07 04:27:51 -070075 EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(0);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000076 call_stats_->Process();
77
78 // Advance clock and verify we get an update.
Peter Boströmd3c94472015-12-09 11:20:58 +010079 fake_clock_.AdvanceTimeMilliseconds(1000);
stefan2328a942015-08-07 04:27:51 -070080 EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(1);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000081 call_stats_->Process();
82
83 // Advance clock just too little to get an update.
Peter Boströmd3c94472015-12-09 11:20:58 +010084 fake_clock_.AdvanceTimeMilliseconds(999);
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +000085 rtcp_rtt_stats->OnRttUpdate(100);
stefan2328a942015-08-07 04:27:51 -070086 EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(0);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000087 call_stats_->Process();
88
89 // Advance enough to trigger a new update.
Peter Boströmd3c94472015-12-09 11:20:58 +010090 fake_clock_.AdvanceTimeMilliseconds(1);
stefan2328a942015-08-07 04:27:51 -070091 EXPECT_CALL(stats_observer, OnRttUpdate(_, _)).Times(1);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +000092 call_stats_->Process();
93
94 call_stats_->DeregisterStatsObserver(&stats_observer);
95}
96
97// Verify all observers get correct estimates and observers can be added and
98// removed.
99TEST_F(CallStatsTest, MultipleObservers) {
100 MockStatsObserver stats_observer_1;
101 call_stats_->RegisterStatsObserver(&stats_observer_1);
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000102 // Add the second observer twice, there should still be only one report to the
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000103 // observer.
104 MockStatsObserver stats_observer_2;
105 call_stats_->RegisterStatsObserver(&stats_observer_2);
106 call_stats_->RegisterStatsObserver(&stats_observer_2);
107
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +0000108 RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000109 const int64_t kRtt = 100;
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000110 rtcp_rtt_stats->OnRttUpdate(kRtt);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000111
112 // Verify both observers are updated.
Peter Boströmd3c94472015-12-09 11:20:58 +0100113 fake_clock_.AdvanceTimeMilliseconds(1000);
stefan2328a942015-08-07 04:27:51 -0700114 EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt)).Times(1);
115 EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt)).Times(1);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000116 call_stats_->Process();
117
118 // Deregister the second observer and verify update is only sent to the first
119 // observer.
120 call_stats_->DeregisterStatsObserver(&stats_observer_2);
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000121 rtcp_rtt_stats->OnRttUpdate(kRtt);
Peter Boströmd3c94472015-12-09 11:20:58 +0100122 fake_clock_.AdvanceTimeMilliseconds(1000);
stefan2328a942015-08-07 04:27:51 -0700123 EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt)).Times(1);
124 EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt)).Times(0);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000125 call_stats_->Process();
126
127 // Deregister the first observer.
128 call_stats_->DeregisterStatsObserver(&stats_observer_1);
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000129 rtcp_rtt_stats->OnRttUpdate(kRtt);
Peter Boströmd3c94472015-12-09 11:20:58 +0100130 fake_clock_.AdvanceTimeMilliseconds(1000);
stefan2328a942015-08-07 04:27:51 -0700131 EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt)).Times(0);
132 EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt)).Times(0);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000133 call_stats_->Process();
134}
135
136// Verify increasing and decreasing rtt triggers callbacks with correct values.
137TEST_F(CallStatsTest, ChangeRtt) {
138 MockStatsObserver stats_observer;
139 call_stats_->RegisterStatsObserver(&stats_observer);
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +0000140 RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000141
142 // Advance clock to be ready for an update.
Peter Boströmd3c94472015-12-09 11:20:58 +0100143 fake_clock_.AdvanceTimeMilliseconds(1000);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000144
145 // Set a first value and verify the callback is triggered.
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000146 const int64_t kFirstRtt = 100;
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000147 rtcp_rtt_stats->OnRttUpdate(kFirstRtt);
stefan2328a942015-08-07 04:27:51 -0700148 EXPECT_CALL(stats_observer, OnRttUpdate(kFirstRtt, kFirstRtt)).Times(1);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000149 call_stats_->Process();
150
151 // Increase rtt and verify the new value is reported.
Peter Boströmd3c94472015-12-09 11:20:58 +0100152 fake_clock_.AdvanceTimeMilliseconds(1000);
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000153 const int64_t kHighRtt = kFirstRtt + 20;
stefan2328a942015-08-07 04:27:51 -0700154 const int64_t kAvgRtt1 = 103;
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000155 rtcp_rtt_stats->OnRttUpdate(kHighRtt);
stefan2328a942015-08-07 04:27:51 -0700156 EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt1, kHighRtt)).Times(1);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000157 call_stats_->Process();
158
159 // Increase time enough for a new update, but not too much to make the
160 // rtt invalid. Report a lower rtt and verify the old/high value still is sent
161 // in the callback.
Peter Boströmd3c94472015-12-09 11:20:58 +0100162 fake_clock_.AdvanceTimeMilliseconds(1000);
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000163 const int64_t kLowRtt = kFirstRtt - 20;
stefan2328a942015-08-07 04:27:51 -0700164 const int64_t kAvgRtt2 = 102;
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000165 rtcp_rtt_stats->OnRttUpdate(kLowRtt);
stefan2328a942015-08-07 04:27:51 -0700166 EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt2, kHighRtt)).Times(1);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000167 call_stats_->Process();
168
asapersson@webrtc.org1ae1d0c2013-11-20 12:46:11 +0000169 // Advance time to make the high report invalid, the lower rtt should now be
170 // in the callback.
Peter Boströmd3c94472015-12-09 11:20:58 +0100171 fake_clock_.AdvanceTimeMilliseconds(1000);
stefan2328a942015-08-07 04:27:51 -0700172 const int64_t kAvgRtt3 = 95;
173 EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt3, kLowRtt)).Times(1);
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000174 call_stats_->Process();
175
176 call_stats_->DeregisterStatsObserver(&stats_observer);
177}
178
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000179TEST_F(CallStatsTest, LastProcessedRtt) {
180 MockStatsObserver stats_observer;
181 call_stats_->RegisterStatsObserver(&stats_observer);
182 RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
Peter Boströmd3c94472015-12-09 11:20:58 +0100183 fake_clock_.AdvanceTimeMilliseconds(1000);
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000184
185 // Set a first values and verify that LastProcessedRtt initially returns the
186 // average rtt.
pkasting@chromium.org16825b12015-01-12 21:51:21 +0000187 const int64_t kRttLow = 10;
188 const int64_t kRttHigh = 30;
189 const int64_t kAvgRtt = 20;
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000190 rtcp_rtt_stats->OnRttUpdate(kRttLow);
191 rtcp_rtt_stats->OnRttUpdate(kRttHigh);
stefan2328a942015-08-07 04:27:51 -0700192 EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt, kRttHigh)).Times(1);
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000193 call_stats_->Process();
194 EXPECT_EQ(kAvgRtt, rtcp_rtt_stats->LastProcessedRtt());
195
196 // Update values and verify LastProcessedRtt.
Peter Boströmd3c94472015-12-09 11:20:58 +0100197 fake_clock_.AdvanceTimeMilliseconds(1000);
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000198 rtcp_rtt_stats->OnRttUpdate(kRttLow);
199 rtcp_rtt_stats->OnRttUpdate(kRttHigh);
stefan2328a942015-08-07 04:27:51 -0700200 EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt, kRttHigh)).Times(1);
asapersson@webrtc.org8084f952014-12-10 11:04:13 +0000201 call_stats_->Process();
202 EXPECT_EQ(kAvgRtt, rtcp_rtt_stats->LastProcessedRtt());
203
204 call_stats_->DeregisterStatsObserver(&stats_observer);
205}
206
sprange2d83d62016-02-19 09:03:26 -0800207TEST_F(CallStatsTest, ProducesHistogramMetrics) {
208 const int64_t kRtt = 123;
209 RtcpRttStats* rtcp_rtt_stats = call_stats_->rtcp_rtt_stats();
210 rtcp_rtt_stats->OnRttUpdate(kRtt);
211 fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds * 1000);
212 rtcp_rtt_stats->OnRttUpdate(kRtt);
213 call_stats_->Process();
214 call_stats_.reset();
215
216 EXPECT_EQ(1, test::NumHistogramSamples(
217 "WebRTC.Video.AverageRoundTripTimeInMilliseconds"));
218 EXPECT_EQ(kRtt, test::LastHistogramSample(
219 "WebRTC.Video.AverageRoundTripTimeInMilliseconds"));
220}
221
mflodman@webrtc.orgb2f474e2012-11-16 13:57:26 +0000222} // namespace webrtc