1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #include "video/call_stats2.h"
12*d9f75844SAndroid Build Coastguard Worker
13*d9f75844SAndroid Build Coastguard Worker #include <memory>
14*d9f75844SAndroid Build Coastguard Worker
15*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/default_task_queue_factory.h"
16*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/task_queue_base.h"
17*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
18*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h"
19*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/metrics.h"
20*d9f75844SAndroid Build Coastguard Worker #include "test/gmock.h"
21*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
22*d9f75844SAndroid Build Coastguard Worker #include "test/run_loop.h"
23*d9f75844SAndroid Build Coastguard Worker
24*d9f75844SAndroid Build Coastguard Worker using ::testing::AnyNumber;
25*d9f75844SAndroid Build Coastguard Worker using ::testing::InvokeWithoutArgs;
26*d9f75844SAndroid Build Coastguard Worker using ::testing::Return;
27*d9f75844SAndroid Build Coastguard Worker
28*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
29*d9f75844SAndroid Build Coastguard Worker namespace internal {
30*d9f75844SAndroid Build Coastguard Worker
31*d9f75844SAndroid Build Coastguard Worker class MockStatsObserver : public CallStatsObserver {
32*d9f75844SAndroid Build Coastguard Worker public:
MockStatsObserver()33*d9f75844SAndroid Build Coastguard Worker MockStatsObserver() {}
~MockStatsObserver()34*d9f75844SAndroid Build Coastguard Worker virtual ~MockStatsObserver() {}
35*d9f75844SAndroid Build Coastguard Worker
36*d9f75844SAndroid Build Coastguard Worker MOCK_METHOD(void, OnRttUpdate, (int64_t, int64_t), (override));
37*d9f75844SAndroid Build Coastguard Worker };
38*d9f75844SAndroid Build Coastguard Worker
39*d9f75844SAndroid Build Coastguard Worker class CallStats2Test : public ::testing::Test {
40*d9f75844SAndroid Build Coastguard Worker public:
CallStats2Test()41*d9f75844SAndroid Build Coastguard Worker CallStats2Test() { call_stats_.EnsureStarted(); }
42*d9f75844SAndroid Build Coastguard Worker
43*d9f75844SAndroid Build Coastguard Worker // Queues an rtt update call on the process thread.
AsyncSimulateRttUpdate(int64_t rtt)44*d9f75844SAndroid Build Coastguard Worker void AsyncSimulateRttUpdate(int64_t rtt) {
45*d9f75844SAndroid Build Coastguard Worker RtcpRttStats* rtcp_rtt_stats = call_stats_.AsRtcpRttStats();
46*d9f75844SAndroid Build Coastguard Worker task_queue_->PostTask(
47*d9f75844SAndroid Build Coastguard Worker [rtcp_rtt_stats, rtt] { rtcp_rtt_stats->OnRttUpdate(rtt); });
48*d9f75844SAndroid Build Coastguard Worker }
49*d9f75844SAndroid Build Coastguard Worker
50*d9f75844SAndroid Build Coastguard Worker protected:
FlushProcessAndWorker()51*d9f75844SAndroid Build Coastguard Worker void FlushProcessAndWorker() {
52*d9f75844SAndroid Build Coastguard Worker task_queue_->PostTask([this] { loop_.PostTask([this] { loop_.Quit(); }); });
53*d9f75844SAndroid Build Coastguard Worker loop_.Run();
54*d9f75844SAndroid Build Coastguard Worker }
55*d9f75844SAndroid Build Coastguard Worker
56*d9f75844SAndroid Build Coastguard Worker test::RunLoop loop_;
57*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<TaskQueueBase, TaskQueueDeleter> task_queue_ =
58*d9f75844SAndroid Build Coastguard Worker CreateDefaultTaskQueueFactory()->CreateTaskQueue(
59*d9f75844SAndroid Build Coastguard Worker "CallStats",
60*d9f75844SAndroid Build Coastguard Worker TaskQueueFactory::Priority::NORMAL);
61*d9f75844SAndroid Build Coastguard Worker
62*d9f75844SAndroid Build Coastguard Worker // Note: Since rtc::Thread doesn't support injecting a Clock, we're going
63*d9f75844SAndroid Build Coastguard Worker // to be using a mix of the fake clock (used by CallStats) as well as the
64*d9f75844SAndroid Build Coastguard Worker // system clock (used by rtc::Thread). This isn't ideal and will result in
65*d9f75844SAndroid Build Coastguard Worker // the tests taking longer to execute in some cases than they need to.
66*d9f75844SAndroid Build Coastguard Worker SimulatedClock fake_clock_{12345};
67*d9f75844SAndroid Build Coastguard Worker CallStats call_stats_{&fake_clock_, loop_.task_queue()};
68*d9f75844SAndroid Build Coastguard Worker };
69*d9f75844SAndroid Build Coastguard Worker
TEST_F(CallStats2Test,AddAndTriggerCallback)70*d9f75844SAndroid Build Coastguard Worker TEST_F(CallStats2Test, AddAndTriggerCallback) {
71*d9f75844SAndroid Build Coastguard Worker static constexpr const int64_t kRtt = 25;
72*d9f75844SAndroid Build Coastguard Worker
73*d9f75844SAndroid Build Coastguard Worker MockStatsObserver stats_observer;
74*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stats_observer, OnRttUpdate(kRtt, kRtt))
75*d9f75844SAndroid Build Coastguard Worker .Times(1)
76*d9f75844SAndroid Build Coastguard Worker .WillOnce(InvokeWithoutArgs([this] { loop_.Quit(); }));
77*d9f75844SAndroid Build Coastguard Worker
78*d9f75844SAndroid Build Coastguard Worker call_stats_.RegisterStatsObserver(&stats_observer);
79*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(-1, call_stats_.LastProcessedRtt());
80*d9f75844SAndroid Build Coastguard Worker
81*d9f75844SAndroid Build Coastguard Worker AsyncSimulateRttUpdate(kRtt);
82*d9f75844SAndroid Build Coastguard Worker loop_.Run();
83*d9f75844SAndroid Build Coastguard Worker
84*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kRtt, call_stats_.LastProcessedRtt());
85*d9f75844SAndroid Build Coastguard Worker
86*d9f75844SAndroid Build Coastguard Worker call_stats_.DeregisterStatsObserver(&stats_observer);
87*d9f75844SAndroid Build Coastguard Worker }
88*d9f75844SAndroid Build Coastguard Worker
TEST_F(CallStats2Test,ProcessTime)89*d9f75844SAndroid Build Coastguard Worker TEST_F(CallStats2Test, ProcessTime) {
90*d9f75844SAndroid Build Coastguard Worker static constexpr const int64_t kRtt = 100;
91*d9f75844SAndroid Build Coastguard Worker static constexpr const int64_t kRtt2 = 80;
92*d9f75844SAndroid Build Coastguard Worker
93*d9f75844SAndroid Build Coastguard Worker MockStatsObserver stats_observer;
94*d9f75844SAndroid Build Coastguard Worker
95*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stats_observer, OnRttUpdate(kRtt, kRtt))
96*d9f75844SAndroid Build Coastguard Worker .Times(2)
97*d9f75844SAndroid Build Coastguard Worker .WillOnce(InvokeWithoutArgs([this] {
98*d9f75844SAndroid Build Coastguard Worker // Advance clock and verify we get an update.
99*d9f75844SAndroid Build Coastguard Worker fake_clock_.AdvanceTimeMilliseconds(CallStats::kUpdateInterval.ms());
100*d9f75844SAndroid Build Coastguard Worker }))
101*d9f75844SAndroid Build Coastguard Worker .WillRepeatedly(InvokeWithoutArgs([this] {
102*d9f75844SAndroid Build Coastguard Worker AsyncSimulateRttUpdate(kRtt2);
103*d9f75844SAndroid Build Coastguard Worker // Advance clock just too little to get an update.
104*d9f75844SAndroid Build Coastguard Worker fake_clock_.AdvanceTimeMilliseconds(CallStats::kUpdateInterval.ms() -
105*d9f75844SAndroid Build Coastguard Worker 1);
106*d9f75844SAndroid Build Coastguard Worker }));
107*d9f75844SAndroid Build Coastguard Worker
108*d9f75844SAndroid Build Coastguard Worker // In case you're reading this and wondering how this number is arrived at,
109*d9f75844SAndroid Build Coastguard Worker // please see comments in the ChangeRtt test that go into some detail.
110*d9f75844SAndroid Build Coastguard Worker static constexpr const int64_t kLastAvg = 94;
111*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stats_observer, OnRttUpdate(kLastAvg, kRtt2))
112*d9f75844SAndroid Build Coastguard Worker .Times(1)
113*d9f75844SAndroid Build Coastguard Worker .WillOnce(InvokeWithoutArgs([this] { loop_.Quit(); }));
114*d9f75844SAndroid Build Coastguard Worker
115*d9f75844SAndroid Build Coastguard Worker call_stats_.RegisterStatsObserver(&stats_observer);
116*d9f75844SAndroid Build Coastguard Worker
117*d9f75844SAndroid Build Coastguard Worker AsyncSimulateRttUpdate(kRtt);
118*d9f75844SAndroid Build Coastguard Worker loop_.Run();
119*d9f75844SAndroid Build Coastguard Worker
120*d9f75844SAndroid Build Coastguard Worker call_stats_.DeregisterStatsObserver(&stats_observer);
121*d9f75844SAndroid Build Coastguard Worker }
122*d9f75844SAndroid Build Coastguard Worker
123*d9f75844SAndroid Build Coastguard Worker // Verify all observers get correct estimates and observers can be added and
124*d9f75844SAndroid Build Coastguard Worker // removed.
TEST_F(CallStats2Test,MultipleObservers)125*d9f75844SAndroid Build Coastguard Worker TEST_F(CallStats2Test, MultipleObservers) {
126*d9f75844SAndroid Build Coastguard Worker MockStatsObserver stats_observer_1;
127*d9f75844SAndroid Build Coastguard Worker call_stats_.RegisterStatsObserver(&stats_observer_1);
128*d9f75844SAndroid Build Coastguard Worker // Add the second observer twice, there should still be only one report to the
129*d9f75844SAndroid Build Coastguard Worker // observer.
130*d9f75844SAndroid Build Coastguard Worker MockStatsObserver stats_observer_2;
131*d9f75844SAndroid Build Coastguard Worker call_stats_.RegisterStatsObserver(&stats_observer_2);
132*d9f75844SAndroid Build Coastguard Worker call_stats_.RegisterStatsObserver(&stats_observer_2);
133*d9f75844SAndroid Build Coastguard Worker
134*d9f75844SAndroid Build Coastguard Worker static constexpr const int64_t kRtt = 100;
135*d9f75844SAndroid Build Coastguard Worker
136*d9f75844SAndroid Build Coastguard Worker // Verify both observers are updated.
137*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt))
138*d9f75844SAndroid Build Coastguard Worker .Times(AnyNumber())
139*d9f75844SAndroid Build Coastguard Worker .WillRepeatedly(Return());
140*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt))
141*d9f75844SAndroid Build Coastguard Worker .Times(AnyNumber())
142*d9f75844SAndroid Build Coastguard Worker .WillOnce(InvokeWithoutArgs([this] { loop_.Quit(); }))
143*d9f75844SAndroid Build Coastguard Worker .WillRepeatedly(Return());
144*d9f75844SAndroid Build Coastguard Worker AsyncSimulateRttUpdate(kRtt);
145*d9f75844SAndroid Build Coastguard Worker loop_.Run();
146*d9f75844SAndroid Build Coastguard Worker
147*d9f75844SAndroid Build Coastguard Worker // Deregister the second observer and verify update is only sent to the first
148*d9f75844SAndroid Build Coastguard Worker // observer.
149*d9f75844SAndroid Build Coastguard Worker call_stats_.DeregisterStatsObserver(&stats_observer_2);
150*d9f75844SAndroid Build Coastguard Worker
151*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt))
152*d9f75844SAndroid Build Coastguard Worker .Times(AnyNumber())
153*d9f75844SAndroid Build Coastguard Worker .WillOnce(InvokeWithoutArgs([this] { loop_.Quit(); }))
154*d9f75844SAndroid Build Coastguard Worker .WillRepeatedly(Return());
155*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt)).Times(0);
156*d9f75844SAndroid Build Coastguard Worker AsyncSimulateRttUpdate(kRtt);
157*d9f75844SAndroid Build Coastguard Worker loop_.Run();
158*d9f75844SAndroid Build Coastguard Worker
159*d9f75844SAndroid Build Coastguard Worker // Deregister the first observer.
160*d9f75844SAndroid Build Coastguard Worker call_stats_.DeregisterStatsObserver(&stats_observer_1);
161*d9f75844SAndroid Build Coastguard Worker
162*d9f75844SAndroid Build Coastguard Worker // Now make sure we don't get any callbacks.
163*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stats_observer_1, OnRttUpdate(kRtt, kRtt)).Times(0);
164*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stats_observer_2, OnRttUpdate(kRtt, kRtt)).Times(0);
165*d9f75844SAndroid Build Coastguard Worker AsyncSimulateRttUpdate(kRtt);
166*d9f75844SAndroid Build Coastguard Worker
167*d9f75844SAndroid Build Coastguard Worker // Flush the queue on the process thread to make sure we return after
168*d9f75844SAndroid Build Coastguard Worker // Process() has been called.
169*d9f75844SAndroid Build Coastguard Worker FlushProcessAndWorker();
170*d9f75844SAndroid Build Coastguard Worker }
171*d9f75844SAndroid Build Coastguard Worker
172*d9f75844SAndroid Build Coastguard Worker // Verify increasing and decreasing rtt triggers callbacks with correct values.
TEST_F(CallStats2Test,ChangeRtt)173*d9f75844SAndroid Build Coastguard Worker TEST_F(CallStats2Test, ChangeRtt) {
174*d9f75844SAndroid Build Coastguard Worker // NOTE: This test assumes things about how old reports are removed
175*d9f75844SAndroid Build Coastguard Worker // inside of call_stats.cc. The threshold ms value is 1500ms, but it's not
176*d9f75844SAndroid Build Coastguard Worker // clear here that how the clock is advanced, affects that algorithm and
177*d9f75844SAndroid Build Coastguard Worker // subsequently the average reported rtt.
178*d9f75844SAndroid Build Coastguard Worker
179*d9f75844SAndroid Build Coastguard Worker MockStatsObserver stats_observer;
180*d9f75844SAndroid Build Coastguard Worker call_stats_.RegisterStatsObserver(&stats_observer);
181*d9f75844SAndroid Build Coastguard Worker
182*d9f75844SAndroid Build Coastguard Worker static constexpr const int64_t kFirstRtt = 100;
183*d9f75844SAndroid Build Coastguard Worker static constexpr const int64_t kLowRtt = kFirstRtt - 20;
184*d9f75844SAndroid Build Coastguard Worker static constexpr const int64_t kHighRtt = kFirstRtt + 20;
185*d9f75844SAndroid Build Coastguard Worker
186*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stats_observer, OnRttUpdate(kFirstRtt, kFirstRtt))
187*d9f75844SAndroid Build Coastguard Worker .Times(1)
188*d9f75844SAndroid Build Coastguard Worker .WillOnce(InvokeWithoutArgs([this] {
189*d9f75844SAndroid Build Coastguard Worker fake_clock_.AdvanceTimeMilliseconds(1000);
190*d9f75844SAndroid Build Coastguard Worker AsyncSimulateRttUpdate(kHighRtt); // Reported at T1 (1000ms).
191*d9f75844SAndroid Build Coastguard Worker }));
192*d9f75844SAndroid Build Coastguard Worker
193*d9f75844SAndroid Build Coastguard Worker // NOTE: This relies on the internal algorithms of call_stats.cc.
194*d9f75844SAndroid Build Coastguard Worker // There's a weight factor there (0.3), that weighs the previous average to
195*d9f75844SAndroid Build Coastguard Worker // the new one by 70%, so the number 103 in this case is arrived at like so:
196*d9f75844SAndroid Build Coastguard Worker // (100) / 1 * 0.7 + (100+120)/2 * 0.3 = 103
197*d9f75844SAndroid Build Coastguard Worker static constexpr const int64_t kAvgRtt1 = 103;
198*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt1, kHighRtt))
199*d9f75844SAndroid Build Coastguard Worker .Times(1)
200*d9f75844SAndroid Build Coastguard Worker .WillOnce(InvokeWithoutArgs([this] {
201*d9f75844SAndroid Build Coastguard Worker // This interacts with an internal implementation detail in call_stats
202*d9f75844SAndroid Build Coastguard Worker // that decays the oldest rtt value. See more below.
203*d9f75844SAndroid Build Coastguard Worker fake_clock_.AdvanceTimeMilliseconds(1000);
204*d9f75844SAndroid Build Coastguard Worker AsyncSimulateRttUpdate(kLowRtt); // Reported at T2 (2000ms).
205*d9f75844SAndroid Build Coastguard Worker }));
206*d9f75844SAndroid Build Coastguard Worker
207*d9f75844SAndroid Build Coastguard Worker // Increase time enough for a new update, but not too much to make the
208*d9f75844SAndroid Build Coastguard Worker // rtt invalid. Report a lower rtt and verify the old/high value still is sent
209*d9f75844SAndroid Build Coastguard Worker // in the callback.
210*d9f75844SAndroid Build Coastguard Worker
211*d9f75844SAndroid Build Coastguard Worker // Here, enough time must have passed in order to remove exactly the first
212*d9f75844SAndroid Build Coastguard Worker // report and nothing else (>1500ms has passed since the first rtt).
213*d9f75844SAndroid Build Coastguard Worker // So, this value is arrived by doing:
214*d9f75844SAndroid Build Coastguard Worker // (kAvgRtt1)/1 * 0.7 + (kHighRtt+kLowRtt)/2 * 0.3 = 102.1
215*d9f75844SAndroid Build Coastguard Worker static constexpr const int64_t kAvgRtt2 = 102;
216*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt2, kHighRtt))
217*d9f75844SAndroid Build Coastguard Worker .Times(1)
218*d9f75844SAndroid Build Coastguard Worker .WillOnce(InvokeWithoutArgs([this] {
219*d9f75844SAndroid Build Coastguard Worker // Advance time to make the high report invalid, the lower rtt should
220*d9f75844SAndroid Build Coastguard Worker // now be in the callback.
221*d9f75844SAndroid Build Coastguard Worker fake_clock_.AdvanceTimeMilliseconds(1000);
222*d9f75844SAndroid Build Coastguard Worker }));
223*d9f75844SAndroid Build Coastguard Worker
224*d9f75844SAndroid Build Coastguard Worker static constexpr const int64_t kAvgRtt3 = 95;
225*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt3, kLowRtt))
226*d9f75844SAndroid Build Coastguard Worker .Times(1)
227*d9f75844SAndroid Build Coastguard Worker .WillOnce(InvokeWithoutArgs([this] { loop_.Quit(); }));
228*d9f75844SAndroid Build Coastguard Worker
229*d9f75844SAndroid Build Coastguard Worker // Trigger the first rtt value and set off the chain of callbacks.
230*d9f75844SAndroid Build Coastguard Worker AsyncSimulateRttUpdate(kFirstRtt); // Reported at T0 (0ms).
231*d9f75844SAndroid Build Coastguard Worker loop_.Run();
232*d9f75844SAndroid Build Coastguard Worker
233*d9f75844SAndroid Build Coastguard Worker call_stats_.DeregisterStatsObserver(&stats_observer);
234*d9f75844SAndroid Build Coastguard Worker }
235*d9f75844SAndroid Build Coastguard Worker
TEST_F(CallStats2Test,LastProcessedRtt)236*d9f75844SAndroid Build Coastguard Worker TEST_F(CallStats2Test, LastProcessedRtt) {
237*d9f75844SAndroid Build Coastguard Worker MockStatsObserver stats_observer;
238*d9f75844SAndroid Build Coastguard Worker call_stats_.RegisterStatsObserver(&stats_observer);
239*d9f75844SAndroid Build Coastguard Worker
240*d9f75844SAndroid Build Coastguard Worker static constexpr const int64_t kRttLow = 10;
241*d9f75844SAndroid Build Coastguard Worker static constexpr const int64_t kRttHigh = 30;
242*d9f75844SAndroid Build Coastguard Worker // The following two average numbers dependend on average + weight
243*d9f75844SAndroid Build Coastguard Worker // calculations in call_stats.cc.
244*d9f75844SAndroid Build Coastguard Worker static constexpr const int64_t kAvgRtt1 = 13;
245*d9f75844SAndroid Build Coastguard Worker static constexpr const int64_t kAvgRtt2 = 15;
246*d9f75844SAndroid Build Coastguard Worker
247*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stats_observer, OnRttUpdate(kRttLow, kRttLow))
248*d9f75844SAndroid Build Coastguard Worker .Times(1)
249*d9f75844SAndroid Build Coastguard Worker .WillOnce(InvokeWithoutArgs([this] {
250*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kRttLow, call_stats_.LastProcessedRtt());
251*d9f75844SAndroid Build Coastguard Worker // Don't advance the clock to make sure that low and high rtt values
252*d9f75844SAndroid Build Coastguard Worker // are associated with the same time stamp.
253*d9f75844SAndroid Build Coastguard Worker AsyncSimulateRttUpdate(kRttHigh);
254*d9f75844SAndroid Build Coastguard Worker }));
255*d9f75844SAndroid Build Coastguard Worker
256*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt1, kRttHigh))
257*d9f75844SAndroid Build Coastguard Worker .Times(AnyNumber())
258*d9f75844SAndroid Build Coastguard Worker .WillOnce(InvokeWithoutArgs([this] {
259*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kAvgRtt1, call_stats_.LastProcessedRtt());
260*d9f75844SAndroid Build Coastguard Worker fake_clock_.AdvanceTimeMilliseconds(CallStats::kUpdateInterval.ms());
261*d9f75844SAndroid Build Coastguard Worker AsyncSimulateRttUpdate(kRttLow);
262*d9f75844SAndroid Build Coastguard Worker AsyncSimulateRttUpdate(kRttHigh);
263*d9f75844SAndroid Build Coastguard Worker }))
264*d9f75844SAndroid Build Coastguard Worker .WillRepeatedly(Return());
265*d9f75844SAndroid Build Coastguard Worker
266*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stats_observer, OnRttUpdate(kAvgRtt2, kRttHigh))
267*d9f75844SAndroid Build Coastguard Worker .Times(AnyNumber())
268*d9f75844SAndroid Build Coastguard Worker .WillOnce(InvokeWithoutArgs([this] {
269*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kAvgRtt2, call_stats_.LastProcessedRtt());
270*d9f75844SAndroid Build Coastguard Worker loop_.Quit();
271*d9f75844SAndroid Build Coastguard Worker }))
272*d9f75844SAndroid Build Coastguard Worker .WillRepeatedly(Return());
273*d9f75844SAndroid Build Coastguard Worker
274*d9f75844SAndroid Build Coastguard Worker // Set a first values and verify that LastProcessedRtt initially returns the
275*d9f75844SAndroid Build Coastguard Worker // average rtt.
276*d9f75844SAndroid Build Coastguard Worker fake_clock_.AdvanceTimeMilliseconds(CallStats::kUpdateInterval.ms());
277*d9f75844SAndroid Build Coastguard Worker AsyncSimulateRttUpdate(kRttLow);
278*d9f75844SAndroid Build Coastguard Worker loop_.Run();
279*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kAvgRtt2, call_stats_.LastProcessedRtt());
280*d9f75844SAndroid Build Coastguard Worker
281*d9f75844SAndroid Build Coastguard Worker call_stats_.DeregisterStatsObserver(&stats_observer);
282*d9f75844SAndroid Build Coastguard Worker }
283*d9f75844SAndroid Build Coastguard Worker
TEST_F(CallStats2Test,ProducesHistogramMetrics)284*d9f75844SAndroid Build Coastguard Worker TEST_F(CallStats2Test, ProducesHistogramMetrics) {
285*d9f75844SAndroid Build Coastguard Worker metrics::Reset();
286*d9f75844SAndroid Build Coastguard Worker static constexpr const int64_t kRtt = 123;
287*d9f75844SAndroid Build Coastguard Worker MockStatsObserver stats_observer;
288*d9f75844SAndroid Build Coastguard Worker call_stats_.RegisterStatsObserver(&stats_observer);
289*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(stats_observer, OnRttUpdate(kRtt, kRtt))
290*d9f75844SAndroid Build Coastguard Worker .Times(AnyNumber())
291*d9f75844SAndroid Build Coastguard Worker .WillRepeatedly(InvokeWithoutArgs([this] { loop_.Quit(); }));
292*d9f75844SAndroid Build Coastguard Worker
293*d9f75844SAndroid Build Coastguard Worker AsyncSimulateRttUpdate(kRtt);
294*d9f75844SAndroid Build Coastguard Worker loop_.Run();
295*d9f75844SAndroid Build Coastguard Worker fake_clock_.AdvanceTimeMilliseconds(metrics::kMinRunTimeInSeconds *
296*d9f75844SAndroid Build Coastguard Worker CallStats::kUpdateInterval.ms());
297*d9f75844SAndroid Build Coastguard Worker AsyncSimulateRttUpdate(kRtt);
298*d9f75844SAndroid Build Coastguard Worker loop_.Run();
299*d9f75844SAndroid Build Coastguard Worker
300*d9f75844SAndroid Build Coastguard Worker call_stats_.DeregisterStatsObserver(&stats_observer);
301*d9f75844SAndroid Build Coastguard Worker
302*d9f75844SAndroid Build Coastguard Worker call_stats_.UpdateHistogramsForTest();
303*d9f75844SAndroid Build Coastguard Worker
304*d9f75844SAndroid Build Coastguard Worker EXPECT_METRIC_EQ(1, metrics::NumSamples(
305*d9f75844SAndroid Build Coastguard Worker "WebRTC.Video.AverageRoundTripTimeInMilliseconds"));
306*d9f75844SAndroid Build Coastguard Worker EXPECT_METRIC_EQ(
307*d9f75844SAndroid Build Coastguard Worker 1, metrics::NumEvents("WebRTC.Video.AverageRoundTripTimeInMilliseconds",
308*d9f75844SAndroid Build Coastguard Worker kRtt));
309*d9f75844SAndroid Build Coastguard Worker }
310*d9f75844SAndroid Build Coastguard Worker
311*d9f75844SAndroid Build Coastguard Worker } // namespace internal
312*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc
313