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 |
(...skipping 13 matching lines...) Expand all Loading... |
24 #include "webrtc/base/fakeclock.h" | 24 #include "webrtc/base/fakeclock.h" |
25 #include "webrtc/base/fakesslidentity.h" | 25 #include "webrtc/base/fakesslidentity.h" |
26 #include "webrtc/base/gunit.h" | 26 #include "webrtc/base/gunit.h" |
27 #include "webrtc/base/logging.h" | 27 #include "webrtc/base/logging.h" |
28 #include "webrtc/base/socketaddress.h" | 28 #include "webrtc/base/socketaddress.h" |
29 #include "webrtc/base/thread_checker.h" | 29 #include "webrtc/base/thread_checker.h" |
30 #include "webrtc/base/timedelta.h" | 30 #include "webrtc/base/timedelta.h" |
31 #include "webrtc/base/timeutils.h" | 31 #include "webrtc/base/timeutils.h" |
32 #include "webrtc/logging/rtc_event_log/rtc_event_log.h" | 32 #include "webrtc/logging/rtc_event_log/rtc_event_log.h" |
33 #include "webrtc/media/base/fakemediaengine.h" | 33 #include "webrtc/media/base/fakemediaengine.h" |
| 34 #include "webrtc/p2p/base/p2pconstants.h" |
34 #include "webrtc/p2p/base/port.h" | 35 #include "webrtc/p2p/base/port.h" |
35 | 36 |
36 using testing::_; | 37 using testing::_; |
37 using testing::Invoke; | 38 using testing::Invoke; |
38 using testing::Return; | 39 using testing::Return; |
39 using testing::ReturnRef; | 40 using testing::ReturnRef; |
40 | 41 |
41 namespace webrtc { | 42 namespace webrtc { |
42 | 43 |
43 namespace { | 44 namespace { |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 | 362 |
362 void ExpectReportContainsCandidatePair( | 363 void ExpectReportContainsCandidatePair( |
363 const rtc::scoped_refptr<const RTCStatsReport>& report, | 364 const rtc::scoped_refptr<const RTCStatsReport>& report, |
364 const cricket::TransportStats& transport_stats) { | 365 const cricket::TransportStats& transport_stats) { |
365 for (const auto& channel_stats : transport_stats.channel_stats) { | 366 for (const auto& channel_stats : transport_stats.channel_stats) { |
366 for (const cricket::ConnectionInfo& info : | 367 for (const cricket::ConnectionInfo& info : |
367 channel_stats.connection_infos) { | 368 channel_stats.connection_infos) { |
368 const std::string& id = "RTCIceCandidatePair_" + | 369 const std::string& id = "RTCIceCandidatePair_" + |
369 info.local_candidate.id() + "_" + info.remote_candidate.id(); | 370 info.local_candidate.id() + "_" + info.remote_candidate.id(); |
370 const RTCStats* stats = report->Get(id); | 371 const RTCStats* stats = report->Get(id); |
371 EXPECT_TRUE(stats); | 372 ASSERT_TRUE(stats); |
372 const RTCIceCandidatePairStats& candidate_pair_stats = | 373 const RTCIceCandidatePairStats& candidate_pair_stats = |
373 stats->cast_to<RTCIceCandidatePairStats>(); | 374 stats->cast_to<RTCIceCandidatePairStats>(); |
374 | 375 |
375 // TODO(hbos): Define all the undefined |candidate_pair_stats| stats. | 376 // TODO(hbos): Define all the undefined |candidate_pair_stats| stats. |
376 // The EXPECT_FALSE are for the undefined stats, see also todos listed | 377 // The EXPECT_FALSE are for the undefined stats, see also todos listed |
377 // in rtcstatscollector.cc. crbug.com/633550 | 378 // in rtcstatscollector.cc. crbug.com/633550 |
378 EXPECT_FALSE(candidate_pair_stats.transport_id.is_defined()); | 379 EXPECT_FALSE(candidate_pair_stats.transport_id.is_defined()); |
379 const RTCIceCandidateStats* local_candidate = | 380 const RTCIceCandidateStats* local_candidate = |
380 ExpectReportContainsCandidate(report, info.local_candidate, true); | 381 ExpectReportContainsCandidate(report, info.local_candidate, true); |
381 EXPECT_EQ(*candidate_pair_stats.local_candidate_id, | 382 EXPECT_EQ(*candidate_pair_stats.local_candidate_id, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 } | 421 } |
421 } | 422 } |
422 } | 423 } |
423 | 424 |
424 void ExpectReportContainsCertificateInfo( | 425 void ExpectReportContainsCertificateInfo( |
425 const rtc::scoped_refptr<const RTCStatsReport>& report, | 426 const rtc::scoped_refptr<const RTCStatsReport>& report, |
426 const CertificateInfo& cert_info) { | 427 const CertificateInfo& cert_info) { |
427 for (size_t i = 0; i < cert_info.fingerprints.size(); ++i) { | 428 for (size_t i = 0; i < cert_info.fingerprints.size(); ++i) { |
428 const RTCStats* stats = report->Get( | 429 const RTCStats* stats = report->Get( |
429 "RTCCertificate_" + cert_info.fingerprints[i]); | 430 "RTCCertificate_" + cert_info.fingerprints[i]); |
430 EXPECT_TRUE(stats); | 431 ASSERT_TRUE(stats); |
431 const RTCCertificateStats& cert_stats = | 432 const RTCCertificateStats& cert_stats = |
432 stats->cast_to<const RTCCertificateStats>(); | 433 stats->cast_to<const RTCCertificateStats>(); |
433 EXPECT_EQ(*cert_stats.fingerprint, cert_info.fingerprints[i]); | 434 EXPECT_EQ(*cert_stats.fingerprint, cert_info.fingerprints[i]); |
434 EXPECT_EQ(*cert_stats.fingerprint_algorithm, "sha-1"); | 435 EXPECT_EQ(*cert_stats.fingerprint_algorithm, "sha-1"); |
435 EXPECT_EQ(*cert_stats.base64_certificate, cert_info.pems[i]); | 436 EXPECT_EQ(*cert_stats.base64_certificate, cert_info.pems[i]); |
436 if (i + 1 < cert_info.fingerprints.size()) { | 437 if (i + 1 < cert_info.fingerprints.size()) { |
437 EXPECT_EQ(*cert_stats.issuer_certificate_id, | 438 EXPECT_EQ(*cert_stats.issuer_certificate_id, |
438 "RTCCertificate_" + cert_info.fingerprints[i + 1]); | 439 "RTCCertificate_" + cert_info.fingerprints[i + 1]); |
439 } else { | 440 } else { |
440 EXPECT_FALSE(cert_stats.issuer_certificate_id.is_defined()); | 441 EXPECT_FALSE(cert_stats.issuer_certificate_id.is_defined()); |
441 } | 442 } |
442 } | 443 } |
443 } | 444 } |
444 | 445 |
| 446 void ExpectReportContainsTransportStats( |
| 447 const rtc::scoped_refptr<const RTCStatsReport>& report, |
| 448 const cricket::TransportStats& transport, |
| 449 const CertificateInfo* local_certinfo, |
| 450 const CertificateInfo* remote_certinfo) { |
| 451 std::string rtcp_transport_stats_id; |
| 452 for (const auto& channel_stats : transport.channel_stats) { |
| 453 if (channel_stats.component == cricket::ICE_CANDIDATE_COMPONENT_RTCP) { |
| 454 rtcp_transport_stats_id = "RTCTransport_" + transport.transport_name + |
| 455 "_" + rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTCP); |
| 456 } |
| 457 } |
| 458 for (const auto& channel_stats : transport.channel_stats) { |
| 459 const cricket::ConnectionInfo* best_connection_info = nullptr; |
| 460 const RTCStats* stats = report->Get( |
| 461 "RTCTransport_" + transport.transport_name + "_" + |
| 462 rtc::ToString<>(channel_stats.component)); |
| 463 ASSERT_TRUE(stats); |
| 464 const RTCTransportStats& transport_stats = |
| 465 stats->cast_to<const RTCTransportStats>(); |
| 466 uint64_t bytes_sent = 0; |
| 467 uint64_t bytes_received = 0; |
| 468 for (const cricket::ConnectionInfo& info : |
| 469 channel_stats.connection_infos) { |
| 470 bytes_sent += info.sent_total_bytes; |
| 471 bytes_received += info.recv_total_bytes; |
| 472 if (info.best_connection) |
| 473 best_connection_info = &info; |
| 474 } |
| 475 EXPECT_EQ(*transport_stats.bytes_sent, bytes_sent); |
| 476 EXPECT_EQ(*transport_stats.bytes_received, bytes_received); |
| 477 if (best_connection_info) { |
| 478 EXPECT_EQ(*transport_stats.active_connection, true); |
| 479 // TODO(hbos): Instead of testing how the ID looks, test that the |
| 480 // corresponding pair's IP addresses are equal to the IP addresses of |
| 481 // the |best_connection_info| data. crbug.com/653873 |
| 482 EXPECT_EQ(*transport_stats.selected_candidate_pair_id, |
| 483 "RTCIceCandidatePair_" + |
| 484 best_connection_info->local_candidate.id() + "_" + |
| 485 best_connection_info->remote_candidate.id()); |
| 486 EXPECT_TRUE(report->Get(*transport_stats.selected_candidate_pair_id)); |
| 487 } else { |
| 488 EXPECT_EQ(*transport_stats.active_connection, false); |
| 489 EXPECT_FALSE(transport_stats.selected_candidate_pair_id.is_defined()); |
| 490 } |
| 491 if (channel_stats.component != cricket::ICE_CANDIDATE_COMPONENT_RTCP && |
| 492 !rtcp_transport_stats_id.empty()) { |
| 493 EXPECT_EQ(*transport_stats.rtcp_transport_stats_id, |
| 494 rtcp_transport_stats_id); |
| 495 } else { |
| 496 EXPECT_FALSE(transport_stats.rtcp_transport_stats_id.is_defined()); |
| 497 } |
| 498 if (local_certinfo && remote_certinfo) { |
| 499 EXPECT_EQ(*transport_stats.local_certificate_id, |
| 500 "RTCCertificate_" + local_certinfo->fingerprints[0]); |
| 501 EXPECT_EQ(*transport_stats.remote_certificate_id, |
| 502 "RTCCertificate_" + remote_certinfo->fingerprints[0]); |
| 503 EXPECT_TRUE(report->Get(*transport_stats.local_certificate_id)); |
| 504 EXPECT_TRUE(report->Get(*transport_stats.remote_certificate_id)); |
| 505 } else { |
| 506 EXPECT_FALSE(transport_stats.local_certificate_id.is_defined()); |
| 507 EXPECT_FALSE(transport_stats.remote_certificate_id.is_defined()); |
| 508 } |
| 509 } |
| 510 } |
| 511 |
445 void ExpectReportContainsDataChannel( | 512 void ExpectReportContainsDataChannel( |
446 const rtc::scoped_refptr<const RTCStatsReport>& report, | 513 const rtc::scoped_refptr<const RTCStatsReport>& report, |
447 const DataChannel& data_channel) { | 514 const DataChannel& data_channel) { |
448 const RTCStats* stats = report->Get("RTCDataChannel_" + | 515 const RTCStats* stats = report->Get("RTCDataChannel_" + |
449 rtc::ToString<>(data_channel.id())); | 516 rtc::ToString<>(data_channel.id())); |
450 EXPECT_TRUE(stats); | 517 EXPECT_TRUE(stats); |
451 const RTCDataChannelStats& data_channel_stats = | 518 const RTCDataChannelStats& data_channel_stats = |
452 stats->cast_to<const RTCDataChannelStats>(); | 519 stats->cast_to<const RTCDataChannelStats>(); |
453 EXPECT_EQ(*data_channel_stats.label, data_channel.label()); | 520 EXPECT_EQ(*data_channel_stats.label, data_channel.label()); |
454 EXPECT_EQ(*data_channel_stats.protocol, data_channel.protocol()); | 521 EXPECT_EQ(*data_channel_stats.protocol, data_channel.protocol()); |
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 test_->data_channels().push_back( | 909 test_->data_channels().push_back( |
843 new MockDataChannel(2, DataChannelInterface::kClosing)); | 910 new MockDataChannel(2, DataChannelInterface::kClosing)); |
844 test_->data_channels().push_back( | 911 test_->data_channels().push_back( |
845 new MockDataChannel(3, DataChannelInterface::kClosed)); | 912 new MockDataChannel(3, DataChannelInterface::kClosed)); |
846 | 913 |
847 collector_->ClearCachedStatsReport(); | 914 collector_->ClearCachedStatsReport(); |
848 report = GetStatsReport(); | 915 report = GetStatsReport(); |
849 EXPECT_EQ(report->GetStatsOfType<RTCPeerConnectionStats>().size(), | 916 EXPECT_EQ(report->GetStatsOfType<RTCPeerConnectionStats>().size(), |
850 static_cast<size_t>(1)) << "Expecting 1 RTCPeerConnectionStats."; | 917 static_cast<size_t>(1)) << "Expecting 1 RTCPeerConnectionStats."; |
851 stats = report->Get("RTCPeerConnection"); | 918 stats = report->Get("RTCPeerConnection"); |
852 EXPECT_TRUE(stats); | 919 ASSERT_TRUE(stats); |
853 { | 920 { |
854 // Expected stats with the above four data channels | 921 // Expected stats with the above four data channels |
855 // TODO(hbos): When the |RTCPeerConnectionStats| is the number of data | 922 // TODO(hbos): When the |RTCPeerConnectionStats| is the number of data |
856 // channels that have been opened and closed, not the numbers currently | 923 // channels that have been opened and closed, not the numbers currently |
857 // open/closed, we would expect opened >= closed and (opened - closed) to be | 924 // open/closed, we would expect opened >= closed and (opened - closed) to be |
858 // the number currently open. crbug.com/636818. | 925 // the number currently open. crbug.com/636818. |
859 const RTCPeerConnectionStats& pcstats = | 926 const RTCPeerConnectionStats& pcstats = |
860 stats->cast_to<RTCPeerConnectionStats>(); | 927 stats->cast_to<RTCPeerConnectionStats>(); |
861 EXPECT_EQ(*pcstats.data_channels_opened, static_cast<uint32_t>(1)); | 928 EXPECT_EQ(*pcstats.data_channels_opened, static_cast<uint32_t>(1)); |
862 EXPECT_EQ(*pcstats.data_channels_closed, static_cast<uint32_t>(3)); | 929 EXPECT_EQ(*pcstats.data_channels_closed, static_cast<uint32_t>(3)); |
863 } | 930 } |
864 } | 931 } |
865 | 932 |
| 933 TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) { |
| 934 std::unique_ptr<cricket::Candidate> rtp_local_candidate = CreateFakeCandidate( |
| 935 "42.42.42.42", 42, "protocol", cricket::LOCAL_PORT_TYPE, 42); |
| 936 std::unique_ptr<cricket::Candidate> rtp_remote_candidate = |
| 937 CreateFakeCandidate("42.42.42.42", 42, "protocol", |
| 938 cricket::LOCAL_PORT_TYPE, 42); |
| 939 std::unique_ptr<cricket::Candidate> rtcp_local_candidate = |
| 940 CreateFakeCandidate("42.42.42.42", 42, "protocol", |
| 941 cricket::LOCAL_PORT_TYPE, 42); |
| 942 std::unique_ptr<cricket::Candidate> rtcp_remote_candidate = |
| 943 CreateFakeCandidate("42.42.42.42", 42, "protocol", |
| 944 cricket::LOCAL_PORT_TYPE, 42); |
| 945 |
| 946 SessionStats session_stats; |
| 947 session_stats.transport_stats["transport"].transport_name = "transport"; |
| 948 |
| 949 cricket::ConnectionInfo rtp_connection_info; |
| 950 rtp_connection_info.best_connection = false; |
| 951 rtp_connection_info.local_candidate = *rtp_local_candidate.get(); |
| 952 rtp_connection_info.remote_candidate = *rtp_remote_candidate.get(); |
| 953 rtp_connection_info.sent_total_bytes = 42; |
| 954 rtp_connection_info.recv_total_bytes = 1337; |
| 955 cricket::TransportChannelStats rtp_transport_channel_stats; |
| 956 rtp_transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP; |
| 957 rtp_transport_channel_stats.connection_infos.push_back(rtp_connection_info); |
| 958 session_stats.transport_stats["transport"].channel_stats.push_back( |
| 959 rtp_transport_channel_stats); |
| 960 |
| 961 |
| 962 // Mock the session to return the desired candidates. |
| 963 EXPECT_CALL(test_->session(), GetTransportStats(_)).WillRepeatedly(Invoke( |
| 964 [this, &session_stats](SessionStats* stats) { |
| 965 *stats = session_stats; |
| 966 return true; |
| 967 })); |
| 968 |
| 969 // Get stats without RTCP, an active connection or certificates. |
| 970 rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport(); |
| 971 ExpectReportContainsTransportStats( |
| 972 report, session_stats.transport_stats["transport"], nullptr, nullptr); |
| 973 |
| 974 cricket::ConnectionInfo rtcp_connection_info; |
| 975 rtcp_connection_info.best_connection = false; |
| 976 rtcp_connection_info.local_candidate = *rtcp_local_candidate.get(); |
| 977 rtcp_connection_info.remote_candidate = *rtcp_remote_candidate.get(); |
| 978 rtcp_connection_info.sent_total_bytes = 1337; |
| 979 rtcp_connection_info.recv_total_bytes = 42; |
| 980 cricket::TransportChannelStats rtcp_transport_channel_stats; |
| 981 rtcp_transport_channel_stats.component = |
| 982 cricket::ICE_CANDIDATE_COMPONENT_RTCP; |
| 983 rtcp_transport_channel_stats.connection_infos.push_back(rtcp_connection_info); |
| 984 session_stats.transport_stats["transport"].channel_stats.push_back( |
| 985 rtcp_transport_channel_stats); |
| 986 |
| 987 collector_->ClearCachedStatsReport(); |
| 988 // Get stats with RTCP and without an active connection or certificates. |
| 989 report = GetStatsReport(); |
| 990 ExpectReportContainsTransportStats( |
| 991 report, session_stats.transport_stats["transport"], nullptr, nullptr); |
| 992 |
| 993 // Get stats with an active connection. |
| 994 rtcp_connection_info.best_connection = true; |
| 995 |
| 996 collector_->ClearCachedStatsReport(); |
| 997 report = GetStatsReport(); |
| 998 ExpectReportContainsTransportStats( |
| 999 report, session_stats.transport_stats["transport"], nullptr, nullptr); |
| 1000 |
| 1001 // Get stats with certificates. |
| 1002 std::unique_ptr<CertificateInfo> local_certinfo = |
| 1003 CreateFakeCertificateAndInfoFromDers( |
| 1004 std::vector<std::string>({ "(local) local", "(local) chain" })); |
| 1005 std::unique_ptr<CertificateInfo> remote_certinfo = |
| 1006 CreateFakeCertificateAndInfoFromDers( |
| 1007 std::vector<std::string>({ "(remote) local", "(remote) chain" })); |
| 1008 EXPECT_CALL(test_->session(), GetLocalCertificate(_, _)).WillRepeatedly( |
| 1009 Invoke([this, &local_certinfo](const std::string& transport_name, |
| 1010 rtc::scoped_refptr<rtc::RTCCertificate>* certificate) { |
| 1011 if (transport_name == "transport") { |
| 1012 *certificate = local_certinfo->certificate; |
| 1013 return true; |
| 1014 } |
| 1015 return false; |
| 1016 })); |
| 1017 EXPECT_CALL(test_->session(), |
| 1018 GetRemoteSSLCertificate_ReturnsRawPointer(_)).WillRepeatedly(Invoke( |
| 1019 [this, &remote_certinfo](const std::string& transport_name) { |
| 1020 if (transport_name == "transport") |
| 1021 return remote_certinfo->certificate->ssl_certificate().GetReference(); |
| 1022 return static_cast<rtc::SSLCertificate*>(nullptr); |
| 1023 })); |
| 1024 |
| 1025 collector_->ClearCachedStatsReport(); |
| 1026 report = GetStatsReport(); |
| 1027 ExpectReportContainsTransportStats( |
| 1028 report, session_stats.transport_stats["transport"], |
| 1029 local_certinfo.get(), remote_certinfo.get()); |
| 1030 } |
| 1031 |
866 class RTCStatsCollectorTestWithFakeCollector : public testing::Test { | 1032 class RTCStatsCollectorTestWithFakeCollector : public testing::Test { |
867 public: | 1033 public: |
868 RTCStatsCollectorTestWithFakeCollector() | 1034 RTCStatsCollectorTestWithFakeCollector() |
869 : test_(new rtc::RefCountedObject<RTCStatsCollectorTestHelper>()), | 1035 : test_(new rtc::RefCountedObject<RTCStatsCollectorTestHelper>()), |
870 collector_(FakeRTCStatsCollector::Create( | 1036 collector_(FakeRTCStatsCollector::Create( |
871 &test_->pc(), 50 * rtc::kNumMicrosecsPerMillisec)) { | 1037 &test_->pc(), 50 * rtc::kNumMicrosecsPerMillisec)) { |
872 } | 1038 } |
873 | 1039 |
874 protected: | 1040 protected: |
875 rtc::scoped_refptr<RTCStatsCollectorTestHelper> test_; | 1041 rtc::scoped_refptr<RTCStatsCollectorTestHelper> test_; |
876 rtc::scoped_refptr<FakeRTCStatsCollector> collector_; | 1042 rtc::scoped_refptr<FakeRTCStatsCollector> collector_; |
877 }; | 1043 }; |
878 | 1044 |
879 TEST_F(RTCStatsCollectorTestWithFakeCollector, ThreadUsageAndResultsMerging) { | 1045 TEST_F(RTCStatsCollectorTestWithFakeCollector, ThreadUsageAndResultsMerging) { |
880 collector_->VerifyThreadUsageAndResultsMerging(); | 1046 collector_->VerifyThreadUsageAndResultsMerging(); |
881 } | 1047 } |
882 | 1048 |
883 } // namespace | 1049 } // namespace |
884 | 1050 |
885 } // namespace webrtc | 1051 } // namespace webrtc |
OLD | NEW |