OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/metrics/metrics_service.h" | 5 #include "chrome/browser/metrics/metrics_service.h" |
6 | 6 |
7 #include <ctype.h> | |
8 #include <string> | 7 #include <string> |
9 | 8 |
10 #include "base/command_line.h" | 9 #include "base/command_line.h" |
11 #include "base/threading/platform_thread.h" | 10 #include "base/threading/platform_thread.h" |
12 #include "chrome/common/chrome_switches.h" | 11 #include "chrome/common/chrome_switches.h" |
13 #include "chrome/common/pref_names.h" | 12 #include "chrome/common/pref_names.h" |
14 #include "chrome/test/base/scoped_testing_local_state.h" | 13 #include "chrome/test/base/scoped_testing_local_state.h" |
15 #include "chrome/test/base/testing_browser_process.h" | 14 #include "chrome/test/base/testing_browser_process.h" |
16 #include "components/variations/metrics_util.h" | 15 #include "components/variations/metrics_util.h" |
17 #include "content/public/common/process_type.h" | 16 #include "content/public/common/process_type.h" |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 } | 89 } |
91 | 90 |
92 virtual ~MetricsServiceTest() { | 91 virtual ~MetricsServiceTest() { |
93 MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE); | 92 MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE); |
94 } | 93 } |
95 | 94 |
96 PrefService* GetLocalState() { | 95 PrefService* GetLocalState() { |
97 return testing_local_state_.Get(); | 96 return testing_local_state_.Get(); |
98 } | 97 } |
99 | 98 |
| 99 // Sets metrics reporting as enabled for testing. |
| 100 void EnableMetricsReporting() { |
| 101 // TODO(asvitkine): Refactor the code to not need this flag and delete it. |
| 102 CommandLine::ForCurrentProcess()->AppendSwitch( |
| 103 switches::kEnableMetricsReportingForTesting); |
| 104 } |
| 105 |
100 // Waits until base::TimeTicks::Now() no longer equals |value|. This should | 106 // Waits until base::TimeTicks::Now() no longer equals |value|. This should |
101 // take between 1-15ms per the documented resolution of base::TimeTicks. | 107 // take between 1-15ms per the documented resolution of base::TimeTicks. |
102 void WaitUntilTimeChanges(const base::TimeTicks& value) { | 108 void WaitUntilTimeChanges(const base::TimeTicks& value) { |
103 while (base::TimeTicks::Now() == value) { | 109 while (base::TimeTicks::Now() == value) { |
104 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); | 110 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); |
105 } | 111 } |
106 } | 112 } |
107 | 113 |
108 // Returns true if there is a synthetic trial in the given vector that matches | 114 // Returns true if there is a synthetic trial in the given vector that matches |
109 // the given trial name and trial group; returns false otherwise. | 115 // the given trial name and trial group; returns false otherwise. |
(...skipping 14 matching lines...) Expand all Loading... |
124 | 130 |
125 private: | 131 private: |
126 content::TestBrowserThreadBundle thread_bundle_; | 132 content::TestBrowserThreadBundle thread_bundle_; |
127 ScopedTestingLocalState testing_local_state_; | 133 ScopedTestingLocalState testing_local_state_; |
128 | 134 |
129 DISALLOW_COPY_AND_ASSIGN(MetricsServiceTest); | 135 DISALLOW_COPY_AND_ASSIGN(MetricsServiceTest); |
130 }; | 136 }; |
131 | 137 |
132 } // namespace | 138 } // namespace |
133 | 139 |
134 // Ensure the ClientId is formatted as expected. | |
135 TEST_F(MetricsServiceTest, ClientIdCorrectlyFormatted) { | |
136 std::string clientid = MetricsService::GenerateClientID(); | |
137 EXPECT_EQ(36U, clientid.length()); | |
138 | |
139 for (size_t i = 0; i < clientid.length(); ++i) { | |
140 char current = clientid[i]; | |
141 if (i == 8 || i == 13 || i == 18 || i == 23) | |
142 EXPECT_EQ('-', current); | |
143 else | |
144 EXPECT_TRUE(isxdigit(current)); | |
145 } | |
146 } | |
147 | |
148 TEST_F(MetricsServiceTest, IsPluginProcess) { | 140 TEST_F(MetricsServiceTest, IsPluginProcess) { |
149 EXPECT_TRUE( | 141 EXPECT_TRUE( |
150 MetricsService::IsPluginProcess(content::PROCESS_TYPE_PLUGIN)); | 142 MetricsService::IsPluginProcess(content::PROCESS_TYPE_PLUGIN)); |
151 EXPECT_TRUE( | 143 EXPECT_TRUE( |
152 MetricsService::IsPluginProcess(content::PROCESS_TYPE_PPAPI_PLUGIN)); | 144 MetricsService::IsPluginProcess(content::PROCESS_TYPE_PPAPI_PLUGIN)); |
153 EXPECT_FALSE( | 145 EXPECT_FALSE( |
154 MetricsService::IsPluginProcess(content::PROCESS_TYPE_GPU)); | 146 MetricsService::IsPluginProcess(content::PROCESS_TYPE_GPU)); |
155 } | 147 } |
156 | 148 |
157 TEST_F(MetricsServiceTest, LowEntropySource0NotReset) { | |
158 MetricsService service; | |
159 | |
160 // Get the low entropy source once, to initialize it. | |
161 service.GetLowEntropySource(); | |
162 | |
163 // Now, set it to 0 and ensure it doesn't get reset. | |
164 service.low_entropy_source_ = 0; | |
165 EXPECT_EQ(0, service.GetLowEntropySource()); | |
166 // Call it another time, just to make sure. | |
167 EXPECT_EQ(0, service.GetLowEntropySource()); | |
168 } | |
169 | |
170 TEST_F(MetricsServiceTest, PermutedEntropyCacheClearedWhenLowEntropyReset) { | |
171 const PrefService::Preference* low_entropy_pref = | |
172 GetLocalState()->FindPreference(prefs::kMetricsLowEntropySource); | |
173 const char* kCachePrefName = prefs::kMetricsPermutedEntropyCache; | |
174 int low_entropy_value = -1; | |
175 | |
176 // First, generate an initial low entropy source value. | |
177 { | |
178 EXPECT_TRUE(low_entropy_pref->IsDefaultValue()); | |
179 | |
180 MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE); | |
181 MetricsService service; | |
182 service.GetLowEntropySource(); | |
183 | |
184 EXPECT_FALSE(low_entropy_pref->IsDefaultValue()); | |
185 EXPECT_TRUE(low_entropy_pref->GetValue()->GetAsInteger(&low_entropy_value)); | |
186 } | |
187 | |
188 // Now, set a dummy value in the permuted entropy cache pref and verify that | |
189 // another call to GetLowEntropySource() doesn't clobber it when | |
190 // --reset-variation-state wasn't specified. | |
191 { | |
192 GetLocalState()->SetString(kCachePrefName, "test"); | |
193 | |
194 MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE); | |
195 MetricsService service; | |
196 service.GetLowEntropySource(); | |
197 | |
198 EXPECT_EQ("test", GetLocalState()->GetString(kCachePrefName)); | |
199 EXPECT_EQ(low_entropy_value, | |
200 GetLocalState()->GetInteger(prefs::kMetricsLowEntropySource)); | |
201 } | |
202 | |
203 // Verify that the cache does get reset if --reset-variations-state is passed. | |
204 { | |
205 CommandLine::ForCurrentProcess()->AppendSwitch( | |
206 switches::kResetVariationState); | |
207 | |
208 MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE); | |
209 MetricsService service; | |
210 service.GetLowEntropySource(); | |
211 | |
212 EXPECT_TRUE(GetLocalState()->GetString(kCachePrefName).empty()); | |
213 } | |
214 } | |
215 | |
216 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCleanShutDown) { | 149 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCleanShutDown) { |
217 base::FieldTrialList field_trial_list(NULL); | 150 EnableMetricsReporting(); |
218 base::FieldTrialList::CreateFieldTrial("UMAStability", "SeparateLog"); | |
219 | |
220 GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, true); | 151 GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, true); |
221 | 152 |
222 TestMetricsService service; | 153 TestMetricsService service; |
223 service.InitializeMetricsRecordingState(MetricsService::REPORTING_ENABLED); | 154 service.InitializeMetricsRecordingState(); |
224 // No initial stability log should be generated. | 155 // No initial stability log should be generated. |
225 EXPECT_FALSE(service.log_manager()->has_unsent_logs()); | 156 EXPECT_FALSE(service.log_manager()->has_unsent_logs()); |
226 EXPECT_FALSE(service.log_manager()->has_staged_log()); | 157 EXPECT_FALSE(service.log_manager()->has_staged_log()); |
227 } | 158 } |
228 | 159 |
229 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCrash) { | 160 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCrash) { |
230 base::FieldTrialList field_trial_list(NULL); | 161 EnableMetricsReporting(); |
231 base::FieldTrialList::CreateFieldTrial("UMAStability", "SeparateLog"); | |
232 | |
233 GetLocalState()->ClearPref(prefs::kStabilityExitedCleanly); | 162 GetLocalState()->ClearPref(prefs::kStabilityExitedCleanly); |
234 | 163 |
235 // Set up prefs to simulate restarting after a crash. | 164 // Set up prefs to simulate restarting after a crash. |
236 | 165 |
237 // Save an existing system profile to prefs, to correspond to what would be | 166 // Save an existing system profile to prefs, to correspond to what would be |
238 // saved from a previous session. | 167 // saved from a previous session. |
239 TestMetricsLog log("client", 1); | 168 TestMetricsLog log("client", 1); |
240 log.RecordEnvironment(std::vector<content::WebPluginInfo>(), | 169 log.RecordEnvironment(std::vector<content::WebPluginInfo>(), |
241 GoogleUpdateMetrics(), | 170 GoogleUpdateMetrics(), |
242 std::vector<chrome_variations::ActiveGroupId>()); | 171 std::vector<chrome_variations::ActiveGroupId>()); |
243 | 172 |
244 // Record stability build time and version from previous session, so that | 173 // Record stability build time and version from previous session, so that |
245 // stability metrics (including exited cleanly flag) won't be cleared. | 174 // stability metrics (including exited cleanly flag) won't be cleared. |
246 GetLocalState()->SetInt64(prefs::kStabilityStatsBuildTime, | 175 GetLocalState()->SetInt64(prefs::kStabilityStatsBuildTime, |
247 MetricsLog::GetBuildTime()); | 176 MetricsLog::GetBuildTime()); |
248 GetLocalState()->SetString(prefs::kStabilityStatsVersion, | 177 GetLocalState()->SetString(prefs::kStabilityStatsVersion, |
249 MetricsLog::GetVersionString()); | 178 MetricsLog::GetVersionString()); |
250 | 179 |
251 GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, false); | 180 GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, false); |
252 | 181 |
253 TestMetricsService service; | 182 TestMetricsService service; |
254 service.InitializeMetricsRecordingState(MetricsService::REPORTING_ENABLED); | 183 service.InitializeMetricsRecordingState(); |
255 | 184 |
256 // The initial stability log should be generated and persisted in unsent logs. | 185 // The initial stability log should be generated and persisted in unsent logs. |
257 MetricsLogManager* log_manager = service.log_manager(); | 186 MetricsLogManager* log_manager = service.log_manager(); |
258 EXPECT_TRUE(log_manager->has_unsent_logs()); | 187 EXPECT_TRUE(log_manager->has_unsent_logs()); |
259 EXPECT_FALSE(log_manager->has_staged_log()); | 188 EXPECT_FALSE(log_manager->has_staged_log()); |
260 | 189 |
261 // Stage the log and retrieve it. | 190 // Stage the log and retrieve it. |
262 log_manager->StageNextLogForUpload(); | 191 log_manager->StageNextLogForUpload(); |
263 EXPECT_TRUE(log_manager->has_staged_log()); | 192 EXPECT_TRUE(log_manager->has_staged_log()); |
264 | 193 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 GetLocalState()->SetBoolean(crash_pref, true); | 297 GetLocalState()->SetBoolean(crash_pref, true); |
369 EXPECT_TRUE(MetricsServiceHelper::IsCrashReportingEnabled()); | 298 EXPECT_TRUE(MetricsServiceHelper::IsCrashReportingEnabled()); |
370 GetLocalState()->ClearPref(crash_pref); | 299 GetLocalState()->ClearPref(crash_pref); |
371 EXPECT_FALSE(MetricsServiceHelper::IsCrashReportingEnabled()); | 300 EXPECT_FALSE(MetricsServiceHelper::IsCrashReportingEnabled()); |
372 #endif // !defined(OS_CHROMEOS) | 301 #endif // !defined(OS_CHROMEOS) |
373 #else // defined(GOOGLE_CHROME_BUILD) | 302 #else // defined(GOOGLE_CHROME_BUILD) |
374 // Chromium branded browsers never have crash reporting enabled. | 303 // Chromium branded browsers never have crash reporting enabled. |
375 EXPECT_FALSE(MetricsServiceHelper::IsCrashReportingEnabled()); | 304 EXPECT_FALSE(MetricsServiceHelper::IsCrashReportingEnabled()); |
376 #endif // defined(GOOGLE_CHROME_BUILD) | 305 #endif // defined(GOOGLE_CHROME_BUILD) |
377 } | 306 } |
378 | |
379 // Check that setting the kMetricsResetIds pref to true causes the client id to | |
380 // be reset. We do not check that the low entropy source is reset because we | |
381 // cannot ensure that metrics service won't generate the same id again. | |
382 TEST_F(MetricsServiceTest, ResetMetricsIDs) { | |
383 // Set an initial client id in prefs. It should not be possible for the | |
384 // metrics service to generate this id randomly. | |
385 const std::string kInitialClientId = "initial client id"; | |
386 GetLocalState()->SetString(prefs::kMetricsClientID, kInitialClientId); | |
387 | |
388 // Make sure the initial client id isn't reset by the metrics service. | |
389 { | |
390 MetricsService service; | |
391 service.ForceClientIdCreation(); | |
392 EXPECT_TRUE(service.metrics_ids_reset_check_performed_); | |
393 EXPECT_EQ(kInitialClientId, service.client_id_); | |
394 } | |
395 | |
396 | |
397 // Set the reset pref to cause the IDs to be reset. | |
398 GetLocalState()->SetBoolean(prefs::kMetricsResetIds, true); | |
399 | |
400 // Cause the actual reset to happen. | |
401 { | |
402 MetricsService service; | |
403 service.ForceClientIdCreation(); | |
404 EXPECT_TRUE(service.metrics_ids_reset_check_performed_); | |
405 EXPECT_NE(kInitialClientId, service.client_id_); | |
406 | |
407 service.GetLowEntropySource(); | |
408 | |
409 EXPECT_FALSE(GetLocalState()->GetBoolean(prefs::kMetricsResetIds)); | |
410 } | |
411 | |
412 std::string new_client_id = | |
413 GetLocalState()->GetString(prefs::kMetricsClientID); | |
414 | |
415 EXPECT_NE(kInitialClientId, new_client_id); | |
416 } | |
OLD | NEW |