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> |
7 #include <string> | 8 #include <string> |
8 | 9 |
9 #include "base/command_line.h" | 10 #include "base/command_line.h" |
10 #include "base/threading/platform_thread.h" | 11 #include "base/threading/platform_thread.h" |
11 #include "chrome/common/chrome_switches.h" | 12 #include "chrome/common/chrome_switches.h" |
12 #include "chrome/common/pref_names.h" | 13 #include "chrome/common/pref_names.h" |
13 #include "chrome/test/base/scoped_testing_local_state.h" | 14 #include "chrome/test/base/scoped_testing_local_state.h" |
14 #include "chrome/test/base/testing_browser_process.h" | 15 #include "chrome/test/base/testing_browser_process.h" |
15 #include "components/variations/metrics_util.h" | 16 #include "components/variations/metrics_util.h" |
16 #include "content/public/common/process_type.h" | 17 #include "content/public/common/process_type.h" |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 } | 90 } |
90 | 91 |
91 virtual ~MetricsServiceTest() { | 92 virtual ~MetricsServiceTest() { |
92 MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE); | 93 MetricsService::SetExecutionPhase(MetricsService::UNINITIALIZED_PHASE); |
93 } | 94 } |
94 | 95 |
95 PrefService* GetLocalState() { | 96 PrefService* GetLocalState() { |
96 return testing_local_state_.Get(); | 97 return testing_local_state_.Get(); |
97 } | 98 } |
98 | 99 |
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 | |
106 // Waits until base::TimeTicks::Now() no longer equals |value|. This should | 100 // Waits until base::TimeTicks::Now() no longer equals |value|. This should |
107 // take between 1-15ms per the documented resolution of base::TimeTicks. | 101 // take between 1-15ms per the documented resolution of base::TimeTicks. |
108 void WaitUntilTimeChanges(const base::TimeTicks& value) { | 102 void WaitUntilTimeChanges(const base::TimeTicks& value) { |
109 while (base::TimeTicks::Now() == value) { | 103 while (base::TimeTicks::Now() == value) { |
110 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); | 104 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(1)); |
111 } | 105 } |
112 } | 106 } |
113 | 107 |
114 // Returns true if there is a synthetic trial in the given vector that matches | 108 // Returns true if there is a synthetic trial in the given vector that matches |
115 // the given trial name and trial group; returns false otherwise. | 109 // the given trial name and trial group; returns false otherwise. |
(...skipping 14 matching lines...) Expand all Loading... |
130 | 124 |
131 private: | 125 private: |
132 content::TestBrowserThreadBundle thread_bundle_; | 126 content::TestBrowserThreadBundle thread_bundle_; |
133 ScopedTestingLocalState testing_local_state_; | 127 ScopedTestingLocalState testing_local_state_; |
134 | 128 |
135 DISALLOW_COPY_AND_ASSIGN(MetricsServiceTest); | 129 DISALLOW_COPY_AND_ASSIGN(MetricsServiceTest); |
136 }; | 130 }; |
137 | 131 |
138 } // namespace | 132 } // namespace |
139 | 133 |
| 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 |
140 TEST_F(MetricsServiceTest, IsPluginProcess) { | 148 TEST_F(MetricsServiceTest, IsPluginProcess) { |
141 EXPECT_TRUE( | 149 EXPECT_TRUE( |
142 MetricsService::IsPluginProcess(content::PROCESS_TYPE_PLUGIN)); | 150 MetricsService::IsPluginProcess(content::PROCESS_TYPE_PLUGIN)); |
143 EXPECT_TRUE( | 151 EXPECT_TRUE( |
144 MetricsService::IsPluginProcess(content::PROCESS_TYPE_PPAPI_PLUGIN)); | 152 MetricsService::IsPluginProcess(content::PROCESS_TYPE_PPAPI_PLUGIN)); |
145 EXPECT_FALSE( | 153 EXPECT_FALSE( |
146 MetricsService::IsPluginProcess(content::PROCESS_TYPE_GPU)); | 154 MetricsService::IsPluginProcess(content::PROCESS_TYPE_GPU)); |
147 } | 155 } |
148 | 156 |
| 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 |
149 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCleanShutDown) { | 216 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCleanShutDown) { |
150 EnableMetricsReporting(); | 217 base::FieldTrialList field_trial_list(NULL); |
| 218 base::FieldTrialList::CreateFieldTrial("UMAStability", "SeparateLog"); |
| 219 |
151 GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, true); | 220 GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, true); |
152 | 221 |
153 TestMetricsService service; | 222 TestMetricsService service; |
154 service.InitializeMetricsRecordingState(); | 223 service.InitializeMetricsRecordingState(MetricsService::REPORTING_ENABLED); |
155 // No initial stability log should be generated. | 224 // No initial stability log should be generated. |
156 EXPECT_FALSE(service.log_manager()->has_unsent_logs()); | 225 EXPECT_FALSE(service.log_manager()->has_unsent_logs()); |
157 EXPECT_FALSE(service.log_manager()->has_staged_log()); | 226 EXPECT_FALSE(service.log_manager()->has_staged_log()); |
158 } | 227 } |
159 | 228 |
160 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCrash) { | 229 TEST_F(MetricsServiceTest, InitialStabilityLogAfterCrash) { |
161 EnableMetricsReporting(); | 230 base::FieldTrialList field_trial_list(NULL); |
| 231 base::FieldTrialList::CreateFieldTrial("UMAStability", "SeparateLog"); |
| 232 |
162 GetLocalState()->ClearPref(prefs::kStabilityExitedCleanly); | 233 GetLocalState()->ClearPref(prefs::kStabilityExitedCleanly); |
163 | 234 |
164 // Set up prefs to simulate restarting after a crash. | 235 // Set up prefs to simulate restarting after a crash. |
165 | 236 |
166 // Save an existing system profile to prefs, to correspond to what would be | 237 // Save an existing system profile to prefs, to correspond to what would be |
167 // saved from a previous session. | 238 // saved from a previous session. |
168 TestMetricsLog log("client", 1); | 239 TestMetricsLog log("client", 1); |
169 log.RecordEnvironment(std::vector<content::WebPluginInfo>(), | 240 log.RecordEnvironment(std::vector<content::WebPluginInfo>(), |
170 GoogleUpdateMetrics(), | 241 GoogleUpdateMetrics(), |
171 std::vector<chrome_variations::ActiveGroupId>()); | 242 std::vector<chrome_variations::ActiveGroupId>()); |
172 | 243 |
173 // Record stability build time and version from previous session, so that | 244 // Record stability build time and version from previous session, so that |
174 // stability metrics (including exited cleanly flag) won't be cleared. | 245 // stability metrics (including exited cleanly flag) won't be cleared. |
175 GetLocalState()->SetInt64(prefs::kStabilityStatsBuildTime, | 246 GetLocalState()->SetInt64(prefs::kStabilityStatsBuildTime, |
176 MetricsLog::GetBuildTime()); | 247 MetricsLog::GetBuildTime()); |
177 GetLocalState()->SetString(prefs::kStabilityStatsVersion, | 248 GetLocalState()->SetString(prefs::kStabilityStatsVersion, |
178 MetricsLog::GetVersionString()); | 249 MetricsLog::GetVersionString()); |
179 | 250 |
180 GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, false); | 251 GetLocalState()->SetBoolean(prefs::kStabilityExitedCleanly, false); |
181 | 252 |
182 TestMetricsService service; | 253 TestMetricsService service; |
183 service.InitializeMetricsRecordingState(); | 254 service.InitializeMetricsRecordingState(MetricsService::REPORTING_ENABLED); |
184 | 255 |
185 // The initial stability log should be generated and persisted in unsent logs. | 256 // The initial stability log should be generated and persisted in unsent logs. |
186 MetricsLogManager* log_manager = service.log_manager(); | 257 MetricsLogManager* log_manager = service.log_manager(); |
187 EXPECT_TRUE(log_manager->has_unsent_logs()); | 258 EXPECT_TRUE(log_manager->has_unsent_logs()); |
188 EXPECT_FALSE(log_manager->has_staged_log()); | 259 EXPECT_FALSE(log_manager->has_staged_log()); |
189 | 260 |
190 // Stage the log and retrieve it. | 261 // Stage the log and retrieve it. |
191 log_manager->StageNextLogForUpload(); | 262 log_manager->StageNextLogForUpload(); |
192 EXPECT_TRUE(log_manager->has_staged_log()); | 263 EXPECT_TRUE(log_manager->has_staged_log()); |
193 | 264 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 GetLocalState()->SetBoolean(crash_pref, true); | 368 GetLocalState()->SetBoolean(crash_pref, true); |
298 EXPECT_TRUE(MetricsServiceHelper::IsCrashReportingEnabled()); | 369 EXPECT_TRUE(MetricsServiceHelper::IsCrashReportingEnabled()); |
299 GetLocalState()->ClearPref(crash_pref); | 370 GetLocalState()->ClearPref(crash_pref); |
300 EXPECT_FALSE(MetricsServiceHelper::IsCrashReportingEnabled()); | 371 EXPECT_FALSE(MetricsServiceHelper::IsCrashReportingEnabled()); |
301 #endif // !defined(OS_CHROMEOS) | 372 #endif // !defined(OS_CHROMEOS) |
302 #else // defined(GOOGLE_CHROME_BUILD) | 373 #else // defined(GOOGLE_CHROME_BUILD) |
303 // Chromium branded browsers never have crash reporting enabled. | 374 // Chromium branded browsers never have crash reporting enabled. |
304 EXPECT_FALSE(MetricsServiceHelper::IsCrashReportingEnabled()); | 375 EXPECT_FALSE(MetricsServiceHelper::IsCrashReportingEnabled()); |
305 #endif // defined(GOOGLE_CHROME_BUILD) | 376 #endif // defined(GOOGLE_CHROME_BUILD) |
306 } | 377 } |
| 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 |