1 // Copyright 2014 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 
5 #include "components/metrics/reporting_service.h"
6 
7 #include <stdint.h>
8 
9 #include <deque>
10 #include <memory>
11 #include <string>
12 
13 #include "base/bind.h"
14 #include "base/hash/sha1.h"
15 #include "base/macros.h"
16 #include "base/strings/string_util.h"
17 #include "base/test/test_simple_task_runner.h"
18 #include "base/threading/thread_task_runner_handle.h"
19 #include "components/metrics/log_store.h"
20 #include "components/metrics/test/test_metrics_service_client.h"
21 #include "components/prefs/testing_pref_service.h"
22 #include "testing/gtest/include/gtest/gtest.h"
23 #include "third_party/zlib/google/compression_utils.h"
24 
25 namespace metrics {
26 
27 namespace {
28 
29 const char kTestUploadUrl[] = "test_url";
30 const char kTestMimeType[] = "test_mime_type";
31 
32 class TestLogStore : public LogStore {
33  public:
TestLogStore()34   TestLogStore() {}
~TestLogStore()35   ~TestLogStore() {}
36 
AddLog(const std::string & log)37   void AddLog(const std::string& log) { logs_.push_back(log); }
38 
39   // LogStore:
has_unsent_logs() const40   bool has_unsent_logs() const override { return !logs_.empty(); }
has_staged_log() const41   bool has_staged_log() const override { return !staged_log_hash_.empty(); }
staged_log() const42   const std::string& staged_log() const override { return logs_.front(); }
staged_log_hash() const43   const std::string& staged_log_hash() const override {
44     return staged_log_hash_;
45   }
staged_log_signature() const46   const std::string& staged_log_signature() const override {
47     return base::EmptyString();
48   }
StageNextLog()49   void StageNextLog() override {
50     if (has_unsent_logs())
51       staged_log_hash_ = base::SHA1HashString(logs_.front());
52   }
DiscardStagedLog()53   void DiscardStagedLog() override {
54     if (!has_staged_log())
55       return;
56     logs_.pop_front();
57     staged_log_hash_.clear();
58   }
MarkStagedLogAsSent()59   void MarkStagedLogAsSent() override {}
TrimAndPersistUnsentLogs()60   void TrimAndPersistUnsentLogs() override {}
LoadPersistedUnsentLogs()61   void LoadPersistedUnsentLogs() override {}
62 
63  private:
64   std::string staged_log_hash_;
65   std::deque<std::string> logs_;
66 };
67 
68 class TestReportingService : public ReportingService {
69  public:
TestReportingService(MetricsServiceClient * client,PrefService * local_state)70   TestReportingService(MetricsServiceClient* client, PrefService* local_state)
71       : ReportingService(client, local_state, 100) {
72     Initialize();
73   }
~TestReportingService()74   ~TestReportingService() override {}
75 
AddLog(const std::string & log)76   void AddLog(const std::string& log) { log_store_.AddLog(log); }
77 
78  private:
79   // ReportingService:
log_store()80   LogStore* log_store() override { return &log_store_; }
GetUploadUrl() const81   GURL GetUploadUrl() const override { return GURL(kTestUploadUrl); }
GetInsecureUploadUrl() const82   GURL GetInsecureUploadUrl() const override { return GURL(kTestUploadUrl); }
upload_mime_type() const83   base::StringPiece upload_mime_type() const override { return kTestMimeType; }
service_type() const84   MetricsLogUploader::MetricServiceType service_type() const override {
85     return MetricsLogUploader::MetricServiceType::UMA;
86   }
87 
88   TestLogStore log_store_;
89 
90   DISALLOW_COPY_AND_ASSIGN(TestReportingService);
91 };
92 
93 class ReportingServiceTest : public testing::Test {
94  public:
ReportingServiceTest()95   ReportingServiceTest()
96       : task_runner_(new base::TestSimpleTaskRunner),
97         task_runner_handle_(task_runner_) {
98     ReportingService::RegisterPrefs(testing_local_state_.registry());
99   }
100 
~ReportingServiceTest()101   ~ReportingServiceTest() override {}
102 
GetLocalState()103   PrefService* GetLocalState() { return &testing_local_state_; }
104 
105  protected:
106   scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
107   base::ThreadTaskRunnerHandle task_runner_handle_;
108   TestMetricsServiceClient client_;
109 
110  private:
111   TestingPrefServiceSimple testing_local_state_;
112 
113   DISALLOW_COPY_AND_ASSIGN(ReportingServiceTest);
114 };
115 
116 }  // namespace
117 
TEST_F(ReportingServiceTest,BasicTest)118 TEST_F(ReportingServiceTest, BasicTest) {
119   TestReportingService service(&client_, GetLocalState());
120   service.AddLog("log1");
121   service.AddLog("log2");
122 
123   service.EnableReporting();
124   task_runner_->RunPendingTasks();
125   client_.uploader()->is_uploading();
126   EXPECT_TRUE(client_.uploader()->is_uploading());
127   EXPECT_EQ(1, client_.uploader()->reporting_info().attempt_count());
128   EXPECT_FALSE(client_.uploader()->reporting_info().has_last_response_code());
129 
130   client_.uploader()->CompleteUpload(404);
131   task_runner_->RunPendingTasks();
132   EXPECT_TRUE(client_.uploader()->is_uploading());
133   EXPECT_EQ(2, client_.uploader()->reporting_info().attempt_count());
134   EXPECT_EQ(404, client_.uploader()->reporting_info().last_response_code());
135 
136   client_.uploader()->CompleteUpload(200);
137   task_runner_->RunPendingTasks();
138   EXPECT_TRUE(client_.uploader()->is_uploading());
139   EXPECT_EQ(1, client_.uploader()->reporting_info().attempt_count());
140   EXPECT_EQ(200, client_.uploader()->reporting_info().last_response_code());
141 
142   client_.uploader()->CompleteUpload(200);
143   EXPECT_EQ(0U, task_runner_->NumPendingTasks());
144   EXPECT_FALSE(client_.uploader()->is_uploading());
145 }
146 
147 }  // namespace metrics
148