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.
5 #include "chrome/browser/metrics/metrics_log.h"
9 #include "base/base64.h"
10 #include "base/basictypes.h"
11 #include "base/command_line.h"
12 #include "base/port.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/prefs/scoped_user_pref_update.h"
15 #include "base/prefs/testing_pref_service.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_util.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/threading/sequenced_worker_pool.h"
21 #include "base/time/time.h"
22 #include "base/tracked_objects.h"
23 #include "chrome/browser/google/google_util.h"
24 #include "chrome/browser/prefs/browser_prefs.h"
25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/chrome_version_info.h"
27 #include "chrome/common/metrics/variations/variations_util.h"
28 #include "chrome/common/pref_names.h"
29 #include "chrome/installer/util/google_update_settings.h"
30 #include "components/metrics/metrics_hashes.h"
31 #include "components/metrics/proto/profiler_event.pb.h"
32 #include "components/metrics/proto/system_profile.pb.h"
33 #include "components/variations/metrics_util.h"
34 #include "content/public/browser/browser_thread.h"
35 #include "content/public/common/process_type.h"
36 #include "content/public/common/webplugininfo.h"
37 #include "content/public/test/test_browser_thread_bundle.h"
38 #include "content/public/test/test_utils.h"
39 #include "testing/gtest/include/gtest/gtest.h"
40 #include "ui/gfx/size.h"
43 #if defined(OS_CHROMEOS)
44 #include "chrome/browser/chromeos/login/fake_user_manager.h"
45 #include "chrome/browser/chromeos/login/user_manager.h"
46 #include "chrome/browser/metrics/metrics_log_chromeos.h"
47 #include "chromeos/dbus/fake_bluetooth_adapter_client.h"
48 #include "chromeos/dbus/fake_bluetooth_agent_manager_client.h"
49 #include "chromeos/dbus/fake_bluetooth_device_client.h"
50 #include "chromeos/dbus/fake_bluetooth_gatt_characteristic_client.h"
51 #include "chromeos/dbus/fake_bluetooth_gatt_descriptor_client.h"
52 #include "chromeos/dbus/fake_bluetooth_gatt_service_client.h"
53 #include "chromeos/dbus/fake_bluetooth_input_client.h"
54 #include "chromeos/dbus/fake_dbus_thread_manager.h"
56 using chromeos::DBusThreadManager
;
57 using chromeos::BluetoothAdapterClient
;
58 using chromeos::BluetoothAgentManagerClient
;
59 using chromeos::BluetoothDeviceClient
;
60 using chromeos::BluetoothGattCharacteristicClient
;
61 using chromeos::BluetoothGattDescriptorClient
;
62 using chromeos::BluetoothGattServiceClient
;
63 using chromeos::BluetoothInputClient
;
64 using chromeos::FakeBluetoothAdapterClient
;
65 using chromeos::FakeBluetoothAgentManagerClient
;
66 using chromeos::FakeBluetoothDeviceClient
;
67 using chromeos::FakeBluetoothGattCharacteristicClient
;
68 using chromeos::FakeBluetoothGattDescriptorClient
;
69 using chromeos::FakeBluetoothGattServiceClient
;
70 using chromeos::FakeBluetoothInputClient
;
71 using chromeos::FakeDBusThreadManager
;
74 using base::TimeDelta
;
75 using metrics::ProfilerEventProto
;
76 using tracked_objects::ProcessDataSnapshot
;
77 using tracked_objects::TaskSnapshot
;
81 const char kClientId
[] = "bogus client ID";
82 const int64 kInstallDate
= 1373051956;
83 const int64 kInstallDateExpected
= 1373050800; // Computed from kInstallDate.
84 const int64 kEnabledDate
= 1373001211;
85 const int64 kEnabledDateExpected
= 1373000400; // Computed from kEnabledDate.
86 const int kSessionId
= 127;
87 const int kScreenWidth
= 1024;
88 const int kScreenHeight
= 768;
89 const int kScreenCount
= 3;
90 const float kScreenScaleFactor
= 2;
91 const char kBrandForTesting
[] = "brand_for_testing";
92 const chrome_variations::ActiveGroupId kFieldTrialIds
[] = {
97 const chrome_variations::ActiveGroupId kSyntheticTrials
[] = {
102 #if defined(ENABLE_PLUGINS)
103 content::WebPluginInfo
CreateFakePluginInfo(
104 const std::string
& name
,
105 const base::FilePath::CharType
* path
,
106 const std::string
& version
,
108 content::WebPluginInfo
plugin(base::UTF8ToUTF16(name
),
109 base::FilePath(path
),
110 base::UTF8ToUTF16(version
),
113 plugin
.type
= content::WebPluginInfo::PLUGIN_TYPE_PEPPER_IN_PROCESS
;
115 plugin
.type
= content::WebPluginInfo::PLUGIN_TYPE_NPAPI
;
118 #endif // defined(ENABLE_PLUGINS)
120 #if defined(OS_CHROMEOS)
121 class TestMetricsLogChromeOS
: public MetricsLogChromeOS
{
123 explicit TestMetricsLogChromeOS(
124 metrics::ChromeUserMetricsExtension
* uma_proto
)
125 : MetricsLogChromeOS(uma_proto
) {
128 #endif // OS_CHROMEOS
130 class TestMetricsLog
: public MetricsLog
{
132 TestMetricsLog(const std::string
& client_id
, int session_id
, LogType log_type
)
133 : MetricsLog(client_id
, session_id
, log_type
),
134 prefs_(&scoped_prefs_
),
135 brand_for_testing_(kBrandForTesting
) {
136 #if defined(OS_CHROMEOS)
137 metrics_log_chromeos_
.reset(new TestMetricsLogChromeOS(
138 MetricsLog::uma_proto()));
139 #endif // OS_CHROMEOS
140 chrome::RegisterLocalState(scoped_prefs_
.registry());
143 // Creates a TestMetricsLog that will use |prefs| as the fake local state.
144 // Useful for tests that need to re-use the local state prefs between logs.
145 TestMetricsLog(const std::string
& client_id
,
148 TestingPrefServiceSimple
* prefs
)
149 : MetricsLog(client_id
, session_id
, log_type
),
151 brand_for_testing_(kBrandForTesting
) {
152 #if defined(OS_CHROMEOS)
153 metrics_log_chromeos_
.reset(new TestMetricsLogChromeOS(
154 MetricsLog::uma_proto()));
155 #endif // OS_CHROMEOS
158 virtual ~TestMetricsLog() {}
160 virtual PrefService
* GetPrefService() OVERRIDE
{
164 const metrics::ChromeUserMetricsExtension
& uma_proto() const {
165 return *MetricsLog::uma_proto();
168 const metrics::SystemProfileProto
& system_profile() const {
169 return uma_proto().system_profile();
174 prefs_
->SetInt64(prefs::kInstallDate
, kInstallDate
);
175 prefs_
->SetString(prefs::kMetricsReportingEnabledTimestamp
,
176 base::Int64ToString(kEnabledDate
));
177 #if defined(OS_CHROMEOS)
178 prefs_
->SetInteger(prefs::kStabilityChildProcessCrashCount
, 10);
179 prefs_
->SetInteger(prefs::kStabilityOtherUserCrashCount
, 11);
180 prefs_
->SetInteger(prefs::kStabilityKernelCrashCount
, 12);
181 prefs_
->SetInteger(prefs::kStabilitySystemUncleanShutdownCount
, 13);
182 #endif // OS_CHROMEOS
185 virtual void GetFieldTrialIds(
186 std::vector
<chrome_variations::ActiveGroupId
>* field_trial_ids
) const
188 ASSERT_TRUE(field_trial_ids
->empty());
190 for (size_t i
= 0; i
< arraysize(kFieldTrialIds
); ++i
) {
191 field_trial_ids
->push_back(kFieldTrialIds
[i
]);
195 virtual gfx::Size
GetScreenSize() const OVERRIDE
{
196 return gfx::Size(kScreenWidth
, kScreenHeight
);
199 virtual float GetScreenDeviceScaleFactor() const OVERRIDE
{
200 return kScreenScaleFactor
;
203 virtual int GetScreenCount() const OVERRIDE
{
207 // Scoped PrefsService, which may not be used if |prefs_ != &scoped_prefs|.
208 TestingPrefServiceSimple scoped_prefs_
;
209 // Weak pointer to the PrefsService used by this log.
210 TestingPrefServiceSimple
* prefs_
;
212 google_util::BrandForTesting brand_for_testing_
;
214 DISALLOW_COPY_AND_ASSIGN(TestMetricsLog
);
219 class MetricsLogTest
: public testing::Test
{
224 virtual void SetUp() OVERRIDE
{
225 #if defined(OS_CHROMEOS)
226 // Enable multi-profiles.
227 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kMultiProfiles
);
229 // Set up the fake Bluetooth environment,
230 scoped_ptr
<FakeDBusThreadManager
> fake_dbus_thread_manager(
231 new FakeDBusThreadManager
);
232 fake_dbus_thread_manager
->SetBluetoothAdapterClient(
233 scoped_ptr
<BluetoothAdapterClient
>(new FakeBluetoothAdapterClient
));
234 fake_dbus_thread_manager
->SetBluetoothDeviceClient(
235 scoped_ptr
<BluetoothDeviceClient
>(new FakeBluetoothDeviceClient
));
236 fake_dbus_thread_manager
->SetBluetoothGattCharacteristicClient(
237 scoped_ptr
<BluetoothGattCharacteristicClient
>(
238 new FakeBluetoothGattCharacteristicClient
));
239 fake_dbus_thread_manager
->SetBluetoothGattDescriptorClient(
240 scoped_ptr
<BluetoothGattDescriptorClient
>(
241 new FakeBluetoothGattDescriptorClient
));
242 fake_dbus_thread_manager
->SetBluetoothGattServiceClient(
243 scoped_ptr
<BluetoothGattServiceClient
>(
244 new FakeBluetoothGattServiceClient
));
245 fake_dbus_thread_manager
->SetBluetoothInputClient(
246 scoped_ptr
<BluetoothInputClient
>(new FakeBluetoothInputClient
));
247 fake_dbus_thread_manager
->SetBluetoothAgentManagerClient(
248 scoped_ptr
<BluetoothAgentManagerClient
>(
249 new FakeBluetoothAgentManagerClient
));
250 DBusThreadManager::InitializeForTesting(fake_dbus_thread_manager
.release());
252 // Grab pointers to members of the thread manager for easier testing.
253 fake_bluetooth_adapter_client_
= static_cast<FakeBluetoothAdapterClient
*>(
254 DBusThreadManager::Get()->GetBluetoothAdapterClient());
255 fake_bluetooth_device_client_
= static_cast<FakeBluetoothDeviceClient
*>(
256 DBusThreadManager::Get()->GetBluetoothDeviceClient());
257 #endif // OS_CHROMEOS
260 virtual void TearDown() OVERRIDE
{
261 #if defined(OS_CHROMEOS)
262 DBusThreadManager::Shutdown();
263 #endif // OS_CHROMEOS
266 // Check that the values in |system_values| correspond to the test data
267 // defined at the top of this file.
268 void CheckSystemProfile(const metrics::SystemProfileProto
& system_profile
) {
269 EXPECT_EQ(kInstallDateExpected
, system_profile
.install_date());
270 EXPECT_EQ(kEnabledDateExpected
, system_profile
.uma_enabled_date());
272 ASSERT_EQ(arraysize(kFieldTrialIds
) + arraysize(kSyntheticTrials
),
273 static_cast<size_t>(system_profile
.field_trial_size()));
274 for (size_t i
= 0; i
< arraysize(kFieldTrialIds
); ++i
) {
275 const metrics::SystemProfileProto::FieldTrial
& field_trial
=
276 system_profile
.field_trial(i
);
277 EXPECT_EQ(kFieldTrialIds
[i
].name
, field_trial
.name_id());
278 EXPECT_EQ(kFieldTrialIds
[i
].group
, field_trial
.group_id());
280 // Verify the right data is present for the synthetic trials.
281 for (size_t i
= 0; i
< arraysize(kSyntheticTrials
); ++i
) {
282 const metrics::SystemProfileProto::FieldTrial
& field_trial
=
283 system_profile
.field_trial(i
+ arraysize(kFieldTrialIds
));
284 EXPECT_EQ(kSyntheticTrials
[i
].name
, field_trial
.name_id());
285 EXPECT_EQ(kSyntheticTrials
[i
].group
, field_trial
.group_id());
288 EXPECT_EQ(kBrandForTesting
, system_profile
.brand_code());
290 const metrics::SystemProfileProto::Hardware
& hardware
=
291 system_profile
.hardware();
292 EXPECT_EQ(kScreenWidth
, hardware
.primary_screen_width());
293 EXPECT_EQ(kScreenHeight
, hardware
.primary_screen_height());
294 EXPECT_EQ(kScreenScaleFactor
, hardware
.primary_screen_scale_factor());
295 EXPECT_EQ(kScreenCount
, hardware
.screen_count());
297 EXPECT_TRUE(hardware
.has_cpu());
298 EXPECT_TRUE(hardware
.cpu().has_vendor_name());
299 EXPECT_TRUE(hardware
.cpu().has_signature());
301 // TODO(isherman): Verify other data written into the protobuf as a result
306 #if defined(OS_CHROMEOS)
307 FakeBluetoothAdapterClient
* fake_bluetooth_adapter_client_
;
308 FakeBluetoothDeviceClient
* fake_bluetooth_device_client_
;
309 #endif // OS_CHROMEOS
312 content::TestBrowserThreadBundle thread_bundle_
;
314 DISALLOW_COPY_AND_ASSIGN(MetricsLogTest
);
317 TEST_F(MetricsLogTest
, RecordEnvironment
) {
318 TestMetricsLog
log(kClientId
, kSessionId
, MetricsLog::ONGOING_LOG
);
320 std::vector
<content::WebPluginInfo
> plugins
;
321 GoogleUpdateMetrics google_update_metrics
;
322 std::vector
<chrome_variations::ActiveGroupId
> synthetic_trials
;
323 // Add two synthetic trials.
324 synthetic_trials
.push_back(kSyntheticTrials
[0]);
325 synthetic_trials
.push_back(kSyntheticTrials
[1]);
327 log
.RecordEnvironment(plugins
, google_update_metrics
, synthetic_trials
);
328 // Check that the system profile on the log has the correct values set.
329 CheckSystemProfile(log
.system_profile());
331 // Check that the system profile has also been written to prefs.
332 PrefService
* local_state
= log
.GetPrefService();
333 const std::string base64_system_profile
=
334 local_state
->GetString(prefs::kStabilitySavedSystemProfile
);
335 EXPECT_FALSE(base64_system_profile
.empty());
336 std::string serialied_system_profile
;
337 EXPECT_TRUE(base::Base64Decode(base64_system_profile
,
338 &serialied_system_profile
));
339 SystemProfileProto decoded_system_profile
;
340 EXPECT_TRUE(decoded_system_profile
.ParseFromString(serialied_system_profile
));
341 CheckSystemProfile(decoded_system_profile
);
344 TEST_F(MetricsLogTest
, LoadSavedEnvironmentFromPrefs
) {
345 const char* kSystemProfilePref
= prefs::kStabilitySavedSystemProfile
;
346 const char* kSystemProfileHashPref
= prefs::kStabilitySavedSystemProfileHash
;
348 TestingPrefServiceSimple prefs
;
349 chrome::RegisterLocalState(prefs
.registry());
351 // The pref value is empty, so loading it from prefs should fail.
353 TestMetricsLog
log(kClientId
, kSessionId
, MetricsLog::ONGOING_LOG
, &prefs
);
354 EXPECT_FALSE(log
.LoadSavedEnvironmentFromPrefs());
357 // Do a RecordEnvironment() call and check whether the pref is recorded.
359 TestMetricsLog
log(kClientId
, kSessionId
, MetricsLog::ONGOING_LOG
, &prefs
);
360 log
.RecordEnvironment(std::vector
<content::WebPluginInfo
>(),
361 GoogleUpdateMetrics(),
362 std::vector
<chrome_variations::ActiveGroupId
>());
363 EXPECT_FALSE(prefs
.GetString(kSystemProfilePref
).empty());
364 EXPECT_FALSE(prefs
.GetString(kSystemProfileHashPref
).empty());
368 TestMetricsLog
log(kClientId
, kSessionId
, MetricsLog::ONGOING_LOG
, &prefs
);
369 EXPECT_TRUE(log
.LoadSavedEnvironmentFromPrefs());
370 // Check some values in the system profile.
371 EXPECT_EQ(kInstallDateExpected
, log
.system_profile().install_date());
372 EXPECT_EQ(kEnabledDateExpected
, log
.system_profile().uma_enabled_date());
373 // Ensure that the call cleared the prefs.
374 EXPECT_TRUE(prefs
.GetString(kSystemProfilePref
).empty());
375 EXPECT_TRUE(prefs
.GetString(kSystemProfileHashPref
).empty());
378 // Ensure that a non-matching hash results in the pref being invalid.
380 TestMetricsLog
log(kClientId
, kSessionId
, MetricsLog::ONGOING_LOG
, &prefs
);
381 // Call RecordEnvironment() to record the pref again.
382 log
.RecordEnvironment(std::vector
<content::WebPluginInfo
>(),
383 GoogleUpdateMetrics(),
384 std::vector
<chrome_variations::ActiveGroupId
>());
388 // Set the hash to a bad value.
389 prefs
.SetString(kSystemProfileHashPref
, "deadbeef");
390 TestMetricsLog
log(kClientId
, kSessionId
, MetricsLog::ONGOING_LOG
, &prefs
);
391 EXPECT_FALSE(log
.LoadSavedEnvironmentFromPrefs());
392 // Ensure that the prefs are cleared, even if the call failed.
393 EXPECT_TRUE(prefs
.GetString(kSystemProfilePref
).empty());
394 EXPECT_TRUE(prefs
.GetString(kSystemProfileHashPref
).empty());
398 TEST_F(MetricsLogTest
, InitialLogStabilityMetrics
) {
399 TestMetricsLog
log(kClientId
, kSessionId
, MetricsLog::INITIAL_STABILITY_LOG
);
400 log
.RecordEnvironment(std::vector
<content::WebPluginInfo
>(),
401 GoogleUpdateMetrics(),
402 std::vector
<chrome_variations::ActiveGroupId
>());
403 log
.RecordStabilityMetrics(base::TimeDelta(), base::TimeDelta());
404 const metrics::SystemProfileProto_Stability
& stability
=
405 log
.system_profile().stability();
407 EXPECT_TRUE(stability
.has_launch_count());
408 EXPECT_TRUE(stability
.has_crash_count());
409 // Initial log metrics:
410 EXPECT_TRUE(stability
.has_incomplete_shutdown_count());
411 EXPECT_TRUE(stability
.has_breakpad_registration_success_count());
412 EXPECT_TRUE(stability
.has_breakpad_registration_failure_count());
413 EXPECT_TRUE(stability
.has_debugger_present_count());
414 EXPECT_TRUE(stability
.has_debugger_not_present_count());
417 TEST_F(MetricsLogTest
, OngoingLogStabilityMetrics
) {
418 TestMetricsLog
log(kClientId
, kSessionId
, MetricsLog::ONGOING_LOG
);
419 log
.RecordEnvironment(std::vector
<content::WebPluginInfo
>(),
420 GoogleUpdateMetrics(),
421 std::vector
<chrome_variations::ActiveGroupId
>());
422 log
.RecordStabilityMetrics(base::TimeDelta(), base::TimeDelta());
423 const metrics::SystemProfileProto_Stability
& stability
=
424 log
.system_profile().stability();
426 EXPECT_TRUE(stability
.has_launch_count());
427 EXPECT_TRUE(stability
.has_crash_count());
428 // Initial log metrics:
429 EXPECT_FALSE(stability
.has_incomplete_shutdown_count());
430 EXPECT_FALSE(stability
.has_breakpad_registration_success_count());
431 EXPECT_FALSE(stability
.has_breakpad_registration_failure_count());
432 EXPECT_FALSE(stability
.has_debugger_present_count());
433 EXPECT_FALSE(stability
.has_debugger_not_present_count());
436 #if defined(ENABLE_PLUGINS)
437 TEST_F(MetricsLogTest
, Plugins
) {
438 TestMetricsLog
log(kClientId
, kSessionId
, MetricsLog::ONGOING_LOG
);
440 std::vector
<content::WebPluginInfo
> plugins
;
441 plugins
.push_back(CreateFakePluginInfo("p1", FILE_PATH_LITERAL("p1.plugin"),
443 plugins
.push_back(CreateFakePluginInfo("p2", FILE_PATH_LITERAL("p2.plugin"),
445 log
.RecordEnvironment(plugins
, GoogleUpdateMetrics(),
446 std::vector
<chrome_variations::ActiveGroupId
>());
448 const metrics::SystemProfileProto
& system_profile
= log
.system_profile();
449 ASSERT_EQ(2, system_profile
.plugin_size());
450 EXPECT_EQ("p1", system_profile
.plugin(0).name());
451 EXPECT_EQ("p1.plugin", system_profile
.plugin(0).filename());
452 EXPECT_EQ("1.5", system_profile
.plugin(0).version());
453 EXPECT_TRUE(system_profile
.plugin(0).is_pepper());
454 EXPECT_EQ("p2", system_profile
.plugin(1).name());
455 EXPECT_EQ("p2.plugin", system_profile
.plugin(1).filename());
456 EXPECT_EQ("2.0", system_profile
.plugin(1).version());
457 EXPECT_FALSE(system_profile
.plugin(1).is_pepper());
459 // Now set some plugin stability stats for p2 and verify they're recorded.
460 scoped_ptr
<base::DictionaryValue
> plugin_dict(new base::DictionaryValue
);
461 plugin_dict
->SetString(prefs::kStabilityPluginName
, "p2");
462 plugin_dict
->SetInteger(prefs::kStabilityPluginLaunches
, 1);
463 plugin_dict
->SetInteger(prefs::kStabilityPluginCrashes
, 2);
464 plugin_dict
->SetInteger(prefs::kStabilityPluginInstances
, 3);
465 plugin_dict
->SetInteger(prefs::kStabilityPluginLoadingErrors
, 4);
467 ListPrefUpdate
update(log
.GetPrefService(), prefs::kStabilityPluginStats
);
468 update
.Get()->Append(plugin_dict
.release());
471 log
.RecordStabilityMetrics(base::TimeDelta(), base::TimeDelta());
472 const metrics::SystemProfileProto_Stability
& stability
=
473 log
.system_profile().stability();
474 ASSERT_EQ(1, stability
.plugin_stability_size());
475 EXPECT_EQ("p2", stability
.plugin_stability(0).plugin().name());
476 EXPECT_EQ("p2.plugin", stability
.plugin_stability(0).plugin().filename());
477 EXPECT_EQ("2.0", stability
.plugin_stability(0).plugin().version());
478 EXPECT_FALSE(stability
.plugin_stability(0).plugin().is_pepper());
479 EXPECT_EQ(1, stability
.plugin_stability(0).launch_count());
480 EXPECT_EQ(2, stability
.plugin_stability(0).crash_count());
481 EXPECT_EQ(3, stability
.plugin_stability(0).instance_count());
482 EXPECT_EQ(4, stability
.plugin_stability(0).loading_error_count());
484 #endif // defined(ENABLE_PLUGINS)
486 // Test that we properly write profiler data to the log.
487 TEST_F(MetricsLogTest
, RecordProfilerData
) {
488 // WARNING: If you broke the below check, you've modified how
489 // metrics::HashMetricName works. Please also modify all server-side code that
490 // relies on the existing way of hashing.
491 EXPECT_EQ(GG_UINT64_C(1518842999910132863),
492 metrics::HashMetricName("birth_thread*"));
494 TestMetricsLog
log(kClientId
, kSessionId
, MetricsLog::ONGOING_LOG
);
495 EXPECT_EQ(0, log
.uma_proto().profiler_event_size());
498 ProcessDataSnapshot process_data
;
499 process_data
.process_id
= 177;
500 process_data
.tasks
.push_back(TaskSnapshot());
501 process_data
.tasks
.back().birth
.location
.file_name
= "a/b/file.h";
502 process_data
.tasks
.back().birth
.location
.function_name
= "function";
503 process_data
.tasks
.back().birth
.location
.line_number
= 1337;
504 process_data
.tasks
.back().birth
.thread_name
= "birth_thread";
505 process_data
.tasks
.back().death_data
.count
= 37;
506 process_data
.tasks
.back().death_data
.run_duration_sum
= 31;
507 process_data
.tasks
.back().death_data
.run_duration_max
= 17;
508 process_data
.tasks
.back().death_data
.run_duration_sample
= 13;
509 process_data
.tasks
.back().death_data
.queue_duration_sum
= 8;
510 process_data
.tasks
.back().death_data
.queue_duration_max
= 5;
511 process_data
.tasks
.back().death_data
.queue_duration_sample
= 3;
512 process_data
.tasks
.back().death_thread_name
= "Still_Alive";
513 process_data
.tasks
.push_back(TaskSnapshot());
514 process_data
.tasks
.back().birth
.location
.file_name
= "c\\d\\file2";
515 process_data
.tasks
.back().birth
.location
.function_name
= "function2";
516 process_data
.tasks
.back().birth
.location
.line_number
= 1773;
517 process_data
.tasks
.back().birth
.thread_name
= "birth_thread2";
518 process_data
.tasks
.back().death_data
.count
= 19;
519 process_data
.tasks
.back().death_data
.run_duration_sum
= 23;
520 process_data
.tasks
.back().death_data
.run_duration_max
= 11;
521 process_data
.tasks
.back().death_data
.run_duration_sample
= 7;
522 process_data
.tasks
.back().death_data
.queue_duration_sum
= 0;
523 process_data
.tasks
.back().death_data
.queue_duration_max
= 0;
524 process_data
.tasks
.back().death_data
.queue_duration_sample
= 0;
525 process_data
.tasks
.back().death_thread_name
= "death_thread";
527 log
.RecordProfilerData(process_data
, content::PROCESS_TYPE_BROWSER
);
528 ASSERT_EQ(1, log
.uma_proto().profiler_event_size());
529 EXPECT_EQ(ProfilerEventProto::STARTUP_PROFILE
,
530 log
.uma_proto().profiler_event(0).profile_type());
531 EXPECT_EQ(ProfilerEventProto::WALL_CLOCK_TIME
,
532 log
.uma_proto().profiler_event(0).time_source());
534 ASSERT_EQ(2, log
.uma_proto().profiler_event(0).tracked_object_size());
536 const ProfilerEventProto::TrackedObject
* tracked_object
=
537 &log
.uma_proto().profiler_event(0).tracked_object(0);
538 EXPECT_EQ(metrics::HashMetricName("file.h"),
539 tracked_object
->source_file_name_hash());
540 EXPECT_EQ(metrics::HashMetricName("function"),
541 tracked_object
->source_function_name_hash());
542 EXPECT_EQ(1337, tracked_object
->source_line_number());
543 EXPECT_EQ(metrics::HashMetricName("birth_thread"),
544 tracked_object
->birth_thread_name_hash());
545 EXPECT_EQ(37, tracked_object
->exec_count());
546 EXPECT_EQ(31, tracked_object
->exec_time_total());
547 EXPECT_EQ(13, tracked_object
->exec_time_sampled());
548 EXPECT_EQ(8, tracked_object
->queue_time_total());
549 EXPECT_EQ(3, tracked_object
->queue_time_sampled());
550 EXPECT_EQ(metrics::HashMetricName("Still_Alive"),
551 tracked_object
->exec_thread_name_hash());
552 EXPECT_EQ(177U, tracked_object
->process_id());
553 EXPECT_EQ(ProfilerEventProto::TrackedObject::BROWSER
,
554 tracked_object
->process_type());
556 tracked_object
= &log
.uma_proto().profiler_event(0).tracked_object(1);
557 EXPECT_EQ(metrics::HashMetricName("file2"),
558 tracked_object
->source_file_name_hash());
559 EXPECT_EQ(metrics::HashMetricName("function2"),
560 tracked_object
->source_function_name_hash());
561 EXPECT_EQ(1773, tracked_object
->source_line_number());
562 EXPECT_EQ(metrics::HashMetricName("birth_thread*"),
563 tracked_object
->birth_thread_name_hash());
564 EXPECT_EQ(19, tracked_object
->exec_count());
565 EXPECT_EQ(23, tracked_object
->exec_time_total());
566 EXPECT_EQ(7, tracked_object
->exec_time_sampled());
567 EXPECT_EQ(0, tracked_object
->queue_time_total());
568 EXPECT_EQ(0, tracked_object
->queue_time_sampled());
569 EXPECT_EQ(metrics::HashMetricName("death_thread"),
570 tracked_object
->exec_thread_name_hash());
571 EXPECT_EQ(177U, tracked_object
->process_id());
572 EXPECT_EQ(ProfilerEventProto::TrackedObject::BROWSER
,
573 tracked_object
->process_type());
577 ProcessDataSnapshot process_data
;
578 process_data
.process_id
= 1177;
579 process_data
.tasks
.push_back(TaskSnapshot());
580 process_data
.tasks
.back().birth
.location
.file_name
= "file3";
581 process_data
.tasks
.back().birth
.location
.function_name
= "function3";
582 process_data
.tasks
.back().birth
.location
.line_number
= 7331;
583 process_data
.tasks
.back().birth
.thread_name
= "birth_thread3";
584 process_data
.tasks
.back().death_data
.count
= 137;
585 process_data
.tasks
.back().death_data
.run_duration_sum
= 131;
586 process_data
.tasks
.back().death_data
.run_duration_max
= 117;
587 process_data
.tasks
.back().death_data
.run_duration_sample
= 113;
588 process_data
.tasks
.back().death_data
.queue_duration_sum
= 108;
589 process_data
.tasks
.back().death_data
.queue_duration_max
= 105;
590 process_data
.tasks
.back().death_data
.queue_duration_sample
= 103;
591 process_data
.tasks
.back().death_thread_name
= "death_thread3";
592 process_data
.tasks
.push_back(TaskSnapshot());
593 process_data
.tasks
.back().birth
.location
.file_name
= "";
594 process_data
.tasks
.back().birth
.location
.function_name
= "";
595 process_data
.tasks
.back().birth
.location
.line_number
= 7332;
596 process_data
.tasks
.back().birth
.thread_name
= "";
597 process_data
.tasks
.back().death_data
.count
= 138;
598 process_data
.tasks
.back().death_data
.run_duration_sum
= 132;
599 process_data
.tasks
.back().death_data
.run_duration_max
= 118;
600 process_data
.tasks
.back().death_data
.run_duration_sample
= 114;
601 process_data
.tasks
.back().death_data
.queue_duration_sum
= 109;
602 process_data
.tasks
.back().death_data
.queue_duration_max
= 106;
603 process_data
.tasks
.back().death_data
.queue_duration_sample
= 104;
604 process_data
.tasks
.back().death_thread_name
= "";
606 log
.RecordProfilerData(process_data
, content::PROCESS_TYPE_RENDERER
);
607 ASSERT_EQ(1, log
.uma_proto().profiler_event_size());
608 EXPECT_EQ(ProfilerEventProto::STARTUP_PROFILE
,
609 log
.uma_proto().profiler_event(0).profile_type());
610 EXPECT_EQ(ProfilerEventProto::WALL_CLOCK_TIME
,
611 log
.uma_proto().profiler_event(0).time_source());
612 ASSERT_EQ(4, log
.uma_proto().profiler_event(0).tracked_object_size());
614 const ProfilerEventProto::TrackedObject
* tracked_object
=
615 &log
.uma_proto().profiler_event(0).tracked_object(2);
616 EXPECT_EQ(metrics::HashMetricName("file3"),
617 tracked_object
->source_file_name_hash());
618 EXPECT_EQ(metrics::HashMetricName("function3"),
619 tracked_object
->source_function_name_hash());
620 EXPECT_EQ(7331, tracked_object
->source_line_number());
621 EXPECT_EQ(metrics::HashMetricName("birth_thread*"),
622 tracked_object
->birth_thread_name_hash());
623 EXPECT_EQ(137, tracked_object
->exec_count());
624 EXPECT_EQ(131, tracked_object
->exec_time_total());
625 EXPECT_EQ(113, tracked_object
->exec_time_sampled());
626 EXPECT_EQ(108, tracked_object
->queue_time_total());
627 EXPECT_EQ(103, tracked_object
->queue_time_sampled());
628 EXPECT_EQ(metrics::HashMetricName("death_thread*"),
629 tracked_object
->exec_thread_name_hash());
630 EXPECT_EQ(1177U, tracked_object
->process_id());
631 EXPECT_EQ(ProfilerEventProto::TrackedObject::RENDERER
,
632 tracked_object
->process_type());
634 tracked_object
= &log
.uma_proto().profiler_event(0).tracked_object(3);
635 EXPECT_EQ(metrics::HashMetricName(""),
636 tracked_object
->source_file_name_hash());
637 EXPECT_EQ(metrics::HashMetricName(""),
638 tracked_object
->source_function_name_hash());
639 EXPECT_EQ(7332, tracked_object
->source_line_number());
640 EXPECT_EQ(metrics::HashMetricName(""),
641 tracked_object
->birth_thread_name_hash());
642 EXPECT_EQ(138, tracked_object
->exec_count());
643 EXPECT_EQ(132, tracked_object
->exec_time_total());
644 EXPECT_EQ(114, tracked_object
->exec_time_sampled());
645 EXPECT_EQ(109, tracked_object
->queue_time_total());
646 EXPECT_EQ(104, tracked_object
->queue_time_sampled());
647 EXPECT_EQ(metrics::HashMetricName(""),
648 tracked_object
->exec_thread_name_hash());
649 EXPECT_EQ(ProfilerEventProto::TrackedObject::RENDERER
,
650 tracked_object
->process_type());
654 TEST_F(MetricsLogTest
, ChromeChannelWrittenToProtobuf
) {
655 TestMetricsLog
log("user@test.com", kSessionId
, MetricsLog::ONGOING_LOG
);
656 EXPECT_TRUE(log
.uma_proto().system_profile().has_channel());
659 #if defined(OS_CHROMEOS)
660 TEST_F(MetricsLogTest
, MultiProfileUserCount
) {
661 std::string
user1("user1@example.com");
662 std::string
user2("user2@example.com");
663 std::string
user3("user3@example.com");
665 // |scoped_enabler| takes over the lifetime of |user_manager|.
666 chromeos::FakeUserManager
* user_manager
= new chromeos::FakeUserManager();
667 chromeos::ScopedUserManagerEnabler
scoped_enabler(user_manager
);
668 user_manager
->AddKioskAppUser(user1
);
669 user_manager
->AddKioskAppUser(user2
);
670 user_manager
->AddKioskAppUser(user3
);
672 user_manager
->LoginUser(user1
);
673 user_manager
->LoginUser(user3
);
675 TestMetricsLog
log(kClientId
, kSessionId
, MetricsLog::ONGOING_LOG
);
676 std::vector
<content::WebPluginInfo
> plugins
;
677 GoogleUpdateMetrics google_update_metrics
;
678 std::vector
<chrome_variations::ActiveGroupId
> synthetic_trials
;
679 log
.RecordEnvironment(plugins
, google_update_metrics
, synthetic_trials
);
680 EXPECT_EQ(2u, log
.system_profile().multi_profile_user_count());
683 TEST_F(MetricsLogTest
, MultiProfileCountInvalidated
) {
684 std::string
user1("user1@example.com");
685 std::string
user2("user2@example.com");
686 std::string
user3("user3@example.com");
688 // |scoped_enabler| takes over the lifetime of |user_manager|.
689 chromeos::FakeUserManager
* user_manager
= new chromeos::FakeUserManager();
690 chromeos::ScopedUserManagerEnabler
scoped_enabler(user_manager
);
691 user_manager
->AddKioskAppUser(user1
);
692 user_manager
->AddKioskAppUser(user2
);
693 user_manager
->AddKioskAppUser(user3
);
695 user_manager
->LoginUser(user1
);
697 TestMetricsLog
log(kClientId
, kSessionId
, MetricsLog::ONGOING_LOG
);
698 EXPECT_EQ(1u, log
.system_profile().multi_profile_user_count());
700 user_manager
->LoginUser(user2
);
701 std::vector
<chrome_variations::ActiveGroupId
> synthetic_trials
;
702 log
.RecordEnvironment(std::vector
<content::WebPluginInfo
>(),
703 GoogleUpdateMetrics(), synthetic_trials
);
704 EXPECT_EQ(0u, log
.system_profile().multi_profile_user_count());
707 TEST_F(MetricsLogTest
, BluetoothHardwareDisabled
) {
708 TestMetricsLog
log(kClientId
, kSessionId
, MetricsLog::ONGOING_LOG
);
709 log
.RecordEnvironment(std::vector
<content::WebPluginInfo
>(),
710 GoogleUpdateMetrics(),
711 std::vector
<chrome_variations::ActiveGroupId
>());
713 EXPECT_TRUE(log
.system_profile().has_hardware());
714 EXPECT_TRUE(log
.system_profile().hardware().has_bluetooth());
716 EXPECT_TRUE(log
.system_profile().hardware().bluetooth().is_present());
717 EXPECT_FALSE(log
.system_profile().hardware().bluetooth().is_enabled());
720 TEST_F(MetricsLogTest
, BluetoothHardwareEnabled
) {
721 FakeBluetoothAdapterClient::Properties
* properties
=
722 fake_bluetooth_adapter_client_
->GetProperties(
723 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
));
724 properties
->powered
.ReplaceValue(true);
726 TestMetricsLog
log(kClientId
, kSessionId
, MetricsLog::ONGOING_LOG
);
727 log
.RecordEnvironment(std::vector
<content::WebPluginInfo
>(),
728 GoogleUpdateMetrics(),
729 std::vector
<chrome_variations::ActiveGroupId
>());
731 EXPECT_TRUE(log
.system_profile().has_hardware());
732 EXPECT_TRUE(log
.system_profile().hardware().has_bluetooth());
734 EXPECT_TRUE(log
.system_profile().hardware().bluetooth().is_present());
735 EXPECT_TRUE(log
.system_profile().hardware().bluetooth().is_enabled());
738 TEST_F(MetricsLogTest
, BluetoothPairedDevices
) {
739 // The fake bluetooth adapter class already claims to be paired with one
740 // device when initialized. Add a second and third fake device to it so we
741 // can test the cases where a device is not paired (LE device, generally)
742 // and a device that does not have Device ID information.
743 fake_bluetooth_device_client_
->CreateDevice(
744 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
745 dbus::ObjectPath(FakeBluetoothDeviceClient::kRequestPinCodePath
));
747 fake_bluetooth_device_client_
->CreateDevice(
748 dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath
),
749 dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath
));
751 FakeBluetoothDeviceClient::Properties
* properties
=
752 fake_bluetooth_device_client_
->GetProperties(
753 dbus::ObjectPath(FakeBluetoothDeviceClient::kConfirmPasskeyPath
));
754 properties
->paired
.ReplaceValue(true);
756 TestMetricsLog
log(kClientId
, kSessionId
, MetricsLog::ONGOING_LOG
);
757 log
.RecordEnvironment(std::vector
<content::WebPluginInfo
>(),
758 GoogleUpdateMetrics(),
759 std::vector
<chrome_variations::ActiveGroupId
>());
761 ASSERT_TRUE(log
.system_profile().has_hardware());
762 ASSERT_TRUE(log
.system_profile().hardware().has_bluetooth());
764 // Only two of the devices should appear.
766 log
.system_profile().hardware().bluetooth().paired_device_size());
768 typedef metrics::SystemProfileProto::Hardware::Bluetooth::PairedDevice
771 // First device should match the Paired Device object, complete with
772 // parsed Device ID information.
773 PairedDevice device1
=
774 log
.system_profile().hardware().bluetooth().paired_device(0);
776 EXPECT_EQ(FakeBluetoothDeviceClient::kPairedDeviceClass
,
777 device1
.bluetooth_class());
778 EXPECT_EQ(PairedDevice::DEVICE_COMPUTER
, device1
.type());
779 EXPECT_EQ(0x001122U
, device1
.vendor_prefix());
780 EXPECT_EQ(PairedDevice::VENDOR_ID_USB
, device1
.vendor_id_source());
781 EXPECT_EQ(0x05ACU
, device1
.vendor_id());
782 EXPECT_EQ(0x030DU
, device1
.product_id());
783 EXPECT_EQ(0x0306U
, device1
.device_id());
785 // Second device should match the Confirm Passkey object, this has
786 // no Device ID information.
787 PairedDevice device2
=
788 log
.system_profile().hardware().bluetooth().paired_device(1);
790 EXPECT_EQ(FakeBluetoothDeviceClient::kConfirmPasskeyClass
,
791 device2
.bluetooth_class());
792 EXPECT_EQ(PairedDevice::DEVICE_PHONE
, device2
.type());
793 EXPECT_EQ(0x207D74U
, device2
.vendor_prefix());
794 EXPECT_EQ(PairedDevice::VENDOR_ID_UNKNOWN
, device2
.vendor_id_source());
796 #endif // OS_CHROMEOS