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