Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 /* | 1 /* | 
| 2 * Copyright 2016 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 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/api/rtcstatscollector.h" | 11 #include "webrtc/api/rtcstatscollector.h" | 
| 12 | 12 | 
| 13 #include <memory> | 13 #include <memory> | 
| 14 #include <string> | 14 #include <string> | 
| 15 #include <vector> | 15 #include <vector> | 
| 16 | 16 | 
| 17 #include "webrtc/api/jsepsessiondescription.h" | 17 #include "webrtc/api/jsepsessiondescription.h" | 
| 18 #include "webrtc/api/stats/rtcstats_objects.h" | 18 #include "webrtc/api/stats/rtcstats_objects.h" | 
| 19 #include "webrtc/api/stats/rtcstatsreport.h" | 19 #include "webrtc/api/stats/rtcstatsreport.h" | 
| 20 #include "webrtc/api/test/mock_datachannel.h" | 20 #include "webrtc/api/test/mock_datachannel.h" | 
| 21 #include "webrtc/api/test/mock_peerconnection.h" | 21 #include "webrtc/api/test/mock_peerconnection.h" | 
| 22 #include "webrtc/api/test/mock_webrtcsession.h" | 22 #include "webrtc/api/test/mock_webrtcsession.h" | 
| 23 #include "webrtc/base/checks.h" | 23 #include "webrtc/base/checks.h" | 
| 24 #include "webrtc/base/fakeclock.h" | 24 #include "webrtc/base/fakeclock.h" | 
| 25 #include "webrtc/base/fakesslidentity.h" | |
| 25 #include "webrtc/base/gunit.h" | 26 #include "webrtc/base/gunit.h" | 
| 26 #include "webrtc/base/logging.h" | 27 #include "webrtc/base/logging.h" | 
| 27 #include "webrtc/base/thread_checker.h" | 28 #include "webrtc/base/thread_checker.h" | 
| 28 #include "webrtc/base/timedelta.h" | 29 #include "webrtc/base/timedelta.h" | 
| 29 #include "webrtc/base/timeutils.h" | 30 #include "webrtc/base/timeutils.h" | 
| 30 #include "webrtc/media/base/fakemediaengine.h" | 31 #include "webrtc/media/base/fakemediaengine.h" | 
| 31 | 32 | 
| 33 using testing::_; | |
| 34 using testing::Invoke; | |
| 32 using testing::Return; | 35 using testing::Return; | 
| 33 using testing::ReturnRef; | 36 using testing::ReturnRef; | 
| 34 | 37 | 
| 35 namespace webrtc { | 38 namespace webrtc { | 
| 36 | 39 | 
| 37 namespace { | 40 namespace { | 
| 38 | 41 | 
| 39 const int64_t kGetStatsReportTimeoutMs = 1000; | 42 const int64_t kGetStatsReportTimeoutMs = 1000; | 
| 40 | 43 | 
| 44 struct CertificateInfo { | |
| 45 rtc::scoped_refptr<rtc::RTCCertificate> certificate; | |
| 46 std::vector<std::string> ders; | |
| 47 std::vector<std::string> pems; | |
| 48 std::vector<std::string> fingerprints; | |
| 49 }; | |
| 50 | |
| 51 std::unique_ptr<CertificateInfo> CreateFakeCertificateAndInfoFromDers( | |
| 52 const std::vector<std::string>& ders) { | |
| 53 RTC_CHECK(!ders.empty()); | |
| 54 std::unique_ptr<CertificateInfo> info(new CertificateInfo()); | |
| 55 info->ders = ders; | |
| 56 for (const std::string& der : ders) { | |
| 57 info->pems.push_back(rtc::SSLIdentity::DerToPem( | |
| 58 "CERTIFICATE", | |
| 59 reinterpret_cast<const unsigned char*>(der.c_str()), | |
| 60 der.length())); | |
| 61 } | |
| 62 info->certificate = | |
| 63 rtc::RTCCertificate::Create(std::unique_ptr<rtc::FakeSSLIdentity>( | |
| 64 new rtc::FakeSSLIdentity(rtc::FakeSSLCertificate(info->pems)))); | |
| 65 // Strip header/footer and newline characters of PEM strings. | |
| 66 for (size_t i = 0; i < info->pems.size(); ++i) { | |
| 67 rtc::replace_substrs("-----BEGIN CERTIFICATE-----", 27, | |
| 68 "", 0, &info->pems[i]); | |
| 69 rtc::replace_substrs("-----END CERTIFICATE-----", 25, | |
| 70 "", 0, &info->pems[i]); | |
| 71 rtc::replace_substrs("\n", 1, | |
| 72 "", 0, &info->pems[i]); | |
| 73 } | |
| 74 // Fingerprint of leaf certificate. | |
| 75 std::unique_ptr<rtc::SSLFingerprint> fp( | |
| 76 rtc::SSLFingerprint::Create("sha-1", | |
| 77 &info->certificate->ssl_certificate())); | |
| 78 EXPECT_TRUE(fp); | |
| 79 info->fingerprints.push_back(fp->GetRfc4572Fingerprint()); | |
| 80 // Fingerprints of the rest of the chain. | |
| 81 std::unique_ptr<rtc::SSLCertChain> chain = | |
| 82 info->certificate->ssl_certificate().GetChain(); | |
| 83 if (chain) { | |
| 84 for (size_t i = 0; i < chain->GetSize(); i++) { | |
| 85 fp.reset(rtc::SSLFingerprint::Create("sha-1", &chain->Get(i))); | |
| 86 EXPECT_TRUE(fp); | |
| 87 info->fingerprints.push_back(fp->GetRfc4572Fingerprint()); | |
| 88 } | |
| 89 } | |
| 90 EXPECT_EQ(info->ders.size(), info->fingerprints.size()); | |
| 91 return info; | |
| 92 } | |
| 93 | |
| 41 class RTCStatsCollectorTestHelper : public SetSessionDescriptionObserver { | 94 class RTCStatsCollectorTestHelper : public SetSessionDescriptionObserver { | 
| 42 public: | 95 public: | 
| 43 RTCStatsCollectorTestHelper() | 96 RTCStatsCollectorTestHelper() | 
| 44 : worker_thread_(rtc::Thread::Current()), | 97 : worker_thread_(rtc::Thread::Current()), | 
| 45 network_thread_(rtc::Thread::Current()), | 98 network_thread_(rtc::Thread::Current()), | 
| 46 channel_manager_(new cricket::ChannelManager( | 99 channel_manager_(new cricket::ChannelManager( | 
| 47 new cricket::FakeMediaEngine(), | 100 new cricket::FakeMediaEngine(), | 
| 48 worker_thread_, | 101 worker_thread_, | 
| 49 network_thread_)), | 102 network_thread_)), | 
| 50 media_controller_( | 103 media_controller_( | 
| 51 MediaControllerInterface::Create(cricket::MediaConfig(), | 104 MediaControllerInterface::Create(cricket::MediaConfig(), | 
| 52 worker_thread_, | 105 worker_thread_, | 
| 53 channel_manager_.get())), | 106 channel_manager_.get())), | 
| 54 session_(media_controller_.get()), | 107 session_(media_controller_.get()), | 
| 55 pc_() { | 108 pc_() { | 
| 56 EXPECT_CALL(pc_, session()).WillRepeatedly(Return(&session_)); | 109 EXPECT_CALL(pc_, session()).WillRepeatedly(Return(&session_)); | 
| 57 EXPECT_CALL(pc_, sctp_data_channels()).WillRepeatedly( | 110 EXPECT_CALL(pc_, sctp_data_channels()).WillRepeatedly( | 
| 58 ReturnRef(data_channels_)); | 111 ReturnRef(data_channels_)); | 
| 112 // Default return values for mocks. | |
| 
 
hta-webrtc
2016/10/03 14:51:36
Move comment before all the EXPECT_CALL lines?
 
hbos
2016/10/03 15:38:49
Done.
 
 | |
| 113 EXPECT_CALL(session_, GetTransportStats(_)).WillRepeatedly(Return(false)); | |
| 59 } | 114 } | 
| 60 | 115 | 
| 61 rtc::ScopedFakeClock& fake_clock() { return fake_clock_; } | 116 rtc::ScopedFakeClock& fake_clock() { return fake_clock_; } | 
| 62 MockWebRtcSession& session() { return session_; } | 117 MockWebRtcSession& session() { return session_; } | 
| 63 MockPeerConnection& pc() { return pc_; } | 118 MockPeerConnection& pc() { return pc_; } | 
| 64 std::vector<rtc::scoped_refptr<DataChannel>>& data_channels() { | 119 std::vector<rtc::scoped_refptr<DataChannel>>& data_channels() { | 
| 65 return data_channels_; | 120 return data_channels_; | 
| 66 } | 121 } | 
| 67 | 122 | 
| 68 // SetSessionDescriptionObserver overrides. | 123 // SetSessionDescriptionObserver overrides. | 
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 246 &test_->pc(), 50 * rtc::kNumMicrosecsPerMillisec)) { | 301 &test_->pc(), 50 * rtc::kNumMicrosecsPerMillisec)) { | 
| 247 } | 302 } | 
| 248 | 303 | 
| 249 rtc::scoped_refptr<const RTCStatsReport> GetStatsReport() { | 304 rtc::scoped_refptr<const RTCStatsReport> GetStatsReport() { | 
| 250 rtc::scoped_refptr<StatsCallback> callback = StatsCallback::Create(); | 305 rtc::scoped_refptr<StatsCallback> callback = StatsCallback::Create(); | 
| 251 collector_->GetStatsReport(callback); | 306 collector_->GetStatsReport(callback); | 
| 252 EXPECT_TRUE_WAIT(callback->report(), kGetStatsReportTimeoutMs); | 307 EXPECT_TRUE_WAIT(callback->report(), kGetStatsReportTimeoutMs); | 
| 253 return callback->report(); | 308 return callback->report(); | 
| 254 } | 309 } | 
| 255 | 310 | 
| 311 void ExpectReportContainsCertificateInfo( | |
| 312 const rtc::scoped_refptr<const RTCStatsReport>& report, | |
| 313 const CertificateInfo& cert_info) { | |
| 314 for (size_t i = 0; i < cert_info.fingerprints.size(); ++i) { | |
| 315 const RTCStats* stats = report->Get( | |
| 316 "RTCCertificate_" + cert_info.fingerprints[i]); | |
| 317 EXPECT_TRUE(stats); | |
| 318 const RTCCertificateStats& cert_stats = | |
| 319 stats->cast_to<const RTCCertificateStats>(); | |
| 320 EXPECT_EQ(*cert_stats.fingerprint, cert_info.fingerprints[i]); | |
| 321 EXPECT_EQ(*cert_stats.fingerprint_algorithm, "sha-1"); | |
| 322 EXPECT_EQ(*cert_stats.base64_certificate, cert_info.pems[i]); | |
| 323 if (i + 1 < cert_info.fingerprints.size()) { | |
| 324 EXPECT_EQ(*cert_stats.issuer_certificate_id, | |
| 325 "RTCCertificate_" + cert_info.fingerprints[i + 1]); | |
| 326 } else { | |
| 327 EXPECT_FALSE(cert_stats.issuer_certificate_id.is_defined()); | |
| 328 } | |
| 329 } | |
| 330 } | |
| 331 | |
| 256 protected: | 332 protected: | 
| 257 rtc::scoped_refptr<RTCStatsCollectorTestHelper> test_; | 333 rtc::scoped_refptr<RTCStatsCollectorTestHelper> test_; | 
| 258 rtc::scoped_refptr<RTCStatsCollector> collector_; | 334 rtc::scoped_refptr<RTCStatsCollector> collector_; | 
| 259 }; | 335 }; | 
| 260 | 336 | 
| 261 TEST_F(RTCStatsCollectorTest, SingleCallback) { | 337 TEST_F(RTCStatsCollectorTest, SingleCallback) { | 
| 262 rtc::scoped_refptr<const RTCStatsReport> result; | 338 rtc::scoped_refptr<const RTCStatsReport> result; | 
| 263 collector_->GetStatsReport(StatsCallback::Create(&result)); | 339 collector_->GetStatsReport(StatsCallback::Create(&result)); | 
| 264 EXPECT_TRUE_WAIT(result, kGetStatsReportTimeoutMs); | 340 EXPECT_TRUE_WAIT(result, kGetStatsReportTimeoutMs); | 
| 265 } | 341 } | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 305 collector_->GetStatsReport(StatsCallback::Create(&c)); | 381 collector_->GetStatsReport(StatsCallback::Create(&c)); | 
| 306 EXPECT_TRUE_WAIT(a, kGetStatsReportTimeoutMs); | 382 EXPECT_TRUE_WAIT(a, kGetStatsReportTimeoutMs); | 
| 307 EXPECT_TRUE_WAIT(b, kGetStatsReportTimeoutMs); | 383 EXPECT_TRUE_WAIT(b, kGetStatsReportTimeoutMs); | 
| 308 EXPECT_TRUE_WAIT(c, kGetStatsReportTimeoutMs); | 384 EXPECT_TRUE_WAIT(c, kGetStatsReportTimeoutMs); | 
| 309 EXPECT_EQ(a.get(), b.get()); | 385 EXPECT_EQ(a.get(), b.get()); | 
| 310 // The act of doing |AdvanceTime| processes all messages. If this was not the | 386 // The act of doing |AdvanceTime| processes all messages. If this was not the | 
| 311 // case we might not require |c| to be fresher than |b|. | 387 // case we might not require |c| to be fresher than |b|. | 
| 312 EXPECT_NE(c.get(), b.get()); | 388 EXPECT_NE(c.get(), b.get()); | 
| 313 } | 389 } | 
| 314 | 390 | 
| 391 TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsSingle) { | |
| 392 std::unique_ptr<CertificateInfo> local(new CertificateInfo()); | |
| 393 local->ders.push_back("(local) single certificate"); | |
| 394 local = CreateFakeCertificateAndInfoFromDers(local->ders); | |
| 
 
hta-webrtc
2016/10/03 14:51:36
Here you are creating an unique_ptr with a generic
 
hbos
2016/10/03 15:38:49
Constructing using a vector instead.
 
 | |
| 395 std::unique_ptr<CertificateInfo> remote(new CertificateInfo()); | |
| 396 remote->ders.push_back("(remote) single certificate"); | |
| 397 remote = CreateFakeCertificateAndInfoFromDers(remote->ders); | |
| 398 | |
| 399 // Mock the session to return the local and remote certificates. | |
| 400 EXPECT_CALL(test_->session(), GetTransportStats(_)).WillRepeatedly(Invoke( | |
| 401 [this](SessionStats* stats) { | |
| 402 stats->transport_stats["transport"].transport_name = "transport"; | |
| 403 return true; | |
| 404 })); | |
| 405 EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly( | |
| 406 Invoke([this, &local](const std::string& transport_name, | |
| 407 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) { | |
| 408 if (transport_name == "transport") { | |
| 409 *certificate = local->certificate; | |
| 410 return true; | |
| 411 } | |
| 412 return false; | |
| 413 })); | |
| 414 EXPECT_CALL(test_->session(), | |
| 415 GetRemoteSSLCertificate_ReturnsRawPointer(_)).WillRepeatedly(Invoke( | |
| 416 [this, &remote](const std::string& transport_name) { | |
| 417 if (transport_name == "transport") | |
| 418 return remote->certificate->ssl_certificate().GetReference(); | |
| 419 return static_cast<rtc::SSLCertificate*>(nullptr); | |
| 420 })); | |
| 421 | |
| 422 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport(); | |
| 423 ExpectReportContainsCertificateInfo(report, *local.get()); | |
| 424 ExpectReportContainsCertificateInfo(report, *remote.get()); | |
| 425 } | |
| 426 | |
| 427 TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsMultiple) { | |
| 428 std::unique_ptr<CertificateInfo> audio_local(new CertificateInfo()); | |
| 429 audio_local->ders.push_back("(local) audio"); | |
| 430 audio_local = CreateFakeCertificateAndInfoFromDers(audio_local->ders); | |
| 431 std::unique_ptr<CertificateInfo> audio_remote(new CertificateInfo()); | |
| 432 audio_remote->ders.push_back("(remote) audio"); | |
| 433 audio_remote = CreateFakeCertificateAndInfoFromDers(audio_remote->ders); | |
| 434 | |
| 435 std::unique_ptr<CertificateInfo> video_local(new CertificateInfo()); | |
| 436 video_local->ders.push_back("(local) video"); | |
| 437 video_local = CreateFakeCertificateAndInfoFromDers(video_local->ders); | |
| 438 std::unique_ptr<CertificateInfo> video_remote(new CertificateInfo()); | |
| 439 video_remote->ders.push_back("(remote) video"); | |
| 440 video_remote = CreateFakeCertificateAndInfoFromDers(video_remote->ders); | |
| 441 | |
| 442 // Mock the session to return the local and remote certificates. | |
| 443 EXPECT_CALL(test_->session(), GetTransportStats(_)).WillRepeatedly(Invoke( | |
| 444 [this](SessionStats* stats) { | |
| 445 stats->transport_stats["audio"].transport_name = "audio"; | |
| 446 stats->transport_stats["video"].transport_name = "video"; | |
| 447 return true; | |
| 448 })); | |
| 449 EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly( | |
| 450 Invoke([this, &audio_local, &video_local]( | |
| 451 const std::string& transport_name, | |
| 452 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) { | |
| 453 if (transport_name == "audio") { | |
| 454 *certificate = audio_local->certificate; | |
| 455 return true; | |
| 456 } | |
| 457 if (transport_name == "video") { | |
| 458 *certificate = video_local->certificate; | |
| 459 return true; | |
| 460 } | |
| 461 return false; | |
| 462 })); | |
| 463 EXPECT_CALL(test_->session(), | |
| 464 GetRemoteSSLCertificate_ReturnsRawPointer(_)).WillRepeatedly(Invoke( | |
| 465 [this, &audio_remote, &video_remote](const std::string& transport_name) { | |
| 466 if (transport_name == "audio") | |
| 467 return audio_remote->certificate->ssl_certificate().GetReference(); | |
| 468 if (transport_name == "video") | |
| 469 return video_remote->certificate->ssl_certificate().GetReference(); | |
| 470 return static_cast<rtc::SSLCertificate*>(nullptr); | |
| 471 })); | |
| 472 | |
| 473 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport(); | |
| 474 ExpectReportContainsCertificateInfo(report, *audio_local.get()); | |
| 475 ExpectReportContainsCertificateInfo(report, *audio_remote.get()); | |
| 476 ExpectReportContainsCertificateInfo(report, *video_local.get()); | |
| 477 ExpectReportContainsCertificateInfo(report, *video_remote.get()); | |
| 
 
hta-webrtc
2016/10/03 14:51:36
Good rename. More readable.
 
hbos
2016/10/03 15:38:49
Acknowledged.
 
 | |
| 478 } | |
| 479 | |
| 480 TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsChain) { | |
| 481 std::unique_ptr<CertificateInfo> local(new CertificateInfo()); | |
| 482 local->ders.push_back("(local) this"); | |
| 483 local->ders.push_back("(local) is"); | |
| 484 local->ders.push_back("(local) a"); | |
| 485 local->ders.push_back("(local) chain"); | |
| 486 local = CreateFakeCertificateAndInfoFromDers(local->ders); | |
| 487 std::unique_ptr<CertificateInfo> remote(new CertificateInfo()); | |
| 488 remote->ders.push_back("(remote) this"); | |
| 489 remote->ders.push_back("(remote) is"); | |
| 490 remote->ders.push_back("(remote) another"); | |
| 491 remote->ders.push_back("(remote) chain"); | |
| 492 remote = CreateFakeCertificateAndInfoFromDers(remote->ders); | |
| 493 | |
| 494 // Mock the session to return the local and remote certificates. | |
| 495 EXPECT_CALL(test_->session(), GetTransportStats(_)).WillRepeatedly(Invoke( | |
| 496 [this](SessionStats* stats) { | |
| 497 stats->transport_stats["transport"].transport_name = "transport"; | |
| 498 return true; | |
| 499 })); | |
| 500 EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly( | |
| 501 Invoke([this, &local](const std::string& transport_name, | |
| 502 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) { | |
| 503 if (transport_name == "transport") { | |
| 504 *certificate = local->certificate; | |
| 505 return true; | |
| 506 } | |
| 507 return false; | |
| 508 })); | |
| 509 EXPECT_CALL(test_->session(), | |
| 510 GetRemoteSSLCertificate_ReturnsRawPointer(_)).WillRepeatedly(Invoke( | |
| 511 [this, &remote](const std::string& transport_name) { | |
| 512 if (transport_name == "transport") | |
| 513 return remote->certificate->ssl_certificate().GetReference(); | |
| 514 return static_cast<rtc::SSLCertificate*>(nullptr); | |
| 515 })); | |
| 516 | |
| 517 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport(); | |
| 518 ExpectReportContainsCertificateInfo(report, *local.get()); | |
| 519 ExpectReportContainsCertificateInfo(report, *remote.get()); | |
| 520 } | |
| 521 | |
| 315 TEST_F(RTCStatsCollectorTest, CollectRTCPeerConnectionStats) { | 522 TEST_F(RTCStatsCollectorTest, CollectRTCPeerConnectionStats) { | 
| 316 int64_t before = rtc::TimeUTCMicros(); | 523 int64_t before = rtc::TimeUTCMicros(); | 
| 317 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport(); | 524 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport(); | 
| 318 int64_t after = rtc::TimeUTCMicros(); | 525 int64_t after = rtc::TimeUTCMicros(); | 
| 319 EXPECT_EQ(report->GetStatsOfType<RTCPeerConnectionStats>().size(), | 526 EXPECT_EQ(report->GetStatsOfType<RTCPeerConnectionStats>().size(), | 
| 320 static_cast<size_t>(1)) << "Expecting 1 RTCPeerConnectionStats."; | 527 static_cast<size_t>(1)) << "Expecting 1 RTCPeerConnectionStats."; | 
| 321 const RTCStats* stats = report->Get("RTCPeerConnection"); | 528 const RTCStats* stats = report->Get("RTCPeerConnection"); | 
| 322 EXPECT_TRUE(stats); | 529 EXPECT_TRUE(stats); | 
| 323 EXPECT_LE(before, stats->timestamp_us()); | 530 EXPECT_LE(before, stats->timestamp_us()); | 
| 324 EXPECT_LE(stats->timestamp_us(), after); | 531 EXPECT_LE(stats->timestamp_us(), after); | 
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 371 rtc::scoped_refptr<FakeRTCStatsCollector> collector_; | 578 rtc::scoped_refptr<FakeRTCStatsCollector> collector_; | 
| 372 }; | 579 }; | 
| 373 | 580 | 
| 374 TEST_F(RTCStatsCollectorTestWithFakeCollector, ThreadUsageAndResultsMerging) { | 581 TEST_F(RTCStatsCollectorTestWithFakeCollector, ThreadUsageAndResultsMerging) { | 
| 375 collector_->VerifyThreadUsageAndResultsMerging(); | 582 collector_->VerifyThreadUsageAndResultsMerging(); | 
| 376 } | 583 } | 
| 377 | 584 | 
| 378 } // namespace | 585 } // namespace | 
| 379 | 586 | 
| 380 } // namespace webrtc | 587 } // namespace webrtc | 
| OLD | NEW |