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