blob: 3c9633a8db1f1ace3f58df1b70ad47b1342a5e97 [file] [log] [blame]
asapersson0e9d6d92016-05-23 06:07:55 -07001/*
2 * Copyright (c) 2016 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
11#include "webrtc/video/stats_counter.h"
12
asapersson0e9d6d92016-05-23 06:07:55 -070013#include "webrtc/system_wrappers/include/clock.h"
kwibergac9f8762016-09-30 22:29:43 -070014#include "webrtc/test/gtest.h"
asapersson0e9d6d92016-05-23 06:07:55 -070015
16namespace webrtc {
17namespace {
asaperssone402a142016-10-06 23:39:15 -070018const int kDefaultProcessIntervalMs = 2000;
asapersson0e9d6d92016-05-23 06:07:55 -070019
20class StatsCounterObserverImpl : public StatsCounterObserver {
21 public:
22 StatsCounterObserverImpl() : num_calls_(0), last_sample_(-1) {}
23 void OnMetricUpdated(int sample) override {
24 ++num_calls_;
25 last_sample_ = sample;
26 }
27 int num_calls_;
28 int last_sample_;
29};
30} // namespace
31
32class StatsCounterTest : public ::testing::Test {
33 protected:
34 StatsCounterTest()
35 : clock_(1234) {}
36
37 void AddSampleAndAdvance(int sample, int interval_ms, AvgCounter* counter) {
38 counter->Add(sample);
39 clock_.AdvanceTimeMilliseconds(interval_ms);
40 }
41
42 void SetSampleAndAdvance(int sample,
43 int interval_ms,
44 RateAccCounter* counter) {
45 counter->Set(sample);
46 clock_.AdvanceTimeMilliseconds(interval_ms);
47 }
48
49 void VerifyStatsIsNotSet(const AggregatedStats& stats) {
50 EXPECT_EQ(0, stats.num_samples);
51 EXPECT_EQ(-1, stats.min);
52 EXPECT_EQ(-1, stats.max);
53 EXPECT_EQ(-1, stats.average);
54 }
55
56 SimulatedClock clock_;
57};
58
59TEST_F(StatsCounterTest, NoSamples) {
asaperssonce2e1362016-09-09 00:13:35 -070060 AvgCounter counter(&clock_, nullptr, false);
asapersson0e9d6d92016-05-23 06:07:55 -070061 VerifyStatsIsNotSet(counter.GetStats());
62}
63
64TEST_F(StatsCounterTest, TestRegisterObserver) {
65 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
66 const int kSample = 22;
asaperssonce2e1362016-09-09 00:13:35 -070067 AvgCounter counter(&clock_, observer, false);
asaperssone402a142016-10-06 23:39:15 -070068 AddSampleAndAdvance(kSample, kDefaultProcessIntervalMs, &counter);
asapersson0e9d6d92016-05-23 06:07:55 -070069 // Trigger process (sample included in next interval).
70 counter.Add(111);
71 EXPECT_EQ(1, observer->num_calls_);
72}
73
asapersson250fd972016-09-08 00:07:21 -070074TEST_F(StatsCounterTest, HasSample) {
asaperssonce2e1362016-09-09 00:13:35 -070075 AvgCounter counter(&clock_, nullptr, false);
asapersson250fd972016-09-08 00:07:21 -070076 EXPECT_FALSE(counter.HasSample());
77 counter.Add(1);
78 EXPECT_TRUE(counter.HasSample());
79}
80
asapersson0e9d6d92016-05-23 06:07:55 -070081TEST_F(StatsCounterTest, VerifyProcessInterval) {
82 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
asaperssonce2e1362016-09-09 00:13:35 -070083 AvgCounter counter(&clock_, observer, false);
asapersson0e9d6d92016-05-23 06:07:55 -070084 counter.Add(4);
asaperssone402a142016-10-06 23:39:15 -070085 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs - 1);
asapersson0e9d6d92016-05-23 06:07:55 -070086 // Try trigger process (interval has not passed).
87 counter.Add(8);
88 EXPECT_EQ(0, observer->num_calls_);
89 VerifyStatsIsNotSet(counter.GetStats());
90 // Make process interval pass.
91 clock_.AdvanceTimeMilliseconds(1);
92 // Trigger process (sample included in next interval).
93 counter.Add(111);
94 EXPECT_EQ(1, observer->num_calls_);
95 EXPECT_EQ(6, observer->last_sample_);
96 // Aggregated stats.
97 AggregatedStats stats = counter.GetStats();
98 EXPECT_EQ(1, stats.num_samples);
99}
100
101TEST_F(StatsCounterTest, TestMetric_AvgCounter) {
102 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
asaperssonce2e1362016-09-09 00:13:35 -0700103 AvgCounter counter(&clock_, observer, false);
asapersson0e9d6d92016-05-23 06:07:55 -0700104 counter.Add(4);
105 counter.Add(8);
106 counter.Add(9);
asaperssone402a142016-10-06 23:39:15 -0700107 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
asapersson0e9d6d92016-05-23 06:07:55 -0700108 // Trigger process (sample included in next interval).
109 counter.Add(111);
110 // Average per interval.
111 EXPECT_EQ(1, observer->num_calls_);
112 EXPECT_EQ(7, observer->last_sample_);
113 // Aggregated stats.
114 AggregatedStats stats = counter.GetStats();
115 EXPECT_EQ(1, stats.num_samples);
116 EXPECT_EQ(7, stats.min);
117 EXPECT_EQ(7, stats.max);
118 EXPECT_EQ(7, stats.average);
119}
120
121TEST_F(StatsCounterTest, TestMetric_MaxCounter) {
asaperssone402a142016-10-06 23:39:15 -0700122 const int64_t kProcessIntervalMs = 1000;
asapersson0e9d6d92016-05-23 06:07:55 -0700123 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
asaperssone402a142016-10-06 23:39:15 -0700124 MaxCounter counter(&clock_, observer, kProcessIntervalMs);
asapersson0e9d6d92016-05-23 06:07:55 -0700125 counter.Add(4);
126 counter.Add(9);
127 counter.Add(8);
128 clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
129 // Trigger process (sample included in next interval).
130 counter.Add(111);
131 // Average per interval.
132 EXPECT_EQ(1, observer->num_calls_);
133 EXPECT_EQ(9, observer->last_sample_);
134 // Aggregated stats.
135 AggregatedStats stats = counter.GetStats();
136 EXPECT_EQ(1, stats.num_samples);
137 EXPECT_EQ(9, stats.min);
138 EXPECT_EQ(9, stats.max);
139 EXPECT_EQ(9, stats.average);
140}
141
142TEST_F(StatsCounterTest, TestMetric_PercentCounter) {
143 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
144 PercentCounter counter(&clock_, observer);
145 counter.Add(true);
146 counter.Add(false);
asaperssone402a142016-10-06 23:39:15 -0700147 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
asapersson0e9d6d92016-05-23 06:07:55 -0700148 // Trigger process (sample included in next interval).
149 counter.Add(false);
150 // Percentage per interval.
151 EXPECT_EQ(1, observer->num_calls_);
152 EXPECT_EQ(50, observer->last_sample_);
153 // Aggregated stats.
154 AggregatedStats stats = counter.GetStats();
155 EXPECT_EQ(1, stats.num_samples);
156 EXPECT_EQ(50, stats.min);
157 EXPECT_EQ(50, stats.max);
158}
159
160TEST_F(StatsCounterTest, TestMetric_PermilleCounter) {
161 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
162 PermilleCounter counter(&clock_, observer);
163 counter.Add(true);
164 counter.Add(false);
asaperssone402a142016-10-06 23:39:15 -0700165 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
asapersson0e9d6d92016-05-23 06:07:55 -0700166 // Trigger process (sample included in next interval).
167 counter.Add(false);
168 // Permille per interval.
169 EXPECT_EQ(1, observer->num_calls_);
170 EXPECT_EQ(500, observer->last_sample_);
171 // Aggregated stats.
172 AggregatedStats stats = counter.GetStats();
173 EXPECT_EQ(1, stats.num_samples);
174 EXPECT_EQ(500, stats.min);
175 EXPECT_EQ(500, stats.max);
176}
177
178TEST_F(StatsCounterTest, TestMetric_RateCounter) {
179 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
asapersson5093b382016-08-15 01:20:30 -0700180 RateCounter counter(&clock_, observer, true);
asapersson0e9d6d92016-05-23 06:07:55 -0700181 counter.Add(186);
182 counter.Add(350);
183 counter.Add(22);
asaperssone402a142016-10-06 23:39:15 -0700184 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
asapersson0e9d6d92016-05-23 06:07:55 -0700185 // Trigger process (sample included in next interval).
186 counter.Add(111);
187 // Rate per interval, (186 + 350 + 22) / 2 sec = 279 samples/sec
188 EXPECT_EQ(1, observer->num_calls_);
189 EXPECT_EQ(279, observer->last_sample_);
190 // Aggregated stats.
191 AggregatedStats stats = counter.GetStats();
192 EXPECT_EQ(1, stats.num_samples);
193 EXPECT_EQ(279, stats.min);
194 EXPECT_EQ(279, stats.max);
195}
196
197TEST_F(StatsCounterTest, TestMetric_RateAccCounter) {
198 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
asapersson5093b382016-08-15 01:20:30 -0700199 RateAccCounter counter(&clock_, observer, true);
asapersson0e9d6d92016-05-23 06:07:55 -0700200 counter.Set(175);
201 counter.Set(188);
asaperssone402a142016-10-06 23:39:15 -0700202 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
asapersson0e9d6d92016-05-23 06:07:55 -0700203 // Trigger process (sample included in next interval).
204 counter.Set(192);
205 // Rate per interval: (188 - 0) / 2 sec = 94 samples/sec
206 EXPECT_EQ(1, observer->num_calls_);
207 EXPECT_EQ(94, observer->last_sample_);
208 // Aggregated stats.
209 AggregatedStats stats = counter.GetStats();
210 EXPECT_EQ(1, stats.num_samples);
211 EXPECT_EQ(94, stats.min);
212 EXPECT_EQ(94, stats.max);
213}
214
215TEST_F(StatsCounterTest, TestGetStats_MultipleIntervals) {
asaperssonce2e1362016-09-09 00:13:35 -0700216 AvgCounter counter(&clock_, nullptr, false);
asapersson0e9d6d92016-05-23 06:07:55 -0700217 const int kSample1 = 1;
218 const int kSample2 = 5;
219 const int kSample3 = 8;
220 const int kSample4 = 11;
221 const int kSample5 = 50;
asaperssone402a142016-10-06 23:39:15 -0700222 AddSampleAndAdvance(kSample1, kDefaultProcessIntervalMs, &counter);
223 AddSampleAndAdvance(kSample2, kDefaultProcessIntervalMs, &counter);
224 AddSampleAndAdvance(kSample3, kDefaultProcessIntervalMs, &counter);
225 AddSampleAndAdvance(kSample4, kDefaultProcessIntervalMs, &counter);
226 AddSampleAndAdvance(kSample5, kDefaultProcessIntervalMs, &counter);
asapersson0e9d6d92016-05-23 06:07:55 -0700227 // Trigger process (sample included in next interval).
228 counter.Add(111);
229 AggregatedStats stats = counter.GetStats();
230 EXPECT_EQ(5, stats.num_samples);
231 EXPECT_EQ(kSample1, stats.min);
232 EXPECT_EQ(kSample5, stats.max);
233 EXPECT_EQ(15, stats.average);
234}
235
236TEST_F(StatsCounterTest, TestGetStatsTwice) {
237 const int kSample1 = 4;
238 const int kSample2 = 7;
asaperssonce2e1362016-09-09 00:13:35 -0700239 AvgCounter counter(&clock_, nullptr, false);
asaperssone402a142016-10-06 23:39:15 -0700240 AddSampleAndAdvance(kSample1, kDefaultProcessIntervalMs, &counter);
asapersson0e9d6d92016-05-23 06:07:55 -0700241 // Trigger process (sample included in next interval).
242 counter.Add(kSample2);
243 AggregatedStats stats = counter.GetStats();
244 EXPECT_EQ(1, stats.num_samples);
245 EXPECT_EQ(kSample1, stats.min);
246 EXPECT_EQ(kSample1, stats.max);
247 // Trigger process (sample included in next interval).
asaperssone402a142016-10-06 23:39:15 -0700248 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
asapersson0e9d6d92016-05-23 06:07:55 -0700249 counter.Add(111);
250 stats = counter.GetStats();
251 EXPECT_EQ(2, stats.num_samples);
252 EXPECT_EQ(kSample1, stats.min);
253 EXPECT_EQ(kSample2, stats.max);
254 EXPECT_EQ(6, stats.average);
255}
256
257TEST_F(StatsCounterTest, TestRateAccCounter_NegativeRateIgnored) {
258 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
259 const int kSample1 = 200; // 200 / 2 sec
260 const int kSample2 = 100; // -100 / 2 sec - negative ignored
261 const int kSample3 = 700; // 600 / 2 sec
asapersson5093b382016-08-15 01:20:30 -0700262 RateAccCounter counter(&clock_, observer, true);
asaperssone402a142016-10-06 23:39:15 -0700263 SetSampleAndAdvance(kSample1, kDefaultProcessIntervalMs, &counter);
264 SetSampleAndAdvance(kSample2, kDefaultProcessIntervalMs, &counter);
265 SetSampleAndAdvance(kSample3, kDefaultProcessIntervalMs, &counter);
asapersson0e9d6d92016-05-23 06:07:55 -0700266 EXPECT_EQ(1, observer->num_calls_);
267 EXPECT_EQ(100, observer->last_sample_);
268 // Trigger process (sample included in next interval).
269 counter.Set(2000);
270 EXPECT_EQ(2, observer->num_calls_);
271 EXPECT_EQ(300, observer->last_sample_);
272 // Aggregated stats.
273 AggregatedStats stats = counter.GetStats();
274 EXPECT_EQ(2, stats.num_samples);
275 EXPECT_EQ(100, stats.min);
276 EXPECT_EQ(300, stats.max);
277 EXPECT_EQ(200, stats.average);
278}
279
asaperssonce2e1362016-09-09 00:13:35 -0700280TEST_F(StatsCounterTest, TestAvgCounter_IntervalsWithoutSamplesIncluded) {
281 // Samples: | 6 | x | x | 8 | // x: empty interval
282 // Stats: | 6 | 6 | 6 | 8 | // x -> last value reported
asapersson0e9d6d92016-05-23 06:07:55 -0700283 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
asaperssonce2e1362016-09-09 00:13:35 -0700284 AvgCounter counter(&clock_, observer, true);
asaperssone402a142016-10-06 23:39:15 -0700285 AddSampleAndAdvance(6, kDefaultProcessIntervalMs * 4 - 1, &counter);
asapersson0e9d6d92016-05-23 06:07:55 -0700286 // Trigger process (sample included in next interval).
287 counter.Add(8);
asaperssonce2e1362016-09-09 00:13:35 -0700288 // [6:3], 3 intervals passed (2 without samples -> last value reported).
289 AggregatedStats stats = counter.ProcessAndGetStats();
290 EXPECT_EQ(3, stats.num_samples);
asapersson0e9d6d92016-05-23 06:07:55 -0700291 EXPECT_EQ(6, stats.min);
asaperssonce2e1362016-09-09 00:13:35 -0700292 EXPECT_EQ(6, stats.max);
293 // Make next interval pass and verify stats: [6:3],[8:1]
294 clock_.AdvanceTimeMilliseconds(1);
295 counter.ProcessAndGetStats();
296 EXPECT_EQ(4, observer->num_calls_);
297 EXPECT_EQ(8, observer->last_sample_);
298}
299
300TEST_F(StatsCounterTest, TestAvgCounter_WithPause) {
301 // Samples: | 6 | x | x | x | - | 22 | x | // x: empty interval, -: paused
302 // Stats: | 6 | 6 | 6 | 6 | - | 22 | 22 | // x -> last value reported
303 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
304 AvgCounter counter(&clock_, observer, true);
305 // Add sample and advance 3 intervals (2 w/o samples -> last value reported).
asaperssone402a142016-10-06 23:39:15 -0700306 AddSampleAndAdvance(6, kDefaultProcessIntervalMs * 4 - 1, &counter);
asaperssonce2e1362016-09-09 00:13:35 -0700307 // Trigger process and verify stats: [6:3]
308 counter.ProcessAndGetStats();
309 EXPECT_EQ(3, observer->num_calls_);
310 EXPECT_EQ(6, observer->last_sample_);
311 // Make next interval pass (1 without samples).
312 // Process and pause. Verify stats: [6:4].
313 clock_.AdvanceTimeMilliseconds(1);
314 counter.ProcessAndPause();
315 EXPECT_EQ(4, observer->num_calls_); // Last value reported.
316 EXPECT_EQ(6, observer->last_sample_);
317 // Make next interval pass (1 without samples -> ignored while paused).
asaperssone402a142016-10-06 23:39:15 -0700318 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 2 - 1);
asaperssonce2e1362016-09-09 00:13:35 -0700319 counter.Add(22); // Stops pause.
320 EXPECT_EQ(4, observer->num_calls_);
321 EXPECT_EQ(6, observer->last_sample_);
322 // Make next interval pass, [6:4][22:1]
323 clock_.AdvanceTimeMilliseconds(1);
324 counter.ProcessAndGetStats();
325 EXPECT_EQ(5, observer->num_calls_);
326 EXPECT_EQ(22, observer->last_sample_);
327 // Make 1 interval pass (1 w/o samples -> pause stopped, last value reported).
asaperssone402a142016-10-06 23:39:15 -0700328 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
asaperssonce2e1362016-09-09 00:13:35 -0700329 counter.ProcessAndGetStats();
330 EXPECT_EQ(6, observer->num_calls_);
331 EXPECT_EQ(22, observer->last_sample_);
asapersson0e9d6d92016-05-23 06:07:55 -0700332}
333
asapersson5093b382016-08-15 01:20:30 -0700334TEST_F(StatsCounterTest, TestRateCounter_IntervalsWithoutSamplesIgnored) {
asaperssonce2e1362016-09-09 00:13:35 -0700335 // Samples: | 50 | x | 20 | // x: empty interval
336 // Stats: | 25 | x | 10 | // x -> ignored
asapersson5093b382016-08-15 01:20:30 -0700337 const bool kIncludeEmptyIntervals = false;
asapersson0e9d6d92016-05-23 06:07:55 -0700338 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
339 const int kSample1 = 50; // 50 / 2 sec
340 const int kSample2 = 20; // 20 / 2 sec
asapersson5093b382016-08-15 01:20:30 -0700341 RateCounter counter(&clock_, observer, kIncludeEmptyIntervals);
342 counter.Add(kSample1);
asaperssone402a142016-10-06 23:39:15 -0700343 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 3 - 1);
asapersson5093b382016-08-15 01:20:30 -0700344 // Trigger process (sample included in next interval).
345 counter.Add(kSample2);
asaperssonce2e1362016-09-09 00:13:35 -0700346 // [25:1], 2 intervals passed (1 without samples -> ignored).
asapersson5093b382016-08-15 01:20:30 -0700347 EXPECT_EQ(1, observer->num_calls_);
348 EXPECT_EQ(25, observer->last_sample_);
asaperssonce2e1362016-09-09 00:13:35 -0700349 // Make next interval pass and verify stats: [10:1],[25:1]
asapersson5093b382016-08-15 01:20:30 -0700350 clock_.AdvanceTimeMilliseconds(1);
asaperssonce2e1362016-09-09 00:13:35 -0700351 counter.ProcessAndGetStats();
asapersson5093b382016-08-15 01:20:30 -0700352 EXPECT_EQ(2, observer->num_calls_);
353 EXPECT_EQ(10, observer->last_sample_);
asapersson5093b382016-08-15 01:20:30 -0700354}
355
356TEST_F(StatsCounterTest, TestRateCounter_IntervalsWithoutSamplesIncluded) {
asaperssonce2e1362016-09-09 00:13:35 -0700357 // Samples: | 50 | x | 20 | // x: empty interval
358 // Stats: | 25 | 0 | 10 | // x -> zero reported
asapersson5093b382016-08-15 01:20:30 -0700359 const bool kIncludeEmptyIntervals = true;
360 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
361 const int kSample1 = 50; // 50 / 2 sec
362 const int kSample2 = 20; // 20 / 2 sec
363 RateCounter counter(&clock_, observer, kIncludeEmptyIntervals);
asapersson0e9d6d92016-05-23 06:07:55 -0700364 counter.Add(kSample1);
asaperssone402a142016-10-06 23:39:15 -0700365 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 3 - 1);
asapersson0e9d6d92016-05-23 06:07:55 -0700366 // Trigger process (sample included in next interval).
367 counter.Add(kSample2);
asaperssonce2e1362016-09-09 00:13:35 -0700368 // [0:1],[25:1], 2 intervals passed (1 without samples -> zero reported).
asapersson0e9d6d92016-05-23 06:07:55 -0700369 EXPECT_EQ(2, observer->num_calls_);
asaperssonce2e1362016-09-09 00:13:35 -0700370 EXPECT_EQ(0, observer->last_sample_);
371 // Make last interval pass and verify stats: [0:1],[10:1],[25:1]
asapersson0e9d6d92016-05-23 06:07:55 -0700372 clock_.AdvanceTimeMilliseconds(1);
asaperssonce2e1362016-09-09 00:13:35 -0700373 AggregatedStats stats = counter.ProcessAndGetStats();
374 EXPECT_EQ(25, stats.max);
asapersson0e9d6d92016-05-23 06:07:55 -0700375 EXPECT_EQ(3, observer->num_calls_);
376 EXPECT_EQ(10, observer->last_sample_);
asaperssonce2e1362016-09-09 00:13:35 -0700377}
378
379TEST_F(StatsCounterTest, TestRateAccCounter_IntervalsWithoutSamplesIncluded) {
380 // Samples: | 12 | x | x | x | 60 | // x: empty interval
381 // Stats: | 6 | 0 | 0 | 0 | 24 | // x -> zero reported
382 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
383 RateAccCounter counter(&clock_, observer, true);
384 VerifyStatsIsNotSet(counter.ProcessAndGetStats());
385 // Advance one interval and verify stats.
asaperssone402a142016-10-06 23:39:15 -0700386 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
asaperssonce2e1362016-09-09 00:13:35 -0700387 VerifyStatsIsNotSet(counter.ProcessAndGetStats());
388 // Add sample and advance 3 intervals (2 w/o samples -> zero reported).
389 counter.Set(12);
asaperssone402a142016-10-06 23:39:15 -0700390 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 4 - 1);
asaperssonce2e1362016-09-09 00:13:35 -0700391 // Trigger process and verify stats: [0:2][6:1]
392 counter.ProcessAndGetStats();
393 EXPECT_EQ(3, observer->num_calls_);
394 EXPECT_EQ(0, observer->last_sample_);
395 // Make next interval pass (1 w/o samples -> zero reported), [0:3][6:1]
396 clock_.AdvanceTimeMilliseconds(1);
397 counter.ProcessAndGetStats();
398 EXPECT_EQ(4, observer->num_calls_);
399 EXPECT_EQ(0, observer->last_sample_);
400 // Insert sample and advance non-complete interval, no change, [0:3][6:1]
asaperssone402a142016-10-06 23:39:15 -0700401 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs - 1);
asaperssonce2e1362016-09-09 00:13:35 -0700402 counter.Set(60);
403 EXPECT_EQ(4, observer->num_calls_);
404 // Make next interval pass, [0:3][6:1][24:1]
405 clock_.AdvanceTimeMilliseconds(1);
406 AggregatedStats stats = counter.ProcessAndGetStats();
407 EXPECT_EQ(5, observer->num_calls_);
408 EXPECT_EQ(24, observer->last_sample_);
409 EXPECT_EQ(6, stats.average);
410}
411
412TEST_F(StatsCounterTest, TestRateAccCounter_IntervalsWithoutSamplesIgnored) {
413 // Samples: | 12 | x | x | x | 60 | // x: empty interval
414 // Stats: | 6 | x | x | x | 24 | // x -> ignored
415 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
416 RateAccCounter counter(&clock_, observer, false);
417 // Add sample and advance 3 intervals (2 w/o samples -> ignored).
418 counter.Set(12);
asaperssone402a142016-10-06 23:39:15 -0700419 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 4 - 1);
asaperssonce2e1362016-09-09 00:13:35 -0700420 // Trigger process and verify stats: [6:1]
421 counter.ProcessAndGetStats();
422 EXPECT_EQ(1, observer->num_calls_);
423 EXPECT_EQ(6, observer->last_sample_);
424 // Make next interval pass (1 w/o samples -> ignored), [6:1]
425 clock_.AdvanceTimeMilliseconds(1);
426 counter.ProcessAndGetStats();
427 EXPECT_EQ(1, observer->num_calls_);
428 // Insert sample and advance non-complete interval, no change, [6:1]
asaperssone402a142016-10-06 23:39:15 -0700429 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs - 1);
asaperssonce2e1362016-09-09 00:13:35 -0700430 counter.Set(60);
431 counter.ProcessAndGetStats();
432 EXPECT_EQ(1, observer->num_calls_);
433 // Make next interval pass, [6:1][24:1]
434 clock_.AdvanceTimeMilliseconds(1);
435 counter.ProcessAndGetStats();
436 EXPECT_EQ(2, observer->num_calls_);
437 EXPECT_EQ(24, observer->last_sample_);
asapersson0e9d6d92016-05-23 06:07:55 -0700438}
439
440} // namespace webrtc