Chromium Code Reviews| 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 "base/trace_event/memory_dump_manager.h" | 5 #include "base/trace_event/memory_dump_manager.h" |
| 6 | 6 |
| 7 #include "base/bind_helpers.h" | 7 #include "base/bind_helpers.h" |
| 8 #include "base/memory/scoped_vector.h" | 8 #include "base/memory/scoped_vector.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| 11 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
| 12 #include "base/test/test_io_thread.h" | 12 #include "base/test/test_io_thread.h" |
| 13 #include "base/thread_task_runner_handle.h" | 13 #include "base/thread_task_runner_handle.h" |
| 14 #include "base/threading/thread.h" | 14 #include "base/threading/thread.h" |
| 15 #include "base/trace_event/memory_dump_provider.h" | 15 #include "base/trace_event/memory_dump_provider.h" |
| 16 #include "base/trace_event/process_memory_dump.h" | 16 #include "base/trace_event/process_memory_dump.h" |
| 17 #include "base/trace_event/trace_config_memory_test_util.h" | |
| 17 #include "testing/gmock/include/gmock/gmock.h" | 18 #include "testing/gmock/include/gmock/gmock.h" |
| 18 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 19 | 20 |
| 20 using testing::_; | 21 using testing::_; |
| 21 using testing::AnyNumber; | 22 using testing::AnyNumber; |
| 22 using testing::AtMost; | 23 using testing::AtMost; |
| 23 using testing::Between; | 24 using testing::Between; |
| 24 using testing::Invoke; | 25 using testing::Invoke; |
| 25 using testing::Return; | 26 using testing::Return; |
| 26 | 27 |
| 27 namespace base { | 28 namespace base { |
| 28 namespace trace_event { | 29 namespace trace_event { |
| 29 namespace { | 30 namespace { |
| 30 MemoryDumpArgs g_high_detail_args = {MemoryDumpArgs::LevelOfDetail::HIGH}; | 31 MemoryDumpArgs g_high_detail_args = {MemoryDumpArgs::LevelOfDetail::HIGH}; |
| 31 MemoryDumpArgs g_low_detail_args = {MemoryDumpArgs::LevelOfDetail::LOW}; | 32 MemoryDumpArgs g_low_detail_args = {MemoryDumpArgs::LevelOfDetail::LOW}; |
| 32 const char kTraceConfigWithTriggersFmt[] = | |
| 33 "{\"included_categories\":[\"%s\"],\"memory_dump_config\":{\"triggers\":[" | |
| 34 "{\"mode\":\"light\", \"periodic_interval_ms\":1}," | |
| 35 "{\"mode\":\"detailed\", \"periodic_interval_ms\":5}]}}"; | |
| 36 } // namespace | 33 } // namespace |
| 37 | 34 |
| 38 // GTest matchers for MemoryDumpRequestArgs arguments. | 35 // GTest matchers for MemoryDumpRequestArgs arguments. |
| 39 MATCHER(IsHighDetail, "") { | 36 MATCHER(IsHighDetail, "") { |
| 40 return arg.level_of_detail == MemoryDumpArgs::LevelOfDetail::HIGH; | 37 return arg.level_of_detail == MemoryDumpArgs::LevelOfDetail::HIGH; |
| 41 } | 38 } |
| 42 | 39 |
| 43 MATCHER(IsLowDetail, "") { | 40 MATCHER(IsLowDetail, "") { |
| 44 return arg.level_of_detail == MemoryDumpArgs::LevelOfDetail::LOW; | 41 return arg.level_of_detail == MemoryDumpArgs::LevelOfDetail::LOW; |
| 45 } | 42 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 109 protected: | 106 protected: |
| 110 void InitializeMemoryDumpManager(bool is_coordinator) { | 107 void InitializeMemoryDumpManager(bool is_coordinator) { |
| 111 mdm_->Initialize(delegate_.get(), is_coordinator); | 108 mdm_->Initialize(delegate_.get(), is_coordinator); |
| 112 } | 109 } |
| 113 | 110 |
| 114 void EnableTracingWithLegacyCategories(const char* category) { | 111 void EnableTracingWithLegacyCategories(const char* category) { |
| 115 TraceLog::GetInstance()->SetEnabled(TraceConfig(category, ""), | 112 TraceLog::GetInstance()->SetEnabled(TraceConfig(category, ""), |
| 116 TraceLog::RECORDING_MODE); | 113 TraceLog::RECORDING_MODE); |
| 117 } | 114 } |
| 118 | 115 |
| 119 void EnableTracingWithTraceConfig(const char* trace_config) { | 116 void EnableTracingWithTraceConfig(const std::string& trace_config) { |
| 120 TraceLog::GetInstance()->SetEnabled(TraceConfig(trace_config), | 117 TraceLog::GetInstance()->SetEnabled(TraceConfig(trace_config), |
| 121 TraceLog::RECORDING_MODE); | 118 TraceLog::RECORDING_MODE); |
| 122 } | 119 } |
| 123 | 120 |
| 124 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } | 121 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } |
| 125 | 122 |
| 126 bool IsPeriodicDumpingEnabled() const { | 123 bool IsPeriodicDumpingEnabled() const { |
| 127 return mdm_->periodic_dump_timer_.IsRunning(); | 124 return mdm_->periodic_dump_timer_.IsRunning(); |
| 128 } | 125 } |
| 129 | 126 |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 579 MemoryDumpCallback callback = | 576 MemoryDumpCallback callback = |
| 580 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), | 577 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), |
| 581 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); | 578 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); |
| 582 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 579 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 583 g_high_detail_args, callback); | 580 g_high_detail_args, callback); |
| 584 run_loop.Run(); | 581 run_loop.Run(); |
| 585 } | 582 } |
| 586 EXPECT_FALSE(last_callback_success_); | 583 EXPECT_FALSE(last_callback_success_); |
| 587 } | 584 } |
| 588 | 585 |
| 586 // Checks that is the MemoryDumpManager is initialized after tracing did already | |
| 587 // being, it will still late-join the party (real use case: startup tracing). | |
|
dsinclair
2015/09/10 16:43:46
nit: s/did already being/already began
Primiano Tucci (use gerrit)
2015/09/10 17:01:24
Done.
| |
| 588 TEST_F(MemoryDumpManagerTest, InitializedAfterStartOfTracing) { | |
| 589 MockMemoryDumpProvider mdp; | |
| 590 mdm_->RegisterDumpProvider(&mdp); | |
| 591 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | |
| 592 | |
| 593 // First check that a RequestGlobalDump() issued before the MemoryDumpManager | |
| 594 // initialization gets NACK-ed cleanly. | |
| 595 { | |
| 596 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); | |
| 597 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(0); | |
| 598 RunLoop run_loop; | |
| 599 MemoryDumpCallback callback = | |
| 600 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), | |
| 601 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); | |
| 602 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | |
| 603 g_high_detail_args, callback); | |
| 604 run_loop.Run(); | |
| 605 EXPECT_FALSE(last_callback_success_); | |
| 606 } | |
| 607 | |
| 608 // Now late-initialize the MemoryDumpManager and check that the | |
| 609 // RequestGlobalDump completes successfully. | |
| 610 { | |
| 611 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(1); | |
| 612 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); | |
| 613 InitializeMemoryDumpManager(false /* is_coordinator */); | |
| 614 RunLoop run_loop; | |
| 615 MemoryDumpCallback callback = | |
| 616 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), | |
| 617 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); | |
| 618 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | |
| 619 g_high_detail_args, callback); | |
| 620 run_loop.Run(); | |
| 621 EXPECT_TRUE(last_callback_success_); | |
| 622 } | |
| 623 DisableTracing(); | |
| 624 } | |
| 625 | |
| 589 // This test (and the MemoryDumpManagerTestCoordinator below) crystallizes the | 626 // This test (and the MemoryDumpManagerTestCoordinator below) crystallizes the |
| 590 // expectations of the chrome://tracing UI and chrome telemetry w.r.t. periodic | 627 // expectations of the chrome://tracing UI and chrome telemetry w.r.t. periodic |
| 591 // dumps in memory-infra, handling gracefully the transition between the legacy | 628 // dumps in memory-infra, handling gracefully the transition between the legacy |
| 592 // and the new-style (JSON-based) TraceConfig. | 629 // and the new-style (JSON-based) TraceConfig. |
| 593 TEST_F(MemoryDumpManagerTest, TraceConfigExpectations) { | 630 TEST_F(MemoryDumpManagerTest, TraceConfigExpectations) { |
| 594 InitializeMemoryDumpManager(false /* is_coordinator */); | 631 InitializeMemoryDumpManager(false /* is_coordinator */); |
| 595 MemoryDumpManagerDelegateForTesting& delegate = *delegate_; | 632 MemoryDumpManagerDelegateForTesting& delegate = *delegate_; |
| 596 | 633 |
| 597 // Don't trigger the default behavior of the mock delegate in this test, | 634 // Don't trigger the default behavior of the mock delegate in this test, |
| 598 // which would short-circuit the dump request to the actual | 635 // which would short-circuit the dump request to the actual |
| 599 // CreateProcessDump(). | 636 // CreateProcessDump(). |
| 600 // We don't want to create any dump in this test, only check whether the dumps | 637 // We don't want to create any dump in this test, only check whether the dumps |
| 601 // are requested or not. | 638 // are requested or not. |
| 602 ON_CALL(delegate, RequestGlobalMemoryDump(_, _)).WillByDefault(Return()); | 639 ON_CALL(delegate, RequestGlobalMemoryDump(_, _)).WillByDefault(Return()); |
| 603 | 640 |
| 604 // Enabling memory-infra in a non-coordinator process should not trigger any | 641 // Enabling memory-infra in a non-coordinator process should not trigger any |
| 605 // periodic dumps. | 642 // periodic dumps. |
| 606 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 643 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 607 EXPECT_FALSE(IsPeriodicDumpingEnabled()); | 644 EXPECT_FALSE(IsPeriodicDumpingEnabled()); |
| 608 DisableTracing(); | 645 DisableTracing(); |
| 609 | 646 |
| 610 // Enabling memory-infra with the new (JSON) TraceConfig in a non-coordinator | 647 // Enabling memory-infra with the new (JSON) TraceConfig in a non-coordinator |
| 611 // process with a fully defined trigger config should NOT enable any periodic | 648 // process with a fully defined trigger config should NOT enable any periodic |
| 612 // dumps. | 649 // dumps. |
| 613 const std::string kTraceConfigWithTriggers = StringPrintf( | 650 EnableTracingWithTraceConfig( |
| 614 kTraceConfigWithTriggersFmt, MemoryDumpManager::kTraceCategory); | 651 TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers(1, 5)); |
| 615 EnableTracingWithTraceConfig(kTraceConfigWithTriggers.c_str()); | |
| 616 EXPECT_FALSE(IsPeriodicDumpingEnabled()); | 652 EXPECT_FALSE(IsPeriodicDumpingEnabled()); |
| 617 DisableTracing(); | 653 DisableTracing(); |
| 618 } | 654 } |
| 619 | 655 |
| 620 TEST_F(MemoryDumpManagerTest, TraceConfigExpectationsWhenIsCoordinator) { | 656 TEST_F(MemoryDumpManagerTest, TraceConfigExpectationsWhenIsCoordinator) { |
| 621 InitializeMemoryDumpManager(true /* is_coordinator */); | 657 InitializeMemoryDumpManager(true /* is_coordinator */); |
| 622 MemoryDumpManagerDelegateForTesting& delegate = *delegate_; | 658 MemoryDumpManagerDelegateForTesting& delegate = *delegate_; |
| 623 ON_CALL(delegate, RequestGlobalMemoryDump(_, _)).WillByDefault(Return()); | 659 ON_CALL(delegate, RequestGlobalMemoryDump(_, _)).WillByDefault(Return()); |
| 624 | 660 |
| 625 // Enabling memory-infra with the legacy TraceConfig (category filter) in | 661 // Enabling memory-infra with the legacy TraceConfig (category filter) in |
| 626 // a coordinator process should enable periodic dumps. | 662 // a coordinator process should enable periodic dumps. |
| 627 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 663 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 628 EXPECT_TRUE(IsPeriodicDumpingEnabled()); | 664 EXPECT_TRUE(IsPeriodicDumpingEnabled()); |
| 629 DisableTracing(); | 665 DisableTracing(); |
| 630 | 666 |
| 631 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator | 667 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator |
| 632 // process without specifying any "memory_dump_config" section should enable | 668 // process without specifying any "memory_dump_config" section should enable |
| 633 // periodic dumps. This is to preserve the behavior chrome://tracing UI, that | 669 // periodic dumps. This is to preserve the behavior chrome://tracing UI, that |
| 634 // is: ticking memory-infra should dump periodically with the default config. | 670 // is: ticking memory-infra should dump periodically with the default config. |
| 635 const std::string kTraceConfigWithNoMemorDumpConfig = StringPrintf( | 671 EnableTracingWithTraceConfig( |
| 636 "{\"included_categories\":[\"%s\"]}", MemoryDumpManager::kTraceCategory); | 672 TraceConfigMemoryTestUtil::GetTraceConfig_NoTriggers()); |
| 637 EnableTracingWithTraceConfig(kTraceConfigWithNoMemorDumpConfig.c_str()); | |
| 638 EXPECT_TRUE(IsPeriodicDumpingEnabled()); | 673 EXPECT_TRUE(IsPeriodicDumpingEnabled()); |
| 639 DisableTracing(); | 674 DisableTracing(); |
| 640 | 675 |
| 641 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator | 676 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator |
| 642 // process with an empty "memory_dump_config" should NOT enable periodic | 677 // process with an empty "memory_dump_config" should NOT enable periodic |
| 643 // dumps. This is the way telemetry is supposed to use memory-infra with | 678 // dumps. This is the way telemetry is supposed to use memory-infra with |
| 644 // only explicitly triggered dumps. | 679 // only explicitly triggered dumps. |
| 645 const std::string kTraceConfigWithNoTriggers = StringPrintf( | 680 EnableTracingWithTraceConfig( |
| 646 "{\"included_categories\":[\"%s\"], \"memory_dump_config\":{}", | 681 TraceConfigMemoryTestUtil::GetTraceConfig_EmptyTriggers()); |
| 647 MemoryDumpManager::kTraceCategory); | |
| 648 EnableTracingWithTraceConfig(kTraceConfigWithNoTriggers.c_str()); | |
| 649 EXPECT_FALSE(IsPeriodicDumpingEnabled()); | 682 EXPECT_FALSE(IsPeriodicDumpingEnabled()); |
| 650 DisableTracing(); | 683 DisableTracing(); |
| 651 | 684 |
| 652 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator | 685 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator |
| 653 // process with a fully defined trigger config should cause periodic dumps to | 686 // process with a fully defined trigger config should cause periodic dumps to |
| 654 // be performed in the correct order. | 687 // be performed in the correct order. |
| 655 RunLoop run_loop; | 688 RunLoop run_loop; |
| 656 auto quit_closure = run_loop.QuitClosure(); | 689 auto quit_closure = run_loop.QuitClosure(); |
| 657 | 690 |
| 658 // The expected sequence with config of light=1ms, heavy=5ms is H,L,L,L,H,... | 691 const int kHeavyDumpRate = 5; |
| 692 const int kLightDumpPeriodMs = 1; | |
| 693 const int kHeavyDumpPeriodMs = kHeavyDumpRate * kLightDumpPeriodMs; | |
| 694 // The expected sequence with light=1ms, heavy=5ms is H,L,L,L,L,H,... | |
| 659 testing::InSequence sequence; | 695 testing::InSequence sequence; |
| 660 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsHighDetailArgs(), _)); | 696 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsHighDetailArgs(), _)); |
| 661 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLowDetailArgs(), _)).Times(3); | 697 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLowDetailArgs(), _)) |
| 698 .Times(kHeavyDumpRate - 1); | |
| 662 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsHighDetailArgs(), _)); | 699 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsHighDetailArgs(), _)); |
| 663 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLowDetailArgs(), _)).Times(2); | 700 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLowDetailArgs(), _)) |
| 701 .Times(kHeavyDumpRate - 2); | |
| 664 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLowDetailArgs(), _)) | 702 EXPECT_CALL(delegate, RequestGlobalMemoryDump(IsLowDetailArgs(), _)) |
| 665 .WillOnce(Invoke([quit_closure](const MemoryDumpRequestArgs& args, | 703 .WillOnce(Invoke([quit_closure](const MemoryDumpRequestArgs& args, |
| 666 const MemoryDumpCallback& callback) { | 704 const MemoryDumpCallback& callback) { |
| 667 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, quit_closure); | 705 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, quit_closure); |
| 668 })); | 706 })); |
| 669 | 707 |
| 670 // Swallow all the final spurious calls until tracing gets disabled. | 708 // Swallow all the final spurious calls until tracing gets disabled. |
| 671 EXPECT_CALL(delegate, RequestGlobalMemoryDump(_, _)).Times(AnyNumber()); | 709 EXPECT_CALL(delegate, RequestGlobalMemoryDump(_, _)).Times(AnyNumber()); |
| 672 | 710 |
| 673 const std::string kTraceConfigWithTriggers = StringPrintf( | 711 EnableTracingWithTraceConfig( |
| 674 kTraceConfigWithTriggersFmt, MemoryDumpManager::kTraceCategory); | 712 TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers( |
| 675 EnableTracingWithTraceConfig(kTraceConfigWithTriggers.c_str()); | 713 kLightDumpPeriodMs, kHeavyDumpPeriodMs)); |
| 676 run_loop.Run(); | 714 run_loop.Run(); |
| 677 DisableTracing(); | 715 DisableTracing(); |
| 678 } | 716 } |
| 679 | 717 |
| 680 } // namespace trace_event | 718 } // namespace trace_event |
| 681 } // namespace base | 719 } // namespace base |
| OLD | NEW |