xref: /aosp_15_r20/external/webrtc/video/stats_counter_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright (c) 2016 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/stats_counter.h"
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/clock.h"
14*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
15*d9f75844SAndroid Build Coastguard Worker 
16*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
17*d9f75844SAndroid Build Coastguard Worker namespace {
18*d9f75844SAndroid Build Coastguard Worker const int kDefaultProcessIntervalMs = 2000;
19*d9f75844SAndroid Build Coastguard Worker const uint32_t kStreamId = 123456;
20*d9f75844SAndroid Build Coastguard Worker 
21*d9f75844SAndroid Build Coastguard Worker class StatsCounterObserverImpl : public StatsCounterObserver {
22*d9f75844SAndroid Build Coastguard Worker  public:
StatsCounterObserverImpl()23*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl() : num_calls_(0), last_sample_(-1) {}
OnMetricUpdated(int sample)24*d9f75844SAndroid Build Coastguard Worker   void OnMetricUpdated(int sample) override {
25*d9f75844SAndroid Build Coastguard Worker     ++num_calls_;
26*d9f75844SAndroid Build Coastguard Worker     last_sample_ = sample;
27*d9f75844SAndroid Build Coastguard Worker   }
28*d9f75844SAndroid Build Coastguard Worker   int num_calls_;
29*d9f75844SAndroid Build Coastguard Worker   int last_sample_;
30*d9f75844SAndroid Build Coastguard Worker };
31*d9f75844SAndroid Build Coastguard Worker }  // namespace
32*d9f75844SAndroid Build Coastguard Worker 
33*d9f75844SAndroid Build Coastguard Worker class StatsCounterTest : public ::testing::Test {
34*d9f75844SAndroid Build Coastguard Worker  protected:
StatsCounterTest()35*d9f75844SAndroid Build Coastguard Worker   StatsCounterTest() : clock_(1234) {}
36*d9f75844SAndroid Build Coastguard Worker 
AddSampleAndAdvance(int sample,int interval_ms,AvgCounter * counter)37*d9f75844SAndroid Build Coastguard Worker   void AddSampleAndAdvance(int sample, int interval_ms, AvgCounter* counter) {
38*d9f75844SAndroid Build Coastguard Worker     counter->Add(sample);
39*d9f75844SAndroid Build Coastguard Worker     clock_.AdvanceTimeMilliseconds(interval_ms);
40*d9f75844SAndroid Build Coastguard Worker   }
41*d9f75844SAndroid Build Coastguard Worker 
SetSampleAndAdvance(int sample,int interval_ms,RateAccCounter * counter)42*d9f75844SAndroid Build Coastguard Worker   void SetSampleAndAdvance(int sample,
43*d9f75844SAndroid Build Coastguard Worker                            int interval_ms,
44*d9f75844SAndroid Build Coastguard Worker                            RateAccCounter* counter) {
45*d9f75844SAndroid Build Coastguard Worker     counter->Set(sample, kStreamId);
46*d9f75844SAndroid Build Coastguard Worker     clock_.AdvanceTimeMilliseconds(interval_ms);
47*d9f75844SAndroid Build Coastguard Worker   }
48*d9f75844SAndroid Build Coastguard Worker 
VerifyStatsIsNotSet(const AggregatedStats & stats)49*d9f75844SAndroid Build Coastguard Worker   void VerifyStatsIsNotSet(const AggregatedStats& stats) {
50*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(0, stats.num_samples);
51*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(-1, stats.min);
52*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(-1, stats.max);
53*d9f75844SAndroid Build Coastguard Worker     EXPECT_EQ(-1, stats.average);
54*d9f75844SAndroid Build Coastguard Worker   }
55*d9f75844SAndroid Build Coastguard Worker 
56*d9f75844SAndroid Build Coastguard Worker   SimulatedClock clock_;
57*d9f75844SAndroid Build Coastguard Worker };
58*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,NoSamples)59*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, NoSamples) {
60*d9f75844SAndroid Build Coastguard Worker   AvgCounter counter(&clock_, nullptr, false);
61*d9f75844SAndroid Build Coastguard Worker   VerifyStatsIsNotSet(counter.GetStats());
62*d9f75844SAndroid Build Coastguard Worker }
63*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestRegisterObserver)64*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestRegisterObserver) {
65*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
66*d9f75844SAndroid Build Coastguard Worker   const int kSample = 22;
67*d9f75844SAndroid Build Coastguard Worker   AvgCounter counter(&clock_, observer, false);
68*d9f75844SAndroid Build Coastguard Worker   AddSampleAndAdvance(kSample, kDefaultProcessIntervalMs, &counter);
69*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
70*d9f75844SAndroid Build Coastguard Worker   counter.Add(111);
71*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
72*d9f75844SAndroid Build Coastguard Worker }
73*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,HasSample)74*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, HasSample) {
75*d9f75844SAndroid Build Coastguard Worker   AvgCounter counter(&clock_, nullptr, false);
76*d9f75844SAndroid Build Coastguard Worker   EXPECT_FALSE(counter.HasSample());
77*d9f75844SAndroid Build Coastguard Worker   counter.Add(1);
78*d9f75844SAndroid Build Coastguard Worker   EXPECT_TRUE(counter.HasSample());
79*d9f75844SAndroid Build Coastguard Worker }
80*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,VerifyProcessInterval)81*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, VerifyProcessInterval) {
82*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
83*d9f75844SAndroid Build Coastguard Worker   AvgCounter counter(&clock_, observer, false);
84*d9f75844SAndroid Build Coastguard Worker   counter.Add(4);
85*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs - 1);
86*d9f75844SAndroid Build Coastguard Worker   // Try trigger process (interval has not passed).
87*d9f75844SAndroid Build Coastguard Worker   counter.Add(8);
88*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0, observer->num_calls_);
89*d9f75844SAndroid Build Coastguard Worker   VerifyStatsIsNotSet(counter.GetStats());
90*d9f75844SAndroid Build Coastguard Worker   // Make process interval pass.
91*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(1);
92*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
93*d9f75844SAndroid Build Coastguard Worker   counter.Add(111);
94*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
95*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, observer->last_sample_);
96*d9f75844SAndroid Build Coastguard Worker   // Aggregated stats.
97*d9f75844SAndroid Build Coastguard Worker   AggregatedStats stats = counter.GetStats();
98*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, stats.num_samples);
99*d9f75844SAndroid Build Coastguard Worker }
100*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestMetric_AvgCounter)101*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestMetric_AvgCounter) {
102*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
103*d9f75844SAndroid Build Coastguard Worker   AvgCounter counter(&clock_, observer, false);
104*d9f75844SAndroid Build Coastguard Worker   counter.Add(4);
105*d9f75844SAndroid Build Coastguard Worker   counter.Add(8);
106*d9f75844SAndroid Build Coastguard Worker   counter.Add(9);
107*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
108*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
109*d9f75844SAndroid Build Coastguard Worker   counter.Add(111);
110*d9f75844SAndroid Build Coastguard Worker   // Average per interval.
111*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
112*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(7, observer->last_sample_);
113*d9f75844SAndroid Build Coastguard Worker   // Aggregated stats.
114*d9f75844SAndroid Build Coastguard Worker   AggregatedStats stats = counter.GetStats();
115*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, stats.num_samples);
116*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(7, stats.min);
117*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(7, stats.max);
118*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(7, stats.average);
119*d9f75844SAndroid Build Coastguard Worker }
120*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestMetric_MaxCounter)121*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestMetric_MaxCounter) {
122*d9f75844SAndroid Build Coastguard Worker   const int64_t kProcessIntervalMs = 1000;
123*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
124*d9f75844SAndroid Build Coastguard Worker   MaxCounter counter(&clock_, observer, kProcessIntervalMs);
125*d9f75844SAndroid Build Coastguard Worker   counter.Add(4);
126*d9f75844SAndroid Build Coastguard Worker   counter.Add(9);
127*d9f75844SAndroid Build Coastguard Worker   counter.Add(8);
128*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
129*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
130*d9f75844SAndroid Build Coastguard Worker   counter.Add(111);
131*d9f75844SAndroid Build Coastguard Worker   // Average per interval.
132*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
133*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(9, observer->last_sample_);
134*d9f75844SAndroid Build Coastguard Worker   // Aggregated stats.
135*d9f75844SAndroid Build Coastguard Worker   AggregatedStats stats = counter.GetStats();
136*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, stats.num_samples);
137*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(9, stats.min);
138*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(9, stats.max);
139*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(9, stats.average);
140*d9f75844SAndroid Build Coastguard Worker }
141*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestMetric_PercentCounter)142*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestMetric_PercentCounter) {
143*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
144*d9f75844SAndroid Build Coastguard Worker   PercentCounter counter(&clock_, observer);
145*d9f75844SAndroid Build Coastguard Worker   counter.Add(true);
146*d9f75844SAndroid Build Coastguard Worker   counter.Add(false);
147*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
148*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
149*d9f75844SAndroid Build Coastguard Worker   counter.Add(false);
150*d9f75844SAndroid Build Coastguard Worker   // Percentage per interval.
151*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
152*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(50, observer->last_sample_);
153*d9f75844SAndroid Build Coastguard Worker   // Aggregated stats.
154*d9f75844SAndroid Build Coastguard Worker   AggregatedStats stats = counter.GetStats();
155*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, stats.num_samples);
156*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(50, stats.min);
157*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(50, stats.max);
158*d9f75844SAndroid Build Coastguard Worker }
159*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestMetric_PermilleCounter)160*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestMetric_PermilleCounter) {
161*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
162*d9f75844SAndroid Build Coastguard Worker   PermilleCounter counter(&clock_, observer);
163*d9f75844SAndroid Build Coastguard Worker   counter.Add(true);
164*d9f75844SAndroid Build Coastguard Worker   counter.Add(false);
165*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
166*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
167*d9f75844SAndroid Build Coastguard Worker   counter.Add(false);
168*d9f75844SAndroid Build Coastguard Worker   // Permille per interval.
169*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
170*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(500, observer->last_sample_);
171*d9f75844SAndroid Build Coastguard Worker   // Aggregated stats.
172*d9f75844SAndroid Build Coastguard Worker   AggregatedStats stats = counter.GetStats();
173*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, stats.num_samples);
174*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(500, stats.min);
175*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(500, stats.max);
176*d9f75844SAndroid Build Coastguard Worker }
177*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestMetric_RateCounter)178*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestMetric_RateCounter) {
179*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
180*d9f75844SAndroid Build Coastguard Worker   RateCounter counter(&clock_, observer, true);
181*d9f75844SAndroid Build Coastguard Worker   counter.Add(186);
182*d9f75844SAndroid Build Coastguard Worker   counter.Add(350);
183*d9f75844SAndroid Build Coastguard Worker   counter.Add(22);
184*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
185*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
186*d9f75844SAndroid Build Coastguard Worker   counter.Add(111);
187*d9f75844SAndroid Build Coastguard Worker   // Rate per interval, (186 + 350 + 22) / 2 sec = 279 samples/sec
188*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
189*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(279, observer->last_sample_);
190*d9f75844SAndroid Build Coastguard Worker   // Aggregated stats.
191*d9f75844SAndroid Build Coastguard Worker   AggregatedStats stats = counter.GetStats();
192*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, stats.num_samples);
193*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(279, stats.min);
194*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(279, stats.max);
195*d9f75844SAndroid Build Coastguard Worker }
196*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestMetric_RateAccCounter)197*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestMetric_RateAccCounter) {
198*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
199*d9f75844SAndroid Build Coastguard Worker   RateAccCounter counter(&clock_, observer, true);
200*d9f75844SAndroid Build Coastguard Worker   counter.Set(175, kStreamId);
201*d9f75844SAndroid Build Coastguard Worker   counter.Set(188, kStreamId);
202*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
203*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
204*d9f75844SAndroid Build Coastguard Worker   counter.Set(192, kStreamId);
205*d9f75844SAndroid Build Coastguard Worker   // Rate per interval: (188 - 0) / 2 sec = 94 samples/sec
206*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
207*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(94, observer->last_sample_);
208*d9f75844SAndroid Build Coastguard Worker   // Aggregated stats.
209*d9f75844SAndroid Build Coastguard Worker   AggregatedStats stats = counter.GetStats();
210*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, stats.num_samples);
211*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(94, stats.min);
212*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(94, stats.max);
213*d9f75844SAndroid Build Coastguard Worker }
214*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestMetric_RateAccCounterWithSetLast)215*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestMetric_RateAccCounterWithSetLast) {
216*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
217*d9f75844SAndroid Build Coastguard Worker   RateAccCounter counter(&clock_, observer, true);
218*d9f75844SAndroid Build Coastguard Worker   counter.SetLast(98, kStreamId);
219*d9f75844SAndroid Build Coastguard Worker   counter.Set(175, kStreamId);
220*d9f75844SAndroid Build Coastguard Worker   counter.Set(188, kStreamId);
221*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
222*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
223*d9f75844SAndroid Build Coastguard Worker   counter.Set(192, kStreamId);
224*d9f75844SAndroid Build Coastguard Worker   // Rate per interval: (188 - 98) / 2 sec = 45 samples/sec
225*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
226*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(45, observer->last_sample_);
227*d9f75844SAndroid Build Coastguard Worker }
228*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestMetric_RateAccCounterWithMultipleStreamIds)229*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestMetric_RateAccCounterWithMultipleStreamIds) {
230*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
231*d9f75844SAndroid Build Coastguard Worker   RateAccCounter counter(&clock_, observer, true);
232*d9f75844SAndroid Build Coastguard Worker   counter.Set(175, kStreamId);
233*d9f75844SAndroid Build Coastguard Worker   counter.Set(188, kStreamId);
234*d9f75844SAndroid Build Coastguard Worker   counter.Set(100, kStreamId + 1);
235*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
236*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
237*d9f75844SAndroid Build Coastguard Worker   counter.Set(150, kStreamId + 1);
238*d9f75844SAndroid Build Coastguard Worker   // Rate per interval: ((188 - 0) + (100 - 0)) / 2 sec = 144 samples/sec
239*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
240*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(144, observer->last_sample_);
241*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
242*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
243*d9f75844SAndroid Build Coastguard Worker   counter.Set(198, kStreamId);
244*d9f75844SAndroid Build Coastguard Worker   // Rate per interval: (0 + (150 - 100)) / 2 sec = 25 samples/sec
245*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2, observer->num_calls_);
246*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(25, observer->last_sample_);
247*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
248*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
249*d9f75844SAndroid Build Coastguard Worker   counter.Set(200, kStreamId);
250*d9f75844SAndroid Build Coastguard Worker   // Rate per interval: ((198 - 188) + (0)) / 2 sec = 5 samples/sec
251*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(3, observer->num_calls_);
252*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(5, observer->last_sample_);
253*d9f75844SAndroid Build Coastguard Worker   // Aggregated stats.
254*d9f75844SAndroid Build Coastguard Worker   AggregatedStats stats = counter.GetStats();
255*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(3, stats.num_samples);
256*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(5, stats.min);
257*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(144, stats.max);
258*d9f75844SAndroid Build Coastguard Worker }
259*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestGetStats_MultipleIntervals)260*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestGetStats_MultipleIntervals) {
261*d9f75844SAndroid Build Coastguard Worker   AvgCounter counter(&clock_, nullptr, false);
262*d9f75844SAndroid Build Coastguard Worker   const int kSample1 = 1;
263*d9f75844SAndroid Build Coastguard Worker   const int kSample2 = 5;
264*d9f75844SAndroid Build Coastguard Worker   const int kSample3 = 8;
265*d9f75844SAndroid Build Coastguard Worker   const int kSample4 = 11;
266*d9f75844SAndroid Build Coastguard Worker   const int kSample5 = 50;
267*d9f75844SAndroid Build Coastguard Worker   AddSampleAndAdvance(kSample1, kDefaultProcessIntervalMs, &counter);
268*d9f75844SAndroid Build Coastguard Worker   AddSampleAndAdvance(kSample2, kDefaultProcessIntervalMs, &counter);
269*d9f75844SAndroid Build Coastguard Worker   AddSampleAndAdvance(kSample3, kDefaultProcessIntervalMs, &counter);
270*d9f75844SAndroid Build Coastguard Worker   AddSampleAndAdvance(kSample4, kDefaultProcessIntervalMs, &counter);
271*d9f75844SAndroid Build Coastguard Worker   AddSampleAndAdvance(kSample5, kDefaultProcessIntervalMs, &counter);
272*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
273*d9f75844SAndroid Build Coastguard Worker   counter.Add(111);
274*d9f75844SAndroid Build Coastguard Worker   AggregatedStats stats = counter.GetStats();
275*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(5, stats.num_samples);
276*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(kSample1, stats.min);
277*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(kSample5, stats.max);
278*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(15, stats.average);
279*d9f75844SAndroid Build Coastguard Worker }
280*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestGetStatsTwice)281*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestGetStatsTwice) {
282*d9f75844SAndroid Build Coastguard Worker   const int kSample1 = 4;
283*d9f75844SAndroid Build Coastguard Worker   const int kSample2 = 7;
284*d9f75844SAndroid Build Coastguard Worker   AvgCounter counter(&clock_, nullptr, false);
285*d9f75844SAndroid Build Coastguard Worker   AddSampleAndAdvance(kSample1, kDefaultProcessIntervalMs, &counter);
286*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
287*d9f75844SAndroid Build Coastguard Worker   counter.Add(kSample2);
288*d9f75844SAndroid Build Coastguard Worker   AggregatedStats stats = counter.GetStats();
289*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, stats.num_samples);
290*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(kSample1, stats.min);
291*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(kSample1, stats.max);
292*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
293*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
294*d9f75844SAndroid Build Coastguard Worker   counter.Add(111);
295*d9f75844SAndroid Build Coastguard Worker   stats = counter.GetStats();
296*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2, stats.num_samples);
297*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(kSample1, stats.min);
298*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(kSample2, stats.max);
299*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, stats.average);
300*d9f75844SAndroid Build Coastguard Worker }
301*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestRateAccCounter_NegativeRateIgnored)302*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestRateAccCounter_NegativeRateIgnored) {
303*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
304*d9f75844SAndroid Build Coastguard Worker   const int kSample1 = 200;  //  200 / 2 sec
305*d9f75844SAndroid Build Coastguard Worker   const int kSample2 = 100;  // -100 / 2 sec - negative ignored
306*d9f75844SAndroid Build Coastguard Worker   const int kSample3 = 700;  //  600 / 2 sec
307*d9f75844SAndroid Build Coastguard Worker   RateAccCounter counter(&clock_, observer, true);
308*d9f75844SAndroid Build Coastguard Worker   SetSampleAndAdvance(kSample1, kDefaultProcessIntervalMs, &counter);
309*d9f75844SAndroid Build Coastguard Worker   SetSampleAndAdvance(kSample2, kDefaultProcessIntervalMs, &counter);
310*d9f75844SAndroid Build Coastguard Worker   SetSampleAndAdvance(kSample3, kDefaultProcessIntervalMs, &counter);
311*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
312*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(100, observer->last_sample_);
313*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
314*d9f75844SAndroid Build Coastguard Worker   counter.Set(2000, kStreamId);
315*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2, observer->num_calls_);
316*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(300, observer->last_sample_);
317*d9f75844SAndroid Build Coastguard Worker   // Aggregated stats.
318*d9f75844SAndroid Build Coastguard Worker   AggregatedStats stats = counter.GetStats();
319*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2, stats.num_samples);
320*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(100, stats.min);
321*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(300, stats.max);
322*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(200, stats.average);
323*d9f75844SAndroid Build Coastguard Worker }
324*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestAvgCounter_IntervalsWithoutSamplesIncluded)325*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestAvgCounter_IntervalsWithoutSamplesIncluded) {
326*d9f75844SAndroid Build Coastguard Worker   // Samples: | 6 | x | x | 8 |  // x: empty interval
327*d9f75844SAndroid Build Coastguard Worker   // Stats:   | 6 | 6 | 6 | 8 |  // x -> last value reported
328*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
329*d9f75844SAndroid Build Coastguard Worker   AvgCounter counter(&clock_, observer, true);
330*d9f75844SAndroid Build Coastguard Worker   AddSampleAndAdvance(6, kDefaultProcessIntervalMs * 4 - 1, &counter);
331*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
332*d9f75844SAndroid Build Coastguard Worker   counter.Add(8);
333*d9f75844SAndroid Build Coastguard Worker   // [6:3], 3 intervals passed (2 without samples -> last value reported).
334*d9f75844SAndroid Build Coastguard Worker   AggregatedStats stats = counter.ProcessAndGetStats();
335*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(3, stats.num_samples);
336*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, stats.min);
337*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, stats.max);
338*d9f75844SAndroid Build Coastguard Worker   // Make next interval pass and verify stats: [6:3],[8:1]
339*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(1);
340*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
341*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(4, observer->num_calls_);
342*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(8, observer->last_sample_);
343*d9f75844SAndroid Build Coastguard Worker }
344*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestAvgCounter_WithPause)345*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestAvgCounter_WithPause) {
346*d9f75844SAndroid Build Coastguard Worker   // Samples: | 6 | x | x | x | - | 22 | x  |  // x: empty interval, -: paused
347*d9f75844SAndroid Build Coastguard Worker   // Stats:   | 6 | 6 | 6 | 6 | - | 22 | 22 |  // x -> last value reported
348*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
349*d9f75844SAndroid Build Coastguard Worker   AvgCounter counter(&clock_, observer, true);
350*d9f75844SAndroid Build Coastguard Worker   // Add sample and advance 3 intervals (2 w/o samples -> last value reported).
351*d9f75844SAndroid Build Coastguard Worker   AddSampleAndAdvance(6, kDefaultProcessIntervalMs * 4 - 1, &counter);
352*d9f75844SAndroid Build Coastguard Worker   // Trigger process and verify stats: [6:3]
353*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
354*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(3, observer->num_calls_);
355*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, observer->last_sample_);
356*d9f75844SAndroid Build Coastguard Worker   // Make next interval pass (1 without samples).
357*d9f75844SAndroid Build Coastguard Worker   // Process and pause. Verify stats: [6:4].
358*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(1);
359*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndPause();
360*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(4, observer->num_calls_);  // Last value reported.
361*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, observer->last_sample_);
362*d9f75844SAndroid Build Coastguard Worker   // Make next interval pass (1 without samples -> ignored while paused).
363*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 2 - 1);
364*d9f75844SAndroid Build Coastguard Worker   counter.Add(22);  // Stops pause.
365*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(4, observer->num_calls_);
366*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, observer->last_sample_);
367*d9f75844SAndroid Build Coastguard Worker   // Make next interval pass, [6:4][22:1]
368*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(1);
369*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
370*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(5, observer->num_calls_);
371*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(22, observer->last_sample_);
372*d9f75844SAndroid Build Coastguard Worker   // Make 1 interval pass (1 w/o samples -> pause stopped, last value reported).
373*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
374*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
375*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, observer->num_calls_);
376*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(22, observer->last_sample_);
377*d9f75844SAndroid Build Coastguard Worker }
378*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestRateAccCounter_AddSampleStopsPause)379*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestRateAccCounter_AddSampleStopsPause) {
380*d9f75844SAndroid Build Coastguard Worker   // Samples: | 12 | 24 |  // -: paused
381*d9f75844SAndroid Build Coastguard Worker   // Stats:   | 6  | 6  |
382*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
383*d9f75844SAndroid Build Coastguard Worker   RateAccCounter counter(&clock_, observer, true);
384*d9f75844SAndroid Build Coastguard Worker   // Add sample and advance 1 intervals.
385*d9f75844SAndroid Build Coastguard Worker   counter.Set(12, kStreamId);
386*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
387*d9f75844SAndroid Build Coastguard Worker   // Trigger process and verify stats: [6:1]
388*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndPause();
389*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
390*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, observer->last_sample_);
391*d9f75844SAndroid Build Coastguard Worker   // Add sample and advance 1 intervals.
392*d9f75844SAndroid Build Coastguard Worker   counter.Set(24, kStreamId);  // Pause stopped.
393*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
394*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
395*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2, observer->num_calls_);
396*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, observer->last_sample_);
397*d9f75844SAndroid Build Coastguard Worker }
398*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestRateAccCounter_AddSameSampleDoesNotStopPause)399*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestRateAccCounter_AddSameSampleDoesNotStopPause) {
400*d9f75844SAndroid Build Coastguard Worker   // Samples: | 12 | 12 | 24 |  // -: paused
401*d9f75844SAndroid Build Coastguard Worker   // Stats:   | 6  | -  | 6  |
402*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
403*d9f75844SAndroid Build Coastguard Worker   RateAccCounter counter(&clock_, observer, true);
404*d9f75844SAndroid Build Coastguard Worker   // Add sample and advance 1 intervals.
405*d9f75844SAndroid Build Coastguard Worker   counter.Set(12, kStreamId);
406*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
407*d9f75844SAndroid Build Coastguard Worker   // Trigger process and verify stats: [6:1]
408*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndPause();
409*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
410*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, observer->last_sample_);
411*d9f75844SAndroid Build Coastguard Worker   // Add same sample and advance 1 intervals.
412*d9f75844SAndroid Build Coastguard Worker   counter.Set(12, kStreamId);  // Pause not stopped.
413*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
414*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
415*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
416*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, observer->last_sample_);
417*d9f75844SAndroid Build Coastguard Worker   // Add new sample and advance 1 intervals.
418*d9f75844SAndroid Build Coastguard Worker   counter.Set(24, kStreamId);  // Pause stopped.
419*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
420*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
421*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2, observer->num_calls_);
422*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, observer->last_sample_);
423*d9f75844SAndroid Build Coastguard Worker }
424*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestRateAccCounter_PauseAndStopPause)425*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestRateAccCounter_PauseAndStopPause) {
426*d9f75844SAndroid Build Coastguard Worker   // Samples: | 12 | 12 | 12 |  // -: paused
427*d9f75844SAndroid Build Coastguard Worker   // Stats:   | 6  | -  | 0  |
428*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
429*d9f75844SAndroid Build Coastguard Worker   RateAccCounter counter(&clock_, observer, true);
430*d9f75844SAndroid Build Coastguard Worker   // Add sample and advance 1 intervals.
431*d9f75844SAndroid Build Coastguard Worker   counter.Set(12, kStreamId);
432*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
433*d9f75844SAndroid Build Coastguard Worker   // Trigger process and verify stats: [6:1]
434*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndPause();
435*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
436*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, observer->last_sample_);
437*d9f75844SAndroid Build Coastguard Worker   // Add same sample and advance 1 intervals.
438*d9f75844SAndroid Build Coastguard Worker   counter.Set(12, kStreamId);  // Pause not stopped.
439*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
440*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
441*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
442*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, observer->last_sample_);
443*d9f75844SAndroid Build Coastguard Worker   // Stop pause, add sample and advance 1 intervals.
444*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndStopPause();
445*d9f75844SAndroid Build Coastguard Worker   counter.Set(12, kStreamId);
446*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
447*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
448*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2, observer->num_calls_);
449*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0, observer->last_sample_);
450*d9f75844SAndroid Build Coastguard Worker }
451*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestAvgCounter_WithoutMinPauseTimePassed)452*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestAvgCounter_WithoutMinPauseTimePassed) {
453*d9f75844SAndroid Build Coastguard Worker   // Samples: | 6 | 2 | - |  // x: empty interval, -: paused
454*d9f75844SAndroid Build Coastguard Worker   // Stats:   | 6 | 2 | - |  // x -> last value reported
455*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
456*d9f75844SAndroid Build Coastguard Worker   AvgCounter counter(&clock_, observer, true);
457*d9f75844SAndroid Build Coastguard Worker   // Add sample and advance 1 intervals.
458*d9f75844SAndroid Build Coastguard Worker   AddSampleAndAdvance(6, kDefaultProcessIntervalMs, &counter);
459*d9f75844SAndroid Build Coastguard Worker   // Process and pause. Verify stats: [6:1].
460*d9f75844SAndroid Build Coastguard Worker   const int64_t kMinMs = 500;
461*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndPauseForDuration(kMinMs);
462*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);  // Last value reported.
463*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, observer->last_sample_);
464*d9f75844SAndroid Build Coastguard Worker   // Min pause time has not pass.
465*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kMinMs - 1);
466*d9f75844SAndroid Build Coastguard Worker   counter.Add(2);  // Pause not stopped.
467*d9f75844SAndroid Build Coastguard Worker   // Make two intervals pass (1 without samples -> ignored while paused).
468*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 2 - (kMinMs - 1));
469*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
470*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2, observer->num_calls_);
471*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2, observer->last_sample_);
472*d9f75844SAndroid Build Coastguard Worker }
473*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestAvgCounter_WithMinPauseTimePassed)474*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestAvgCounter_WithMinPauseTimePassed) {
475*d9f75844SAndroid Build Coastguard Worker   // Samples: | 6 | 2 | x |  // x: empty interval, -: paused
476*d9f75844SAndroid Build Coastguard Worker   // Stats:   | 6 | 2 | 2 |  // x -> last value reported
477*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
478*d9f75844SAndroid Build Coastguard Worker   AvgCounter counter(&clock_, observer, true);
479*d9f75844SAndroid Build Coastguard Worker   // Add sample and advance 1 intervals.
480*d9f75844SAndroid Build Coastguard Worker   AddSampleAndAdvance(6, kDefaultProcessIntervalMs, &counter);
481*d9f75844SAndroid Build Coastguard Worker   // Process and pause. Verify stats: [6:1].
482*d9f75844SAndroid Build Coastguard Worker   const int64_t kMinMs = 500;
483*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndPauseForDuration(kMinMs);
484*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);  // Last value reported.
485*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, observer->last_sample_);
486*d9f75844SAndroid Build Coastguard Worker   // Make min pause time pass.
487*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kMinMs);
488*d9f75844SAndroid Build Coastguard Worker   counter.Add(2);  // Stop pause.
489*d9f75844SAndroid Build Coastguard Worker   // Make two intervals pass (1 without samples -> last value reported).
490*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 2 - kMinMs);
491*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
492*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(3, observer->num_calls_);
493*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2, observer->last_sample_);
494*d9f75844SAndroid Build Coastguard Worker }
495*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestRateCounter_IntervalsWithoutSamplesIgnored)496*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestRateCounter_IntervalsWithoutSamplesIgnored) {
497*d9f75844SAndroid Build Coastguard Worker   // Samples: | 50 | x | 20 |  // x: empty interval
498*d9f75844SAndroid Build Coastguard Worker   // Stats:   | 25 | x | 10 |  // x -> ignored
499*d9f75844SAndroid Build Coastguard Worker   const bool kIncludeEmptyIntervals = false;
500*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
501*d9f75844SAndroid Build Coastguard Worker   const int kSample1 = 50;  //  50 / 2 sec
502*d9f75844SAndroid Build Coastguard Worker   const int kSample2 = 20;  //  20 / 2 sec
503*d9f75844SAndroid Build Coastguard Worker   RateCounter counter(&clock_, observer, kIncludeEmptyIntervals);
504*d9f75844SAndroid Build Coastguard Worker   counter.Add(kSample1);
505*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 3 - 1);
506*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
507*d9f75844SAndroid Build Coastguard Worker   counter.Add(kSample2);
508*d9f75844SAndroid Build Coastguard Worker   // [25:1], 2 intervals passed (1 without samples -> ignored).
509*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
510*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(25, observer->last_sample_);
511*d9f75844SAndroid Build Coastguard Worker   // Make next interval pass and verify stats: [10:1],[25:1]
512*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(1);
513*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
514*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2, observer->num_calls_);
515*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(10, observer->last_sample_);
516*d9f75844SAndroid Build Coastguard Worker }
517*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestRateCounter_IntervalsWithoutSamplesIncluded)518*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestRateCounter_IntervalsWithoutSamplesIncluded) {
519*d9f75844SAndroid Build Coastguard Worker   // Samples: | 50 | x | 20 |  // x: empty interval
520*d9f75844SAndroid Build Coastguard Worker   // Stats:   | 25 | 0 | 10 |  // x -> zero reported
521*d9f75844SAndroid Build Coastguard Worker   const bool kIncludeEmptyIntervals = true;
522*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
523*d9f75844SAndroid Build Coastguard Worker   const int kSample1 = 50;  //  50 / 2 sec
524*d9f75844SAndroid Build Coastguard Worker   const int kSample2 = 20;  //  20 / 2 sec
525*d9f75844SAndroid Build Coastguard Worker   RateCounter counter(&clock_, observer, kIncludeEmptyIntervals);
526*d9f75844SAndroid Build Coastguard Worker   counter.Add(kSample1);
527*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 3 - 1);
528*d9f75844SAndroid Build Coastguard Worker   // Trigger process (sample included in next interval).
529*d9f75844SAndroid Build Coastguard Worker   counter.Add(kSample2);
530*d9f75844SAndroid Build Coastguard Worker   // [0:1],[25:1], 2 intervals passed (1 without samples -> zero reported).
531*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2, observer->num_calls_);
532*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0, observer->last_sample_);
533*d9f75844SAndroid Build Coastguard Worker   // Make last interval pass and verify stats: [0:1],[10:1],[25:1]
534*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(1);
535*d9f75844SAndroid Build Coastguard Worker   AggregatedStats stats = counter.ProcessAndGetStats();
536*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(25, stats.max);
537*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(3, observer->num_calls_);
538*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(10, observer->last_sample_);
539*d9f75844SAndroid Build Coastguard Worker }
540*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestRateAccCounter_IntervalsWithoutSamplesIncluded)541*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestRateAccCounter_IntervalsWithoutSamplesIncluded) {
542*d9f75844SAndroid Build Coastguard Worker   // Samples: | 12 | x | x | x | 60 |  // x: empty interval
543*d9f75844SAndroid Build Coastguard Worker   // Stats:   | 6  | 0 | 0 | 0 | 24 |  // x -> zero reported
544*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
545*d9f75844SAndroid Build Coastguard Worker   RateAccCounter counter(&clock_, observer, true);
546*d9f75844SAndroid Build Coastguard Worker   VerifyStatsIsNotSet(counter.ProcessAndGetStats());
547*d9f75844SAndroid Build Coastguard Worker   // Advance one interval and verify stats.
548*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
549*d9f75844SAndroid Build Coastguard Worker   VerifyStatsIsNotSet(counter.ProcessAndGetStats());
550*d9f75844SAndroid Build Coastguard Worker   // Add sample and advance 3 intervals (2 w/o samples -> zero reported).
551*d9f75844SAndroid Build Coastguard Worker   counter.Set(12, kStreamId);
552*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 4 - 1);
553*d9f75844SAndroid Build Coastguard Worker   // Trigger process and verify stats: [0:2][6:1]
554*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
555*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(3, observer->num_calls_);
556*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0, observer->last_sample_);
557*d9f75844SAndroid Build Coastguard Worker   // Make next interval pass (1 w/o samples -> zero reported), [0:3][6:1]
558*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(1);
559*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
560*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(4, observer->num_calls_);
561*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(0, observer->last_sample_);
562*d9f75844SAndroid Build Coastguard Worker   // Insert sample and advance non-complete interval, no change, [0:3][6:1]
563*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs - 1);
564*d9f75844SAndroid Build Coastguard Worker   counter.Set(60, kStreamId);
565*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(4, observer->num_calls_);
566*d9f75844SAndroid Build Coastguard Worker   // Make next interval pass, [0:3][6:1][24:1]
567*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(1);
568*d9f75844SAndroid Build Coastguard Worker   AggregatedStats stats = counter.ProcessAndGetStats();
569*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(5, observer->num_calls_);
570*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(24, observer->last_sample_);
571*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, stats.average);
572*d9f75844SAndroid Build Coastguard Worker }
573*d9f75844SAndroid Build Coastguard Worker 
TEST_F(StatsCounterTest,TestRateAccCounter_IntervalsWithoutSamplesIgnored)574*d9f75844SAndroid Build Coastguard Worker TEST_F(StatsCounterTest, TestRateAccCounter_IntervalsWithoutSamplesIgnored) {
575*d9f75844SAndroid Build Coastguard Worker   // Samples: | 12 | x | x | x | 60 |  // x: empty interval
576*d9f75844SAndroid Build Coastguard Worker   // Stats:   | 6  | x | x | x | 24 |  // x -> ignored
577*d9f75844SAndroid Build Coastguard Worker   StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
578*d9f75844SAndroid Build Coastguard Worker   RateAccCounter counter(&clock_, observer, false);
579*d9f75844SAndroid Build Coastguard Worker   // Add sample and advance 3 intervals (2 w/o samples -> ignored).
580*d9f75844SAndroid Build Coastguard Worker   counter.Set(12, kStreamId);
581*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 4 - 1);
582*d9f75844SAndroid Build Coastguard Worker   // Trigger process and verify stats: [6:1]
583*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
584*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
585*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(6, observer->last_sample_);
586*d9f75844SAndroid Build Coastguard Worker   // Make next interval pass (1 w/o samples -> ignored), [6:1]
587*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(1);
588*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
589*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
590*d9f75844SAndroid Build Coastguard Worker   // Insert sample and advance non-complete interval, no change, [6:1]
591*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs - 1);
592*d9f75844SAndroid Build Coastguard Worker   counter.Set(60, kStreamId);
593*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
594*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(1, observer->num_calls_);
595*d9f75844SAndroid Build Coastguard Worker   // Make next interval pass, [6:1][24:1]
596*d9f75844SAndroid Build Coastguard Worker   clock_.AdvanceTimeMilliseconds(1);
597*d9f75844SAndroid Build Coastguard Worker   counter.ProcessAndGetStats();
598*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(2, observer->num_calls_);
599*d9f75844SAndroid Build Coastguard Worker   EXPECT_EQ(24, observer->last_sample_);
600*d9f75844SAndroid Build Coastguard Worker }
601*d9f75844SAndroid Build Coastguard Worker 
602*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
603