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

Side by Side Diff: webrtc/api/rtcstatscollector_unittest.cc

Issue 2243123002: RTCCertificateStats added. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Addressed comments Created 4 years, 2 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
« no previous file with comments | « webrtc/api/rtcstatscollector.cc ('k') | webrtc/api/stats/rtcstats_objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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_() {
109 // Default return values for mocks.
56 EXPECT_CALL(pc_, session()).WillRepeatedly(Return(&session_)); 110 EXPECT_CALL(pc_, session()).WillRepeatedly(Return(&session_));
57 EXPECT_CALL(pc_, sctp_data_channels()).WillRepeatedly( 111 EXPECT_CALL(pc_, sctp_data_channels()).WillRepeatedly(
58 ReturnRef(data_channels_)); 112 ReturnRef(data_channels_));
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
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
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_certinfo =
393 CreateFakeCertificateAndInfoFromDers(
394 std::vector<std::string>({ "(local) single certificate" }));
395 std::unique_ptr<CertificateInfo> remote_certinfo =
396 CreateFakeCertificateAndInfoFromDers(
397 std::vector<std::string>({ "(remote) single certificate" }));
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_certinfo](const std::string& transport_name,
407 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
408 if (transport_name == "transport") {
409 *certificate = local_certinfo->certificate;
410 return true;
411 }
412 return false;
413 }));
414 EXPECT_CALL(test_->session(),
415 GetRemoteSSLCertificate_ReturnsRawPointer(_)).WillRepeatedly(Invoke(
416 [this, &remote_certinfo](const std::string& transport_name) {
417 if (transport_name == "transport")
418 return remote_certinfo->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_certinfo.get());
424 ExpectReportContainsCertificateInfo(report, *remote_certinfo.get());
425 }
426
427 TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsMultiple) {
428 std::unique_ptr<CertificateInfo> audio_local_certinfo =
429 CreateFakeCertificateAndInfoFromDers(
430 std::vector<std::string>({ "(local) audio" }));
431 audio_local_certinfo = CreateFakeCertificateAndInfoFromDers(
432 audio_local_certinfo->ders);
433 std::unique_ptr<CertificateInfo> audio_remote_certinfo =
434 CreateFakeCertificateAndInfoFromDers(
435 std::vector<std::string>({ "(remote) audio" }));
436 audio_remote_certinfo = CreateFakeCertificateAndInfoFromDers(
437 audio_remote_certinfo->ders);
438
439 std::unique_ptr<CertificateInfo> video_local_certinfo =
440 CreateFakeCertificateAndInfoFromDers(
441 std::vector<std::string>({ "(local) video" }));
442 video_local_certinfo = CreateFakeCertificateAndInfoFromDers(
443 video_local_certinfo->ders);
444 std::unique_ptr<CertificateInfo> video_remote_certinfo =
445 CreateFakeCertificateAndInfoFromDers(
446 std::vector<std::string>({ "(remote) video" }));
447 video_remote_certinfo = CreateFakeCertificateAndInfoFromDers(
448 video_remote_certinfo->ders);
449
450 // Mock the session to return the local and remote certificates.
451 EXPECT_CALL(test_->session(), GetTransportStats(_)).WillRepeatedly(Invoke(
452 [this](SessionStats* stats) {
453 stats->transport_stats["audio"].transport_name = "audio";
454 stats->transport_stats["video"].transport_name = "video";
455 return true;
456 }));
457 EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly(
458 Invoke([this, &audio_local_certinfo, &video_local_certinfo](
459 const std::string& transport_name,
460 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
461 if (transport_name == "audio") {
462 *certificate = audio_local_certinfo->certificate;
463 return true;
464 }
465 if (transport_name == "video") {
466 *certificate = video_local_certinfo->certificate;
467 return true;
468 }
469 return false;
470 }));
471 EXPECT_CALL(test_->session(),
472 GetRemoteSSLCertificate_ReturnsRawPointer(_)).WillRepeatedly(Invoke(
473 [this, &audio_remote_certinfo, &video_remote_certinfo](
474 const std::string& transport_name) {
475 if (transport_name == "audio") {
476 return audio_remote_certinfo->certificate->ssl_certificate()
477 .GetReference();
478 }
479 if (transport_name == "video") {
480 return video_remote_certinfo->certificate->ssl_certificate()
481 .GetReference();
482 }
483 return static_cast<rtc::SSLCertificate*>(nullptr);
484 }));
485
486 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
487 ExpectReportContainsCertificateInfo(report, *audio_local_certinfo.get());
488 ExpectReportContainsCertificateInfo(report, *audio_remote_certinfo.get());
489 ExpectReportContainsCertificateInfo(report, *video_local_certinfo.get());
490 ExpectReportContainsCertificateInfo(report, *video_remote_certinfo.get());
491 }
492
493 TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsChain) {
494 std::vector<std::string> local_ders;
495 local_ders.push_back("(local) this");
496 local_ders.push_back("(local) is");
497 local_ders.push_back("(local) a");
498 local_ders.push_back("(local) chain");
499 std::unique_ptr<CertificateInfo> local_certinfo =
500 CreateFakeCertificateAndInfoFromDers(local_ders);
501 std::vector<std::string> remote_ders;
502 remote_ders.push_back("(remote) this");
503 remote_ders.push_back("(remote) is");
504 remote_ders.push_back("(remote) another");
505 remote_ders.push_back("(remote) chain");
506 std::unique_ptr<CertificateInfo> remote_certinfo =
507 CreateFakeCertificateAndInfoFromDers(remote_ders);
508
509 // Mock the session to return the local and remote certificates.
510 EXPECT_CALL(test_->session(), GetTransportStats(_)).WillRepeatedly(Invoke(
511 [this](SessionStats* stats) {
512 stats->transport_stats["transport"].transport_name = "transport";
513 return true;
514 }));
515 EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly(
516 Invoke([this, &local_certinfo](const std::string& transport_name,
517 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) {
518 if (transport_name == "transport") {
519 *certificate = local_certinfo->certificate;
520 return true;
521 }
522 return false;
523 }));
524 EXPECT_CALL(test_->session(),
525 GetRemoteSSLCertificate_ReturnsRawPointer(_)).WillRepeatedly(Invoke(
526 [this, &remote_certinfo](const std::string& transport_name) {
527 if (transport_name == "transport")
528 return remote_certinfo->certificate->ssl_certificate().GetReference();
529 return static_cast<rtc::SSLCertificate*>(nullptr);
530 }));
531
532 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
533 ExpectReportContainsCertificateInfo(report, *local_certinfo.get());
534 ExpectReportContainsCertificateInfo(report, *remote_certinfo.get());
535 }
536
315 TEST_F(RTCStatsCollectorTest, CollectRTCPeerConnectionStats) { 537 TEST_F(RTCStatsCollectorTest, CollectRTCPeerConnectionStats) {
316 int64_t before = rtc::TimeUTCMicros(); 538 int64_t before = rtc::TimeUTCMicros();
317 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport(); 539 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
318 int64_t after = rtc::TimeUTCMicros(); 540 int64_t after = rtc::TimeUTCMicros();
319 EXPECT_EQ(report->GetStatsOfType<RTCPeerConnectionStats>().size(), 541 EXPECT_EQ(report->GetStatsOfType<RTCPeerConnectionStats>().size(),
320 static_cast<size_t>(1)) << "Expecting 1 RTCPeerConnectionStats."; 542 static_cast<size_t>(1)) << "Expecting 1 RTCPeerConnectionStats.";
321 const RTCStats* stats = report->Get("RTCPeerConnection"); 543 const RTCStats* stats = report->Get("RTCPeerConnection");
322 EXPECT_TRUE(stats); 544 EXPECT_TRUE(stats);
323 EXPECT_LE(before, stats->timestamp_us()); 545 EXPECT_LE(before, stats->timestamp_us());
324 EXPECT_LE(stats->timestamp_us(), after); 546 EXPECT_LE(stats->timestamp_us(), after);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 rtc::scoped_refptr<FakeRTCStatsCollector> collector_; 593 rtc::scoped_refptr<FakeRTCStatsCollector> collector_;
372 }; 594 };
373 595
374 TEST_F(RTCStatsCollectorTestWithFakeCollector, ThreadUsageAndResultsMerging) { 596 TEST_F(RTCStatsCollectorTestWithFakeCollector, ThreadUsageAndResultsMerging) {
375 collector_->VerifyThreadUsageAndResultsMerging(); 597 collector_->VerifyThreadUsageAndResultsMerging();
376 } 598 }
377 599
378 } // namespace 600 } // namespace
379 601
380 } // namespace webrtc 602 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/api/rtcstatscollector.cc ('k') | webrtc/api/stats/rtcstats_objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698