• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "components/metrics/metrics_state_manager.h"
6 
7 #include <ctype.h>
8 #include <string>
9 
10 #include "base/bind.h"
11 #include "base/command_line.h"
12 #include "base/prefs/testing_pref_service.h"
13 #include "components/metrics/metrics_pref_names.h"
14 #include "components/metrics/metrics_switches.h"
15 #include "components/variations/caching_permuted_entropy_provider.h"
16 #include "components/variations/pref_names.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 
19 namespace metrics {
20 
21 class MetricsStateManagerTest : public testing::Test {
22  public:
MetricsStateManagerTest()23   MetricsStateManagerTest() : is_metrics_reporting_enabled_(false) {
24     MetricsStateManager::RegisterPrefs(prefs_.registry());
25   }
26 
CreateStateManager()27   scoped_ptr<MetricsStateManager> CreateStateManager() {
28     return MetricsStateManager::Create(
29         &prefs_,
30         base::Bind(&MetricsStateManagerTest::is_metrics_reporting_enabled,
31                    base::Unretained(this))).Pass();
32   }
33 
34   // Sets metrics reporting as enabled for testing.
EnableMetricsReporting()35   void EnableMetricsReporting() {
36     is_metrics_reporting_enabled_ = true;
37   }
38 
39  protected:
40   TestingPrefServiceSimple prefs_;
41 
42  private:
is_metrics_reporting_enabled() const43   bool is_metrics_reporting_enabled() const {
44     return is_metrics_reporting_enabled_;
45   }
46 
47   bool is_metrics_reporting_enabled_;
48 
49   DISALLOW_COPY_AND_ASSIGN(MetricsStateManagerTest);
50 };
51 
52 // Ensure the ClientId is formatted as expected.
TEST_F(MetricsStateManagerTest,ClientIdCorrectlyFormatted)53 TEST_F(MetricsStateManagerTest, ClientIdCorrectlyFormatted) {
54   scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
55   state_manager->ForceClientIdCreation();
56 
57   const std::string client_id = state_manager->client_id();
58   EXPECT_EQ(36U, client_id.length());
59 
60   for (size_t i = 0; i < client_id.length(); ++i) {
61     char current = client_id[i];
62     if (i == 8 || i == 13 || i == 18 || i == 23)
63       EXPECT_EQ('-', current);
64     else
65       EXPECT_TRUE(isxdigit(current));
66   }
67 }
68 
TEST_F(MetricsStateManagerTest,EntropySourceUsed_Low)69 TEST_F(MetricsStateManagerTest, EntropySourceUsed_Low) {
70   scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
71   state_manager->CreateEntropyProvider();
72   EXPECT_EQ(MetricsStateManager::ENTROPY_SOURCE_LOW,
73             state_manager->entropy_source_returned());
74 }
75 
TEST_F(MetricsStateManagerTest,EntropySourceUsed_High)76 TEST_F(MetricsStateManagerTest, EntropySourceUsed_High) {
77   EnableMetricsReporting();
78   scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
79   state_manager->CreateEntropyProvider();
80   EXPECT_EQ(MetricsStateManager::ENTROPY_SOURCE_HIGH,
81             state_manager->entropy_source_returned());
82 }
83 
TEST_F(MetricsStateManagerTest,LowEntropySource0NotReset)84 TEST_F(MetricsStateManagerTest, LowEntropySource0NotReset) {
85   scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
86 
87   // Get the low entropy source once, to initialize it.
88   state_manager->GetLowEntropySource();
89 
90   // Now, set it to 0 and ensure it doesn't get reset.
91   state_manager->low_entropy_source_ = 0;
92   EXPECT_EQ(0, state_manager->GetLowEntropySource());
93   // Call it another time, just to make sure.
94   EXPECT_EQ(0, state_manager->GetLowEntropySource());
95 }
96 
TEST_F(MetricsStateManagerTest,PermutedEntropyCacheClearedWhenLowEntropyReset)97 TEST_F(MetricsStateManagerTest,
98        PermutedEntropyCacheClearedWhenLowEntropyReset) {
99   const PrefService::Preference* low_entropy_pref =
100       prefs_.FindPreference(prefs::kMetricsLowEntropySource);
101   const char* kCachePrefName = prefs::kVariationsPermutedEntropyCache;
102   int low_entropy_value = -1;
103 
104   // First, generate an initial low entropy source value.
105   {
106     EXPECT_TRUE(low_entropy_pref->IsDefaultValue());
107 
108     scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
109     state_manager->GetLowEntropySource();
110 
111     EXPECT_FALSE(low_entropy_pref->IsDefaultValue());
112     EXPECT_TRUE(low_entropy_pref->GetValue()->GetAsInteger(&low_entropy_value));
113   }
114 
115   // Now, set a dummy value in the permuted entropy cache pref and verify that
116   // another call to GetLowEntropySource() doesn't clobber it when
117   // --reset-variation-state wasn't specified.
118   {
119     prefs_.SetString(kCachePrefName, "test");
120 
121     scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
122     state_manager->GetLowEntropySource();
123 
124     EXPECT_EQ("test", prefs_.GetString(kCachePrefName));
125     EXPECT_EQ(low_entropy_value,
126               prefs_.GetInteger(prefs::kMetricsLowEntropySource));
127   }
128 
129   // Verify that the cache does get reset if --reset-variations-state is passed.
130   {
131     CommandLine::ForCurrentProcess()->AppendSwitch(
132         switches::kResetVariationState);
133 
134     scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
135     state_manager->GetLowEntropySource();
136 
137     EXPECT_TRUE(prefs_.GetString(kCachePrefName).empty());
138   }
139 }
140 
141 // Check that setting the kMetricsResetIds pref to true causes the client id to
142 // be reset. We do not check that the low entropy source is reset because we
143 // cannot ensure that metrics state manager won't generate the same id again.
TEST_F(MetricsStateManagerTest,ResetMetricsIDs)144 TEST_F(MetricsStateManagerTest, ResetMetricsIDs) {
145   // Set an initial client id in prefs. It should not be possible for the
146   // metrics state manager to generate this id randomly.
147   const std::string kInitialClientId = "initial client id";
148   prefs_.SetString(prefs::kMetricsClientID, kInitialClientId);
149 
150   // Make sure the initial client id isn't reset by the metrics state manager.
151   {
152     scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
153     state_manager->ForceClientIdCreation();
154     EXPECT_EQ(kInitialClientId, state_manager->client_id());
155   }
156 
157   // Set the reset pref to cause the IDs to be reset.
158   prefs_.SetBoolean(prefs::kMetricsResetIds, true);
159 
160   // Cause the actual reset to happen.
161   {
162     scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
163     state_manager->ForceClientIdCreation();
164     EXPECT_NE(kInitialClientId, state_manager->client_id());
165 
166     state_manager->GetLowEntropySource();
167 
168     EXPECT_FALSE(prefs_.GetBoolean(prefs::kMetricsResetIds));
169   }
170 
171   EXPECT_NE(kInitialClientId, prefs_.GetString(prefs::kMetricsClientID));
172 }
173 
174 }  // namespace metrics
175