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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/metrics/metrics_log.h" 6 7 #include <string> 8 9 #include "base/base64.h" 10 #include "base/basictypes.h" 11 #include "base/command_line.h" 12 #include "base/message_loop/message_loop.h" 13 #include "base/port.h" 14 #include "base/prefs/pref_service.h" 15 #include "base/prefs/scoped_user_pref_update.h" 16 #include "base/prefs/testing_pref_service.h" 17 #include "base/strings/string_number_conversions.h" 18 #include "base/strings/string_util.h" 19 #include "base/strings/stringprintf.h" 20 #include "base/strings/utf_string_conversions.h" 21 #include "base/threading/sequenced_worker_pool.h" 22 #include "base/time/time.h" 23 #include "base/tracked_objects.h" 24 #include "chrome/browser/google/google_util.h" 25 #include "chrome/browser/prefs/browser_prefs.h" 26 #include "chrome/common/chrome_switches.h" 27 #include "chrome/common/metrics/proto/profiler_event.pb.h" 28 #include "chrome/common/metrics/proto/system_profile.pb.h" 29 #include "chrome/common/metrics/variations/variations_util.h" 30 #include "chrome/common/pref_names.h" 31 #include "chrome/installer/util/google_update_settings.h" 32 #include "components/variations/metrics_util.h" 33 #include "content/public/browser/browser_thread.h" 34 #include "content/public/common/process_type.h" 35 #include "content/public/common/webplugininfo.h" 36 #include "content/public/test/test_utils.h" 37 #include "testing/gtest/include/gtest/gtest.h" 38 #include "ui/gfx/size.h" 39 #include "url/gurl.h" 40 41 #if defined(OS_CHROMEOS) 42 #include "chrome/browser/chromeos/login/fake_user_manager.h" 43 #include "chrome/browser/chromeos/login/user_manager.h" 44 #include "chromeos/dbus/fake_bluetooth_adapter_client.h" 45 #include "chromeos/dbus/fake_bluetooth_device_client.h" 46 #include "chromeos/dbus/fake_bluetooth_input_client.h" 47 #include "chromeos/dbus/fake_dbus_thread_manager.h" 48 #endif // OS_CHROMEOS 49 50 using base::TimeDelta; 51 using metrics::ProfilerEventProto; 52 using tracked_objects::ProcessDataSnapshot; 53 using tracked_objects::TaskSnapshot; 54 55 namespace { 56 57 const char kClientId[] = "bogus client ID"; 58 const int64 kInstallDate = 1373051956; 59 const int64 kInstallDateExpected = 1373050800; // Computed from kInstallDate. 60 const int64 kEnabledDate = 1373001211; 61 const int64 kEnabledDateExpected = 1373000400; // Computed from kEnabledDate. 62 const int kSessionId = 127; 63 const int kScreenWidth = 1024; 64 const int kScreenHeight = 768; 65 const int kScreenCount = 3; 66 const float kScreenScaleFactor = 2; 67 const char kBrandForTesting[] = "brand_for_testing"; 68 const chrome_variations::ActiveGroupId kFieldTrialIds[] = { 69 {37, 43}, 70 {13, 47}, 71 {23, 17} 72 }; 73 const chrome_variations::ActiveGroupId kSyntheticTrials[] = { 74 {55, 15}, 75 {66, 16} 76 }; 77 78 #if defined(ENABLE_PLUGINS) 79 content::WebPluginInfo CreateFakePluginInfo( 80 const std::string& name, 81 const base::FilePath::CharType* path, 82 const std::string& version, 83 bool is_pepper) { 84 content::WebPluginInfo plugin(UTF8ToUTF16(name), 85 base::FilePath(path), 86 UTF8ToUTF16(version), 87 base::string16()); 88 if (is_pepper) 89 plugin.type = content::WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS; 90 else 91 plugin.type = content::WebPluginInfo::PLUGIN_TYPE_NPAPI; 92 return plugin; 93 } 94 #endif // defined(ENABLE_PLUGINS) 95 96 class TestMetricsLog : public MetricsLog { 97 public: 98 TestMetricsLog(const std::string& client_id, int session_id) 99 : MetricsLog(client_id, session_id), 100 prefs_(&scoped_prefs_), 101 brand_for_testing_(kBrandForTesting) { 102 chrome::RegisterLocalState(scoped_prefs_.registry()); 103 InitPrefs(); 104 } 105 // Creates a TestMetricsLog that will use |prefs| as the fake local state. 106 // Useful for tests that need to re-use the local state prefs between logs. 107 TestMetricsLog(const std::string& client_id, 108 int session_id, 109 TestingPrefServiceSimple* prefs) 110 : MetricsLog(client_id, session_id), 111 prefs_(prefs), 112 brand_for_testing_(kBrandForTesting) { 113 InitPrefs(); 114 } 115 virtual ~TestMetricsLog() {} 116 117 virtual PrefService* GetPrefService() OVERRIDE { 118 return prefs_; 119 } 120 121 const metrics::ChromeUserMetricsExtension& uma_proto() const { 122 return *MetricsLog::uma_proto(); 123 } 124 125 const metrics::SystemProfileProto& system_profile() const { 126 return uma_proto().system_profile(); 127 } 128 129 private: 130 void InitPrefs() { 131 prefs_->SetInt64(prefs::kInstallDate, kInstallDate); 132 prefs_->SetString(prefs::kMetricsClientIDTimestamp, 133 base::Int64ToString(kEnabledDate)); 134 #if defined(OS_CHROMEOS) 135 prefs_->SetInteger(prefs::kStabilityChildProcessCrashCount, 10); 136 prefs_->SetInteger(prefs::kStabilityOtherUserCrashCount, 11); 137 prefs_->SetInteger(prefs::kStabilityKernelCrashCount, 12); 138 prefs_->SetInteger(prefs::kStabilitySystemUncleanShutdownCount, 13); 139 #endif // OS_CHROMEOS 140 } 141 142 virtual void GetFieldTrialIds( 143 std::vector<chrome_variations::ActiveGroupId>* field_trial_ids) const 144 OVERRIDE { 145 ASSERT_TRUE(field_trial_ids->empty()); 146 147 for (size_t i = 0; i < arraysize(kFieldTrialIds); ++i) { 148 field_trial_ids->push_back(kFieldTrialIds[i]); 149 } 150 } 151 152 virtual gfx::Size GetScreenSize() const OVERRIDE { 153 return gfx::Size(kScreenWidth, kScreenHeight); 154 } 155 156 virtual float GetScreenDeviceScaleFactor() const OVERRIDE { 157 return kScreenScaleFactor; 158 } 159 160 virtual int GetScreenCount() const OVERRIDE { 161 return kScreenCount; 162 } 163 164 // Scoped PrefsService, which may not be used if |prefs_ != &scoped_prefs|. 165 TestingPrefServiceSimple scoped_prefs_; 166 // Weak pointer to the PrefsService used by this log. 167 TestingPrefServiceSimple* prefs_; 168 169 google_util::BrandForTesting brand_for_testing_; 170 171 DISALLOW_COPY_AND_ASSIGN(TestMetricsLog); 172 }; 173 174 } // namespace 175 176 class MetricsLogTest : public testing::Test { 177 public: 178 MetricsLogTest() : message_loop_(base::MessageLoop::TYPE_IO) {} 179 180 protected: 181 virtual void SetUp() OVERRIDE { 182 #if defined(OS_CHROMEOS) 183 chromeos::FakeDBusThreadManager* fake_dbus_thread_manager = 184 new chromeos::FakeDBusThreadManager; 185 fake_dbus_thread_manager->SetBluetoothAdapterClient( 186 scoped_ptr<chromeos::BluetoothAdapterClient>( 187 new chromeos::FakeBluetoothAdapterClient)); 188 fake_dbus_thread_manager->SetBluetoothDeviceClient( 189 scoped_ptr<chromeos::BluetoothDeviceClient>( 190 new chromeos::FakeBluetoothDeviceClient)); 191 fake_dbus_thread_manager->SetBluetoothInputClient( 192 scoped_ptr<chromeos::BluetoothInputClient>( 193 new chromeos::FakeBluetoothInputClient)); 194 chromeos::DBusThreadManager::InitializeForTesting(fake_dbus_thread_manager); 195 196 // Enable multi-profiles. 197 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kMultiProfiles); 198 #endif // OS_CHROMEOS 199 } 200 201 virtual void TearDown() OVERRIDE { 202 // Drain the blocking pool from PostTaskAndReply executed by 203 // MetrticsLog.network_observer_. 204 content::BrowserThread::GetBlockingPool()->FlushForTesting(); 205 content::RunAllPendingInMessageLoop(); 206 207 #if defined(OS_CHROMEOS) 208 chromeos::DBusThreadManager::Shutdown(); 209 #endif // OS_CHROMEOS 210 } 211 212 // Check that the values in |system_values| correspond to the test data 213 // defined at the top of this file. 214 void CheckSystemProfile(const metrics::SystemProfileProto& system_profile) { 215 EXPECT_EQ(kInstallDateExpected, system_profile.install_date()); 216 EXPECT_EQ(kEnabledDateExpected, system_profile.uma_enabled_date()); 217 218 ASSERT_EQ(arraysize(kFieldTrialIds) + arraysize(kSyntheticTrials), 219 static_cast<size_t>(system_profile.field_trial_size())); 220 for (size_t i = 0; i < arraysize(kFieldTrialIds); ++i) { 221 const metrics::SystemProfileProto::FieldTrial& field_trial = 222 system_profile.field_trial(i); 223 EXPECT_EQ(kFieldTrialIds[i].name, field_trial.name_id()); 224 EXPECT_EQ(kFieldTrialIds[i].group, field_trial.group_id()); 225 } 226 // Verify the right data is present for the synthetic trials. 227 for (size_t i = 0; i < arraysize(kSyntheticTrials); ++i) { 228 const metrics::SystemProfileProto::FieldTrial& field_trial = 229 system_profile.field_trial(i + arraysize(kFieldTrialIds)); 230 EXPECT_EQ(kSyntheticTrials[i].name, field_trial.name_id()); 231 EXPECT_EQ(kSyntheticTrials[i].group, field_trial.group_id()); 232 } 233 234 EXPECT_EQ(kBrandForTesting, system_profile.brand_code()); 235 236 const metrics::SystemProfileProto::Hardware& hardware = 237 system_profile.hardware(); 238 EXPECT_EQ(kScreenWidth, hardware.primary_screen_width()); 239 EXPECT_EQ(kScreenHeight, hardware.primary_screen_height()); 240 EXPECT_EQ(kScreenScaleFactor, hardware.primary_screen_scale_factor()); 241 EXPECT_EQ(kScreenCount, hardware.screen_count()); 242 243 EXPECT_TRUE(hardware.has_cpu()); 244 EXPECT_TRUE(hardware.cpu().has_vendor_name()); 245 EXPECT_TRUE(hardware.cpu().has_signature()); 246 247 // TODO(isherman): Verify other data written into the protobuf as a result 248 // of this call. 249 } 250 251 private: 252 // This is necessary because eventually some tests call base::RepeatingTimer 253 // functions and a message loop is required for that. 254 base::MessageLoop message_loop_; 255 256 DISALLOW_COPY_AND_ASSIGN(MetricsLogTest); 257 }; 258 259 TEST_F(MetricsLogTest, RecordEnvironment) { 260 TestMetricsLog log(kClientId, kSessionId); 261 262 std::vector<content::WebPluginInfo> plugins; 263 GoogleUpdateMetrics google_update_metrics; 264 std::vector<chrome_variations::ActiveGroupId> synthetic_trials; 265 // Add two synthetic trials. 266 synthetic_trials.push_back(kSyntheticTrials[0]); 267 synthetic_trials.push_back(kSyntheticTrials[1]); 268 269 log.RecordEnvironment(plugins, google_update_metrics, synthetic_trials); 270 // Check that the system profile on the log has the correct values set. 271 CheckSystemProfile(log.system_profile()); 272 273 // Check that the system profile has also been written to prefs. 274 PrefService* local_state = log.GetPrefService(); 275 const std::string base64_system_profile = 276 local_state->GetString(prefs::kStabilitySavedSystemProfile); 277 EXPECT_FALSE(base64_system_profile.empty()); 278 std::string serialied_system_profile; 279 EXPECT_TRUE(base::Base64Decode(base64_system_profile, 280 &serialied_system_profile)); 281 SystemProfileProto decoded_system_profile; 282 EXPECT_TRUE(decoded_system_profile.ParseFromString(serialied_system_profile)); 283 CheckSystemProfile(decoded_system_profile); 284 } 285 286 TEST_F(MetricsLogTest, LoadSavedEnvironmentFromPrefs) { 287 const char* kSystemProfilePref = prefs::kStabilitySavedSystemProfile; 288 const char* kSystemProfileHashPref = prefs::kStabilitySavedSystemProfileHash; 289 290 TestingPrefServiceSimple prefs; 291 chrome::RegisterLocalState(prefs.registry()); 292 293 // The pref value is empty, so loading it from prefs should fail. 294 { 295 TestMetricsLog log(kClientId, kSessionId, &prefs); 296 EXPECT_FALSE(log.LoadSavedEnvironmentFromPrefs()); 297 } 298 299 // Do a RecordEnvironment() call and check whether the pref is recorded. 300 { 301 TestMetricsLog log(kClientId, kSessionId, &prefs); 302 log.RecordEnvironment(std::vector<content::WebPluginInfo>(), 303 GoogleUpdateMetrics(), 304 std::vector<chrome_variations::ActiveGroupId>()); 305 EXPECT_FALSE(prefs.GetString(kSystemProfilePref).empty()); 306 EXPECT_FALSE(prefs.GetString(kSystemProfileHashPref).empty()); 307 } 308 309 { 310 TestMetricsLog log(kClientId, kSessionId, &prefs); 311 EXPECT_TRUE(log.LoadSavedEnvironmentFromPrefs()); 312 // Check some values in the system profile. 313 EXPECT_EQ(kInstallDateExpected, log.system_profile().install_date()); 314 EXPECT_EQ(kEnabledDateExpected, log.system_profile().uma_enabled_date()); 315 // Ensure that the call cleared the prefs. 316 EXPECT_TRUE(prefs.GetString(kSystemProfilePref).empty()); 317 EXPECT_TRUE(prefs.GetString(kSystemProfileHashPref).empty()); 318 } 319 320 // Ensure that a non-matching hash results in the pref being invalid. 321 { 322 TestMetricsLog log(kClientId, kSessionId, &prefs); 323 // Call RecordEnvironment() to record the pref again. 324 log.RecordEnvironment(std::vector<content::WebPluginInfo>(), 325 GoogleUpdateMetrics(), 326 std::vector<chrome_variations::ActiveGroupId>()); 327 } 328 329 { 330 // Set the hash to a bad value. 331 prefs.SetString(kSystemProfileHashPref, "deadbeef"); 332 TestMetricsLog log(kClientId, kSessionId, &prefs); 333 EXPECT_FALSE(log.LoadSavedEnvironmentFromPrefs()); 334 // Ensure that the prefs are cleared, even if the call failed. 335 EXPECT_TRUE(prefs.GetString(kSystemProfilePref).empty()); 336 EXPECT_TRUE(prefs.GetString(kSystemProfileHashPref).empty()); 337 } 338 } 339 340 TEST_F(MetricsLogTest, InitialLogStabilityMetrics) { 341 TestMetricsLog log(kClientId, kSessionId); 342 log.RecordEnvironment(std::vector<content::WebPluginInfo>(), 343 GoogleUpdateMetrics(), 344 std::vector<chrome_variations::ActiveGroupId>()); 345 log.RecordStabilityMetrics(base::TimeDelta(), MetricsLog::INITIAL_LOG); 346 const metrics::SystemProfileProto_Stability& stability = 347 log.system_profile().stability(); 348 // Required metrics: 349 EXPECT_TRUE(stability.has_launch_count()); 350 EXPECT_TRUE(stability.has_crash_count()); 351 // Initial log metrics: 352 EXPECT_TRUE(stability.has_incomplete_shutdown_count()); 353 EXPECT_TRUE(stability.has_breakpad_registration_success_count()); 354 EXPECT_TRUE(stability.has_breakpad_registration_failure_count()); 355 EXPECT_TRUE(stability.has_debugger_present_count()); 356 EXPECT_TRUE(stability.has_debugger_not_present_count()); 357 } 358 359 TEST_F(MetricsLogTest, OngoingLogStabilityMetrics) { 360 TestMetricsLog log(kClientId, kSessionId); 361 log.RecordEnvironment(std::vector<content::WebPluginInfo>(), 362 GoogleUpdateMetrics(), 363 std::vector<chrome_variations::ActiveGroupId>()); 364 log.RecordStabilityMetrics(base::TimeDelta(), MetricsLog::ONGOING_LOG); 365 const metrics::SystemProfileProto_Stability& stability = 366 log.system_profile().stability(); 367 // Required metrics: 368 EXPECT_TRUE(stability.has_launch_count()); 369 EXPECT_TRUE(stability.has_crash_count()); 370 // Initial log metrics: 371 EXPECT_FALSE(stability.has_incomplete_shutdown_count()); 372 EXPECT_FALSE(stability.has_breakpad_registration_success_count()); 373 EXPECT_FALSE(stability.has_breakpad_registration_failure_count()); 374 EXPECT_FALSE(stability.has_debugger_present_count()); 375 EXPECT_FALSE(stability.has_debugger_not_present_count()); 376 } 377 378 #if defined(ENABLE_PLUGINS) 379 TEST_F(MetricsLogTest, Plugins) { 380 TestMetricsLog log(kClientId, kSessionId); 381 382 std::vector<content::WebPluginInfo> plugins; 383 plugins.push_back(CreateFakePluginInfo("p1", FILE_PATH_LITERAL("p1.plugin"), 384 "1.5", true)); 385 plugins.push_back(CreateFakePluginInfo("p2", FILE_PATH_LITERAL("p2.plugin"), 386 "2.0", false)); 387 log.RecordEnvironment(plugins, GoogleUpdateMetrics(), 388 std::vector<chrome_variations::ActiveGroupId>()); 389 390 const metrics::SystemProfileProto& system_profile = log.system_profile(); 391 ASSERT_EQ(2, system_profile.plugin_size()); 392 EXPECT_EQ("p1", system_profile.plugin(0).name()); 393 EXPECT_EQ("p1.plugin", system_profile.plugin(0).filename()); 394 EXPECT_EQ("1.5", system_profile.plugin(0).version()); 395 EXPECT_TRUE(system_profile.plugin(0).is_pepper()); 396 EXPECT_EQ("p2", system_profile.plugin(1).name()); 397 EXPECT_EQ("p2.plugin", system_profile.plugin(1).filename()); 398 EXPECT_EQ("2.0", system_profile.plugin(1).version()); 399 EXPECT_FALSE(system_profile.plugin(1).is_pepper()); 400 401 // Now set some plugin stability stats for p2 and verify they're recorded. 402 scoped_ptr<base::DictionaryValue> plugin_dict(new DictionaryValue); 403 plugin_dict->SetString(prefs::kStabilityPluginName, "p2"); 404 plugin_dict->SetInteger(prefs::kStabilityPluginLaunches, 1); 405 plugin_dict->SetInteger(prefs::kStabilityPluginCrashes, 2); 406 plugin_dict->SetInteger(prefs::kStabilityPluginInstances, 3); 407 plugin_dict->SetInteger(prefs::kStabilityPluginLoadingErrors, 4); 408 { 409 ListPrefUpdate update(log.GetPrefService(), prefs::kStabilityPluginStats); 410 update.Get()->Append(plugin_dict.release()); 411 } 412 413 log.RecordStabilityMetrics(base::TimeDelta(), MetricsLog::ONGOING_LOG); 414 const metrics::SystemProfileProto_Stability& stability = 415 log.system_profile().stability(); 416 ASSERT_EQ(1, stability.plugin_stability_size()); 417 EXPECT_EQ("p2", stability.plugin_stability(0).plugin().name()); 418 EXPECT_EQ("p2.plugin", stability.plugin_stability(0).plugin().filename()); 419 EXPECT_EQ("2.0", stability.plugin_stability(0).plugin().version()); 420 EXPECT_FALSE(stability.plugin_stability(0).plugin().is_pepper()); 421 EXPECT_EQ(1, stability.plugin_stability(0).launch_count()); 422 EXPECT_EQ(2, stability.plugin_stability(0).crash_count()); 423 EXPECT_EQ(3, stability.plugin_stability(0).instance_count()); 424 EXPECT_EQ(4, stability.plugin_stability(0).loading_error_count()); 425 } 426 #endif // defined(ENABLE_PLUGINS) 427 428 // Test that we properly write profiler data to the log. 429 TEST_F(MetricsLogTest, RecordProfilerData) { 430 TestMetricsLog log(kClientId, kSessionId); 431 EXPECT_EQ(0, log.uma_proto().profiler_event_size()); 432 433 { 434 ProcessDataSnapshot process_data; 435 process_data.process_id = 177; 436 process_data.tasks.push_back(TaskSnapshot()); 437 process_data.tasks.back().birth.location.file_name = "file"; 438 process_data.tasks.back().birth.location.function_name = "function"; 439 process_data.tasks.back().birth.location.line_number = 1337; 440 process_data.tasks.back().birth.thread_name = "birth_thread"; 441 process_data.tasks.back().death_data.count = 37; 442 process_data.tasks.back().death_data.run_duration_sum = 31; 443 process_data.tasks.back().death_data.run_duration_max = 17; 444 process_data.tasks.back().death_data.run_duration_sample = 13; 445 process_data.tasks.back().death_data.queue_duration_sum = 8; 446 process_data.tasks.back().death_data.queue_duration_max = 5; 447 process_data.tasks.back().death_data.queue_duration_sample = 3; 448 process_data.tasks.back().death_thread_name = "Still_Alive"; 449 process_data.tasks.push_back(TaskSnapshot()); 450 process_data.tasks.back().birth.location.file_name = "file2"; 451 process_data.tasks.back().birth.location.function_name = "function2"; 452 process_data.tasks.back().birth.location.line_number = 1773; 453 process_data.tasks.back().birth.thread_name = "birth_thread2"; 454 process_data.tasks.back().death_data.count = 19; 455 process_data.tasks.back().death_data.run_duration_sum = 23; 456 process_data.tasks.back().death_data.run_duration_max = 11; 457 process_data.tasks.back().death_data.run_duration_sample = 7; 458 process_data.tasks.back().death_data.queue_duration_sum = 0; 459 process_data.tasks.back().death_data.queue_duration_max = 0; 460 process_data.tasks.back().death_data.queue_duration_sample = 0; 461 process_data.tasks.back().death_thread_name = "death_thread"; 462 463 log.RecordProfilerData(process_data, content::PROCESS_TYPE_BROWSER); 464 ASSERT_EQ(1, log.uma_proto().profiler_event_size()); 465 EXPECT_EQ(ProfilerEventProto::STARTUP_PROFILE, 466 log.uma_proto().profiler_event(0).profile_type()); 467 EXPECT_EQ(ProfilerEventProto::WALL_CLOCK_TIME, 468 log.uma_proto().profiler_event(0).time_source()); 469 470 ASSERT_EQ(2, log.uma_proto().profiler_event(0).tracked_object_size()); 471 472 const ProfilerEventProto::TrackedObject* tracked_object = 473 &log.uma_proto().profiler_event(0).tracked_object(0); 474 EXPECT_EQ(GG_UINT64_C(10123486280357988687), 475 tracked_object->source_file_name_hash()); 476 EXPECT_EQ(GG_UINT64_C(13962325592283560029), 477 tracked_object->source_function_name_hash()); 478 EXPECT_EQ(1337, tracked_object->source_line_number()); 479 EXPECT_EQ(GG_UINT64_C(3400908935414830400), 480 tracked_object->birth_thread_name_hash()); 481 EXPECT_EQ(37, tracked_object->exec_count()); 482 EXPECT_EQ(31, tracked_object->exec_time_total()); 483 EXPECT_EQ(13, tracked_object->exec_time_sampled()); 484 EXPECT_EQ(8, tracked_object->queue_time_total()); 485 EXPECT_EQ(3, tracked_object->queue_time_sampled()); 486 EXPECT_EQ(GG_UINT64_C(10151977472163283085), 487 tracked_object->exec_thread_name_hash()); 488 EXPECT_EQ(177U, tracked_object->process_id()); 489 EXPECT_EQ(ProfilerEventProto::TrackedObject::BROWSER, 490 tracked_object->process_type()); 491 492 tracked_object = &log.uma_proto().profiler_event(0).tracked_object(1); 493 EXPECT_EQ(GG_UINT64_C(2025659946535236365), 494 tracked_object->source_file_name_hash()); 495 EXPECT_EQ(GG_UINT64_C(55232426147951219), 496 tracked_object->source_function_name_hash()); 497 EXPECT_EQ(1773, tracked_object->source_line_number()); 498 EXPECT_EQ(GG_UINT64_C(15727396632046120663), 499 tracked_object->birth_thread_name_hash()); 500 EXPECT_EQ(19, tracked_object->exec_count()); 501 EXPECT_EQ(23, tracked_object->exec_time_total()); 502 EXPECT_EQ(7, tracked_object->exec_time_sampled()); 503 EXPECT_EQ(0, tracked_object->queue_time_total()); 504 EXPECT_EQ(0, tracked_object->queue_time_sampled()); 505 EXPECT_EQ(GG_UINT64_C(14275151213201158253), 506 tracked_object->exec_thread_name_hash()); 507 EXPECT_EQ(177U, tracked_object->process_id()); 508 EXPECT_EQ(ProfilerEventProto::TrackedObject::BROWSER, 509 tracked_object->process_type()); 510 } 511 512 { 513 ProcessDataSnapshot process_data; 514 process_data.process_id = 1177; 515 process_data.tasks.push_back(TaskSnapshot()); 516 process_data.tasks.back().birth.location.file_name = "file3"; 517 process_data.tasks.back().birth.location.function_name = "function3"; 518 process_data.tasks.back().birth.location.line_number = 7331; 519 process_data.tasks.back().birth.thread_name = "birth_thread3"; 520 process_data.tasks.back().death_data.count = 137; 521 process_data.tasks.back().death_data.run_duration_sum = 131; 522 process_data.tasks.back().death_data.run_duration_max = 117; 523 process_data.tasks.back().death_data.run_duration_sample = 113; 524 process_data.tasks.back().death_data.queue_duration_sum = 108; 525 process_data.tasks.back().death_data.queue_duration_max = 105; 526 process_data.tasks.back().death_data.queue_duration_sample = 103; 527 process_data.tasks.back().death_thread_name = "death_thread3"; 528 529 log.RecordProfilerData(process_data, content::PROCESS_TYPE_RENDERER); 530 ASSERT_EQ(1, log.uma_proto().profiler_event_size()); 531 EXPECT_EQ(ProfilerEventProto::STARTUP_PROFILE, 532 log.uma_proto().profiler_event(0).profile_type()); 533 EXPECT_EQ(ProfilerEventProto::WALL_CLOCK_TIME, 534 log.uma_proto().profiler_event(0).time_source()); 535 ASSERT_EQ(3, log.uma_proto().profiler_event(0).tracked_object_size()); 536 537 const ProfilerEventProto::TrackedObject* tracked_object = 538 &log.uma_proto().profiler_event(0).tracked_object(2); 539 EXPECT_EQ(GG_UINT64_C(2686523203278102732), 540 tracked_object->source_file_name_hash()); 541 EXPECT_EQ(GG_UINT64_C(5081672290546182009), 542 tracked_object->source_function_name_hash()); 543 EXPECT_EQ(7331, tracked_object->source_line_number()); 544 EXPECT_EQ(GG_UINT64_C(8768512930949373716), 545 tracked_object->birth_thread_name_hash()); 546 EXPECT_EQ(137, tracked_object->exec_count()); 547 EXPECT_EQ(131, tracked_object->exec_time_total()); 548 EXPECT_EQ(113, tracked_object->exec_time_sampled()); 549 EXPECT_EQ(108, tracked_object->queue_time_total()); 550 EXPECT_EQ(103, tracked_object->queue_time_sampled()); 551 EXPECT_EQ(GG_UINT64_C(7246674144371406371), 552 tracked_object->exec_thread_name_hash()); 553 EXPECT_EQ(1177U, tracked_object->process_id()); 554 EXPECT_EQ(ProfilerEventProto::TrackedObject::RENDERER, 555 tracked_object->process_type()); 556 } 557 } 558 559 #if defined(OS_CHROMEOS) 560 TEST_F(MetricsLogTest, MultiProfileUserCount) { 561 std::string user1("user1 (at) example.com"); 562 std::string user2("user2 (at) example.com"); 563 std::string user3("user3 (at) example.com"); 564 565 // |scoped_enabler| takes over the lifetime of |user_manager|. 566 chromeos::FakeUserManager* user_manager = new chromeos::FakeUserManager(); 567 chromeos::ScopedUserManagerEnabler scoped_enabler(user_manager); 568 user_manager->AddKioskAppUser(user1); 569 user_manager->AddKioskAppUser(user2); 570 user_manager->AddKioskAppUser(user3); 571 572 user_manager->LoginUser(user1); 573 user_manager->LoginUser(user3); 574 575 TestMetricsLog log(kClientId, kSessionId); 576 std::vector<content::WebPluginInfo> plugins; 577 GoogleUpdateMetrics google_update_metrics; 578 std::vector<chrome_variations::ActiveGroupId> synthetic_trials; 579 log.RecordEnvironment(plugins, google_update_metrics, synthetic_trials); 580 EXPECT_EQ(2u, log.system_profile().multi_profile_user_count()); 581 } 582 583 TEST_F(MetricsLogTest, MultiProfileCountInvalidated) { 584 std::string user1("user1 (at) example.com"); 585 std::string user2("user2 (at) example.com"); 586 std::string user3("user3 (at) example.com"); 587 588 // |scoped_enabler| takes over the lifetime of |user_manager|. 589 chromeos::FakeUserManager* user_manager = new chromeos::FakeUserManager(); 590 chromeos::ScopedUserManagerEnabler scoped_enabler(user_manager); 591 user_manager->AddKioskAppUser(user1); 592 user_manager->AddKioskAppUser(user2); 593 user_manager->AddKioskAppUser(user3); 594 595 user_manager->LoginUser(user1); 596 597 TestMetricsLog log(kClientId, kSessionId); 598 EXPECT_EQ(1u, log.system_profile().multi_profile_user_count()); 599 600 user_manager->LoginUser(user2); 601 std::vector<chrome_variations::ActiveGroupId> synthetic_trials; 602 log.RecordEnvironment(std::vector<content::WebPluginInfo>(), 603 GoogleUpdateMetrics(), synthetic_trials); 604 EXPECT_EQ(0u, log.system_profile().multi_profile_user_count()); 605 } 606 #endif // OS_CHROMEOS 607