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

Side by Side Diff: chrome/browser/ssl/chrome_expect_ct_reporter_unittest.cc

Issue 1866203003: Add UMA metric for Expect CT failure (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ssl/chrome_expect_ct_reporter.h" 5 #include "chrome/browser/ssl/chrome_expect_ct_reporter.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/base64.h" 9 #include "base/base64.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/feature_list.h" 11 #include "base/feature_list.h"
12 #include "base/json/json_reader.h" 12 #include "base/json/json_reader.h"
13 #include "base/run_loop.h"
14 #include "base/test/histogram_tester.h"
13 #include "base/values.h" 15 #include "base/values.h"
14 #include "chrome/common/chrome_features.h" 16 #include "chrome/common/chrome_features.h"
17 #include "content/public/test/test_browser_thread_bundle.h"
15 #include "net/base/test_data_directory.h" 18 #include "net/base/test_data_directory.h"
16 #include "net/ssl/signed_certificate_timestamp_and_status.h" 19 #include "net/ssl/signed_certificate_timestamp_and_status.h"
17 #include "net/test/cert_test_util.h" 20 #include "net/test/cert_test_util.h"
21 #include "net/test/url_request/url_request_failed_job.h"
18 #include "net/url_request/certificate_report_sender.h" 22 #include "net/url_request/certificate_report_sender.h"
23 #include "net/url_request/url_request_filter.h"
19 #include "net/url_request/url_request_test_util.h" 24 #include "net/url_request/url_request_test_util.h"
20 #include "testing/gtest/include/gtest/gtest.h" 25 #include "testing/gtest/include/gtest/gtest.h"
21 #include "url/gurl.h" 26 #include "url/gurl.h"
22 27
23 namespace { 28 namespace {
24 29
25 // A test CertificateReportSender that exposes the latest report URI and 30 // A test CertificateReportSender that exposes the latest report URI and
26 // serialized report to be sent. 31 // serialized report to be sent.
27 class TestCertificateReportSender : public net::CertificateReportSender { 32 class TestCertificateReportSender : public net::CertificateReportSender {
28 public: 33 public:
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 const base::ListValue* report_invalid_scts = nullptr; 248 const base::ListValue* report_invalid_scts = nullptr;
244 ASSERT_TRUE(report_dict->GetList("invalid-scts", &report_invalid_scts)); 249 ASSERT_TRUE(report_dict->GetList("invalid-scts", &report_invalid_scts));
245 const base::ListValue* report_valid_scts = nullptr; 250 const base::ListValue* report_valid_scts = nullptr;
246 ASSERT_TRUE(report_dict->GetList("valid-scts", &report_valid_scts)); 251 ASSERT_TRUE(report_dict->GetList("valid-scts", &report_valid_scts));
247 252
248 ASSERT_NO_FATAL_FAILURE(CheckReportSCTs( 253 ASSERT_NO_FATAL_FAILURE(CheckReportSCTs(
249 ssl_info.signed_certificate_timestamps, *report_unknown_scts, 254 ssl_info.signed_certificate_timestamps, *report_unknown_scts,
250 *report_invalid_scts, *report_valid_scts)); 255 *report_invalid_scts, *report_valid_scts));
251 } 256 }
252 257
258 // A test network delegate that allows the user to specify a callback to
259 // be run whenever a net::URLRequest is destroyed.
260 class TestExpectCTNetworkDelegate : public net::NetworkDelegateImpl {
meacer 2016/04/07 18:12:11 Seems like this should derive from net::NetworkDel
estark 2016/04/07 18:25:12 Hmm, I don't think so. I don't quite understand wh
meacer 2016/04/07 18:32:29 Ok never mind. Looks like NetworkDelegateImpl is j
261 public:
262 TestExpectCTNetworkDelegate()
263 : url_request_destroyed_callback_(base::Bind(&base::DoNothing)) {}
264
265 void set_url_request_destroyed_callback(const base::Closure& callback) {
266 url_request_destroyed_callback_ = callback;
267 }
268
269 // net::NetworkDelegateImpl:
270 void OnURLRequestDestroyed(net::URLRequest* request) override {
271 url_request_destroyed_callback_.Run();
272 }
273
274 private:
275 base::Closure url_request_destroyed_callback_;
276
277 DISALLOW_COPY_AND_ASSIGN(TestExpectCTNetworkDelegate);
278 };
279
280 // A test fixture that allows tests to send a report and wait until the
281 // net::URLRequest that sent the report is destroyed.
282 class ChromeExpectCTReporterWaitTest : public ::testing::Test {
283 public:
284 ChromeExpectCTReporterWaitTest()
285 : context_(true),
286 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {
287 context_.set_network_delegate(&network_delegate_);
288 context_.Init();
289 }
290
291 void SetUp() override { net::URLRequestFailedJob::AddUrlHandler(); }
292
293 void TearDown() override {
294 net::URLRequestFilter::GetInstance()->ClearHandlers();
295 }
296
297 net::TestURLRequestContext* context() { return &context_; }
298
299 protected:
300 void SendReport(ChromeExpectCTReporter* reporter,
301 const net::HostPortPair& host_port,
302 const GURL& report_uri,
303 const net::SSLInfo& ssl_info) {
304 base::RunLoop run_loop;
305 network_delegate_.set_url_request_destroyed_callback(
306 run_loop.QuitClosure());
307 reporter->OnExpectCTFailed(host_port, report_uri, ssl_info);
308 run_loop.Run();
309 }
310
311 private:
312 TestExpectCTNetworkDelegate network_delegate_;
313 net::TestURLRequestContext context_;
314 content::TestBrowserThreadBundle thread_bundle_;
meacer 2016/04/07 18:12:11 DISALLOW_COPY_AND_ASSIGN
estark 2016/04/07 18:25:12 Done.
315 };
316
253 void EnableFeature() { 317 void EnableFeature() {
254 base::FeatureList::ClearInstanceForTesting(); 318 base::FeatureList::ClearInstanceForTesting();
255 std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList); 319 std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
256 feature_list->InitializeFromCommandLine(features::kExpectCTReporting.name, 320 feature_list->InitializeFromCommandLine(features::kExpectCTReporting.name,
257 ""); 321 "");
258 base::FeatureList::SetInstance(std::move(feature_list)); 322 base::FeatureList::SetInstance(std::move(feature_list));
259 } 323 }
260 324
261 } // namespace 325 } // namespace
262 326
(...skipping 29 matching lines...) Expand all
292 reporter.report_sender_.reset(sender); 356 reporter.report_sender_.reset(sender);
293 EXPECT_TRUE(sender->latest_report_uri().is_empty()); 357 EXPECT_TRUE(sender->latest_report_uri().is_empty());
294 EXPECT_TRUE(sender->latest_serialized_report().empty()); 358 EXPECT_TRUE(sender->latest_serialized_report().empty());
295 359
296 reporter.OnExpectCTFailed(net::HostPortPair("example.test", 443), GURL(), 360 reporter.OnExpectCTFailed(net::HostPortPair("example.test", 443), GURL(),
297 net::SSLInfo()); 361 net::SSLInfo());
298 EXPECT_TRUE(sender->latest_report_uri().is_empty()); 362 EXPECT_TRUE(sender->latest_report_uri().is_empty());
299 EXPECT_TRUE(sender->latest_serialized_report().empty()); 363 EXPECT_TRUE(sender->latest_serialized_report().empty());
300 } 364 }
301 365
366 // Test that if a report fails to send, the UMA metric is recorded.
367 TEST_F(ChromeExpectCTReporterWaitTest, SendReportFailure) {
368 EnableFeature();
369 base::HistogramTester histograms;
370 const std::string histogram_name = "SSL.ExpectCTReportFailure";
371 histograms.ExpectTotalCount(histogram_name, 0);
372
373 ChromeExpectCTReporter reporter(context());
374
375 net::SSLInfo ssl_info;
376 ssl_info.cert =
377 net::ImportCertFromFile(net::GetTestCertsDirectory(), "ok_cert.pem");
378 ssl_info.unverified_cert = net::ImportCertFromFile(
379 net::GetTestCertsDirectory(), "localhost_cert.pem");
380
381 net::HostPortPair host_port("example.test", 443);
382 GURL report_uri(
383 net::URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_FAILED));
384
385 SendReport(&reporter, host_port, report_uri, ssl_info);
386
387 histograms.ExpectTotalCount(histogram_name, 1);
388 histograms.ExpectBucketCount(histogram_name, net::ERR_CONNECTION_FAILED, 1);
389 }
390
302 // Test that a sent report has the right format. 391 // Test that a sent report has the right format.
303 TEST(ChromeExpectCTReporterTest, SendReport) { 392 TEST(ChromeExpectCTReporterTest, SendReport) {
304 EnableFeature(); 393 EnableFeature();
305 TestCertificateReportSender* sender = new TestCertificateReportSender(); 394 TestCertificateReportSender* sender = new TestCertificateReportSender();
306 net::TestURLRequestContext context; 395 net::TestURLRequestContext context;
307 ChromeExpectCTReporter reporter(&context); 396 ChromeExpectCTReporter reporter(&context);
308 reporter.report_sender_.reset(sender); 397 reporter.report_sender_.reset(sender);
309 EXPECT_TRUE(sender->latest_report_uri().is_empty()); 398 EXPECT_TRUE(sender->latest_report_uri().is_empty());
310 EXPECT_TRUE(sender->latest_serialized_report().empty()); 399 EXPECT_TRUE(sender->latest_serialized_report().empty());
311 400
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 net::HostPortPair host_port("example.test", 443); 439 net::HostPortPair host_port("example.test", 443);
351 GURL report_uri("http://example-report.test"); 440 GURL report_uri("http://example-report.test");
352 441
353 // Check that the report is sent and contains the correct information. 442 // Check that the report is sent and contains the correct information.
354 reporter.OnExpectCTFailed(host_port, report_uri, ssl_info); 443 reporter.OnExpectCTFailed(host_port, report_uri, ssl_info);
355 EXPECT_EQ(report_uri, sender->latest_report_uri()); 444 EXPECT_EQ(report_uri, sender->latest_report_uri());
356 EXPECT_FALSE(sender->latest_serialized_report().empty()); 445 EXPECT_FALSE(sender->latest_serialized_report().empty());
357 ASSERT_NO_FATAL_FAILURE(CheckExpectCTReport( 446 ASSERT_NO_FATAL_FAILURE(CheckExpectCTReport(
358 sender->latest_serialized_report(), host_port, ssl_info)); 447 sender->latest_serialized_report(), host_port, ssl_info));
359 } 448 }
OLDNEW
« no previous file with comments | « chrome/browser/ssl/chrome_expect_ct_reporter.cc ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698