Update libjingle to 53920541.
R=mallinath@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/2371004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@4945 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/talk/app/webrtc/statscollector_unittest.cc b/talk/app/webrtc/statscollector_unittest.cc
index cce1645bc..9829832 100644
--- a/talk/app/webrtc/statscollector_unittest.cc
+++ b/talk/app/webrtc/statscollector_unittest.cc
@@ -30,6 +30,8 @@
#include "talk/app/webrtc/mediastream.h"
#include "talk/app/webrtc/videotrack.h"
+#include "talk/base/base64.h"
+#include "talk/base/fakesslidentity.h"
#include "talk/base/gunit.h"
#include "talk/media/base/fakemediaengine.h"
#include "talk/media/devices/fakedevicemanager.h"
@@ -60,11 +62,12 @@
public:
explicit MockWebRtcSession(cricket::ChannelManager* channel_manager)
: WebRtcSession(channel_manager, talk_base::Thread::Current(),
- NULL, NULL, NULL) {
+ talk_base::Thread::Current(), NULL, NULL) {
}
MOCK_METHOD0(video_channel, cricket::VideoChannel*());
MOCK_METHOD2(GetTrackIdBySsrc, bool(uint32, std::string*));
MOCK_METHOD1(GetStats, bool(cricket::SessionStats*));
+ MOCK_METHOD1(GetTransport, cricket::Transport*(const std::string&));
};
class MockVideoMediaChannel : public cricket::FakeVideoMediaChannel {
@@ -76,8 +79,21 @@
MOCK_METHOD1(GetStats, bool(cricket::VideoMediaInfo*));
};
+bool GetValue(const webrtc::StatsReport* report,
+ const std::string& name,
+ std::string* value) {
+ webrtc::StatsReport::Values::const_iterator it = report->values.begin();
+ for (; it != report->values.end(); ++it) {
+ if (it->name == name) {
+ *value = it->value;
+ return true;
+ }
+ }
+ return false;
+}
+
std::string ExtractStatsValue(const std::string& type,
- webrtc::StatsReports reports,
+ const webrtc::StatsReports& reports,
const std::string name) {
if (reports.empty()) {
return kNoReports;
@@ -85,12 +101,9 @@
for (size_t i = 0; i < reports.size(); ++i) {
if (reports[i].type != type)
continue;
- webrtc::StatsReport::Values::const_iterator it =
- reports[i].values.begin();
- for (; it != reports[i].values.end(); ++it) {
- if (it->name == name) {
- return it->value;
- }
+ std::string ret;
+ if (GetValue(&reports[i], name, &ret)) {
+ return ret;
}
}
@@ -99,9 +112,8 @@
// Finds the |n|-th report of type |type| in |reports|.
// |n| starts from 1 for finding the first report.
-const webrtc::StatsReport* FindNthReportByType(webrtc::StatsReports reports,
- const std::string& type,
- int n) {
+const webrtc::StatsReport* FindNthReportByType(
+ const webrtc::StatsReports& reports, const std::string& type, int n) {
for (size_t i = 0; i < reports.size(); ++i) {
if (reports[i].type == type) {
n--;
@@ -112,7 +124,7 @@
return NULL;
}
-const webrtc::StatsReport* FindReportById(webrtc::StatsReports reports,
+const webrtc::StatsReport* FindReportById(const webrtc::StatsReports& reports,
const std::string& id) {
for (size_t i = 0; i < reports.size(); ++i) {
if (reports[i].id == id) {
@@ -134,6 +146,42 @@
webrtc::StatsReport::kStatsReportTypeBwe, reports, name);
}
+std::string DerToPem(const std::string& der) {
+ return talk_base::SSLIdentity::DerToPem(
+ talk_base::kPemTypeCertificate,
+ reinterpret_cast<const unsigned char*>(der.c_str()),
+ der.length());
+}
+
+std::vector<std::string> DersToPems(
+ const std::vector<std::string>& ders) {
+ std::vector<std::string> pems(ders.size());
+ std::transform(ders.begin(), ders.end(), pems.begin(), DerToPem);
+ return pems;
+}
+
+void CheckCertChainReports(const webrtc::StatsReports& reports,
+ const std::vector<std::string>& ders,
+ const std::string& start_id) {
+ std::string certificate_id = start_id;
+ size_t i = 0;
+ while (true) {
+ const webrtc::StatsReport* report = FindReportById(reports, certificate_id);
+ ASSERT_TRUE(report != NULL);
+ std::string der_base64;
+ EXPECT_TRUE(GetValue(
+ report, webrtc::StatsReport::kStatsValueNameDer, &der_base64));
+ std::string der = talk_base::Base64::Decode(der_base64,
+ talk_base::Base64::DO_STRICT);
+ EXPECT_EQ(ders[i], der);
+ ++i;
+ if (!GetValue(
+ report, webrtc::StatsReport::kStatsValueNameIssuerId, &certificate_id))
+ break;
+ }
+ EXPECT_EQ(ders.size(), i);
+}
+
class StatsCollectorTest : public testing::Test {
protected:
StatsCollectorTest()
@@ -147,6 +195,77 @@
EXPECT_CALL(session_, GetStats(_)).WillRepeatedly(Return(false));
}
+ void TestCertificateReports(const talk_base::FakeSSLCertificate& local_cert,
+ const std::vector<std::string>& local_ders,
+ const talk_base::FakeSSLCertificate& remote_cert,
+ const std::vector<std::string>& remote_ders) {
+ webrtc::StatsCollector stats; // Implementation under test.
+ webrtc::StatsReports reports; // returned values.
+ stats.set_session(&session_);
+
+ // Fake stats to process.
+ cricket::TransportChannelStats channel_stats;
+ channel_stats.component = 1;
+
+ cricket::TransportStats transport_stats;
+ transport_stats.content_name = "audio";
+ transport_stats.channel_stats.push_back(channel_stats);
+
+ cricket::SessionStats session_stats;
+ session_stats.transport_stats[transport_stats.content_name] =
+ transport_stats;
+
+ // Fake certificates to report.
+ talk_base::FakeSSLIdentity local_identity(local_cert);
+ talk_base::scoped_ptr<talk_base::FakeSSLCertificate> remote_cert_copy(
+ remote_cert.GetReference());
+
+ // Fake transport object.
+ talk_base::scoped_ptr<cricket::FakeTransport> transport(
+ new cricket::FakeTransport(
+ session_.signaling_thread(),
+ session_.worker_thread(),
+ transport_stats.content_name));
+ transport->SetIdentity(&local_identity);
+ cricket::FakeTransportChannel* channel =
+ static_cast<cricket::FakeTransportChannel*>(
+ transport->CreateChannel(channel_stats.component));
+ EXPECT_FALSE(channel == NULL);
+ channel->SetRemoteCertificate(remote_cert_copy.get());
+
+ // Configure MockWebRtcSession
+ EXPECT_CALL(session_, GetTransport(transport_stats.content_name))
+ .WillOnce(Return(transport.get()));
+ EXPECT_CALL(session_, GetStats(_))
+ .WillOnce(DoAll(SetArgPointee<0>(session_stats),
+ Return(true)));
+ EXPECT_CALL(session_, video_channel())
+ .WillRepeatedly(ReturnNull());
+
+ stats.UpdateStats();
+
+ stats.GetStats(NULL, &reports);
+
+ const webrtc::StatsReport* channel_report = FindNthReportByType(
+ reports, webrtc::StatsReport::kStatsReportTypeComponent, 1);
+ EXPECT_TRUE(channel_report != NULL);
+
+ // Check local certificate chain.
+ std::string local_certificate_id = ExtractStatsValue(
+ webrtc::StatsReport::kStatsReportTypeComponent,
+ reports,
+ webrtc::StatsReport::kStatsValueNameLocalCertificateId);
+ EXPECT_NE(kNotFound, local_certificate_id);
+ CheckCertChainReports(reports, local_ders, local_certificate_id);
+
+ // Check remote certificate chain.
+ std::string remote_certificate_id = ExtractStatsValue(
+ webrtc::StatsReport::kStatsReportTypeComponent,
+ reports,
+ webrtc::StatsReport::kStatsValueNameRemoteCertificateId);
+ EXPECT_NE(kNotFound, remote_certificate_id);
+ CheckCertChainReports(reports, remote_ders, remote_certificate_id);
+ }
cricket::FakeMediaEngine* media_engine_;
talk_base::scoped_ptr<cricket::ChannelManager> channel_manager_;
MockWebRtcSession session_;
@@ -439,4 +558,142 @@
ASSERT_FALSE(transport_report == NULL);
}
+// This test verifies that all chained certificates are correctly
+// reported
+TEST_F(StatsCollectorTest, DISABLED_ChainedCertificateReportsCreated) {
+ // Build local certificate chain.
+ std::vector<std::string> local_ders(5);
+ local_ders[0] = "These";
+ local_ders[1] = "are";
+ local_ders[2] = "some";
+ local_ders[3] = "der";
+ local_ders[4] = "values";
+ talk_base::FakeSSLCertificate local_cert(DersToPems(local_ders));
+
+ // Build remote certificate chain
+ std::vector<std::string> remote_ders(4);
+ remote_ders[0] = "A";
+ remote_ders[1] = "non-";
+ remote_ders[2] = "intersecting";
+ remote_ders[3] = "set";
+ talk_base::FakeSSLCertificate remote_cert(DersToPems(remote_ders));
+
+ TestCertificateReports(local_cert, local_ders, remote_cert, remote_ders);
+}
+
+// This test verifies that all certificates without chains are correctly
+// reported.
+TEST_F(StatsCollectorTest, DISABLED_ChainlessCertificateReportsCreated) {
+ // Build local certificate.
+ std::string local_der = "This is the local der.";
+ talk_base::FakeSSLCertificate local_cert(DerToPem(local_der));
+
+ // Build remote certificate.
+ std::string remote_der = "This is somebody else's der.";
+ talk_base::FakeSSLCertificate remote_cert(DerToPem(remote_der));
+
+ TestCertificateReports(local_cert, std::vector<std::string>(1, local_der),
+ remote_cert, std::vector<std::string>(1, remote_der));
+}
+
+// This test verifies that the stats are generated correctly when no
+// transport is present.
+TEST_F(StatsCollectorTest, DISABLED_NoTransport) {
+ webrtc::StatsCollector stats; // Implementation under test.
+ webrtc::StatsReports reports; // returned values.
+ stats.set_session(&session_);
+
+ // Fake stats to process.
+ cricket::TransportChannelStats channel_stats;
+ channel_stats.component = 1;
+
+ cricket::TransportStats transport_stats;
+ transport_stats.content_name = "audio";
+ transport_stats.channel_stats.push_back(channel_stats);
+
+ cricket::SessionStats session_stats;
+ session_stats.transport_stats[transport_stats.content_name] =
+ transport_stats;
+
+ // Configure MockWebRtcSession
+ EXPECT_CALL(session_, GetTransport(transport_stats.content_name))
+ .WillOnce(ReturnNull());
+ EXPECT_CALL(session_, GetStats(_))
+ .WillOnce(DoAll(SetArgPointee<0>(session_stats),
+ Return(true)));
+ EXPECT_CALL(session_, video_channel())
+ .WillRepeatedly(ReturnNull());
+
+ stats.UpdateStats();
+ stats.GetStats(NULL, &reports);
+
+ // Check that the local certificate is absent.
+ std::string local_certificate_id = ExtractStatsValue(
+ webrtc::StatsReport::kStatsReportTypeComponent,
+ reports,
+ webrtc::StatsReport::kStatsValueNameLocalCertificateId);
+ ASSERT_EQ(kNotFound, local_certificate_id);
+
+ // Check that the remote certificate is absent.
+ std::string remote_certificate_id = ExtractStatsValue(
+ webrtc::StatsReport::kStatsReportTypeComponent,
+ reports,
+ webrtc::StatsReport::kStatsValueNameRemoteCertificateId);
+ ASSERT_EQ(kNotFound, remote_certificate_id);
+}
+
+// This test verifies that the stats are generated correctly when the transport
+// does not have any certificates.
+TEST_F(StatsCollectorTest, DISABLED_NoCertificates) {
+ webrtc::StatsCollector stats; // Implementation under test.
+ webrtc::StatsReports reports; // returned values.
+ stats.set_session(&session_);
+
+ // Fake stats to process.
+ cricket::TransportChannelStats channel_stats;
+ channel_stats.component = 1;
+
+ cricket::TransportStats transport_stats;
+ transport_stats.content_name = "audio";
+ transport_stats.channel_stats.push_back(channel_stats);
+
+ cricket::SessionStats session_stats;
+ session_stats.transport_stats[transport_stats.content_name] =
+ transport_stats;
+
+ // Fake transport object.
+ talk_base::scoped_ptr<cricket::FakeTransport> transport(
+ new cricket::FakeTransport(
+ session_.signaling_thread(),
+ session_.worker_thread(),
+ transport_stats.content_name));
+
+ // Configure MockWebRtcSession
+ EXPECT_CALL(session_, GetTransport(transport_stats.content_name))
+ .WillOnce(Return(transport.get()));
+ EXPECT_CALL(session_, GetStats(_))
+ .WillOnce(DoAll(SetArgPointee<0>(session_stats),
+ Return(true)));
+ EXPECT_CALL(session_, video_channel())
+ .WillRepeatedly(ReturnNull());
+
+ stats.UpdateStats();
+ stats.GetStats(NULL, &reports);
+
+ // Check that the local certificate is absent.
+ std::string local_certificate_id = ExtractStatsValue(
+ webrtc::StatsReport::kStatsReportTypeComponent,
+ reports,
+ webrtc::StatsReport::kStatsValueNameLocalCertificateId);
+ ASSERT_EQ(kNotFound, local_certificate_id);
+
+ // Check that the remote certificate is absent.
+ std::string remote_certificate_id = ExtractStatsValue(
+ webrtc::StatsReport::kStatsReportTypeComponent,
+ reports,
+ webrtc::StatsReport::kStatsValueNameRemoteCertificateId);
+ ASSERT_EQ(kNotFound, remote_certificate_id);
+}
+
+
} // namespace