Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(143)

Side by Side Diff: webrtc/video/stats_counter_unittest.cc

Issue 1640053003: Add class which periodically computes statistics. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: add MaxCounter Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
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
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 #include "webrtc/system_wrappers/include/clock.h"
16
17 namespace webrtc {
18 namespace {
19 const int kProcessIntervalMs = 2000;
20
21 class 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
33 class StatsCounterTest : public ::testing::Test {
34 protected:
35 StatsCounterTest()
36 : clock_(1234), observer_(new StatsCounterObserverImpl()) {}
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) {
46 counter->Set(sample);
47 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 StatsCounterObserverImpl* observer_;
59 };
60
61 TEST_F(StatsCounterTest, NoSamples) {
62 AvgCounter counter(&clock_, nullptr);
63 VerifyStatsIsNotSet(counter.GetStats());
64 }
65
66 TEST_F(StatsCounterTest, TestRegisterObserver) {
67 const int kSample = 22;
68 AvgCounter counter(&clock_, observer_);
69 AddSampleAndAdvance(kSample, kProcessIntervalMs, &counter);
70 // Trigger process (sample included in next interval).
71 counter.Add(111);
72 EXPECT_EQ(1, observer_->num_calls_);
73 }
74
75 TEST_F(StatsCounterTest, TestNoObserver) {
76 const int kSample = 22;
77 AvgCounter counter(&clock_, nullptr);
78 AddSampleAndAdvance(kSample, kProcessIntervalMs, &counter);
79 // Trigger process (sample included in next interval).
80 counter.Add(111);
81 EXPECT_EQ(0, observer_->num_calls_);
82 }
83
84 TEST_F(StatsCounterTest, VerifyProcessInterval) {
85 AvgCounter counter(&clock_, observer_);
86 counter.Add(4);
87 clock_.AdvanceTimeMilliseconds(kProcessIntervalMs - 1);
88 // Try trigger process (interval has not passed).
89 counter.Add(8);
90 EXPECT_EQ(0, observer_->num_calls_);
91 VerifyStatsIsNotSet(counter.GetStats());
92 // Make process interval pass.
93 clock_.AdvanceTimeMilliseconds(1);
94 // Trigger process (sample included in next interval).
95 counter.Add(111);
96 EXPECT_EQ(1, observer_->num_calls_);
97 EXPECT_EQ(6, observer_->last_sample_);
98 // Aggregated stats.
99 AggregatedStats stats = counter.GetStats();
100 EXPECT_EQ(1, stats.num_samples);
101 }
102
103 TEST_F(StatsCounterTest, TestMetric_AvgCounter) {
104 AvgCounter counter(&clock_, observer_);
105 counter.Add(4);
106 counter.Add(8);
107 counter.Add(9);
108 clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
109 // 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
122 TEST_F(StatsCounterTest, TestMetric_MaxCounter) {
123 MaxCounter counter(&clock_, observer_);
124 counter.Add(4);
125 counter.Add(9);
126 counter.Add(8);
127 clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
128 // Trigger process (sample included in next interval).
129 counter.Add(111);
130 // Average per interval.
131 EXPECT_EQ(1, observer_->num_calls_);
132 EXPECT_EQ(9, observer_->last_sample_);
133 // Aggregated stats.
134 AggregatedStats stats = counter.GetStats();
135 EXPECT_EQ(1, stats.num_samples);
136 EXPECT_EQ(9, stats.min);
137 EXPECT_EQ(9, stats.max);
138 EXPECT_EQ(9, stats.average);
139 }
140
141 TEST_F(StatsCounterTest, TestMetric_PercentCounter) {
142 PercentCounter counter(&clock_, observer_);
143 counter.Add(true);
144 counter.Add(false);
145 clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
146 // Trigger process (sample included in next interval).
147 counter.Add(false);
148 // Percentage per interval.
149 EXPECT_EQ(1, observer_->num_calls_);
150 EXPECT_EQ(50, observer_->last_sample_);
151 // Aggregated stats.
152 AggregatedStats stats = counter.GetStats();
153 EXPECT_EQ(1, stats.num_samples);
154 EXPECT_EQ(50, stats.min);
155 EXPECT_EQ(50, stats.max);
156 }
157
158 TEST_F(StatsCounterTest, TestMetric_PermilleCounter) {
159 PermilleCounter counter(&clock_, observer_);
160 counter.Add(true);
161 counter.Add(false);
162 clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
163 // Trigger process (sample included in next interval).
164 counter.Add(false);
165 // Permille per interval.
166 EXPECT_EQ(1, observer_->num_calls_);
167 EXPECT_EQ(500, observer_->last_sample_);
168 // Aggregated stats.
169 AggregatedStats stats = counter.GetStats();
170 EXPECT_EQ(1, stats.num_samples);
171 EXPECT_EQ(500, stats.min);
172 EXPECT_EQ(500, stats.max);
173 }
174
175 TEST_F(StatsCounterTest, TestMetric_RateCounter) {
176 RateCounter counter(&clock_, observer_);
177 counter.Add(186);
178 counter.Add(350);
179 counter.Add(22);
180 clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
181 // Trigger process (sample included in next interval).
182 counter.Add(111);
183 // Rate per interval, (186 + 350 + 22) / 2 sec = 279 samples/sec
184 EXPECT_EQ(1, observer_->num_calls_);
185 EXPECT_EQ(279, observer_->last_sample_);
186 // Aggregated stats.
187 AggregatedStats stats = counter.GetStats();
188 EXPECT_EQ(1, stats.num_samples);
189 EXPECT_EQ(279, stats.min);
190 EXPECT_EQ(279, stats.max);
191 }
192
193 TEST_F(StatsCounterTest, TestMetric_RateAccCounter) {
194 RateAccCounter counter(&clock_, observer_);
195 counter.Set(175);
196 counter.Set(188);
197 clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
198 // Trigger process (sample included in next interval).
199 counter.Set(192);
200 // Rate per interval: (188 - 0) / 2 sec = 94 samples/sec
201 EXPECT_EQ(1, observer_->num_calls_);
202 EXPECT_EQ(94, observer_->last_sample_);
203 // Aggregated stats.
204 AggregatedStats stats = counter.GetStats();
205 EXPECT_EQ(1, stats.num_samples);
206 EXPECT_EQ(94, stats.min);
207 EXPECT_EQ(94, stats.max);
208 }
209
210 TEST_F(StatsCounterTest, TestGetStats_MultipleIntervals) {
211 AvgCounter counter(&clock_, nullptr);
212 const int kSample1 = 1;
213 const int kSample2 = 5;
214 const int kSample3 = 8;
215 const int kSample4 = 11;
216 const int kSample5 = 50;
217 AddSampleAndAdvance(kSample1, kProcessIntervalMs, &counter);
218 AddSampleAndAdvance(kSample2, kProcessIntervalMs, &counter);
219 AddSampleAndAdvance(kSample3, kProcessIntervalMs, &counter);
220 AddSampleAndAdvance(kSample4, kProcessIntervalMs, &counter);
221 AddSampleAndAdvance(kSample5, kProcessIntervalMs, &counter);
222 // Trigger process (sample included in next interval).
223 counter.Add(111);
224 AggregatedStats stats = counter.GetStats();
225 EXPECT_EQ(5, stats.num_samples);
226 EXPECT_EQ(kSample1, stats.min);
227 EXPECT_EQ(kSample5, stats.max);
228 EXPECT_EQ(15, stats.average);
229 }
230
231 TEST_F(StatsCounterTest, TestGetStatsTwice) {
232 const int kSample1 = 4;
233 const int kSample2 = 7;
234 AvgCounter counter(&clock_, nullptr);
235 AddSampleAndAdvance(kSample1, kProcessIntervalMs, &counter);
236 // Trigger process (sample included in next interval).
237 counter.Add(kSample2);
238 AggregatedStats stats = counter.GetStats();
239 EXPECT_EQ(1, stats.num_samples);
240 EXPECT_EQ(kSample1, stats.min);
241 EXPECT_EQ(kSample1, stats.max);
242 // Trigger process (sample included in next interval).
243 clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
244 counter.Add(111);
245 stats = counter.GetStats();
246 EXPECT_EQ(2, stats.num_samples);
247 EXPECT_EQ(kSample1, stats.min);
248 EXPECT_EQ(kSample2, stats.max);
249 EXPECT_EQ(6, stats.average);
250 }
251
252 TEST_F(StatsCounterTest, TestRateAccCounter_NegativeRateIgnored) {
253 const int kSample1 = 200; // 200 / 2 sec
254 const int kSample2 = 100; // -100 / 2 sec - negative ignored
255 const int kSample3 = 700; // 600 / 2 sec
256 RateAccCounter counter(&clock_, observer_);
257 SetSampleAndAdvance(kSample1, kProcessIntervalMs, &counter);
258 SetSampleAndAdvance(kSample2, kProcessIntervalMs, &counter);
259 SetSampleAndAdvance(kSample3, kProcessIntervalMs, &counter);
260 EXPECT_EQ(1, observer_->num_calls_);
261 EXPECT_EQ(100, observer_->last_sample_);
262 // Trigger process (sample included in next interval).
263 counter.Set(2000);
264 EXPECT_EQ(2, observer_->num_calls_);
265 EXPECT_EQ(300, observer_->last_sample_);
266 // Aggregated stats.
267 AggregatedStats stats = counter.GetStats();
268 EXPECT_EQ(2, stats.num_samples);
269 EXPECT_EQ(100, stats.min);
270 EXPECT_EQ(300, stats.max);
271 EXPECT_EQ(200, stats.average);
272 }
273
274 TEST_F(StatsCounterTest, TestAvgCounter_IntervalsWithoutSamplesIgnored) {
275 AvgCounter counter(&clock_, observer_);
276 AddSampleAndAdvance(6, kProcessIntervalMs * 4 - 1, &counter);
277 // Trigger process (sample included in next interval).
278 counter.Add(8);
279 // [6:1], two intervals without samples passed.
280 EXPECT_EQ(1, observer_->num_calls_);
281 EXPECT_EQ(6, observer_->last_sample_);
282 // Make last interval pass.
283 clock_.AdvanceTimeMilliseconds(1);
284 counter.Add(111); // Trigger process (sample included in next interval).
285 // [6:1],[8:1]
286 EXPECT_EQ(2, observer_->num_calls_);
287 EXPECT_EQ(8, observer_->last_sample_);
288 // Aggregated stats.
289 AggregatedStats stats = counter.GetStats();
290 EXPECT_EQ(2, stats.num_samples);
291 EXPECT_EQ(6, stats.min);
292 EXPECT_EQ(8, stats.max);
293 }
294
295 TEST_F(StatsCounterTest, TestRateCounter_IntervalsWithoutSamplesIncluded) {
296 const int kSample1 = 50; // 50 / 2 sec
297 const int kSample2 = 20; // 20 / 2 sec
298 RateCounter counter(&clock_, observer_);
299 counter.Add(kSample1);
300 clock_.AdvanceTimeMilliseconds(kProcessIntervalMs * 3 - 1);
301 // Trigger process (sample included in next interval).
302 counter.Add(kSample2);
303 // [0:1],[25:1], one interval without samples passed.
304 EXPECT_EQ(2, observer_->num_calls_);
305 EXPECT_EQ(25, observer_->last_sample_);
306 // Make last interval pass.
307 clock_.AdvanceTimeMilliseconds(1);
308 counter.Add(111); // Trigger process (sample included in next interval).
309 // [0:1],[10:1],[25:1]
310 EXPECT_EQ(3, observer_->num_calls_);
311 EXPECT_EQ(10, observer_->last_sample_);
312 // Aggregated stats.
313 AggregatedStats stats = counter.GetStats();
314 EXPECT_EQ(3, stats.num_samples);
315 EXPECT_EQ(0, stats.min);
316 EXPECT_EQ(25, stats.max);
317 }
318
319 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698