| 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 |