blob: c77b3424c7c44e71d453d54549a304ceb0b3655e [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
17#include <gtest/gtest.h>
18
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>
23#include <base/sys_info.h>
24
25#include "constants.h"
Samuel Tan28a78b72015-09-23 14:39:35 -070026#include "metrics/metrics_library_mock.h"
Bertrand SIMONNET1df10c42015-09-09 10:39:51 -070027#include "persistent_integer.h"
Bertrand SIMONNET4b915ae2015-07-28 15:38:14 -070028#include "serialization/metric_sample.h"
29#include "uploader/metrics_log.h"
30#include "uploader/mock/mock_system_profile_setter.h"
31#include "uploader/mock/sender_mock.h"
32#include "uploader/proto/chrome_user_metrics_extension.pb.h"
33#include "uploader/proto/histogram_event.pb.h"
34#include "uploader/proto/system_profile.pb.h"
35#include "uploader/system_profile_cache.h"
36#include "uploader/upload_service.h"
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070037
38class UploadServiceTest : public testing::Test {
39 protected:
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070040 virtual void SetUp() {
41 CHECK(dir_.CreateUniqueTempDir());
Bertrand SIMONNET4c8a8ad2015-09-09 13:27:33 -070042 metrics_lib_.InitForTest(dir_.path());
Bertrand SIMONNET3598d952015-09-28 11:04:29 -070043 ASSERT_EQ(0, base::WriteFile(
44 dir_.path().Append(metrics::kConsentFileName), "", 0));
Bertrand SIMONNET608e4282015-11-12 17:52:17 -080045 upload_service_.reset(new UploadService("", base::TimeDelta(),
46 dir_.path()));
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070047
Bertrand SIMONNET12531862015-08-31 11:11:57 -070048 upload_service_->sender_.reset(new SenderMock);
Bertrand SIMONNET608e4282015-11-12 17:52:17 -080049 upload_service_->InitForTest(new MockSystemProfileSetter);
Bertrand SIMONNET12531862015-08-31 11:11:57 -070050 upload_service_->GatherHistograms();
51 upload_service_->Reset();
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070052 }
53
54 scoped_ptr<metrics::MetricSample> Crash(const std::string& name) {
55 return metrics::MetricSample::CrashSample(name);
56 }
57
Bertrand SIMONNET12531862015-08-31 11:11:57 -070058 void SetTestingProperty(const std::string& name, const std::string& value) {
Bertrand SIMONNET608e4282015-11-12 17:52:17 -080059 base::FilePath filepath =
60 dir_.path().Append("etc/os-release.d").Append(name);
Bertrand SIMONNETeb697ab2015-10-14 13:26:42 -070061 ASSERT_TRUE(base::CreateDirectory(filepath.DirName()));
Bertrand SIMONNET12531862015-08-31 11:11:57 -070062 ASSERT_EQ(
63 value.size(),
Bertrand SIMONNETeb697ab2015-10-14 13:26:42 -070064 base::WriteFile(filepath, value.data(), value.size()));
Bertrand SIMONNET12531862015-08-31 11:11:57 -070065 }
66
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070067 base::ScopedTempDir dir_;
Bertrand SIMONNET12531862015-08-31 11:11:57 -070068 scoped_ptr<UploadService> upload_service_;
Bertrand SIMONNET4c8a8ad2015-09-09 13:27:33 -070069 MetricsLibrary metrics_lib_;
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070070
71 scoped_ptr<base::AtExitManager> exit_manager_;
72};
73
74// Tests that the right crash increments a values.
75TEST_F(UploadServiceTest, LogUserCrash) {
Bertrand SIMONNET12531862015-08-31 11:11:57 -070076 upload_service_->AddSample(*Crash("user").get());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070077
Bertrand SIMONNET12531862015-08-31 11:11:57 -070078 MetricsLog* log = upload_service_->current_log_.get();
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070079 metrics::ChromeUserMetricsExtension* proto = log->uma_proto();
80
81 EXPECT_EQ(1, proto->system_profile().stability().other_user_crash_count());
82}
83
84TEST_F(UploadServiceTest, LogUncleanShutdown) {
Bertrand SIMONNET12531862015-08-31 11:11:57 -070085 upload_service_->AddSample(*Crash("uncleanshutdown"));
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070086
Bertrand SIMONNET12531862015-08-31 11:11:57 -070087 EXPECT_EQ(1, upload_service_->current_log_
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070088 ->uma_proto()
89 ->system_profile()
90 .stability()
91 .unclean_system_shutdown_count());
92}
93
94TEST_F(UploadServiceTest, LogKernelCrash) {
Bertrand SIMONNET12531862015-08-31 11:11:57 -070095 upload_service_->AddSample(*Crash("kernel"));
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070096
Bertrand SIMONNET12531862015-08-31 11:11:57 -070097 EXPECT_EQ(1, upload_service_->current_log_
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -070098 ->uma_proto()
99 ->system_profile()
100 .stability()
101 .kernel_crash_count());
102}
103
104TEST_F(UploadServiceTest, UnknownCrashIgnored) {
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700105 upload_service_->AddSample(*Crash("foo"));
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700106
107 // The log should be empty.
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700108 EXPECT_FALSE(upload_service_->current_log_);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700109}
110
111TEST_F(UploadServiceTest, FailedSendAreRetried) {
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700112 SenderMock* sender = new SenderMock();
113 upload_service_->sender_.reset(sender);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700114
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700115 sender->set_should_succeed(false);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700116
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700117 upload_service_->AddSample(*Crash("user"));
118 upload_service_->UploadEvent();
119 EXPECT_EQ(1, sender->send_call_count());
120 std::string sent_string = sender->last_message();
121
122 upload_service_->UploadEvent();
123 EXPECT_EQ(2, sender->send_call_count());
124 EXPECT_EQ(sent_string, sender->last_message());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700125}
126
127TEST_F(UploadServiceTest, DiscardLogsAfterTooManyFailedUpload) {
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700128 SenderMock* sender = new SenderMock();
129 upload_service_->sender_.reset(sender);
130
131 sender->set_should_succeed(false);
132
133 upload_service_->AddSample(*Crash("user"));
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700134
135 for (int i = 0; i < UploadService::kMaxFailedUpload; i++) {
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700136 upload_service_->UploadEvent();
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700137 }
138
Bertrand SIMONNET1df10c42015-09-09 10:39:51 -0700139 EXPECT_TRUE(upload_service_->HasStagedLog());
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700140 upload_service_->UploadEvent();
Bertrand SIMONNET1df10c42015-09-09 10:39:51 -0700141 EXPECT_FALSE(upload_service_->HasStagedLog());
142
143 // Log a new sample. The failed upload counter should be reset.
144 upload_service_->AddSample(*Crash("user"));
145 for (int i = 0; i < UploadService::kMaxFailedUpload; i++) {
146 upload_service_->UploadEvent();
147 }
148 // The log is not discarded after multiple failed uploads.
149 EXPECT_TRUE(upload_service_->HasStagedLog());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700150}
151
152TEST_F(UploadServiceTest, EmptyLogsAreNotSent) {
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700153 SenderMock* sender = new SenderMock();
154 upload_service_->sender_.reset(sender);
155 upload_service_->UploadEvent();
156 EXPECT_FALSE(upload_service_->current_log_);
157 EXPECT_EQ(0, sender->send_call_count());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700158}
159
160TEST_F(UploadServiceTest, LogEmptyByDefault) {
Bertrand SIMONNET608e4282015-11-12 17:52:17 -0800161 UploadService upload_service("", base::TimeDelta(), dir_.path());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700162
163 // current_log_ should be initialized later as it needs AtExitManager to exit
164 // in order to gather system information from SysInfo.
165 EXPECT_FALSE(upload_service.current_log_);
166}
167
168TEST_F(UploadServiceTest, CanSendMultipleTimes) {
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700169 SenderMock* sender = new SenderMock();
170 upload_service_->sender_.reset(sender);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700171
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700172 upload_service_->AddSample(*Crash("user"));
173 upload_service_->UploadEvent();
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700174
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700175 std::string first_message = sender->last_message();
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700176
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700177 upload_service_->AddSample(*Crash("kernel"));
178 upload_service_->UploadEvent();
179
180 EXPECT_NE(first_message, sender->last_message());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700181}
182
183TEST_F(UploadServiceTest, LogEmptyAfterUpload) {
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700184 upload_service_->AddSample(*Crash("user"));
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700185
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700186 EXPECT_TRUE(upload_service_->current_log_);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700187
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700188 upload_service_->UploadEvent();
189 EXPECT_FALSE(upload_service_->current_log_);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700190}
191
192TEST_F(UploadServiceTest, LogContainsAggregatedValues) {
193 scoped_ptr<metrics::MetricSample> histogram =
194 metrics::MetricSample::HistogramSample("foo", 10, 0, 42, 10);
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700195 upload_service_->AddSample(*histogram.get());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700196
197
198 scoped_ptr<metrics::MetricSample> histogram2 =
199 metrics::MetricSample::HistogramSample("foo", 11, 0, 42, 10);
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700200 upload_service_->AddSample(*histogram2.get());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700201
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700202 upload_service_->GatherHistograms();
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700203 metrics::ChromeUserMetricsExtension* proto =
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700204 upload_service_->current_log_->uma_proto();
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700205 EXPECT_EQ(1, proto->histogram_event().size());
206}
207
208TEST_F(UploadServiceTest, ExtractChannelFromString) {
209 EXPECT_EQ(
210 SystemProfileCache::ProtoChannelFromString(
211 "developer-build"),
212 metrics::SystemProfileProto::CHANNEL_UNKNOWN);
213
214 EXPECT_EQ(metrics::SystemProfileProto::CHANNEL_DEV,
Bertrand SIMONNETdc225c82015-11-12 14:04:03 -0800215 SystemProfileCache::ProtoChannelFromString("dev-channel"));
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700216
217 EXPECT_EQ(metrics::SystemProfileProto::CHANNEL_STABLE,
Bertrand SIMONNETdc225c82015-11-12 14:04:03 -0800218 SystemProfileCache::ProtoChannelFromString("stable-channel"));
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700219
220 EXPECT_EQ(metrics::SystemProfileProto::CHANNEL_UNKNOWN,
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700221 SystemProfileCache::ProtoChannelFromString("this is a test"));
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700222}
223
224TEST_F(UploadServiceTest, ValuesInConfigFileAreSent) {
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700225 SenderMock* sender = new SenderMock();
226 upload_service_->sender_.reset(sender);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700227
Bertrand SIMONNETeb697ab2015-10-14 13:26:42 -0700228 SetTestingProperty(metrics::kProductId, "hello");
229 SetTestingProperty(metrics::kProductVersion, "1.2.3.4");
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700230
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700231 scoped_ptr<metrics::MetricSample> histogram =
232 metrics::MetricSample::SparseHistogramSample("myhistogram", 1);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700233 // Reset to create the new log with the profile setter.
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700234 upload_service_->system_profile_setter_.reset(
235 new SystemProfileCache(true, dir_.path()));
236 upload_service_->Reset();
237 upload_service_->AddSample(*histogram.get());
238 upload_service_->UploadEvent();
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700239
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700240 EXPECT_EQ(1, sender->send_call_count());
241 EXPECT_TRUE(sender->is_good_proto());
242 EXPECT_EQ(1, sender->last_message_proto().histogram_event().size());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700243
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700244 EXPECT_NE(0, sender->last_message_proto().client_id());
245 EXPECT_NE(0, sender->last_message_proto().system_profile().build_timestamp());
246 EXPECT_NE(0, sender->last_message_proto().session_id());
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700247}
248
249TEST_F(UploadServiceTest, PersistentGUID) {
250 std::string tmp_file = dir_.path().Append("tmpfile").value();
251
252 std::string first_guid = SystemProfileCache::GetPersistentGUID(tmp_file);
253 std::string second_guid = SystemProfileCache::GetPersistentGUID(tmp_file);
254
255 // The GUID are cached.
256 EXPECT_EQ(first_guid, second_guid);
257
258 base::DeleteFile(base::FilePath(tmp_file), false);
259
260 first_guid = SystemProfileCache::GetPersistentGUID(tmp_file);
261 base::DeleteFile(base::FilePath(tmp_file), false);
262 second_guid = SystemProfileCache::GetPersistentGUID(tmp_file);
263
264 // Random GUIDs are generated (not all the same).
265 EXPECT_NE(first_guid, second_guid);
266}
267
268TEST_F(UploadServiceTest, SessionIdIncrementedAtInitialization) {
Bertrand SIMONNETeb697ab2015-10-14 13:26:42 -0700269 SetTestingProperty(metrics::kProductId, "hello");
Bertrand SIMONNET12531862015-08-31 11:11:57 -0700270 SystemProfileCache cache(true, dir_.path());
271 cache.Initialize();
272 int session_id = cache.profile_.session_id;
273 cache.initialized_ = false;
274 cache.Initialize();
275 EXPECT_EQ(cache.profile_.session_id, session_id + 1);
Bertrand SIMONNET46b49da2014-06-25 14:38:07 -0700276}
Bertrand SIMONNET4c8a8ad2015-09-09 13:27:33 -0700277
278// Test that we can log metrics from the metrics library and have the uploader
279// upload them.
280TEST_F(UploadServiceTest, LogFromTheMetricsLibrary) {
281 SenderMock* sender = new SenderMock();
282 upload_service_->sender_.reset(sender);
283
284 upload_service_->UploadEvent();
285 EXPECT_EQ(0, sender->send_call_count());
286
287 metrics_lib_.SendEnumToUMA("testname", 2, 10);
288 upload_service_->UploadEvent();
289
290 EXPECT_EQ(1, sender->send_call_count());
291}
Bertrand SIMONNET1d15d462015-11-17 13:20:06 -0800292
293// The product id must be set for metrics to be uploaded.
294// If it is not set, the system profile cache should fail to initialize.
295TEST_F(UploadServiceTest, ProductIdMandatory) {
296 SystemProfileCache cache(true, dir_.path());
297 ASSERT_FALSE(cache.Initialize());
298 SetTestingProperty(metrics::kProductId, "");
299 ASSERT_FALSE(cache.Initialize());
300 SetTestingProperty(metrics::kProductId, "hello");
301 ASSERT_TRUE(cache.Initialize());
302}