OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/perf/perf_provider_chromeos.h" | 5 #include "chrome/browser/metrics/perf/perf_provider_chromeos.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
12 #include "base/test/test_simple_task_runner.h" | 12 #include "base/test/test_simple_task_runner.h" |
13 #include "base/thread_task_runner_handle.h" | 13 #include "base/thread_task_runner_handle.h" |
14 #include "chrome/browser/metrics/perf/windowed_incognito_observer.h" | 14 #include "chrome/browser/metrics/perf/windowed_incognito_observer.h" |
15 #include "chromeos/dbus/dbus_thread_manager.h" | 15 #include "chromeos/dbus/dbus_thread_manager.h" |
16 #include "chromeos/login/login_state.h" | 16 #include "chromeos/login/login_state.h" |
17 #include "components/metrics/proto/sampled_profile.pb.h" | 17 #include "components/metrics/proto/sampled_profile.pb.h" |
18 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
19 | 19 |
20 namespace metrics { | 20 namespace metrics { |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 // Return values for perf. | 24 // Return values for perf. |
25 const int kPerfSuccess = 0; | 25 const int kPerfSuccess = 0; |
26 const int kPerfFailure = 1; | 26 const int kPerfFailure = 1; |
27 | 27 |
| 28 const char kPerfRecordCyclesCmd[] = |
| 29 "perf record -a -e cycles -c 1000003"; |
| 30 const char kPerfRecordCallgraphCmd[] = |
| 31 "perf record -a -e cycles -g -c 4000037"; |
| 32 const char kPerfRecordLBRCmd[] = |
| 33 "perf record -a -e r2c4 -b -c 20011"; |
| 34 const char kPerfStatMemoryBandwidthCmd[] = |
| 35 "perf stat -a -e cycles -e instructions " |
| 36 "-e uncore_imc/data_reads/ -e uncore_imc/data_writes/ " |
| 37 "-e cpu/event=0xD0,umask=0x11,name=MEM_UOPS_RETIRED-STLB_MISS_LOADS/ " |
| 38 "-e cpu/event=0xD0,umask=0x12,name=MEM_UOPS_RETIRED-STLB_MISS_STORES/"; |
| 39 |
28 // Converts a protobuf to serialized format as a byte vector. | 40 // Converts a protobuf to serialized format as a byte vector. |
29 std::vector<uint8_t> SerializeMessageToVector( | 41 std::vector<uint8_t> SerializeMessageToVector( |
30 const google::protobuf::MessageLite& message) { | 42 const google::protobuf::MessageLite& message) { |
31 std::vector<uint8_t> result(message.ByteSize()); | 43 std::vector<uint8_t> result(message.ByteSize()); |
32 message.SerializeToArray(result.data(), result.size()); | 44 message.SerializeToArray(result.data(), result.size()); |
33 return result; | 45 return result; |
34 } | 46 } |
35 | 47 |
36 // Returns an example PerfDataProto. The contents don't have to make sense. They | 48 // Returns an example PerfDataProto. The contents don't have to make sense. They |
37 // just need to constitute a semantically valid protobuf. | 49 // just need to constitute a semantically valid protobuf. |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 EXPECT_EQ(SampledProfile::RESUME_FROM_SUSPEND, profile3.trigger_event()); | 464 EXPECT_EQ(SampledProfile::RESUME_FROM_SUSPEND, profile3.trigger_event()); |
453 EXPECT_TRUE(profile3.has_ms_after_login()); | 465 EXPECT_TRUE(profile3.has_ms_after_login()); |
454 EXPECT_EQ(60000, profile3.suspend_duration_ms()); | 466 EXPECT_EQ(60000, profile3.suspend_duration_ms()); |
455 EXPECT_EQ(1500, profile3.ms_after_resume()); | 467 EXPECT_EQ(1500, profile3.ms_after_resume()); |
456 ASSERT_TRUE(profile3.has_perf_data()); | 468 ASSERT_TRUE(profile3.has_perf_data()); |
457 EXPECT_FALSE(profile3.has_perf_stat()); | 469 EXPECT_FALSE(profile3.has_perf_stat()); |
458 EXPECT_EQ(SerializeMessageToVector(perf_data_proto_), | 470 EXPECT_EQ(SerializeMessageToVector(perf_data_proto_), |
459 SerializeMessageToVector(profile3.perf_data())); | 471 SerializeMessageToVector(profile3.perf_data())); |
460 } | 472 } |
461 | 473 |
| 474 TEST_F(PerfProviderTest, DefaultCommandsBasedOnUarch_IvyBridge) { |
| 475 CPUIdentity cpuid; |
| 476 cpuid.arch = "x86_64"; |
| 477 cpuid.vendor = "GenuineIntel"; |
| 478 cpuid.family = 0x06; |
| 479 cpuid.model = 0x3a; // IvyBridge |
| 480 cpuid.model_name = ""; |
| 481 std::vector<RandomSelector::WeightAndValue> cmds = |
| 482 internal::GetDefaultCommandsForCpu(cpuid); |
| 483 ASSERT_GE(cmds.size(), 2UL); |
| 484 EXPECT_EQ(cmds[0].value, kPerfRecordCyclesCmd); |
| 485 EXPECT_EQ(cmds[1].value, kPerfRecordCallgraphCmd); |
| 486 auto found = std::find_if( |
| 487 cmds.begin(), cmds.end(), |
| 488 [](const RandomSelector::WeightAndValue& cmd) -> bool { |
| 489 return cmd.value == kPerfStatMemoryBandwidthCmd; |
| 490 }); |
| 491 EXPECT_NE(cmds.end(), found); |
| 492 found = std::find_if( |
| 493 cmds.begin(), cmds.end(), |
| 494 [](const RandomSelector::WeightAndValue& cmd) -> bool { |
| 495 return cmd.value == kPerfRecordLBRCmd; |
| 496 }); |
| 497 EXPECT_NE(cmds.end(), found); |
| 498 } |
| 499 |
| 500 TEST_F(PerfProviderTest, DefaultCommandsBasedOnUarch_SandyBridge) { |
| 501 CPUIdentity cpuid; |
| 502 cpuid.arch = "x86_64"; |
| 503 cpuid.vendor = "GenuineIntel"; |
| 504 cpuid.family = 0x06; |
| 505 cpuid.model = 0x2a; // SandyBridge |
| 506 cpuid.model_name = ""; |
| 507 std::vector<RandomSelector::WeightAndValue> cmds = |
| 508 internal::GetDefaultCommandsForCpu(cpuid); |
| 509 ASSERT_GE(cmds.size(), 2UL); |
| 510 EXPECT_EQ(cmds[0].value, kPerfRecordCyclesCmd); |
| 511 EXPECT_EQ(cmds[1].value, kPerfRecordCallgraphCmd); |
| 512 auto found = std::find_if( |
| 513 cmds.begin(), cmds.end(), |
| 514 [](const RandomSelector::WeightAndValue& cmd) -> bool { |
| 515 return cmd.value == kPerfStatMemoryBandwidthCmd; |
| 516 }); |
| 517 EXPECT_EQ(cmds.end(), found) << "SandyBridge does not support this command"; |
| 518 found = std::find_if( |
| 519 cmds.begin(), cmds.end(), |
| 520 [](const RandomSelector::WeightAndValue& cmd) -> bool { |
| 521 return cmd.value == kPerfRecordLBRCmd; |
| 522 }); |
| 523 EXPECT_NE(cmds.end(), found); |
| 524 } |
| 525 |
| 526 TEST_F(PerfProviderTest, DefaultCommandsBasedOnArch_Arm) { |
| 527 CPUIdentity cpuid; |
| 528 cpuid.arch = "armv7l"; |
| 529 cpuid.vendor = ""; |
| 530 cpuid.family = 0; |
| 531 cpuid.model = 0; |
| 532 cpuid.model_name = ""; |
| 533 std::vector<RandomSelector::WeightAndValue> cmds = |
| 534 internal::GetDefaultCommandsForCpu(cpuid); |
| 535 ASSERT_GE(cmds.size(), 2UL); |
| 536 EXPECT_EQ(cmds[0].value, kPerfRecordCyclesCmd); |
| 537 EXPECT_EQ(cmds[1].value, kPerfRecordCallgraphCmd); |
| 538 const auto found = std::find_if( |
| 539 cmds.begin(), cmds.end(), |
| 540 [](const RandomSelector::WeightAndValue& cmd) -> bool { |
| 541 return cmd.value == kPerfRecordLBRCmd; |
| 542 }); |
| 543 EXPECT_EQ(cmds.end(), found) << "ARM does not support this command"; |
| 544 } |
| 545 |
| 546 TEST_F(PerfProviderTest, DefaultCommandsBasedOnArch_x86_32) { |
| 547 CPUIdentity cpuid; |
| 548 cpuid.arch = "x86"; |
| 549 cpuid.vendor = "GenuineIntel"; |
| 550 cpuid.family = 0x06; |
| 551 cpuid.model = 0x2f; // Westmere |
| 552 cpuid.model_name = ""; |
| 553 std::vector<RandomSelector::WeightAndValue> cmds = |
| 554 internal::GetDefaultCommandsForCpu(cpuid); |
| 555 ASSERT_GE(cmds.size(), 2UL); |
| 556 EXPECT_EQ(cmds[0].value, kPerfRecordCyclesCmd); |
| 557 EXPECT_EQ(cmds[1].value, kPerfRecordCallgraphCmd); |
| 558 auto found = std::find_if( |
| 559 cmds.begin(), cmds.end(), |
| 560 [](const RandomSelector::WeightAndValue& cmd) -> bool { |
| 561 return cmd.value == kPerfStatMemoryBandwidthCmd; |
| 562 }); |
| 563 EXPECT_EQ(cmds.end(), found) << "x86_32 does not support this command"; |
| 564 found = std::find_if( |
| 565 cmds.begin(), cmds.end(), |
| 566 [](const RandomSelector::WeightAndValue& cmd) -> bool { |
| 567 return cmd.value == kPerfRecordLBRCmd; |
| 568 }); |
| 569 EXPECT_EQ(cmds.end(), found) << "x86_32 does not support this command"; |
| 570 } |
| 571 |
| 572 TEST_F(PerfProviderTest, DefaultCommandsBasedOnArch_Unknown) { |
| 573 CPUIdentity cpuid; |
| 574 cpuid.arch = "nonsense"; |
| 575 cpuid.vendor = ""; |
| 576 cpuid.family = 0; |
| 577 cpuid.model = 0; |
| 578 cpuid.model_name = ""; |
| 579 std::vector<RandomSelector::WeightAndValue> cmds = |
| 580 internal::GetDefaultCommandsForCpu(cpuid); |
| 581 EXPECT_EQ(1UL, cmds.size()); |
| 582 EXPECT_EQ(cmds[0].value, kPerfRecordCyclesCmd); |
| 583 } |
| 584 |
462 } // namespace metrics | 585 } // namespace metrics |
OLD | NEW |