1 // Copyright 2014 The Chromium Authors
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/metrics_state_manager.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <memory>
11 #include <string>
12 #include <utility>
13
14 #include "base/command_line.h"
15 #include "base/files/file_path.h"
16 #include "base/functional/bind.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_util.h"
19 #include "base/test/metrics/histogram_tester.h"
20 #include "base/test/scoped_feature_list.h"
21 #include "build/build_config.h"
22 #include "components/metrics/client_info.h"
23 #include "components/metrics/metrics_data_validation.h"
24 #include "components/metrics/metrics_log.h"
25 #include "components/metrics/metrics_pref_names.h"
26 #include "components/metrics/metrics_service.h"
27 #include "components/metrics/metrics_switches.h"
28 #include "components/metrics/test/test_enabled_state_provider.h"
29 #include "components/prefs/testing_pref_service.h"
30 #include "components/variations/pref_names.h"
31 #include "testing/gmock/include/gmock/gmock.h"
32 #include "testing/gtest/include/gtest/gtest.h"
33 #include "third_party/abseil-cpp/absl/strings/ascii.h"
34
35 namespace metrics {
36 namespace {
37
38 // Verifies that the client id follows the expected pattern.
VerifyClientId(const std::string & client_id)39 void VerifyClientId(const std::string& client_id) {
40 EXPECT_EQ(36U, client_id.length());
41
42 for (size_t i = 0; i < client_id.length(); ++i) {
43 char current = client_id[i];
44 if (i == 8 || i == 13 || i == 18 || i == 23)
45 EXPECT_EQ('-', current);
46 else
47 EXPECT_TRUE(absl::ascii_isxdigit(static_cast<unsigned char>(current)));
48 }
49 }
50
51 MATCHER(HaveClonedInstallInfo, "") {
52 return (
53 !arg.FindPreference(prefs::kClonedResetCount)->IsDefaultValue() &&
54 !arg.FindPreference(prefs::kFirstClonedResetTimestamp)
55 ->IsDefaultValue() &&
56 !arg.FindPreference(prefs::kLastClonedResetTimestamp)->IsDefaultValue());
57 }
58
59 MATCHER(HaveNoClonedInstallInfo, "") {
60 return (
61 arg.FindPreference(prefs::kClonedResetCount)->IsDefaultValue() &&
62 arg.FindPreference(prefs::kFirstClonedResetTimestamp)->IsDefaultValue() &&
63 arg.FindPreference(prefs::kLastClonedResetTimestamp)->IsDefaultValue());
64 }
65
66 } // namespace
67
68 class MetricsStateManagerTest : public testing::Test {
69 public:
MetricsStateManagerTest()70 MetricsStateManagerTest()
71 : test_begin_time_(base::Time::Now().ToTimeT()),
72 enabled_state_provider_(new TestEnabledStateProvider(false, false)) {
73 MetricsService::RegisterPrefs(prefs_.registry());
74 }
75
76 MetricsStateManagerTest(const MetricsStateManagerTest&) = delete;
77 MetricsStateManagerTest& operator=(const MetricsStateManagerTest&) = delete;
78
CreateStateManager(const std::string & external_client_id="")79 std::unique_ptr<MetricsStateManager> CreateStateManager(
80 const std::string& external_client_id = "") {
81 std::unique_ptr<MetricsStateManager> state_manager =
82 MetricsStateManager::Create(
83 &prefs_, enabled_state_provider_.get(), std::wstring(),
84 base::FilePath(), StartupVisibility::kUnknown, {},
85 base::BindRepeating(
86 &MetricsStateManagerTest::MockStoreClientInfoBackup,
87 base::Unretained(this)),
88 base::BindRepeating(
89 &MetricsStateManagerTest::LoadFakeClientInfoBackup,
90 base::Unretained(this)),
91 external_client_id);
92 state_manager->InstantiateFieldTrialList();
93 return state_manager;
94 }
95
96 // Sets metrics reporting as enabled for testing.
EnableMetricsReporting()97 void EnableMetricsReporting() {
98 enabled_state_provider_->set_consent(true);
99 enabled_state_provider_->set_enabled(true);
100 }
101
SetClientInfoPrefs(const ClientInfo & client_info)102 void SetClientInfoPrefs(const ClientInfo& client_info) {
103 prefs_.SetString(prefs::kMetricsClientID, client_info.client_id);
104 prefs_.SetInt64(prefs::kInstallDate, client_info.installation_date);
105 prefs_.SetInt64(prefs::kMetricsReportingEnabledTimestamp,
106 client_info.reporting_enabled_date);
107 }
108
SetFakeClientInfoBackup(const ClientInfo & client_info)109 void SetFakeClientInfoBackup(const ClientInfo& client_info) {
110 fake_client_info_backup_ = std::make_unique<ClientInfo>();
111 fake_client_info_backup_->client_id = client_info.client_id;
112 fake_client_info_backup_->installation_date = client_info.installation_date;
113 fake_client_info_backup_->reporting_enabled_date =
114 client_info.reporting_enabled_date;
115 }
116
117 // The number of times that the code tries to load ClientInfo.
118 int client_info_load_count_ = 0;
119
120 protected:
121 TestingPrefServiceSimple prefs_;
122
123 // Last ClientInfo stored by the MetricsStateManager via
124 // MockStoreClientInfoBackup.
125 std::unique_ptr<ClientInfo> stored_client_info_backup_;
126
127 // If set, will be returned via LoadFakeClientInfoBackup if requested by the
128 // MetricsStateManager.
129 std::unique_ptr<ClientInfo> fake_client_info_backup_;
130
131 const int64_t test_begin_time_;
132
133 private:
134 // Stores the |client_info| in |stored_client_info_backup_| for verification
135 // by the tests later.
MockStoreClientInfoBackup(const ClientInfo & client_info)136 void MockStoreClientInfoBackup(const ClientInfo& client_info) {
137 stored_client_info_backup_ = std::make_unique<ClientInfo>();
138 stored_client_info_backup_->client_id = client_info.client_id;
139 stored_client_info_backup_->installation_date =
140 client_info.installation_date;
141 stored_client_info_backup_->reporting_enabled_date =
142 client_info.reporting_enabled_date;
143
144 // Respect the contract that storing an empty client_id voids the existing
145 // backup (required for the last section of the ForceClientIdCreation test
146 // below).
147 if (client_info.client_id.empty())
148 fake_client_info_backup_.reset();
149 }
150
151 // Hands out a copy of |fake_client_info_backup_| if it is set.
LoadFakeClientInfoBackup()152 std::unique_ptr<ClientInfo> LoadFakeClientInfoBackup() {
153 ++client_info_load_count_;
154 if (!fake_client_info_backup_)
155 return nullptr;
156
157 std::unique_ptr<ClientInfo> backup_copy(new ClientInfo);
158 backup_copy->client_id = fake_client_info_backup_->client_id;
159 backup_copy->installation_date =
160 fake_client_info_backup_->installation_date;
161 backup_copy->reporting_enabled_date =
162 fake_client_info_backup_->reporting_enabled_date;
163 return backup_copy;
164 }
165
166 std::unique_ptr<TestEnabledStateProvider> enabled_state_provider_;
167 };
168
TEST_F(MetricsStateManagerTest,ClientIdCorrectlyFormatted_ConsentInitially)169 TEST_F(MetricsStateManagerTest, ClientIdCorrectlyFormatted_ConsentInitially) {
170 // With consent set initially, client id should be created in the constructor.
171 EnableMetricsReporting();
172 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
173
174 const std::string client_id = state_manager->client_id();
175 VerifyClientId(client_id);
176 }
177
TEST_F(MetricsStateManagerTest,ClientIdCorrectlyFormatted_ConsentLater)178 TEST_F(MetricsStateManagerTest, ClientIdCorrectlyFormatted_ConsentLater) {
179 // With consent set initially, client id should be created on consent grant.
180 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
181 EXPECT_EQ(std::string(), state_manager->client_id());
182
183 EnableMetricsReporting();
184 state_manager->ForceClientIdCreation();
185 const std::string client_id = state_manager->client_id();
186 VerifyClientId(client_id);
187 }
188
TEST_F(MetricsStateManagerTest,EntropySourceUsed_Low)189 TEST_F(MetricsStateManagerTest, EntropySourceUsed_Low) {
190 // Set the install date pref, which makes sure we don't trigger the first run
191 // behavior where a provisional client id is generated and used to return a
192 // high entropy source.
193 prefs_.SetInt64(prefs::kInstallDate, base::Time::Now().ToTimeT());
194
195 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
196 // |enable_limited_entropy_mode| is irrelevant but is set for test coverage.
197 state_manager->CreateEntropyProviders(
198 /*enable_limited_entropy_mode=*/true);
199 EXPECT_EQ(state_manager->entropy_source_returned(),
200 MetricsStateManager::ENTROPY_SOURCE_LOW);
201 EXPECT_EQ(state_manager->initial_client_id_for_testing(), "");
202 }
203
TEST_F(MetricsStateManagerTest,EntropySourceUsed_High)204 TEST_F(MetricsStateManagerTest, EntropySourceUsed_High) {
205 EnableMetricsReporting();
206 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
207 // |enable_limited_entropy_mode| is irrelevant but is set for test coverage.
208 state_manager->CreateEntropyProviders(
209 /*enable_limited_entropy_mode=*/true);
210 EXPECT_EQ(state_manager->entropy_source_returned(),
211 MetricsStateManager::ENTROPY_SOURCE_HIGH);
212 EXPECT_EQ(state_manager->initial_client_id_for_testing(),
213 state_manager->client_id());
214 }
215
TEST_F(MetricsStateManagerTest,EntropySourceUsed_High_ExternalClientId)216 TEST_F(MetricsStateManagerTest, EntropySourceUsed_High_ExternalClientId) {
217 EnableMetricsReporting();
218 const std::string kExternalClientId = "abc";
219 std::unique_ptr<MetricsStateManager> state_manager(
220 CreateStateManager(kExternalClientId));
221 // |enable_limited_entropy_mode| is irrelevant but is set for test coverage.
222 state_manager->CreateEntropyProviders(
223 /*enable_limited_entropy_mode=*/true);
224 EXPECT_EQ(state_manager->entropy_source_returned(),
225 MetricsStateManager::ENTROPY_SOURCE_HIGH);
226 EXPECT_EQ(state_manager->client_id(), kExternalClientId);
227 EXPECT_EQ(state_manager->initial_client_id_for_testing(), kExternalClientId);
228 }
229
TEST_F(MetricsStateManagerTest,EntropySourceUsed_High_ExternalClientId_MetricsReportingDisabled)230 TEST_F(MetricsStateManagerTest,
231 EntropySourceUsed_High_ExternalClientId_MetricsReportingDisabled) {
232 const std::string kExternalClientId = "abc";
233 std::unique_ptr<MetricsStateManager> state_manager(
234 CreateStateManager(kExternalClientId));
235 // |enable_limited_entropy_mode| is irrelevant but is set for test coverage.
236 state_manager->CreateEntropyProviders(
237 /*enable_limited_entropy_mode=*/true);
238 EXPECT_TRUE(state_manager->client_id().empty());
239 EXPECT_EQ(state_manager->entropy_source_returned(),
240 MetricsStateManager::ENTROPY_SOURCE_HIGH);
241 EXPECT_EQ(state_manager->initial_client_id_for_testing(), kExternalClientId);
242 }
243
244 // Check that setting the kMetricsResetIds pref to true causes the client id to
245 // be reset. We do not check that the low entropy source is reset because we
246 // cannot ensure that metrics state manager won't generate the same id again.
TEST_F(MetricsStateManagerTest,ResetMetricsIDs)247 TEST_F(MetricsStateManagerTest, ResetMetricsIDs) {
248 // Set an initial client id in prefs. It should not be possible for the
249 // metrics state manager to generate this id randomly.
250 const std::string kInitialClientId = "initial client id";
251 prefs_.SetString(prefs::kMetricsClientID, kInitialClientId);
252
253 EnableMetricsReporting();
254
255 // No cloned install info should have been stored.
256 EXPECT_THAT(prefs_, HaveNoClonedInstallInfo());
257
258 // Make sure the initial client id isn't reset by the metrics state manager.
259 {
260 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
261 state_manager->ForceClientIdCreation();
262 EXPECT_EQ(state_manager->client_id(), kInitialClientId);
263 EXPECT_FALSE(state_manager->metrics_ids_were_reset_);
264 EXPECT_THAT(prefs_, HaveNoClonedInstallInfo());
265 }
266
267 // Set the reset pref to cause the IDs to be reset.
268 prefs_.SetBoolean(prefs::kMetricsResetIds, true);
269
270 // Cause the actual reset to happen.
271 {
272 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
273 state_manager->ForceClientIdCreation();
274 EXPECT_NE(state_manager->client_id(), kInitialClientId);
275 EXPECT_TRUE(state_manager->metrics_ids_were_reset_);
276 EXPECT_EQ(state_manager->previous_client_id_, kInitialClientId);
277 EXPECT_EQ(client_info_load_count_, 0);
278
279 state_manager->GetLowEntropySource();
280
281 EXPECT_FALSE(prefs_.GetBoolean(prefs::kMetricsResetIds));
282
283 EXPECT_THAT(prefs_, HaveClonedInstallInfo());
284 EXPECT_EQ(prefs_.GetInteger(prefs::kClonedResetCount), 1);
285 EXPECT_EQ(prefs_.GetInt64(prefs::kFirstClonedResetTimestamp),
286 prefs_.GetInt64(prefs::kLastClonedResetTimestamp));
287 }
288
289 EXPECT_NE(prefs_.GetString(prefs::kMetricsClientID), kInitialClientId);
290 }
291
TEST_F(MetricsStateManagerTest,LogHasSessionShutdownCleanly)292 TEST_F(MetricsStateManagerTest, LogHasSessionShutdownCleanly) {
293 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
294 prefs_.SetBoolean(prefs::kStabilityExitedCleanly, false);
295 state_manager->LogHasSessionShutdownCleanly(
296 /*has_session_shutdown_cleanly=*/true);
297 EXPECT_TRUE(prefs_.GetBoolean(prefs::kStabilityExitedCleanly));
298 }
299
TEST_F(MetricsStateManagerTest,LogSessionHasNotYetShutdownCleanly)300 TEST_F(MetricsStateManagerTest, LogSessionHasNotYetShutdownCleanly) {
301 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
302 ASSERT_TRUE(prefs_.GetBoolean(prefs::kStabilityExitedCleanly));
303 state_manager->LogHasSessionShutdownCleanly(
304 /*has_session_shutdown_cleanly=*/false);
305 EXPECT_FALSE(prefs_.GetBoolean(prefs::kStabilityExitedCleanly));
306 }
307
TEST_F(MetricsStateManagerTest,ForceClientIdCreation)308 TEST_F(MetricsStateManagerTest, ForceClientIdCreation) {
309 const int64_t kFakeInstallationDate = 12345;
310 prefs_.SetInt64(prefs::kInstallDate, kFakeInstallationDate);
311
312 {
313 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
314
315 // client_id shouldn't be auto-generated if metrics reporting is not
316 // enabled.
317 EXPECT_EQ(state_manager->client_id(), std::string());
318 EXPECT_EQ(prefs_.GetInt64(prefs::kMetricsReportingEnabledTimestamp), 0);
319
320 // Confirm that the initial ForceClientIdCreation call creates the client id
321 // and backs it up via MockStoreClientInfoBackup.
322 EXPECT_FALSE(stored_client_info_backup_);
323 EnableMetricsReporting();
324 state_manager->ForceClientIdCreation();
325 EXPECT_NE(state_manager->client_id(), std::string());
326 EXPECT_GE(prefs_.GetInt64(prefs::kMetricsReportingEnabledTimestamp),
327 test_begin_time_);
328
329 ASSERT_TRUE(stored_client_info_backup_);
330 EXPECT_EQ(client_info_load_count_, 1);
331 EXPECT_EQ(state_manager->client_id(),
332 stored_client_info_backup_->client_id);
333 EXPECT_EQ(stored_client_info_backup_->installation_date,
334 kFakeInstallationDate);
335 EXPECT_EQ(prefs_.GetInt64(prefs::kMetricsReportingEnabledTimestamp),
336 stored_client_info_backup_->reporting_enabled_date);
337 }
338 }
339
TEST_F(MetricsStateManagerTest,ForceClientIdCreation_ConsentIntitially_NoInstallDate)340 TEST_F(MetricsStateManagerTest,
341 ForceClientIdCreation_ConsentIntitially_NoInstallDate) {
342 // Confirm that the initial ForceClientIdCreation call creates the install
343 // date and then backs it up via MockStoreClientInfoBackup.
344 EXPECT_FALSE(stored_client_info_backup_);
345 EnableMetricsReporting();
346 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
347
348 ASSERT_TRUE(stored_client_info_backup_);
349 EXPECT_NE(stored_client_info_backup_->installation_date, 0);
350 EXPECT_EQ(client_info_load_count_, 1);
351 }
352
353 #if !BUILDFLAG(IS_WIN)
TEST_F(MetricsStateManagerTest,ProvisionalClientId_PromotedToClientId)354 TEST_F(MetricsStateManagerTest, ProvisionalClientId_PromotedToClientId) {
355 // Force enable the creation of a provisional client ID on first run for
356 // consistency between Chromium and Chrome builds.
357 MetricsStateManager::enable_provisional_client_id_for_testing_ = true;
358
359 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
360
361 // Verify that there was a provisional client id created.
362 std::string provisional_client_id =
363 prefs_.GetString(prefs::kMetricsProvisionalClientID);
364 VerifyClientId(provisional_client_id);
365 // No client id should have been stored.
366 EXPECT_TRUE(prefs_.FindPreference(prefs::kMetricsClientID)->IsDefaultValue());
367 int low_entropy_source = state_manager->GetLowEntropySource();
368 // The default entropy provider should be the high entropy one since we have a
369 // provisional client ID. |enable_limited_entropy_mode| is irrelevant but is
370 // set to true for test coverage.
371 state_manager->CreateEntropyProviders(
372 /*enable_limited_entropy_mode=*/true);
373 EXPECT_EQ(state_manager->entropy_source_returned(),
374 MetricsStateManager::ENTROPY_SOURCE_HIGH);
375 // The high entropy source used should be the provisional client ID.
376 EXPECT_EQ(state_manager->initial_client_id_for_testing(),
377 provisional_client_id);
378
379 // Forcing client id creation should promote the provisional client id to
380 // become the real client id and keep the low entropy source.
381 EnableMetricsReporting();
382 state_manager->ForceClientIdCreation();
383 std::string client_id = state_manager->client_id();
384 EXPECT_EQ(provisional_client_id, client_id);
385 EXPECT_EQ(prefs_.GetString(prefs::kMetricsClientID), client_id);
386 EXPECT_TRUE(prefs_.FindPreference(prefs::kMetricsProvisionalClientID)
387 ->IsDefaultValue());
388 EXPECT_TRUE(prefs_.GetString(prefs::kMetricsProvisionalClientID).empty());
389 EXPECT_EQ(state_manager->GetLowEntropySource(), low_entropy_source);
390 EXPECT_EQ(client_info_load_count_, 1);
391 }
392
TEST_F(MetricsStateManagerTest,ProvisionalClientId_PersistedAcrossFirstRuns)393 TEST_F(MetricsStateManagerTest, ProvisionalClientId_PersistedAcrossFirstRuns) {
394 // Force enable the creation of a provisional client ID on first run for
395 // consistency between Chromium and Chrome builds.
396 MetricsStateManager::enable_provisional_client_id_for_testing_ = true;
397
398 std::string provisional_client_id;
399
400 // Simulate a first run, and verify that a provisional client id is generated.
401 // We also do not enable nor disable UMA in order to simulate exiting during
402 // the first run flow.
403 {
404 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
405 // Verify that there was a provisional client id created.
406 provisional_client_id =
407 prefs_.GetString(prefs::kMetricsProvisionalClientID);
408 VerifyClientId(provisional_client_id);
409 // No client id should have been stored.
410 EXPECT_TRUE(
411 prefs_.FindPreference(prefs::kMetricsClientID)->IsDefaultValue());
412 // The default entropy provider should be the high entropy one since we have
413 // a provisional client ID. |enable_limited_entropy_mode| is irrelevant but
414 // is set to true for test coverage.
415 state_manager->CreateEntropyProviders(
416 /*enable_limited_entropy_mode=*/true);
417 EXPECT_EQ(state_manager->entropy_source_returned(),
418 MetricsStateManager::ENTROPY_SOURCE_HIGH);
419 // The high entropy source used should be the provisional client ID.
420 EXPECT_EQ(state_manager->initial_client_id_for_testing(),
421 provisional_client_id);
422 }
423
424 // Now, simulate a second run, and verify that the provisional client ID is
425 // the same.
426 {
427 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
428 // Verify that the same provisional client ID as the first run is used.
429 EXPECT_EQ(provisional_client_id,
430 prefs_.GetString(prefs::kMetricsProvisionalClientID));
431 // There still should not be any stored client ID.
432 EXPECT_TRUE(
433 prefs_.FindPreference(prefs::kMetricsClientID)->IsDefaultValue());
434 // The default entropy provider should be the high entropy one since we have
435 // a provisional client ID. |enable_limited_entropy_mode| is irrelevant but
436 // is set to true for test coverage.
437 state_manager->CreateEntropyProviders(
438 /*enable_limited_entropy_mode=*/true);
439 EXPECT_EQ(state_manager->entropy_source_returned(),
440 MetricsStateManager::ENTROPY_SOURCE_HIGH);
441 // The high entropy source used should be the provisional client ID.
442 EXPECT_EQ(state_manager->initial_client_id_for_testing(),
443 provisional_client_id);
444 }
445 }
446 #endif // !BUILDFLAG(IS_WIN)
447
TEST_F(MetricsStateManagerTest,LoadPrefs)448 TEST_F(MetricsStateManagerTest, LoadPrefs) {
449 ClientInfo client_info;
450 client_info.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF";
451 client_info.installation_date = 1112;
452 client_info.reporting_enabled_date = 2223;
453 SetClientInfoPrefs(client_info);
454
455 EnableMetricsReporting();
456 {
457 EXPECT_FALSE(fake_client_info_backup_);
458 EXPECT_FALSE(stored_client_info_backup_);
459
460 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
461
462 // client_id should be auto-obtained from the constructor when metrics
463 // reporting is enabled.
464 EXPECT_EQ(state_manager->client_id(), client_info.client_id);
465
466 // The backup should not be modified.
467 ASSERT_FALSE(stored_client_info_backup_);
468
469 // Re-forcing client id creation shouldn't cause another backup and
470 // shouldn't affect the existing client id.
471 state_manager->ForceClientIdCreation();
472 EXPECT_FALSE(stored_client_info_backup_);
473 EXPECT_EQ(state_manager->client_id(), client_info.client_id);
474 EXPECT_EQ(client_info_load_count_, 0);
475 }
476 }
477
TEST_F(MetricsStateManagerTest,PreferPrefs)478 TEST_F(MetricsStateManagerTest, PreferPrefs) {
479 ClientInfo client_info;
480 client_info.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF";
481 client_info.installation_date = 1112;
482 client_info.reporting_enabled_date = 2223;
483 SetClientInfoPrefs(client_info);
484
485 ClientInfo client_info2;
486 client_info2.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE";
487 client_info2.installation_date = 1111;
488 client_info2.reporting_enabled_date = 2222;
489 SetFakeClientInfoBackup(client_info2);
490
491 EnableMetricsReporting();
492 {
493 // The backup should be ignored if we already have a client id.
494
495 EXPECT_FALSE(stored_client_info_backup_);
496
497 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
498 EXPECT_EQ(state_manager->client_id(), client_info.client_id);
499
500 // The backup should not be modified.
501 ASSERT_FALSE(stored_client_info_backup_);
502 EXPECT_EQ(client_info_load_count_, 0);
503 }
504 }
505
TEST_F(MetricsStateManagerTest,RestoreBackup)506 TEST_F(MetricsStateManagerTest, RestoreBackup) {
507 ClientInfo client_info;
508 client_info.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF";
509 client_info.installation_date = 1112;
510 client_info.reporting_enabled_date = 2223;
511 SetClientInfoPrefs(client_info);
512
513 ClientInfo client_info2;
514 client_info2.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE";
515 client_info2.installation_date = 1111;
516 client_info2.reporting_enabled_date = 2222;
517 SetFakeClientInfoBackup(client_info2);
518
519 prefs_.ClearPref(prefs::kMetricsClientID);
520 prefs_.ClearPref(prefs::kMetricsReportingEnabledTimestamp);
521
522 EnableMetricsReporting();
523 {
524 // The backup should kick in if the client id has gone missing. It should
525 // replace remaining and missing dates as well.
526
527 EXPECT_FALSE(stored_client_info_backup_);
528
529 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
530 EXPECT_EQ(state_manager->client_id(), client_info2.client_id);
531 EXPECT_EQ(prefs_.GetInt64(prefs::kInstallDate),
532 client_info2.installation_date);
533 EXPECT_EQ(prefs_.GetInt64(prefs::kMetricsReportingEnabledTimestamp),
534 client_info2.reporting_enabled_date);
535
536 EXPECT_TRUE(stored_client_info_backup_);
537 EXPECT_EQ(client_info_load_count_, 1);
538 }
539 }
540
TEST_F(MetricsStateManagerTest,ResetBackup)541 TEST_F(MetricsStateManagerTest, ResetBackup) {
542 ClientInfo client_info;
543 client_info.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE";
544 client_info.installation_date = 1111;
545 client_info.reporting_enabled_date = 2222;
546
547 SetFakeClientInfoBackup(client_info);
548 SetClientInfoPrefs(client_info);
549
550 prefs_.SetBoolean(prefs::kMetricsResetIds, true);
551
552 EnableMetricsReporting();
553 {
554 // Upon request to reset metrics ids, the existing backup should not be
555 // restored.
556
557 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
558
559 // A brand new client id should have been generated.
560 EXPECT_NE(state_manager->client_id(), std::string());
561 EXPECT_NE(state_manager->client_id(), client_info.client_id);
562 EXPECT_TRUE(state_manager->metrics_ids_were_reset_);
563 EXPECT_EQ(state_manager->previous_client_id_, client_info.client_id);
564 EXPECT_TRUE(stored_client_info_backup_);
565 EXPECT_EQ(client_info_load_count_, 0);
566
567 // The installation date should not have been affected.
568 EXPECT_EQ(prefs_.GetInt64(prefs::kInstallDate),
569 client_info.installation_date);
570
571 // The metrics-reporting-enabled date will be reset to Now().
572 EXPECT_GE(prefs_.GetInt64(prefs::kMetricsReportingEnabledTimestamp),
573 test_begin_time_);
574 }
575 }
576
TEST_F(MetricsStateManagerTest,CheckProvider)577 TEST_F(MetricsStateManagerTest, CheckProvider) {
578 int64_t kInstallDate = 1373051956;
579 int64_t kInstallDateExpected = 1373050800; // Computed from kInstallDate.
580 int64_t kEnabledDate = 1373001211;
581 int64_t kEnabledDateExpected = 1373000400; // Computed from kEnabledDate.
582
583 ClientInfo client_info;
584 client_info.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE";
585 client_info.installation_date = kInstallDate;
586 client_info.reporting_enabled_date = kEnabledDate;
587
588 SetFakeClientInfoBackup(client_info);
589 SetClientInfoPrefs(client_info);
590
591 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
592 std::unique_ptr<MetricsProvider> provider = state_manager->GetProvider();
593 SystemProfileProto system_profile;
594 provider->ProvideSystemProfileMetrics(&system_profile);
595 EXPECT_EQ(system_profile.install_date(), kInstallDateExpected);
596 EXPECT_EQ(system_profile.uma_enabled_date(), kEnabledDateExpected);
597
598 base::HistogramTester histogram_tester;
599 ChromeUserMetricsExtension uma_proto;
600 provider->ProvidePreviousSessionData(&uma_proto);
601 // The client_id field in the proto should not be overwritten.
602 EXPECT_FALSE(uma_proto.has_client_id());
603 // Nothing should have been emitted to the cloned install histogram.
604 histogram_tester.ExpectTotalCount("UMA.IsClonedInstall", 0);
605 }
606
TEST_F(MetricsStateManagerTest,CheckProviderLogNormal)607 TEST_F(MetricsStateManagerTest, CheckProviderLogNormal) {
608 base::test::ScopedFeatureList scoped_feature_list;
609 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
610 // Set the random seed to have a deterministic test.
611 std::unique_ptr<MetricsProvider> provider =
612 state_manager->GetProviderAndSetRandomSeedForTesting(42);
613
614 base::HistogramTester histogram_tester;
615 ChromeUserMetricsExtension uma_proto;
616 provider->ProvideCurrentSessionData(&uma_proto);
617 histogram_tester.ExpectUniqueSample("UMA.DataValidation.LogNormal", 189, 1);
618 }
619
TEST_F(MetricsStateManagerTest,CheckProviderLogNormalWithParams)620 TEST_F(MetricsStateManagerTest, CheckProviderLogNormalWithParams) {
621 base::test::ScopedFeatureList scoped_feature_list;
622 scoped_feature_list.InitAndEnableFeatureWithParameters(
623 kNonUniformityValidationFeature, {{"delta", "10.0"}});
624 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
625 // Set the random seed to have a deterministic test.
626 std::unique_ptr<MetricsProvider> provider =
627 state_manager->GetProviderAndSetRandomSeedForTesting(42);
628
629 base::HistogramTester histogram_tester;
630 ChromeUserMetricsExtension uma_proto;
631 provider->ProvideCurrentSessionData(&uma_proto);
632 histogram_tester.ExpectUniqueSample("UMA.DataValidation.LogNormal", 2081, 1);
633 }
634
TEST_F(MetricsStateManagerTest,CheckClientIdWasNotUsedToAssignFieldTrial)635 TEST_F(MetricsStateManagerTest, CheckClientIdWasNotUsedToAssignFieldTrial) {
636 EnableMetricsReporting();
637 ClientInfo client_info;
638 client_info.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE";
639 client_info.installation_date = 1373051956;
640 client_info.reporting_enabled_date = 1373001211;
641
642 SetFakeClientInfoBackup(client_info);
643 SetClientInfoPrefs(client_info);
644
645 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
646 std::unique_ptr<MetricsProvider> provider = state_manager->GetProvider();
647 // The client_id in the new log doesn't match the initial_client_id we used to
648 // assign field trials.
649 prefs_.SetString(prefs::kMetricsClientID, "New client id");
650 SystemProfileProto system_profile;
651 provider->ProvideSystemProfileMetrics(&system_profile);
652 EXPECT_TRUE(system_profile.has_client_id_was_used_for_trial_assignment());
653 EXPECT_FALSE(system_profile.client_id_was_used_for_trial_assignment());
654 }
655
TEST_F(MetricsStateManagerTest,CheckClientIdWasUsedToAssignFieldTrial)656 TEST_F(MetricsStateManagerTest, CheckClientIdWasUsedToAssignFieldTrial) {
657 EnableMetricsReporting();
658 ClientInfo client_info;
659 client_info.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE";
660 client_info.installation_date = 1373051956;
661 client_info.reporting_enabled_date = 1373001211;
662
663 SetFakeClientInfoBackup(client_info);
664 SetClientInfoPrefs(client_info);
665
666 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
667 std::unique_ptr<MetricsProvider> provider = state_manager->GetProvider();
668 SystemProfileProto system_profile;
669 provider->ProvideSystemProfileMetrics(&system_profile);
670 EXPECT_TRUE(system_profile.client_id_was_used_for_trial_assignment());
671 }
672
TEST_F(MetricsStateManagerTest,CheckProviderResetIds)673 TEST_F(MetricsStateManagerTest, CheckProviderResetIds) {
674 int64_t kInstallDate = 1373001211;
675 int64_t kInstallDateExpected = 1373000400; // Computed from kInstallDate.
676 int64_t kEnabledDate = 1373051956;
677 int64_t kEnabledDateExpected = 1373050800; // Computed from kEnabledDate.
678
679 ClientInfo client_info;
680 client_info.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE";
681 client_info.installation_date = kInstallDate;
682 client_info.reporting_enabled_date = kEnabledDate;
683
684 SetFakeClientInfoBackup(client_info);
685 SetClientInfoPrefs(client_info);
686
687 // Set the reset pref to cause the IDs to be reset.
688 prefs_.SetBoolean(prefs::kMetricsResetIds, true);
689 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
690 // Verify that MetricsStateManager has the a new client_id after reset and has
691 // the right previous_client_id (equals to the client_id before being reset).
692 EXPECT_NE(state_manager->client_id(), client_info.client_id);
693 EXPECT_TRUE(state_manager->metrics_ids_were_reset_);
694 EXPECT_EQ(state_manager->previous_client_id_, client_info.client_id);
695 EXPECT_EQ(client_info_load_count_, 0);
696
697 uint64_t hashed_previous_client_id =
698 MetricsLog::Hash(state_manager->previous_client_id_);
699 std::unique_ptr<MetricsProvider> provider = state_manager->GetProvider();
700 SystemProfileProto system_profile;
701 provider->ProvideSystemProfileMetrics(&system_profile);
702 EXPECT_EQ(system_profile.install_date(), kInstallDateExpected);
703 EXPECT_EQ(system_profile.uma_enabled_date(), kEnabledDateExpected);
704 auto cloned_install_info = system_profile.cloned_install_info();
705 EXPECT_EQ(cloned_install_info.count(), 1);
706 EXPECT_EQ(cloned_install_info.cloned_from_client_id(),
707 hashed_previous_client_id);
708 // Make sure the first_timestamp is updated and is the same as the
709 // last_timestamp.
710 EXPECT_EQ(cloned_install_info.last_timestamp(),
711 cloned_install_info.first_timestamp());
712 EXPECT_NE(cloned_install_info.first_timestamp(), 0);
713
714 base::HistogramTester histogram_tester;
715 ChromeUserMetricsExtension uma_proto;
716 // The system_profile in the |uma_proto| is provided in
717 // https://source.chromium.org/chromium/chromium/src/+/main:components/metrics/metrics_service.cc;drc=4b86ff6c58f5651a4e2f44abb22d93c3593155cb;l=759
718 // and it's hard to be tested here. For logs from the previous session:
719 // 1. if the previous session is the detection session, the
720 // |uma_proto.system_profile| won't contain the latest cloned_install_info
721 // message.
722 // 2. if the previous session is a normal session, the
723 // |uma_proto.system_profile| should contain the cloned_install_info message
724 // as long as it's saved in prefs.
725 provider->ProvidePreviousSessionData(&uma_proto);
726 EXPECT_EQ(uma_proto.client_id(), hashed_previous_client_id);
727 histogram_tester.ExpectUniqueSample("UMA.IsClonedInstall", 1, 1);
728
729 // Since we set the pref and didn't call SaveMachineId(), this should do
730 // nothing
731 provider->ProvideCurrentSessionData(&uma_proto);
732 histogram_tester.ExpectUniqueSample("UMA.IsClonedInstall", 1, 1);
733
734 // Set the pref through SaveMachineId and expect previous to do nothing and
735 // current to log the histogram
736 prefs_.SetInteger(prefs::kMetricsMachineId, 2216820);
737 state_manager->cloned_install_detector_.SaveMachineId(&prefs_, "test");
738 provider->ProvideCurrentSessionData(&uma_proto);
739 histogram_tester.ExpectUniqueSample("UMA.IsClonedInstall", 1, 2);
740 }
741
TEST_F(MetricsStateManagerTest,CheckProviderResetIds_PreviousIdOnlyReportInResetSession)742 TEST_F(MetricsStateManagerTest,
743 CheckProviderResetIds_PreviousIdOnlyReportInResetSession) {
744 int64_t kInstallDate = 1373001211;
745 int64_t kInstallDateExpected = 1373000400; // Computed from kInstallDate.
746 int64_t kEnabledDate = 1373051956;
747 int64_t kEnabledDateExpected = 1373050800; // Computed from kEnabledDate.
748
749 ClientInfo client_info;
750 client_info.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE";
751 client_info.installation_date = kInstallDate;
752 client_info.reporting_enabled_date = kEnabledDate;
753
754 SetFakeClientInfoBackup(client_info);
755 SetClientInfoPrefs(client_info);
756
757 // In the reset session:
758 // Set the reset pref to cause the IDs to be reset.
759 prefs_.SetBoolean(prefs::kMetricsResetIds, true);
760
761 {
762 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
763 EXPECT_NE(state_manager->client_id(), client_info.client_id);
764 EXPECT_TRUE(state_manager->metrics_ids_were_reset_);
765 // Verify that MetricsStateManager has the right previous_client_id (the ID
766 // that was there before being reset).
767 EXPECT_EQ(state_manager->previous_client_id_, client_info.client_id);
768 EXPECT_EQ(client_info_load_count_, 0);
769
770 std::unique_ptr<MetricsProvider> provider = state_manager->GetProvider();
771 SystemProfileProto system_profile;
772 provider->ProvideSystemProfileMetrics(&system_profile);
773 EXPECT_EQ(system_profile.install_date(), kInstallDateExpected);
774 EXPECT_EQ(system_profile.uma_enabled_date(), kEnabledDateExpected);
775 auto cloned_install_info = system_profile.cloned_install_info();
776 // |cloned_from_client_id| should be uploaded in the reset session.
777 EXPECT_EQ(cloned_install_info.cloned_from_client_id(),
778 MetricsLog::Hash(state_manager->previous_client_id_));
779 // Make sure the first_timestamp is updated and is the same as the
780 // last_timestamp.
781 EXPECT_EQ(cloned_install_info.count(), 1);
782 EXPECT_EQ(cloned_install_info.last_timestamp(),
783 cloned_install_info.first_timestamp());
784 EXPECT_NE(cloned_install_info.last_timestamp(), 0);
785 }
786 // In the normal session:
787 {
788 std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
789 EXPECT_FALSE(state_manager->metrics_ids_were_reset_);
790 std::unique_ptr<MetricsProvider> provider = state_manager->GetProvider();
791 SystemProfileProto system_profile;
792 provider->ProvideSystemProfileMetrics(&system_profile);
793
794 auto cloned_install_info = system_profile.cloned_install_info();
795 // |cloned_from_client_id| shouldn't be reported in the normal session.
796 EXPECT_FALSE(cloned_install_info.has_cloned_from_client_id());
797 // Other cloned_install_info fields should continue be reported once set.
798 EXPECT_EQ(cloned_install_info.count(), 1);
799 EXPECT_EQ(cloned_install_info.last_timestamp(),
800 cloned_install_info.first_timestamp());
801 EXPECT_NE(cloned_install_info.last_timestamp(), 0);
802 }
803 }
804
TEST_F(MetricsStateManagerTest,UseExternalClientId)805 TEST_F(MetricsStateManagerTest, UseExternalClientId) {
806 base::HistogramTester histogram_tester;
807 std::string external_client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE";
808 std::unique_ptr<MetricsStateManager> state_manager(
809 CreateStateManager(external_client_id));
810 EnableMetricsReporting();
811 state_manager->ForceClientIdCreation();
812 EXPECT_EQ(external_client_id, state_manager->client_id());
813 histogram_tester.ExpectUniqueSample("UMA.ClientIdSource", 5, 1);
814 }
815
816 } // namespace metrics
817