blob: 183f2609a82e58e34654cccb0b7e2aeaf74af39f [file] [log] [blame]
asapersson0dc337c2016-05-23 13:07:551/*
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
asapersson0dc337c2016-05-23 13:07:5513#include "webrtc/system_wrappers/include/clock.h"
kwiberg36a24792016-10-01 05:29:4314#include "webrtc/test/gtest.h"
asapersson0dc337c2016-05-23 13:07:5515
16namespace webrtc {
17namespace {
asapersson81fe97b2016-10-07 06:39:1518const int kDefaultProcessIntervalMs = 2000;
asapersson77138d42016-11-01 07:21:3419const uint32_t kStreamId = 123456;
asapersson0dc337c2016-05-23 13:07:5520
21class StatsCounterObserverImpl : public StatsCounterObserver {
22 public:
23 StatsCounterObserverImpl() : num_calls_(0), last_sample_(-1) {}
24 void OnMetricUpdated(int sample) override {
25 ++num_calls_;
26 last_sample_ = sample;
27 }
28 int num_calls_;
29 int last_sample_;
30};
31} // namespace
32
33class StatsCounterTest : public ::testing::Test {
34 protected:
35 StatsCounterTest()
36 : clock_(1234) {}
37
38 void AddSampleAndAdvance(int sample, int interval_ms, AvgCounter* counter) {
39 counter->Add(sample);
40 clock_.AdvanceTimeMilliseconds(interval_ms);
41 }
42
43 void SetSampleAndAdvance(int sample,
44 int interval_ms,
45 RateAccCounter* counter) {
asapersson77138d42016-11-01 07:21:3446 counter->Set(sample, kStreamId);
asapersson0dc337c2016-05-23 13:07:5547 clock_.AdvanceTimeMilliseconds(interval_ms);
48 }
49
50 void VerifyStatsIsNotSet(const AggregatedStats& stats) {
51 EXPECT_EQ(0, stats.num_samples);
52 EXPECT_EQ(-1, stats.min);
53 EXPECT_EQ(-1, stats.max);
54 EXPECT_EQ(-1, stats.average);
55 }
56
57 SimulatedClock clock_;
58};
59
60TEST_F(StatsCounterTest, NoSamples) {
asapersson7df4dab2016-09-09 07:13:3561 AvgCounter counter(&clock_, nullptr, false);
asapersson0dc337c2016-05-23 13:07:5562 VerifyStatsIsNotSet(counter.GetStats());
63}
64
65TEST_F(StatsCounterTest, TestRegisterObserver) {
66 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
67 const int kSample = 22;
asapersson7df4dab2016-09-09 07:13:3568 AvgCounter counter(&clock_, observer, false);
asapersson81fe97b2016-10-07 06:39:1569 AddSampleAndAdvance(kSample, kDefaultProcessIntervalMs, &counter);
asapersson0dc337c2016-05-23 13:07:5570 // Trigger process (sample included in next interval).
71 counter.Add(111);
72 EXPECT_EQ(1, observer->num_calls_);
73}
74
asapersson88788132016-09-08 07:07:2175TEST_F(StatsCounterTest, HasSample) {
asapersson7df4dab2016-09-09 07:13:3576 AvgCounter counter(&clock_, nullptr, false);
asapersson88788132016-09-08 07:07:2177 EXPECT_FALSE(counter.HasSample());
78 counter.Add(1);
79 EXPECT_TRUE(counter.HasSample());
80}
81
asapersson0dc337c2016-05-23 13:07:5582TEST_F(StatsCounterTest, VerifyProcessInterval) {
83 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
asapersson7df4dab2016-09-09 07:13:3584 AvgCounter counter(&clock_, observer, false);
asapersson0dc337c2016-05-23 13:07:5585 counter.Add(4);
asapersson81fe97b2016-10-07 06:39:1586 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs - 1);
asapersson0dc337c2016-05-23 13:07:5587 // Try trigger process (interval has not passed).
88 counter.Add(8);
89 EXPECT_EQ(0, observer->num_calls_);
90 VerifyStatsIsNotSet(counter.GetStats());
91 // Make process interval pass.
92 clock_.AdvanceTimeMilliseconds(1);
93 // Trigger process (sample included in next interval).
94 counter.Add(111);
95 EXPECT_EQ(1, observer->num_calls_);
96 EXPECT_EQ(6, observer->last_sample_);
97 // Aggregated stats.
98 AggregatedStats stats = counter.GetStats();
99 EXPECT_EQ(1, stats.num_samples);
100}
101
102TEST_F(StatsCounterTest, TestMetric_AvgCounter) {
103 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
asapersson7df4dab2016-09-09 07:13:35104 AvgCounter counter(&clock_, observer, false);
asapersson0dc337c2016-05-23 13:07:55105 counter.Add(4);
106 counter.Add(8);
107 counter.Add(9);
asapersson81fe97b2016-10-07 06:39:15108 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
asapersson0dc337c2016-05-23 13:07:55109 // Trigger process (sample included in next interval).
110 counter.Add(111);
111 // Average per interval.
112 EXPECT_EQ(1, observer->num_calls_);
113 EXPECT_EQ(7, observer->last_sample_);
114 // Aggregated stats.
115 AggregatedStats stats = counter.GetStats();
116 EXPECT_EQ(1, stats.num_samples);
117 EXPECT_EQ(7, stats.min);
118 EXPECT_EQ(7, stats.max);
119 EXPECT_EQ(7, stats.average);
120}
121
122TEST_F(StatsCounterTest, TestMetric_MaxCounter) {
asapersson81fe97b2016-10-07 06:39:15123 const int64_t kProcessIntervalMs = 1000;
asapersson0dc337c2016-05-23 13:07:55124 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
asapersson81fe97b2016-10-07 06:39:15125 MaxCounter counter(&clock_, observer, kProcessIntervalMs);
asapersson0dc337c2016-05-23 13:07:55126 counter.Add(4);
127 counter.Add(9);
128 counter.Add(8);
129 clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
130 // Trigger process (sample included in next interval).
131 counter.Add(111);
132 // Average per interval.
133 EXPECT_EQ(1, observer->num_calls_);
134 EXPECT_EQ(9, observer->last_sample_);
135 // Aggregated stats.
136 AggregatedStats stats = counter.GetStats();
137 EXPECT_EQ(1, stats.num_samples);
138 EXPECT_EQ(9, stats.min);
139 EXPECT_EQ(9, stats.max);
140 EXPECT_EQ(9, stats.average);
141}
142
143TEST_F(StatsCounterTest, TestMetric_PercentCounter) {
144 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
145 PercentCounter counter(&clock_, observer);
146 counter.Add(true);
147 counter.Add(false);
asapersson81fe97b2016-10-07 06:39:15148 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
asapersson0dc337c2016-05-23 13:07:55149 // Trigger process (sample included in next interval).
150 counter.Add(false);
151 // Percentage per interval.
152 EXPECT_EQ(1, observer->num_calls_);
153 EXPECT_EQ(50, observer->last_sample_);
154 // Aggregated stats.
155 AggregatedStats stats = counter.GetStats();
156 EXPECT_EQ(1, stats.num_samples);
157 EXPECT_EQ(50, stats.min);
158 EXPECT_EQ(50, stats.max);
159}
160
161TEST_F(StatsCounterTest, TestMetric_PermilleCounter) {
162 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
163 PermilleCounter counter(&clock_, observer);
164 counter.Add(true);
165 counter.Add(false);
asapersson81fe97b2016-10-07 06:39:15166 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
asapersson0dc337c2016-05-23 13:07:55167 // Trigger process (sample included in next interval).
168 counter.Add(false);
169 // Permille per interval.
170 EXPECT_EQ(1, observer->num_calls_);
171 EXPECT_EQ(500, observer->last_sample_);
172 // Aggregated stats.
173 AggregatedStats stats = counter.GetStats();
174 EXPECT_EQ(1, stats.num_samples);
175 EXPECT_EQ(500, stats.min);
176 EXPECT_EQ(500, stats.max);
177}
178
179TEST_F(StatsCounterTest, TestMetric_RateCounter) {
180 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
asapersson68731192016-08-15 08:20:30181 RateCounter counter(&clock_, observer, true);
asapersson0dc337c2016-05-23 13:07:55182 counter.Add(186);
183 counter.Add(350);
184 counter.Add(22);
asapersson81fe97b2016-10-07 06:39:15185 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
asapersson0dc337c2016-05-23 13:07:55186 // Trigger process (sample included in next interval).
187 counter.Add(111);
188 // Rate per interval, (186 + 350 + 22) / 2 sec = 279 samples/sec
189 EXPECT_EQ(1, observer->num_calls_);
190 EXPECT_EQ(279, observer->last_sample_);
191 // Aggregated stats.
192 AggregatedStats stats = counter.GetStats();
193 EXPECT_EQ(1, stats.num_samples);
194 EXPECT_EQ(279, stats.min);
195 EXPECT_EQ(279, stats.max);
196}
197
198TEST_F(StatsCounterTest, TestMetric_RateAccCounter) {
199 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
asapersson68731192016-08-15 08:20:30200 RateAccCounter counter(&clock_, observer, true);
asapersson77138d42016-11-01 07:21:34201 counter.Set(175, kStreamId);
202 counter.Set(188, kStreamId);
asapersson81fe97b2016-10-07 06:39:15203 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
asapersson0dc337c2016-05-23 13:07:55204 // Trigger process (sample included in next interval).
asapersson77138d42016-11-01 07:21:34205 counter.Set(192, kStreamId);
asapersson0dc337c2016-05-23 13:07:55206 // Rate per interval: (188 - 0) / 2 sec = 94 samples/sec
207 EXPECT_EQ(1, observer->num_calls_);
208 EXPECT_EQ(94, observer->last_sample_);
209 // Aggregated stats.
210 AggregatedStats stats = counter.GetStats();
211 EXPECT_EQ(1, stats.num_samples);
212 EXPECT_EQ(94, stats.min);
213 EXPECT_EQ(94, stats.max);
214}
215
asaperssoneedca5a2017-02-06 13:18:35216TEST_F(StatsCounterTest, TestMetric_RateAccCounterWithSetLast) {
217 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
218 RateAccCounter counter(&clock_, observer, true);
219 counter.SetLast(98, kStreamId);
220 counter.Set(175, kStreamId);
221 counter.Set(188, kStreamId);
222 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
223 // Trigger process (sample included in next interval).
224 counter.Set(192, kStreamId);
225 // Rate per interval: (188 - 98) / 2 sec = 45 samples/sec
226 EXPECT_EQ(1, observer->num_calls_);
227 EXPECT_EQ(45, observer->last_sample_);
228}
229
asapersson77138d42016-11-01 07:21:34230TEST_F(StatsCounterTest, TestMetric_RateAccCounterWithMultipleStreamIds) {
231 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
232 RateAccCounter counter(&clock_, observer, true);
233 counter.Set(175, kStreamId);
234 counter.Set(188, kStreamId);
235 counter.Set(100, kStreamId + 1);
236 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
237 // Trigger process (sample included in next interval).
238 counter.Set(150, kStreamId + 1);
239 // Rate per interval: ((188 - 0) + (100 - 0)) / 2 sec = 144 samples/sec
240 EXPECT_EQ(1, observer->num_calls_);
241 EXPECT_EQ(144, observer->last_sample_);
242 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
243 // Trigger process (sample included in next interval).
244 counter.Set(198, kStreamId);
245 // Rate per interval: (0 + (150 - 100)) / 2 sec = 25 samples/sec
246 EXPECT_EQ(2, observer->num_calls_);
247 EXPECT_EQ(25, observer->last_sample_);
248 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
249 // Trigger process (sample included in next interval).
250 counter.Set(200, kStreamId);
251 // Rate per interval: ((198 - 188) + (0)) / 2 sec = 5 samples/sec
252 EXPECT_EQ(3, observer->num_calls_);
253 EXPECT_EQ(5, observer->last_sample_);
254 // Aggregated stats.
255 AggregatedStats stats = counter.GetStats();
256 EXPECT_EQ(3, stats.num_samples);
257 EXPECT_EQ(5, stats.min);
258 EXPECT_EQ(144, stats.max);
259}
260
asapersson0dc337c2016-05-23 13:07:55261TEST_F(StatsCounterTest, TestGetStats_MultipleIntervals) {
asapersson7df4dab2016-09-09 07:13:35262 AvgCounter counter(&clock_, nullptr, false);
asapersson0dc337c2016-05-23 13:07:55263 const int kSample1 = 1;
264 const int kSample2 = 5;
265 const int kSample3 = 8;
266 const int kSample4 = 11;
267 const int kSample5 = 50;
asapersson81fe97b2016-10-07 06:39:15268 AddSampleAndAdvance(kSample1, kDefaultProcessIntervalMs, &counter);
269 AddSampleAndAdvance(kSample2, kDefaultProcessIntervalMs, &counter);
270 AddSampleAndAdvance(kSample3, kDefaultProcessIntervalMs, &counter);
271 AddSampleAndAdvance(kSample4, kDefaultProcessIntervalMs, &counter);
272 AddSampleAndAdvance(kSample5, kDefaultProcessIntervalMs, &counter);
asapersson0dc337c2016-05-23 13:07:55273 // Trigger process (sample included in next interval).
274 counter.Add(111);
275 AggregatedStats stats = counter.GetStats();
276 EXPECT_EQ(5, stats.num_samples);
277 EXPECT_EQ(kSample1, stats.min);
278 EXPECT_EQ(kSample5, stats.max);
279 EXPECT_EQ(15, stats.average);
280}
281
282TEST_F(StatsCounterTest, TestGetStatsTwice) {
283 const int kSample1 = 4;
284 const int kSample2 = 7;
asapersson7df4dab2016-09-09 07:13:35285 AvgCounter counter(&clock_, nullptr, false);
asapersson81fe97b2016-10-07 06:39:15286 AddSampleAndAdvance(kSample1, kDefaultProcessIntervalMs, &counter);
asapersson0dc337c2016-05-23 13:07:55287 // Trigger process (sample included in next interval).
288 counter.Add(kSample2);
289 AggregatedStats stats = counter.GetStats();
290 EXPECT_EQ(1, stats.num_samples);
291 EXPECT_EQ(kSample1, stats.min);
292 EXPECT_EQ(kSample1, stats.max);
293 // Trigger process (sample included in next interval).
asapersson81fe97b2016-10-07 06:39:15294 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
asapersson0dc337c2016-05-23 13:07:55295 counter.Add(111);
296 stats = counter.GetStats();
297 EXPECT_EQ(2, stats.num_samples);
298 EXPECT_EQ(kSample1, stats.min);
299 EXPECT_EQ(kSample2, stats.max);
300 EXPECT_EQ(6, stats.average);
301}
302
303TEST_F(StatsCounterTest, TestRateAccCounter_NegativeRateIgnored) {
304 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
305 const int kSample1 = 200; // 200 / 2 sec
306 const int kSample2 = 100; // -100 / 2 sec - negative ignored
307 const int kSample3 = 700; // 600 / 2 sec
asapersson68731192016-08-15 08:20:30308 RateAccCounter counter(&clock_, observer, true);
asapersson81fe97b2016-10-07 06:39:15309 SetSampleAndAdvance(kSample1, kDefaultProcessIntervalMs, &counter);
310 SetSampleAndAdvance(kSample2, kDefaultProcessIntervalMs, &counter);
311 SetSampleAndAdvance(kSample3, kDefaultProcessIntervalMs, &counter);
asapersson0dc337c2016-05-23 13:07:55312 EXPECT_EQ(1, observer->num_calls_);
313 EXPECT_EQ(100, observer->last_sample_);
314 // Trigger process (sample included in next interval).
asapersson77138d42016-11-01 07:21:34315 counter.Set(2000, kStreamId);
asapersson0dc337c2016-05-23 13:07:55316 EXPECT_EQ(2, observer->num_calls_);
317 EXPECT_EQ(300, observer->last_sample_);
318 // Aggregated stats.
319 AggregatedStats stats = counter.GetStats();
320 EXPECT_EQ(2, stats.num_samples);
321 EXPECT_EQ(100, stats.min);
322 EXPECT_EQ(300, stats.max);
323 EXPECT_EQ(200, stats.average);
324}
325
asapersson7df4dab2016-09-09 07:13:35326TEST_F(StatsCounterTest, TestAvgCounter_IntervalsWithoutSamplesIncluded) {
327 // Samples: | 6 | x | x | 8 | // x: empty interval
328 // Stats: | 6 | 6 | 6 | 8 | // x -> last value reported
asapersson0dc337c2016-05-23 13:07:55329 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
asapersson7df4dab2016-09-09 07:13:35330 AvgCounter counter(&clock_, observer, true);
asapersson81fe97b2016-10-07 06:39:15331 AddSampleAndAdvance(6, kDefaultProcessIntervalMs * 4 - 1, &counter);
asapersson0dc337c2016-05-23 13:07:55332 // Trigger process (sample included in next interval).
333 counter.Add(8);
asapersson7df4dab2016-09-09 07:13:35334 // [6:3], 3 intervals passed (2 without samples -> last value reported).
335 AggregatedStats stats = counter.ProcessAndGetStats();
336 EXPECT_EQ(3, stats.num_samples);
asapersson0dc337c2016-05-23 13:07:55337 EXPECT_EQ(6, stats.min);
asapersson7df4dab2016-09-09 07:13:35338 EXPECT_EQ(6, stats.max);
339 // Make next interval pass and verify stats: [6:3],[8:1]
340 clock_.AdvanceTimeMilliseconds(1);
341 counter.ProcessAndGetStats();
342 EXPECT_EQ(4, observer->num_calls_);
343 EXPECT_EQ(8, observer->last_sample_);
344}
345
346TEST_F(StatsCounterTest, TestAvgCounter_WithPause) {
347 // Samples: | 6 | x | x | x | - | 22 | x | // x: empty interval, -: paused
348 // Stats: | 6 | 6 | 6 | 6 | - | 22 | 22 | // x -> last value reported
349 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
350 AvgCounter counter(&clock_, observer, true);
351 // Add sample and advance 3 intervals (2 w/o samples -> last value reported).
asapersson81fe97b2016-10-07 06:39:15352 AddSampleAndAdvance(6, kDefaultProcessIntervalMs * 4 - 1, &counter);
asapersson7df4dab2016-09-09 07:13:35353 // Trigger process and verify stats: [6:3]
354 counter.ProcessAndGetStats();
355 EXPECT_EQ(3, observer->num_calls_);
356 EXPECT_EQ(6, observer->last_sample_);
357 // Make next interval pass (1 without samples).
358 // Process and pause. Verify stats: [6:4].
359 clock_.AdvanceTimeMilliseconds(1);
360 counter.ProcessAndPause();
361 EXPECT_EQ(4, observer->num_calls_); // Last value reported.
362 EXPECT_EQ(6, observer->last_sample_);
363 // Make next interval pass (1 without samples -> ignored while paused).
asapersson81fe97b2016-10-07 06:39:15364 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 2 - 1);
asapersson7df4dab2016-09-09 07:13:35365 counter.Add(22); // Stops pause.
366 EXPECT_EQ(4, observer->num_calls_);
367 EXPECT_EQ(6, observer->last_sample_);
368 // Make next interval pass, [6:4][22:1]
369 clock_.AdvanceTimeMilliseconds(1);
370 counter.ProcessAndGetStats();
371 EXPECT_EQ(5, observer->num_calls_);
372 EXPECT_EQ(22, observer->last_sample_);
373 // Make 1 interval pass (1 w/o samples -> pause stopped, last value reported).
asapersson81fe97b2016-10-07 06:39:15374 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
asapersson7df4dab2016-09-09 07:13:35375 counter.ProcessAndGetStats();
376 EXPECT_EQ(6, observer->num_calls_);
377 EXPECT_EQ(22, observer->last_sample_);
asapersson0dc337c2016-05-23 13:07:55378}
379
asaperssoneedca5a2017-02-06 13:18:35380TEST_F(StatsCounterTest, TestRateAccCounter_AddSampleStopsPause) {
381 // Samples: | 12 | 24 | // -: paused
382 // Stats: | 6 | 6 |
383 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
384 RateAccCounter counter(&clock_, observer, true);
385 // Add sample and advance 1 intervals.
386 counter.Set(12, kStreamId);
387 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
388 // Trigger process and verify stats: [6:1]
389 counter.ProcessAndPause();
390 EXPECT_EQ(1, observer->num_calls_);
391 EXPECT_EQ(6, observer->last_sample_);
392 // Add sample and advance 1 intervals.
393 counter.Set(24, kStreamId); // Pause stopped.
394 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
395 counter.ProcessAndGetStats();
396 EXPECT_EQ(2, observer->num_calls_);
397 EXPECT_EQ(6, observer->last_sample_);
398}
399
400TEST_F(StatsCounterTest, TestRateAccCounter_AddSameSampleDoesNotStopPause) {
401 // Samples: | 12 | 12 | 24 | // -: paused
402 // Stats: | 6 | - | 6 |
403 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
404 RateAccCounter counter(&clock_, observer, true);
405 // Add sample and advance 1 intervals.
406 counter.Set(12, kStreamId);
407 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
408 // Trigger process and verify stats: [6:1]
409 counter.ProcessAndPause();
410 EXPECT_EQ(1, observer->num_calls_);
411 EXPECT_EQ(6, observer->last_sample_);
412 // Add same sample and advance 1 intervals.
413 counter.Set(12, kStreamId); // Pause not stopped.
414 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
415 counter.ProcessAndGetStats();
416 EXPECT_EQ(1, observer->num_calls_);
417 EXPECT_EQ(6, observer->last_sample_);
418 // Add new sample and advance 1 intervals.
419 counter.Set(24, kStreamId); // Pause stopped.
420 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
421 counter.ProcessAndGetStats();
422 EXPECT_EQ(2, observer->num_calls_);
423 EXPECT_EQ(6, observer->last_sample_);
424}
425
426TEST_F(StatsCounterTest, TestRateAccCounter_PauseAndStopPause) {
427 // Samples: | 12 | 12 | 12 | // -: paused
428 // Stats: | 6 | - | 0 |
429 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
430 RateAccCounter counter(&clock_, observer, true);
431 // Add sample and advance 1 intervals.
432 counter.Set(12, kStreamId);
433 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
434 // Trigger process and verify stats: [6:1]
435 counter.ProcessAndPause();
436 EXPECT_EQ(1, observer->num_calls_);
437 EXPECT_EQ(6, observer->last_sample_);
438 // Add same sample and advance 1 intervals.
439 counter.Set(12, kStreamId); // Pause not stopped.
440 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
441 counter.ProcessAndGetStats();
442 EXPECT_EQ(1, observer->num_calls_);
443 EXPECT_EQ(6, observer->last_sample_);
444 // Stop pause, add sample and advance 1 intervals.
445 counter.ProcessAndStopPause();
446 counter.Set(12, kStreamId);
447 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
448 counter.ProcessAndGetStats();
449 EXPECT_EQ(2, observer->num_calls_);
450 EXPECT_EQ(0, observer->last_sample_);
451}
452
453TEST_F(StatsCounterTest, TestAvgCounter_WithoutMinPauseTimePassed) {
454 // Samples: | 6 | 2 | - | // x: empty interval, -: paused
455 // Stats: | 6 | 2 | - | // x -> last value reported
456 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
457 AvgCounter counter(&clock_, observer, true);
458 // Add sample and advance 1 intervals.
459 AddSampleAndAdvance(6, kDefaultProcessIntervalMs, &counter);
460 // Process and pause. Verify stats: [6:1].
461 const int64_t kMinMs = 500;
462 counter.ProcessAndPauseForDuration(kMinMs);
463 EXPECT_EQ(1, observer->num_calls_); // Last value reported.
464 EXPECT_EQ(6, observer->last_sample_);
465 // Min pause time has not pass.
466 clock_.AdvanceTimeMilliseconds(kMinMs - 1);
467 counter.Add(2); // Pause not stopped.
468 // Make two intervals pass (1 without samples -> ignored while paused).
469 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 2 - (kMinMs - 1));
470 counter.ProcessAndGetStats();
471 EXPECT_EQ(2, observer->num_calls_);
472 EXPECT_EQ(2, observer->last_sample_);
473}
474
475TEST_F(StatsCounterTest, TestAvgCounter_WithMinPauseTimePassed) {
476 // Samples: | 6 | 2 | x | // x: empty interval, -: paused
477 // Stats: | 6 | 2 | 2 | // x -> last value reported
478 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
479 AvgCounter counter(&clock_, observer, true);
480 // Add sample and advance 1 intervals.
481 AddSampleAndAdvance(6, kDefaultProcessIntervalMs, &counter);
482 // Process and pause. Verify stats: [6:1].
483 const int64_t kMinMs = 500;
484 counter.ProcessAndPauseForDuration(kMinMs);
485 EXPECT_EQ(1, observer->num_calls_); // Last value reported.
486 EXPECT_EQ(6, observer->last_sample_);
487 // Make min pause time pass.
488 clock_.AdvanceTimeMilliseconds(kMinMs);
489 counter.Add(2); // Stop pause.
490 // Make two intervals pass (1 without samples -> last value reported).
491 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 2 - kMinMs);
492 counter.ProcessAndGetStats();
493 EXPECT_EQ(3, observer->num_calls_);
494 EXPECT_EQ(2, observer->last_sample_);
495}
496
asapersson68731192016-08-15 08:20:30497TEST_F(StatsCounterTest, TestRateCounter_IntervalsWithoutSamplesIgnored) {
asapersson7df4dab2016-09-09 07:13:35498 // Samples: | 50 | x | 20 | // x: empty interval
499 // Stats: | 25 | x | 10 | // x -> ignored
asapersson68731192016-08-15 08:20:30500 const bool kIncludeEmptyIntervals = false;
asapersson0dc337c2016-05-23 13:07:55501 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
502 const int kSample1 = 50; // 50 / 2 sec
503 const int kSample2 = 20; // 20 / 2 sec
asapersson68731192016-08-15 08:20:30504 RateCounter counter(&clock_, observer, kIncludeEmptyIntervals);
505 counter.Add(kSample1);
asapersson81fe97b2016-10-07 06:39:15506 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 3 - 1);
asapersson68731192016-08-15 08:20:30507 // Trigger process (sample included in next interval).
508 counter.Add(kSample2);
asapersson7df4dab2016-09-09 07:13:35509 // [25:1], 2 intervals passed (1 without samples -> ignored).
asapersson68731192016-08-15 08:20:30510 EXPECT_EQ(1, observer->num_calls_);
511 EXPECT_EQ(25, observer->last_sample_);
asapersson7df4dab2016-09-09 07:13:35512 // Make next interval pass and verify stats: [10:1],[25:1]
asapersson68731192016-08-15 08:20:30513 clock_.AdvanceTimeMilliseconds(1);
asapersson7df4dab2016-09-09 07:13:35514 counter.ProcessAndGetStats();
asapersson68731192016-08-15 08:20:30515 EXPECT_EQ(2, observer->num_calls_);
516 EXPECT_EQ(10, observer->last_sample_);
asapersson68731192016-08-15 08:20:30517}
518
519TEST_F(StatsCounterTest, TestRateCounter_IntervalsWithoutSamplesIncluded) {
asapersson7df4dab2016-09-09 07:13:35520 // Samples: | 50 | x | 20 | // x: empty interval
521 // Stats: | 25 | 0 | 10 | // x -> zero reported
asapersson68731192016-08-15 08:20:30522 const bool kIncludeEmptyIntervals = true;
523 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
524 const int kSample1 = 50; // 50 / 2 sec
525 const int kSample2 = 20; // 20 / 2 sec
526 RateCounter counter(&clock_, observer, kIncludeEmptyIntervals);
asapersson0dc337c2016-05-23 13:07:55527 counter.Add(kSample1);
asapersson81fe97b2016-10-07 06:39:15528 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 3 - 1);
asapersson0dc337c2016-05-23 13:07:55529 // Trigger process (sample included in next interval).
530 counter.Add(kSample2);
asapersson7df4dab2016-09-09 07:13:35531 // [0:1],[25:1], 2 intervals passed (1 without samples -> zero reported).
asapersson0dc337c2016-05-23 13:07:55532 EXPECT_EQ(2, observer->num_calls_);
asapersson7df4dab2016-09-09 07:13:35533 EXPECT_EQ(0, observer->last_sample_);
534 // Make last interval pass and verify stats: [0:1],[10:1],[25:1]
asapersson0dc337c2016-05-23 13:07:55535 clock_.AdvanceTimeMilliseconds(1);
asapersson7df4dab2016-09-09 07:13:35536 AggregatedStats stats = counter.ProcessAndGetStats();
537 EXPECT_EQ(25, stats.max);
asapersson0dc337c2016-05-23 13:07:55538 EXPECT_EQ(3, observer->num_calls_);
539 EXPECT_EQ(10, observer->last_sample_);
asapersson7df4dab2016-09-09 07:13:35540}
541
542TEST_F(StatsCounterTest, TestRateAccCounter_IntervalsWithoutSamplesIncluded) {
543 // Samples: | 12 | x | x | x | 60 | // x: empty interval
544 // Stats: | 6 | 0 | 0 | 0 | 24 | // x -> zero reported
545 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
546 RateAccCounter counter(&clock_, observer, true);
547 VerifyStatsIsNotSet(counter.ProcessAndGetStats());
548 // Advance one interval and verify stats.
asapersson81fe97b2016-10-07 06:39:15549 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs);
asapersson7df4dab2016-09-09 07:13:35550 VerifyStatsIsNotSet(counter.ProcessAndGetStats());
551 // Add sample and advance 3 intervals (2 w/o samples -> zero reported).
asapersson77138d42016-11-01 07:21:34552 counter.Set(12, kStreamId);
asapersson81fe97b2016-10-07 06:39:15553 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 4 - 1);
asapersson7df4dab2016-09-09 07:13:35554 // Trigger process and verify stats: [0:2][6:1]
555 counter.ProcessAndGetStats();
556 EXPECT_EQ(3, observer->num_calls_);
557 EXPECT_EQ(0, observer->last_sample_);
558 // Make next interval pass (1 w/o samples -> zero reported), [0:3][6:1]
559 clock_.AdvanceTimeMilliseconds(1);
560 counter.ProcessAndGetStats();
561 EXPECT_EQ(4, observer->num_calls_);
562 EXPECT_EQ(0, observer->last_sample_);
563 // Insert sample and advance non-complete interval, no change, [0:3][6:1]
asapersson81fe97b2016-10-07 06:39:15564 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs - 1);
asapersson77138d42016-11-01 07:21:34565 counter.Set(60, kStreamId);
asapersson7df4dab2016-09-09 07:13:35566 EXPECT_EQ(4, observer->num_calls_);
567 // Make next interval pass, [0:3][6:1][24:1]
568 clock_.AdvanceTimeMilliseconds(1);
569 AggregatedStats stats = counter.ProcessAndGetStats();
570 EXPECT_EQ(5, observer->num_calls_);
571 EXPECT_EQ(24, observer->last_sample_);
572 EXPECT_EQ(6, stats.average);
573}
574
575TEST_F(StatsCounterTest, TestRateAccCounter_IntervalsWithoutSamplesIgnored) {
576 // Samples: | 12 | x | x | x | 60 | // x: empty interval
577 // Stats: | 6 | x | x | x | 24 | // x -> ignored
578 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl();
579 RateAccCounter counter(&clock_, observer, false);
580 // Add sample and advance 3 intervals (2 w/o samples -> ignored).
asapersson77138d42016-11-01 07:21:34581 counter.Set(12, kStreamId);
asapersson81fe97b2016-10-07 06:39:15582 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 4 - 1);
asapersson7df4dab2016-09-09 07:13:35583 // Trigger process and verify stats: [6:1]
584 counter.ProcessAndGetStats();
585 EXPECT_EQ(1, observer->num_calls_);
586 EXPECT_EQ(6, observer->last_sample_);
587 // Make next interval pass (1 w/o samples -> ignored), [6:1]
588 clock_.AdvanceTimeMilliseconds(1);
589 counter.ProcessAndGetStats();
590 EXPECT_EQ(1, observer->num_calls_);
591 // Insert sample and advance non-complete interval, no change, [6:1]
asapersson81fe97b2016-10-07 06:39:15592 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs - 1);
asapersson77138d42016-11-01 07:21:34593 counter.Set(60, kStreamId);
asapersson7df4dab2016-09-09 07:13:35594 counter.ProcessAndGetStats();
595 EXPECT_EQ(1, observer->num_calls_);
596 // Make next interval pass, [6:1][24:1]
597 clock_.AdvanceTimeMilliseconds(1);
598 counter.ProcessAndGetStats();
599 EXPECT_EQ(2, observer->num_calls_);
600 EXPECT_EQ(24, observer->last_sample_);
asapersson0dc337c2016-05-23 13:07:55601}
602
603} // namespace webrtc