net_metrics_log_uploader_unittest.cc 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // Copyright 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/metrics/net/net_metrics_log_uploader.h"
  5. #include <memory>
  6. #include "base/base64.h"
  7. #include "base/bind.h"
  8. #include "base/run_loop.h"
  9. #include "base/test/bind.h"
  10. #include "base/test/task_environment.h"
  11. #include "components/encrypted_messages/encrypted_message.pb.h"
  12. #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
  13. #include "services/network/test/test_url_loader_factory.h"
  14. #include "services/network/test/test_utils.h"
  15. #include "testing/gtest/include/gtest/gtest.h"
  16. #include "third_party/metrics_proto/reporting_info.pb.h"
  17. #include "third_party/zlib/google/compression_utils.h"
  18. #include "url/gurl.h"
  19. namespace metrics {
  20. class NetMetricsLogUploaderTest : public testing::Test {
  21. public:
  22. NetMetricsLogUploaderTest()
  23. : on_upload_complete_count_(0),
  24. test_shared_url_loader_factory_(
  25. base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
  26. &test_url_loader_factory_)) {
  27. test_url_loader_factory_.SetInterceptor(base::BindLambdaForTesting(
  28. [&](const network::ResourceRequest& request) {
  29. upload_data_ = network::GetUploadData(request);
  30. headers_ = request.headers;
  31. loop_.Quit();
  32. }));
  33. }
  34. NetMetricsLogUploaderTest(const NetMetricsLogUploaderTest&) = delete;
  35. NetMetricsLogUploaderTest& operator=(const NetMetricsLogUploaderTest&) =
  36. delete;
  37. void CreateAndOnUploadCompleteReuseUploader() {
  38. ReportingInfo reporting_info;
  39. reporting_info.set_attempt_count(10);
  40. uploader_ = std::make_unique<NetMetricsLogUploader>(
  41. test_shared_url_loader_factory_, GURL("https://dummy_server"),
  42. "dummy_mime", MetricsLogUploader::UMA,
  43. base::BindRepeating(
  44. &NetMetricsLogUploaderTest::OnUploadCompleteReuseUploader,
  45. base::Unretained(this)));
  46. uploader_->UploadLog("initial_dummy_data", "initial_dummy_hash",
  47. "initial_dummy_signature", reporting_info);
  48. }
  49. void CreateUploaderAndUploadToSecureURL(const std::string& url) {
  50. ReportingInfo dummy_reporting_info;
  51. uploader_ = std::make_unique<NetMetricsLogUploader>(
  52. test_shared_url_loader_factory_, GURL(url), "dummy_mime",
  53. MetricsLogUploader::UMA,
  54. base::BindRepeating(&NetMetricsLogUploaderTest::DummyOnUploadComplete,
  55. base::Unretained(this)));
  56. uploader_->UploadLog("dummy_data", "dummy_hash", "dummy_signature",
  57. dummy_reporting_info);
  58. }
  59. void CreateUploaderAndUploadToInsecureURL() {
  60. ReportingInfo dummy_reporting_info;
  61. uploader_ = std::make_unique<NetMetricsLogUploader>(
  62. test_shared_url_loader_factory_, GURL("http://dummy_insecure_server"),
  63. "dummy_mime", MetricsLogUploader::UMA,
  64. base::BindRepeating(&NetMetricsLogUploaderTest::DummyOnUploadComplete,
  65. base::Unretained(this)));
  66. std::string compressed_message;
  67. // Compress the data since the encryption code expects a compressed log,
  68. // and tries to decompress it before encrypting it.
  69. compression::GzipCompress("dummy_data", &compressed_message);
  70. uploader_->UploadLog(compressed_message, "dummy_hash", "dummy_signature",
  71. dummy_reporting_info);
  72. }
  73. void DummyOnUploadComplete(int response_code,
  74. int error_code,
  75. bool was_https) {}
  76. void OnUploadCompleteReuseUploader(int response_code,
  77. int error_code,
  78. bool was_https) {
  79. ++on_upload_complete_count_;
  80. if (on_upload_complete_count_ == 1) {
  81. ReportingInfo reporting_info;
  82. reporting_info.set_attempt_count(20);
  83. uploader_->UploadLog("dummy_data", "dummy_hash", "dummy_signature",
  84. reporting_info);
  85. }
  86. }
  87. int on_upload_complete_count() const {
  88. return on_upload_complete_count_;
  89. }
  90. network::TestURLLoaderFactory* test_url_loader_factory() {
  91. return &test_url_loader_factory_;
  92. }
  93. const net::HttpRequestHeaders& last_request_headers() { return headers_; }
  94. const std::string& last_upload_data() { return upload_data_; }
  95. void WaitForRequest() { loop_.Run(); }
  96. private:
  97. std::unique_ptr<NetMetricsLogUploader> uploader_;
  98. int on_upload_complete_count_;
  99. network::TestURLLoaderFactory test_url_loader_factory_;
  100. scoped_refptr<network::SharedURLLoaderFactory>
  101. test_shared_url_loader_factory_;
  102. base::test::TaskEnvironment task_environment_;
  103. base::RunLoop loop_;
  104. std::string upload_data_;
  105. net::HttpRequestHeaders headers_;
  106. };
  107. void CheckReportingInfoHeader(net::HttpRequestHeaders headers,
  108. int expected_attempt_count) {
  109. std::string reporting_info_base64;
  110. EXPECT_TRUE(
  111. headers.GetHeader("X-Chrome-UMA-ReportingInfo", &reporting_info_base64));
  112. std::string reporting_info_string;
  113. EXPECT_TRUE(
  114. base::Base64Decode(reporting_info_base64, &reporting_info_string));
  115. ReportingInfo reporting_info;
  116. EXPECT_TRUE(reporting_info.ParseFromString(reporting_info_string));
  117. EXPECT_EQ(reporting_info.attempt_count(), expected_attempt_count);
  118. }
  119. TEST_F(NetMetricsLogUploaderTest, OnUploadCompleteReuseUploader) {
  120. CreateAndOnUploadCompleteReuseUploader();
  121. WaitForRequest();
  122. // Mimic the initial fetcher callback.
  123. CheckReportingInfoHeader(last_request_headers(), 10);
  124. auto* pending_request_0 = test_url_loader_factory()->GetPendingRequest(0);
  125. test_url_loader_factory()->SimulateResponseWithoutRemovingFromPendingList(
  126. pending_request_0, "");
  127. // Mimic the second fetcher callback.
  128. CheckReportingInfoHeader(last_request_headers(), 20);
  129. auto* pending_request_1 = test_url_loader_factory()->GetPendingRequest(1);
  130. test_url_loader_factory()->SimulateResponseWithoutRemovingFromPendingList(
  131. pending_request_1, "");
  132. EXPECT_EQ(on_upload_complete_count(), 2);
  133. }
  134. // Test that attempting to upload to an HTTP URL results in an encrypted
  135. // message.
  136. TEST_F(NetMetricsLogUploaderTest, MessageOverHTTPIsEncrypted) {
  137. CreateUploaderAndUploadToInsecureURL();
  138. WaitForRequest();
  139. encrypted_messages::EncryptedMessage message;
  140. EXPECT_TRUE(message.ParseFromString(last_upload_data()));
  141. }
  142. // Test that attempting to upload to an HTTPS URL results in an unencrypted
  143. // message.
  144. TEST_F(NetMetricsLogUploaderTest, MessageOverHTTPSIsNotEncrypted) {
  145. CreateUploaderAndUploadToSecureURL("https://dummy_secure_server");
  146. WaitForRequest();
  147. EXPECT_EQ(last_upload_data(), "dummy_data");
  148. }
  149. // Test that attempting to upload to localhost over http results in an
  150. // unencrypted message.
  151. TEST_F(NetMetricsLogUploaderTest, MessageOverHTTPLocalhostIsNotEncrypted) {
  152. CreateUploaderAndUploadToSecureURL("http://localhost");
  153. WaitForRequest();
  154. EXPECT_EQ(last_upload_data(), "dummy_data");
  155. }
  156. } // namespace metrics