OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include "webrtc/video/stats_counter.h" | 11 #include "webrtc/video/stats_counter.h" |
12 | 12 |
13 #include "webrtc/system_wrappers/include/clock.h" | 13 #include "webrtc/system_wrappers/include/clock.h" |
14 #include "webrtc/test/gtest.h" | 14 #include "webrtc/test/gtest.h" |
15 | 15 |
16 namespace webrtc { | 16 namespace webrtc { |
17 namespace { | 17 namespace { |
18 const int kDefaultProcessIntervalMs = 2000; | 18 const int kDefaultProcessIntervalMs = 2000; |
| 19 const uint32_t kStreamId = 123456; |
19 | 20 |
20 class StatsCounterObserverImpl : public StatsCounterObserver { | 21 class StatsCounterObserverImpl : public StatsCounterObserver { |
21 public: | 22 public: |
22 StatsCounterObserverImpl() : num_calls_(0), last_sample_(-1) {} | 23 StatsCounterObserverImpl() : num_calls_(0), last_sample_(-1) {} |
23 void OnMetricUpdated(int sample) override { | 24 void OnMetricUpdated(int sample) override { |
24 ++num_calls_; | 25 ++num_calls_; |
25 last_sample_ = sample; | 26 last_sample_ = sample; |
26 } | 27 } |
27 int num_calls_; | 28 int num_calls_; |
28 int last_sample_; | 29 int last_sample_; |
29 }; | 30 }; |
30 } // namespace | 31 } // namespace |
31 | 32 |
32 class StatsCounterTest : public ::testing::Test { | 33 class StatsCounterTest : public ::testing::Test { |
33 protected: | 34 protected: |
34 StatsCounterTest() | 35 StatsCounterTest() |
35 : clock_(1234) {} | 36 : clock_(1234) {} |
36 | 37 |
37 void AddSampleAndAdvance(int sample, int interval_ms, AvgCounter* counter) { | 38 void AddSampleAndAdvance(int sample, int interval_ms, AvgCounter* counter) { |
38 counter->Add(sample); | 39 counter->Add(sample); |
39 clock_.AdvanceTimeMilliseconds(interval_ms); | 40 clock_.AdvanceTimeMilliseconds(interval_ms); |
40 } | 41 } |
41 | 42 |
42 void SetSampleAndAdvance(int sample, | 43 void SetSampleAndAdvance(int sample, |
43 int interval_ms, | 44 int interval_ms, |
44 RateAccCounter* counter) { | 45 RateAccCounter* counter) { |
45 counter->Set(sample); | 46 counter->Set(sample, kStreamId); |
46 clock_.AdvanceTimeMilliseconds(interval_ms); | 47 clock_.AdvanceTimeMilliseconds(interval_ms); |
47 } | 48 } |
48 | 49 |
49 void VerifyStatsIsNotSet(const AggregatedStats& stats) { | 50 void VerifyStatsIsNotSet(const AggregatedStats& stats) { |
50 EXPECT_EQ(0, stats.num_samples); | 51 EXPECT_EQ(0, stats.num_samples); |
51 EXPECT_EQ(-1, stats.min); | 52 EXPECT_EQ(-1, stats.min); |
52 EXPECT_EQ(-1, stats.max); | 53 EXPECT_EQ(-1, stats.max); |
53 EXPECT_EQ(-1, stats.average); | 54 EXPECT_EQ(-1, stats.average); |
54 } | 55 } |
55 | 56 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 // Aggregated stats. | 191 // Aggregated stats. |
191 AggregatedStats stats = counter.GetStats(); | 192 AggregatedStats stats = counter.GetStats(); |
192 EXPECT_EQ(1, stats.num_samples); | 193 EXPECT_EQ(1, stats.num_samples); |
193 EXPECT_EQ(279, stats.min); | 194 EXPECT_EQ(279, stats.min); |
194 EXPECT_EQ(279, stats.max); | 195 EXPECT_EQ(279, stats.max); |
195 } | 196 } |
196 | 197 |
197 TEST_F(StatsCounterTest, TestMetric_RateAccCounter) { | 198 TEST_F(StatsCounterTest, TestMetric_RateAccCounter) { |
198 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl(); | 199 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl(); |
199 RateAccCounter counter(&clock_, observer, true); | 200 RateAccCounter counter(&clock_, observer, true); |
200 counter.Set(175); | 201 counter.Set(175, kStreamId); |
201 counter.Set(188); | 202 counter.Set(188, kStreamId); |
202 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs); | 203 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs); |
203 // Trigger process (sample included in next interval). | 204 // Trigger process (sample included in next interval). |
204 counter.Set(192); | 205 counter.Set(192, kStreamId); |
205 // Rate per interval: (188 - 0) / 2 sec = 94 samples/sec | 206 // Rate per interval: (188 - 0) / 2 sec = 94 samples/sec |
206 EXPECT_EQ(1, observer->num_calls_); | 207 EXPECT_EQ(1, observer->num_calls_); |
207 EXPECT_EQ(94, observer->last_sample_); | 208 EXPECT_EQ(94, observer->last_sample_); |
208 // Aggregated stats. | 209 // Aggregated stats. |
209 AggregatedStats stats = counter.GetStats(); | 210 AggregatedStats stats = counter.GetStats(); |
210 EXPECT_EQ(1, stats.num_samples); | 211 EXPECT_EQ(1, stats.num_samples); |
211 EXPECT_EQ(94, stats.min); | 212 EXPECT_EQ(94, stats.min); |
212 EXPECT_EQ(94, stats.max); | 213 EXPECT_EQ(94, stats.max); |
213 } | 214 } |
214 | 215 |
| 216 TEST_F(StatsCounterTest, TestMetric_RateAccCounterWithMultipleStreamIds) { |
| 217 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl(); |
| 218 RateAccCounter counter(&clock_, observer, true); |
| 219 counter.Set(175, kStreamId); |
| 220 counter.Set(188, kStreamId); |
| 221 counter.Set(100, kStreamId + 1); |
| 222 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs); |
| 223 // Trigger process (sample included in next interval). |
| 224 counter.Set(150, kStreamId + 1); |
| 225 // Rate per interval: ((188 - 0) + (100 - 0)) / 2 sec = 144 samples/sec |
| 226 EXPECT_EQ(1, observer->num_calls_); |
| 227 EXPECT_EQ(144, observer->last_sample_); |
| 228 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs); |
| 229 // Trigger process (sample included in next interval). |
| 230 counter.Set(198, kStreamId); |
| 231 // Rate per interval: (0 + (150 - 100)) / 2 sec = 25 samples/sec |
| 232 EXPECT_EQ(2, observer->num_calls_); |
| 233 EXPECT_EQ(25, observer->last_sample_); |
| 234 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs); |
| 235 // Trigger process (sample included in next interval). |
| 236 counter.Set(200, kStreamId); |
| 237 // Rate per interval: ((198 - 188) + (0)) / 2 sec = 5 samples/sec |
| 238 EXPECT_EQ(3, observer->num_calls_); |
| 239 EXPECT_EQ(5, observer->last_sample_); |
| 240 // Aggregated stats. |
| 241 AggregatedStats stats = counter.GetStats(); |
| 242 EXPECT_EQ(3, stats.num_samples); |
| 243 EXPECT_EQ(5, stats.min); |
| 244 EXPECT_EQ(144, stats.max); |
| 245 } |
| 246 |
215 TEST_F(StatsCounterTest, TestGetStats_MultipleIntervals) { | 247 TEST_F(StatsCounterTest, TestGetStats_MultipleIntervals) { |
216 AvgCounter counter(&clock_, nullptr, false); | 248 AvgCounter counter(&clock_, nullptr, false); |
217 const int kSample1 = 1; | 249 const int kSample1 = 1; |
218 const int kSample2 = 5; | 250 const int kSample2 = 5; |
219 const int kSample3 = 8; | 251 const int kSample3 = 8; |
220 const int kSample4 = 11; | 252 const int kSample4 = 11; |
221 const int kSample5 = 50; | 253 const int kSample5 = 50; |
222 AddSampleAndAdvance(kSample1, kDefaultProcessIntervalMs, &counter); | 254 AddSampleAndAdvance(kSample1, kDefaultProcessIntervalMs, &counter); |
223 AddSampleAndAdvance(kSample2, kDefaultProcessIntervalMs, &counter); | 255 AddSampleAndAdvance(kSample2, kDefaultProcessIntervalMs, &counter); |
224 AddSampleAndAdvance(kSample3, kDefaultProcessIntervalMs, &counter); | 256 AddSampleAndAdvance(kSample3, kDefaultProcessIntervalMs, &counter); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 const int kSample1 = 200; // 200 / 2 sec | 291 const int kSample1 = 200; // 200 / 2 sec |
260 const int kSample2 = 100; // -100 / 2 sec - negative ignored | 292 const int kSample2 = 100; // -100 / 2 sec - negative ignored |
261 const int kSample3 = 700; // 600 / 2 sec | 293 const int kSample3 = 700; // 600 / 2 sec |
262 RateAccCounter counter(&clock_, observer, true); | 294 RateAccCounter counter(&clock_, observer, true); |
263 SetSampleAndAdvance(kSample1, kDefaultProcessIntervalMs, &counter); | 295 SetSampleAndAdvance(kSample1, kDefaultProcessIntervalMs, &counter); |
264 SetSampleAndAdvance(kSample2, kDefaultProcessIntervalMs, &counter); | 296 SetSampleAndAdvance(kSample2, kDefaultProcessIntervalMs, &counter); |
265 SetSampleAndAdvance(kSample3, kDefaultProcessIntervalMs, &counter); | 297 SetSampleAndAdvance(kSample3, kDefaultProcessIntervalMs, &counter); |
266 EXPECT_EQ(1, observer->num_calls_); | 298 EXPECT_EQ(1, observer->num_calls_); |
267 EXPECT_EQ(100, observer->last_sample_); | 299 EXPECT_EQ(100, observer->last_sample_); |
268 // Trigger process (sample included in next interval). | 300 // Trigger process (sample included in next interval). |
269 counter.Set(2000); | 301 counter.Set(2000, kStreamId); |
270 EXPECT_EQ(2, observer->num_calls_); | 302 EXPECT_EQ(2, observer->num_calls_); |
271 EXPECT_EQ(300, observer->last_sample_); | 303 EXPECT_EQ(300, observer->last_sample_); |
272 // Aggregated stats. | 304 // Aggregated stats. |
273 AggregatedStats stats = counter.GetStats(); | 305 AggregatedStats stats = counter.GetStats(); |
274 EXPECT_EQ(2, stats.num_samples); | 306 EXPECT_EQ(2, stats.num_samples); |
275 EXPECT_EQ(100, stats.min); | 307 EXPECT_EQ(100, stats.min); |
276 EXPECT_EQ(300, stats.max); | 308 EXPECT_EQ(300, stats.max); |
277 EXPECT_EQ(200, stats.average); | 309 EXPECT_EQ(200, stats.average); |
278 } | 310 } |
279 | 311 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 TEST_F(StatsCounterTest, TestRateAccCounter_IntervalsWithoutSamplesIncluded) { | 411 TEST_F(StatsCounterTest, TestRateAccCounter_IntervalsWithoutSamplesIncluded) { |
380 // Samples: | 12 | x | x | x | 60 | // x: empty interval | 412 // Samples: | 12 | x | x | x | 60 | // x: empty interval |
381 // Stats: | 6 | 0 | 0 | 0 | 24 | // x -> zero reported | 413 // Stats: | 6 | 0 | 0 | 0 | 24 | // x -> zero reported |
382 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl(); | 414 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl(); |
383 RateAccCounter counter(&clock_, observer, true); | 415 RateAccCounter counter(&clock_, observer, true); |
384 VerifyStatsIsNotSet(counter.ProcessAndGetStats()); | 416 VerifyStatsIsNotSet(counter.ProcessAndGetStats()); |
385 // Advance one interval and verify stats. | 417 // Advance one interval and verify stats. |
386 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs); | 418 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs); |
387 VerifyStatsIsNotSet(counter.ProcessAndGetStats()); | 419 VerifyStatsIsNotSet(counter.ProcessAndGetStats()); |
388 // Add sample and advance 3 intervals (2 w/o samples -> zero reported). | 420 // Add sample and advance 3 intervals (2 w/o samples -> zero reported). |
389 counter.Set(12); | 421 counter.Set(12, kStreamId); |
390 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 4 - 1); | 422 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 4 - 1); |
391 // Trigger process and verify stats: [0:2][6:1] | 423 // Trigger process and verify stats: [0:2][6:1] |
392 counter.ProcessAndGetStats(); | 424 counter.ProcessAndGetStats(); |
393 EXPECT_EQ(3, observer->num_calls_); | 425 EXPECT_EQ(3, observer->num_calls_); |
394 EXPECT_EQ(0, observer->last_sample_); | 426 EXPECT_EQ(0, observer->last_sample_); |
395 // Make next interval pass (1 w/o samples -> zero reported), [0:3][6:1] | 427 // Make next interval pass (1 w/o samples -> zero reported), [0:3][6:1] |
396 clock_.AdvanceTimeMilliseconds(1); | 428 clock_.AdvanceTimeMilliseconds(1); |
397 counter.ProcessAndGetStats(); | 429 counter.ProcessAndGetStats(); |
398 EXPECT_EQ(4, observer->num_calls_); | 430 EXPECT_EQ(4, observer->num_calls_); |
399 EXPECT_EQ(0, observer->last_sample_); | 431 EXPECT_EQ(0, observer->last_sample_); |
400 // Insert sample and advance non-complete interval, no change, [0:3][6:1] | 432 // Insert sample and advance non-complete interval, no change, [0:3][6:1] |
401 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs - 1); | 433 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs - 1); |
402 counter.Set(60); | 434 counter.Set(60, kStreamId); |
403 EXPECT_EQ(4, observer->num_calls_); | 435 EXPECT_EQ(4, observer->num_calls_); |
404 // Make next interval pass, [0:3][6:1][24:1] | 436 // Make next interval pass, [0:3][6:1][24:1] |
405 clock_.AdvanceTimeMilliseconds(1); | 437 clock_.AdvanceTimeMilliseconds(1); |
406 AggregatedStats stats = counter.ProcessAndGetStats(); | 438 AggregatedStats stats = counter.ProcessAndGetStats(); |
407 EXPECT_EQ(5, observer->num_calls_); | 439 EXPECT_EQ(5, observer->num_calls_); |
408 EXPECT_EQ(24, observer->last_sample_); | 440 EXPECT_EQ(24, observer->last_sample_); |
409 EXPECT_EQ(6, stats.average); | 441 EXPECT_EQ(6, stats.average); |
410 } | 442 } |
411 | 443 |
412 TEST_F(StatsCounterTest, TestRateAccCounter_IntervalsWithoutSamplesIgnored) { | 444 TEST_F(StatsCounterTest, TestRateAccCounter_IntervalsWithoutSamplesIgnored) { |
413 // Samples: | 12 | x | x | x | 60 | // x: empty interval | 445 // Samples: | 12 | x | x | x | 60 | // x: empty interval |
414 // Stats: | 6 | x | x | x | 24 | // x -> ignored | 446 // Stats: | 6 | x | x | x | 24 | // x -> ignored |
415 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl(); | 447 StatsCounterObserverImpl* observer = new StatsCounterObserverImpl(); |
416 RateAccCounter counter(&clock_, observer, false); | 448 RateAccCounter counter(&clock_, observer, false); |
417 // Add sample and advance 3 intervals (2 w/o samples -> ignored). | 449 // Add sample and advance 3 intervals (2 w/o samples -> ignored). |
418 counter.Set(12); | 450 counter.Set(12, kStreamId); |
419 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 4 - 1); | 451 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs * 4 - 1); |
420 // Trigger process and verify stats: [6:1] | 452 // Trigger process and verify stats: [6:1] |
421 counter.ProcessAndGetStats(); | 453 counter.ProcessAndGetStats(); |
422 EXPECT_EQ(1, observer->num_calls_); | 454 EXPECT_EQ(1, observer->num_calls_); |
423 EXPECT_EQ(6, observer->last_sample_); | 455 EXPECT_EQ(6, observer->last_sample_); |
424 // Make next interval pass (1 w/o samples -> ignored), [6:1] | 456 // Make next interval pass (1 w/o samples -> ignored), [6:1] |
425 clock_.AdvanceTimeMilliseconds(1); | 457 clock_.AdvanceTimeMilliseconds(1); |
426 counter.ProcessAndGetStats(); | 458 counter.ProcessAndGetStats(); |
427 EXPECT_EQ(1, observer->num_calls_); | 459 EXPECT_EQ(1, observer->num_calls_); |
428 // Insert sample and advance non-complete interval, no change, [6:1] | 460 // Insert sample and advance non-complete interval, no change, [6:1] |
429 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs - 1); | 461 clock_.AdvanceTimeMilliseconds(kDefaultProcessIntervalMs - 1); |
430 counter.Set(60); | 462 counter.Set(60, kStreamId); |
431 counter.ProcessAndGetStats(); | 463 counter.ProcessAndGetStats(); |
432 EXPECT_EQ(1, observer->num_calls_); | 464 EXPECT_EQ(1, observer->num_calls_); |
433 // Make next interval pass, [6:1][24:1] | 465 // Make next interval pass, [6:1][24:1] |
434 clock_.AdvanceTimeMilliseconds(1); | 466 clock_.AdvanceTimeMilliseconds(1); |
435 counter.ProcessAndGetStats(); | 467 counter.ProcessAndGetStats(); |
436 EXPECT_EQ(2, observer->num_calls_); | 468 EXPECT_EQ(2, observer->num_calls_); |
437 EXPECT_EQ(24, observer->last_sample_); | 469 EXPECT_EQ(24, observer->last_sample_); |
438 } | 470 } |
439 | 471 |
440 } // namespace webrtc | 472 } // namespace webrtc |
OLD | NEW |