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