xref: /aosp_15_r20/external/cronet/components/metrics/metrics_state_manager_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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