Home | History | Annotate | Download | only in metrics
      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