blob: 70112f4a9641bb8deb390713ffbf1fa25535fbfc [file] [log] [blame]
Bertrand SIMONNET52e5b992015-08-10 15:18:00 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070016
Bertrand SIMONNET6c9fbb92015-12-21 14:56:40 -080017#include <memory>
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070018
Bertrand SIMONNET12531862015-08-31 11:11:57 -070019#include <base/at_exit.h>
20#include <base/files/file_util.h>
21#include <base/files/scoped_temp_dir.h>
22#include <base/logging.h>
Bertrand SIMONNET6b8629a2015-11-18 13:46:33 -080023#include <base/metrics/sparse_histogram.h>
24#include <base/metrics/statistics_recorder.h>
Bertrand SIMONNET12531862015-08-31 11:11:57 -070025#include <base/sys_info.h>
Bertrand SIMONNET6c9fbb92015-12-21 14:56:40 -080026#include <gtest/gtest.h>
Bertrand SIMONNET12531862015-08-31 11:11:57 -070027
28#include "constants.h"
Bertrand SIMONNET1df10c42015-09-09 10:39:51 -070029#include "persistent_integer.h"
Bertrand SIMONNET4b915ae2015-07-28 15:38:14 -070030#include "uploader/metrics_log.h"
31#include "uploader/mock/mock_system_profile_setter.h"
32#include "uploader/mock/sender_mock.h"
33#include "uploader/proto/chrome_user_metrics_extension.pb.h"
34#include "uploader/proto/histogram_event.pb.h"
35#include "uploader/proto/system_profile.pb.h"
36#include "uploader/system_profile_cache.h"
37#include "uploader/upload_service.h"
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070038
39class UploadServiceTest : public testing::Test {
40 protected:
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070041 virtual void SetUp() {
42 CHECK(dir_.CreateUniqueTempDir());
Bertrand SIMONNET6b8629a2015-11-18 13:46:33 -080043 // Make sure the statistics recorder is inactive (contains no metrics) then
44 // initialize it.
45 ASSERT_FALSE(base::StatisticsRecorder::IsActive());
46 base::StatisticsRecorder::Initialize();
Bertrand SIMONNET9d3a4ae2015-11-25 13:49:12 -080047
Bertrand SIMONNET05865042015-12-15 12:33:01 -080048 private_dir_ = dir_.path().Append("private");
49 shared_dir_ = dir_.path().Append("shared");
Bertrand SIMONNET9d3a4ae2015-11-25 13:49:12 -080050
Bertrand SIMONNET05865042015-12-15 12:33:01 -080051 EXPECT_TRUE(base::CreateDirectory(private_dir_));
52 EXPECT_TRUE(base::CreateDirectory(shared_dir_));
Bertrand SIMONNET9d3a4ae2015-11-25 13:49:12 -080053
Bertrand SIMONNET05865042015-12-15 12:33:01 -080054 ASSERT_EQ(0, base::WriteFile(shared_dir_.Append(metrics::kConsentFileName),
Bertrand SIMONNET9d3a4ae2015-11-25 13:49:12 -080055 "", 0));
Bertrand SIMONNET6b8629a2015-11-18 13:46:33 -080056
Bertrand SIMONNET05865042015-12-15 12:33:01 -080057 upload_service_.reset(new UploadService(
58 "", base::TimeDelta(), base::TimeDelta(), private_dir_, shared_dir_));
Bertrand SIMONNETb6c77af2015-12-08 17:46:00 -080059 counters_ = upload_service_->counters_;
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070060
Bertrand SIMONNET12531862015-08-31 11:11:57 -070061 upload_service_->sender_.reset(new SenderMock);
Bertrand SIMONNET608e4282015-11-12 17:52:17 -080062 upload_service_->InitForTest(new MockSystemProfileSetter);
Bertrand SIMONNET12531862015-08-31 11:11:57 -070063 upload_service_->GatherHistograms();
64 upload_service_->Reset();
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070065 }
66
Bertrand SIMONNET6b8629a2015-11-18 13:46:33 -080067 void SendSparseHistogram(const std::string& name, int sample) {
68 base::HistogramBase* histogram = base::SparseHistogram::FactoryGet(
69 name, base::Histogram::kUmaTargetedHistogramFlag);
70 histogram->Add(sample);
71 }
72
73 void SendHistogram(
74 const std::string& name, int sample, int min, int max, int nbuckets) {
75 base::HistogramBase* histogram = base::Histogram::FactoryGet(
76 name, min, max, nbuckets, base::Histogram::kUmaTargetedHistogramFlag);
77 histogram->Add(sample);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070078 }
79
Bertrand SIMONNET12531862015-08-31 11:11:57 -070080 void SetTestingProperty(const std::string& name, const std::string& value) {
Bertrand SIMONNET608e4282015-11-12 17:52:17 -080081 base::FilePath filepath =
82 dir_.path().Append("etc/os-release.d").Append(name);
Bertrand SIMONNETeb697ab2015-10-14 13:26:42 -070083 ASSERT_TRUE(base::CreateDirectory(filepath.DirName()));
Bertrand SIMONNET05865042015-12-15 12:33:01 -080084 ASSERT_EQ(value.size(),
85 base::WriteFile(filepath, value.data(), value.size()));
Bertrand SIMONNET12531862015-08-31 11:11:57 -070086 }
87
Bertrand SIMONNET6b8629a2015-11-18 13:46:33 -080088 const metrics::SystemProfileProto_Stability GetCurrentStability() {
Bertrand SIMONNET6c9fbb92015-12-21 14:56:40 -080089 EXPECT_TRUE(upload_service_->current_log_.get());
Bertrand SIMONNET6b8629a2015-11-18 13:46:33 -080090
Bertrand SIMONNET05865042015-12-15 12:33:01 -080091 return upload_service_->current_log_->uma_proto()
92 ->system_profile()
93 .stability();
Bertrand SIMONNET6b8629a2015-11-18 13:46:33 -080094 }
95
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070096 base::ScopedTempDir dir_;
Bertrand SIMONNET6c9fbb92015-12-21 14:56:40 -080097 std::unique_ptr<UploadService> upload_service_;
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070098
Bertrand SIMONNET6c9fbb92015-12-21 14:56:40 -080099 std::unique_ptr<base::AtExitManager> exit_manager_;
Bertrand SIMONNET6b8629a2015-11-18 13:46:33 -0800100 std::shared_ptr<CrashCounters> counters_;
Bertrand SIMONNET05865042015-12-15 12:33:01 -0800101 base::FilePath private_dir_;
102 base::FilePath shared_dir_;
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700103};
104
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700105TEST_F(UploadServiceTest, FailedSendAreRetried) {
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700106 SenderMock* sender = new SenderMock();
107 upload_service_->sender_.reset(sender);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700108
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700109 sender->set_should_succeed(false);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700110
Bertrand SIMONNET6b8629a2015-11-18 13:46:33 -0800111 SendSparseHistogram("hello", 1);
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700112 upload_service_->UploadEvent();
113 EXPECT_EQ(1, sender->send_call_count());
114 std::string sent_string = sender->last_message();
115
116 upload_service_->UploadEvent();
117 EXPECT_EQ(2, sender->send_call_count());
118 EXPECT_EQ(sent_string, sender->last_message());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700119}
120
121TEST_F(UploadServiceTest, DiscardLogsAfterTooManyFailedUpload) {
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700122 SenderMock* sender = new SenderMock();
123 upload_service_->sender_.reset(sender);
124
125 sender->set_should_succeed(false);
126
Bertrand SIMONNET6b8629a2015-11-18 13:46:33 -0800127 SendSparseHistogram("hello", 1);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700128
129 for (int i = 0; i < UploadService::kMaxFailedUpload; i++) {
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700130 upload_service_->UploadEvent();
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700131 }
132
Bertrand SIMONNET1df10c42015-09-09 10:39:51 -0700133 EXPECT_TRUE(upload_service_->HasStagedLog());
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700134 upload_service_->UploadEvent();
Bertrand SIMONNET1df10c42015-09-09 10:39:51 -0700135 EXPECT_FALSE(upload_service_->HasStagedLog());
136
137 // Log a new sample. The failed upload counter should be reset.
Bertrand SIMONNET6b8629a2015-11-18 13:46:33 -0800138 SendSparseHistogram("hello", 1);
Bertrand SIMONNET1df10c42015-09-09 10:39:51 -0700139 for (int i = 0; i < UploadService::kMaxFailedUpload; i++) {
140 upload_service_->UploadEvent();
141 }
142 // The log is not discarded after multiple failed uploads.
143 EXPECT_TRUE(upload_service_->HasStagedLog());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700144}
145
146TEST_F(UploadServiceTest, EmptyLogsAreNotSent) {
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700147 SenderMock* sender = new SenderMock();
148 upload_service_->sender_.reset(sender);
149 upload_service_->UploadEvent();
150 EXPECT_FALSE(upload_service_->current_log_);
151 EXPECT_EQ(0, sender->send_call_count());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700152}
153
154TEST_F(UploadServiceTest, LogEmptyByDefault) {
Bertrand SIMONNETb6c77af2015-12-08 17:46:00 -0800155 // current_log_ should be initialized later as it needs AtExitManager to exist
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700156 // in order to gather system information from SysInfo.
Bertrand SIMONNETb6c77af2015-12-08 17:46:00 -0800157 EXPECT_FALSE(upload_service_->current_log_);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700158}
159
160TEST_F(UploadServiceTest, CanSendMultipleTimes) {
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700161 SenderMock* sender = new SenderMock();
162 upload_service_->sender_.reset(sender);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700163
Bertrand SIMONNET6b8629a2015-11-18 13:46:33 -0800164 SendSparseHistogram("hello", 1);
165
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700166 upload_service_->UploadEvent();
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700167
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700168 std::string first_message = sender->last_message();
Bertrand SIMONNET6b8629a2015-11-18 13:46:33 -0800169 SendSparseHistogram("hello", 2);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700170
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700171 upload_service_->UploadEvent();
172
173 EXPECT_NE(first_message, sender->last_message());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700174}
175
176TEST_F(UploadServiceTest, LogEmptyAfterUpload) {
Bertrand SIMONNET6b8629a2015-11-18 13:46:33 -0800177 SendSparseHistogram("hello", 2);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700178
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700179 upload_service_->UploadEvent();
180 EXPECT_FALSE(upload_service_->current_log_);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700181}
182
183TEST_F(UploadServiceTest, LogContainsAggregatedValues) {
Bertrand SIMONNET6b8629a2015-11-18 13:46:33 -0800184 SendHistogram("foo", 11, 0, 42, 10);
185 SendHistogram("foo", 12, 0, 42, 10);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700186
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700187 upload_service_->GatherHistograms();
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700188 metrics::ChromeUserMetricsExtension* proto =
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700189 upload_service_->current_log_->uma_proto();
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700190 EXPECT_EQ(1, proto->histogram_event().size());
191}
192
Bertrand SIMONNET6b8629a2015-11-18 13:46:33 -0800193TEST_F(UploadServiceTest, LogContainsCrashCounts) {
194 // By default, there is no current log.
195 upload_service_->GatherHistograms();
196 EXPECT_FALSE(upload_service_->current_log_);
197
198 // If the user crash counter is incremented, we add the count to the current
199 // log.
200 counters_->IncrementUserCrashCount();
201 upload_service_->GatherHistograms();
202 EXPECT_EQ(1, GetCurrentStability().other_user_crash_count());
203
204 // If the kernel crash counter is incremented, we add the count to the current
205 // log.
206 counters_->IncrementKernelCrashCount();
207 upload_service_->GatherHistograms();
208 EXPECT_EQ(1, GetCurrentStability().kernel_crash_count());
209
210 // If the kernel crash counter is incremented, we add the count to the current
211 // log.
212 counters_->IncrementUncleanShutdownCount();
213 counters_->IncrementUncleanShutdownCount();
214 upload_service_->GatherHistograms();
215 EXPECT_EQ(2, GetCurrentStability().unclean_system_shutdown_count());
216
217 // If no counter is incremented, the reported numbers don't change.
218 upload_service_->GatherHistograms();
219 EXPECT_EQ(1, GetCurrentStability().other_user_crash_count());
220 EXPECT_EQ(1, GetCurrentStability().kernel_crash_count());
221 EXPECT_EQ(2, GetCurrentStability().unclean_system_shutdown_count());
222}
223
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700224TEST_F(UploadServiceTest, ExtractChannelFromString) {
Bertrand SIMONNET05865042015-12-15 12:33:01 -0800225 EXPECT_EQ(SystemProfileCache::ProtoChannelFromString("developer-build"),
226 metrics::SystemProfileProto::CHANNEL_UNKNOWN);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700227
228 EXPECT_EQ(metrics::SystemProfileProto::CHANNEL_DEV,
Bertrand SIMONNETdc225c82015-11-12 14:04:03 -0800229 SystemProfileCache::ProtoChannelFromString("dev-channel"));
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700230
231 EXPECT_EQ(metrics::SystemProfileProto::CHANNEL_STABLE,
Bertrand SIMONNETdc225c82015-11-12 14:04:03 -0800232 SystemProfileCache::ProtoChannelFromString("stable-channel"));
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700233
234 EXPECT_EQ(metrics::SystemProfileProto::CHANNEL_UNKNOWN,
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700235 SystemProfileCache::ProtoChannelFromString("this is a test"));
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700236}
237
238TEST_F(UploadServiceTest, ValuesInConfigFileAreSent) {
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700239 SenderMock* sender = new SenderMock();
240 upload_service_->sender_.reset(sender);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700241
Bertrand SIMONNETeb697ab2015-10-14 13:26:42 -0700242 SetTestingProperty(metrics::kProductId, "hello");
243 SetTestingProperty(metrics::kProductVersion, "1.2.3.4");
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700244
Bertrand SIMONNET6b8629a2015-11-18 13:46:33 -0800245 SendSparseHistogram("hello", 1);
246
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700247 // Reset to create the new log with the profile setter.
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700248 upload_service_->system_profile_setter_.reset(
249 new SystemProfileCache(true, dir_.path()));
250 upload_service_->Reset();
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700251 upload_service_->UploadEvent();
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700252
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700253 EXPECT_EQ(1, sender->send_call_count());
254 EXPECT_TRUE(sender->is_good_proto());
255 EXPECT_EQ(1, sender->last_message_proto().histogram_event().size());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700256
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700257 EXPECT_NE(0, sender->last_message_proto().client_id());
258 EXPECT_NE(0, sender->last_message_proto().system_profile().build_timestamp());
259 EXPECT_NE(0, sender->last_message_proto().session_id());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700260}
261
262TEST_F(UploadServiceTest, PersistentGUID) {
263 std::string tmp_file = dir_.path().Append("tmpfile").value();
264
265 std::string first_guid = SystemProfileCache::GetPersistentGUID(tmp_file);
266 std::string second_guid = SystemProfileCache::GetPersistentGUID(tmp_file);
267
268 // The GUID are cached.
269 EXPECT_EQ(first_guid, second_guid);
270
271 base::DeleteFile(base::FilePath(tmp_file), false);
272
273 first_guid = SystemProfileCache::GetPersistentGUID(tmp_file);
274 base::DeleteFile(base::FilePath(tmp_file), false);
275 second_guid = SystemProfileCache::GetPersistentGUID(tmp_file);
276
277 // Random GUIDs are generated (not all the same).
278 EXPECT_NE(first_guid, second_guid);
279}
280
281TEST_F(UploadServiceTest, SessionIdIncrementedAtInitialization) {
Bertrand SIMONNETeb697ab2015-10-14 13:26:42 -0700282 SetTestingProperty(metrics::kProductId, "hello");
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700283 SystemProfileCache cache(true, dir_.path());
284 cache.Initialize();
285 int session_id = cache.profile_.session_id;
286 cache.initialized_ = false;
287 cache.Initialize();
288 EXPECT_EQ(cache.profile_.session_id, session_id + 1);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700289}
Bertrand SIMONNET4c8a8ad2015-09-09 13:27:33 -0700290
Bertrand SIMONNET1d15d462015-11-17 13:20:06 -0800291// The product id must be set for metrics to be uploaded.
292// If it is not set, the system profile cache should fail to initialize.
293TEST_F(UploadServiceTest, ProductIdMandatory) {
294 SystemProfileCache cache(true, dir_.path());
295 ASSERT_FALSE(cache.Initialize());
296 SetTestingProperty(metrics::kProductId, "");
297 ASSERT_FALSE(cache.Initialize());
298 SetTestingProperty(metrics::kProductId, "hello");
299 ASSERT_TRUE(cache.Initialize());
300}
Bertrand SIMONNET05865042015-12-15 12:33:01 -0800301
302TEST_F(UploadServiceTest, CurrentLogSavedAndResumed) {
303 SendHistogram("hello", 10, 0, 100, 10);
304 upload_service_->PersistToDisk();
305 EXPECT_EQ(
306 1, upload_service_->current_log_->uma_proto()->histogram_event().size());
307 upload_service_.reset(new UploadService(
308 "", base::TimeDelta(), base::TimeDelta(), private_dir_, shared_dir_));
309 upload_service_->InitForTest(nullptr);
310
311 SendHistogram("hello", 10, 0, 100, 10);
312 upload_service_->GatherHistograms();
313 EXPECT_EQ(2, upload_service_->GetOrCreateCurrentLog()
314 ->uma_proto()
315 ->histogram_event()
316 .size());
317}
318
319TEST_F(UploadServiceTest, PersistEmptyLog) {
320 upload_service_->PersistToDisk();
321 EXPECT_FALSE(base::PathExists(upload_service_->saved_log_path_));
322}
323
324TEST_F(UploadServiceTest, CorruptedSavedLog) {
325 // Write a bogus saved log.
326 EXPECT_EQ(5, base::WriteFile(upload_service_->saved_log_path_, "hello", 5));
327
328 upload_service_.reset(new UploadService(
329 "", base::TimeDelta(), base::TimeDelta(), private_dir_, shared_dir_));
330
331 upload_service_->InitForTest(nullptr);
332 // If the log is unreadable, we drop it and continue execution.
333 ASSERT_NE(nullptr, upload_service_->GetOrCreateCurrentLog());
334 ASSERT_FALSE(base::PathExists(upload_service_->saved_log_path_));
335}