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

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: rebase 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 StatsCounter::AggStats::Stats& 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 StatsCounter::AggStats::Stats 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 StatsCounter::AggStats::Stats 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_PercentCounter) {
123 PercentCounter counter(&clock_, observer_);
124 counter.Add(true);
125 counter.Add(false);
126 clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
127 // Trigger process (sample included in next interval).
128 counter.Add(false);
129 // Percentage per interval.
130 EXPECT_EQ(1, observer_->num_calls_);
131 EXPECT_EQ(50, observer_->last_sample_);
132 // Aggregated stats.
133 StatsCounter::AggStats::Stats stats = counter.GetStats();
134 EXPECT_EQ(1, stats.num_samples);
135 EXPECT_EQ(50, stats.min);
136 EXPECT_EQ(50, stats.max);
137 }
138
139 TEST_F(StatsCounterTest, TestMetric_PermilleCounter) {
140 PermilleCounter counter(&clock_, observer_);
141 counter.Add(true);
142 counter.Add(false);
143 clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
144 // Trigger process (sample included in next interval).
145 counter.Add(false);
146 // Permille per interval.
147 EXPECT_EQ(1, observer_->num_calls_);
148 EXPECT_EQ(500, observer_->last_sample_);
149 // Aggregated stats.
150 StatsCounter::AggStats::Stats stats = counter.GetStats();
151 EXPECT_EQ(1, stats.num_samples);
152 EXPECT_EQ(500, stats.min);
153 EXPECT_EQ(500, stats.max);
154 }
155
156 TEST_F(StatsCounterTest, TestMetric_RateCounter) {
157 RateCounter counter(&clock_, observer_);
158 counter.Add(186);
159 counter.Add(350);
160 counter.Add(22);
161 clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
162 // Trigger process (sample included in next interval).
163 counter.Add(111);
164 // Rate per interval, (186 + 350 + 22) / 2 sec = 279 samples/sec
165 EXPECT_EQ(1, observer_->num_calls_);
166 EXPECT_EQ(279, observer_->last_sample_);
167 // Aggregated stats.
168 StatsCounter::AggStats::Stats stats = counter.GetStats();
169 EXPECT_EQ(1, stats.num_samples);
170 EXPECT_EQ(279, stats.min);
171 EXPECT_EQ(279, stats.max);
172 }
173
174 TEST_F(StatsCounterTest, TestMetric_RateAccCounter) {
175 RateAccCounter counter(&clock_, observer_);
176 counter.Set(175);
177 counter.Set(188);
178 clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
179 // Trigger process (sample included in next interval).
180 counter.Set(192);
181 // Rate per interval: (188 - 0) / 2 sec = 94 samples/sec
182 EXPECT_EQ(1, observer_->num_calls_);
183 EXPECT_EQ(94, observer_->last_sample_);
184 // Aggregated stats.
185 StatsCounter::AggStats::Stats stats = counter.GetStats();
186 EXPECT_EQ(1, stats.num_samples);
187 EXPECT_EQ(94, stats.min);
188 EXPECT_EQ(94, stats.max);
189 }
190
191 TEST_F(StatsCounterTest, TestGetStats_MultipleIntervals) {
192 AvgCounter counter(&clock_, nullptr);
193 const int kSample1 = 1;
194 const int kSample2 = 5;
195 const int kSample3 = 8;
196 const int kSample4 = 11;
197 const int kSample5 = 50;
198 AddSampleAndAdvance(kSample1, kProcessIntervalMs, &counter);
199 AddSampleAndAdvance(kSample2, kProcessIntervalMs, &counter);
200 AddSampleAndAdvance(kSample3, kProcessIntervalMs, &counter);
201 AddSampleAndAdvance(kSample4, kProcessIntervalMs, &counter);
202 AddSampleAndAdvance(kSample5, kProcessIntervalMs, &counter);
203 // Trigger process (sample included in next interval).
204 counter.Add(111);
205 StatsCounter::AggStats::Stats stats = counter.GetStats();
206 EXPECT_EQ(5, stats.num_samples);
207 EXPECT_EQ(kSample1, stats.min);
208 EXPECT_EQ(kSample5, stats.max);
209 EXPECT_EQ(15, stats.average);
210 }
211
212 TEST_F(StatsCounterTest, TestGetStatsTwice) {
213 const int kSample1 = 4;
214 const int kSample2 = 7;
215 AvgCounter counter(&clock_, nullptr);
216 AddSampleAndAdvance(kSample1, kProcessIntervalMs, &counter);
217 // Trigger process (sample included in next interval).
218 counter.Add(kSample2);
219 StatsCounter::AggStats::Stats stats = counter.GetStats();
220 EXPECT_EQ(1, stats.num_samples);
221 EXPECT_EQ(kSample1, stats.min);
222 EXPECT_EQ(kSample1, stats.max);
223 // Trigger process (sample included in next interval).
224 clock_.AdvanceTimeMilliseconds(kProcessIntervalMs);
225 counter.Add(111);
226 stats = counter.GetStats();
227 EXPECT_EQ(2, stats.num_samples);
228 EXPECT_EQ(kSample1, stats.min);
229 EXPECT_EQ(kSample2, stats.max);
230 EXPECT_EQ(6, stats.average);
231 }
232
233 TEST_F(StatsCounterTest, TestRateAccCounter_NegativeRateIgnored) {
234 const int kSample1 = 200; // 200 / 2 sec
235 const int kSample2 = 100; // -100 / 2 sec - negative ignored
236 const int kSample3 = 700; // 600 / 2 sec
237 RateAccCounter counter(&clock_, observer_);
238 SetSampleAndAdvance(kSample1, kProcessIntervalMs, &counter);
239 SetSampleAndAdvance(kSample2, kProcessIntervalMs, &counter);
240 SetSampleAndAdvance(kSample3, kProcessIntervalMs, &counter);
241 EXPECT_EQ(1, observer_->num_calls_);
242 EXPECT_EQ(100, observer_->last_sample_);
243 // Trigger process (sample included in next interval).
244 counter.Set(2000);
245 EXPECT_EQ(2, observer_->num_calls_);
246 EXPECT_EQ(300, observer_->last_sample_);
247 // Aggregated stats.
248 StatsCounter::AggStats::Stats stats = counter.GetStats();
249 EXPECT_EQ(2, stats.num_samples);
250 EXPECT_EQ(100, stats.min);
251 EXPECT_EQ(300, stats.max);
252 EXPECT_EQ(200, stats.average);
253 }
254
255 TEST_F(StatsCounterTest, TestAvgCounter_IntervalsWithoutSamplesIgnored) {
256 AvgCounter counter(&clock_, observer_);
257 AddSampleAndAdvance(6, kProcessIntervalMs * 4 - 1, &counter);
258 // Trigger process (sample included in next interval).
259 counter.Add(8);
260 // [6:1], two intervals without samples passed.
261 EXPECT_EQ(1, observer_->num_calls_);
262 EXPECT_EQ(6, observer_->last_sample_);
263 // Make last interval pass.
264 clock_.AdvanceTimeMilliseconds(1);
265 counter.Add(111); // Trigger process (sample included in next interval).
266 // [6:1],[8:1]
267 EXPECT_EQ(2, observer_->num_calls_);
268 EXPECT_EQ(8, observer_->last_sample_);
269 // Aggregated stats.
270 StatsCounter::AggStats::Stats stats = counter.GetStats();
271 EXPECT_EQ(2, stats.num_samples);
272 EXPECT_EQ(6, stats.min);
273 EXPECT_EQ(8, stats.max);
274 }
275
276 TEST_F(StatsCounterTest, TestRateCounter_IntervalsWithoutSamplesIncluded) {
277 const int kSample1 = 50; // 50 / 2 sec
278 const int kSample2 = 20; // 20 / 2 sec
279 RateCounter counter(&clock_, observer_);
280 counter.Add(kSample1);
281 clock_.AdvanceTimeMilliseconds(kProcessIntervalMs * 3 - 1);
282 // Trigger process (sample included in next interval).
283 counter.Add(kSample2);
284 // [0:1],[25:1], one interval without samples passed.
285 EXPECT_EQ(2, observer_->num_calls_);
286 EXPECT_EQ(25, observer_->last_sample_);
287 // Make last interval pass.
288 clock_.AdvanceTimeMilliseconds(1);
289 counter.Add(111); // Trigger process (sample included in next interval).
290 // [0:1],[10:1],[25:1]
291 EXPECT_EQ(3, observer_->num_calls_);
292 EXPECT_EQ(10, observer_->last_sample_);
293 // Aggregated stats.
294 StatsCounter::AggStats::Stats stats = counter.GetStats();
295 EXPECT_EQ(3, stats.num_samples);
296 EXPECT_EQ(0, stats.min);
297 EXPECT_EQ(25, stats.max);
298 }
299
300 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698