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 <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <vector> | 10 #include <vector> |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 133 | 133 |
| 134 // Promote the CreateProcessDump to public so it can be used by test fixtures. | 134 // Promote the CreateProcessDump to public so it can be used by test fixtures. |
| 135 using MemoryDumpManagerDelegate::CreateProcessDump; | 135 using MemoryDumpManagerDelegate::CreateProcessDump; |
| 136 }; | 136 }; |
| 137 | 137 |
| 138 class MockMemoryDumpProvider : public MemoryDumpProvider { | 138 class MockMemoryDumpProvider : public MemoryDumpProvider { |
| 139 public: | 139 public: |
| 140 MOCK_METHOD0(Destructor, void()); | 140 MOCK_METHOD0(Destructor, void()); |
| 141 MOCK_METHOD2(OnMemoryDump, | 141 MOCK_METHOD2(OnMemoryDump, |
| 142 bool(const MemoryDumpArgs& args, ProcessMemoryDump* pmd)); | 142 bool(const MemoryDumpArgs& args, ProcessMemoryDump* pmd)); |
| 143 MOCK_METHOD1(PollFastMemoryTotal, void(uint64_t* memory_total)); | |
| 144 MOCK_METHOD1(SetFastMemoryPollingEnabled, void(bool enabled)); | |
| 143 | 145 |
| 144 MockMemoryDumpProvider() : enable_mock_destructor(false) { | 146 MockMemoryDumpProvider() : enable_mock_destructor(false) { |
| 145 ON_CALL(*this, OnMemoryDump(_, _)) | 147 ON_CALL(*this, OnMemoryDump(_, _)) |
| 146 .WillByDefault(Invoke([](const MemoryDumpArgs&, | 148 .WillByDefault(Invoke([](const MemoryDumpArgs&, |
| 147 ProcessMemoryDump* pmd) -> bool { | 149 ProcessMemoryDump* pmd) -> bool { |
| 148 // |session_state| should not be null under any circumstances when | 150 // |session_state| should not be null under any circumstances when |
| 149 // invoking a memory dump. The problem might arise in race conditions | 151 // invoking a memory dump. The problem might arise in race conditions |
| 150 // like crbug.com/600570 . | 152 // like crbug.com/600570 . |
| 151 EXPECT_TRUE(pmd->session_state().get() != nullptr); | 153 EXPECT_TRUE(pmd->session_state().get() != nullptr); |
| 152 return true; | 154 return true; |
| 153 })); | 155 })); |
| 156 | |
| 157 ON_CALL(*this, PollFastMemoryTotal(_)) | |
|
Primiano Tucci (use gerrit)
2016/12/16 12:34:40
I think you don't need this really, by default the
ssid
2016/12/16 18:58:22
If I do not add this, it says:
GMOCK WARNING:
Unin
Primiano Tucci (use gerrit)
2016/12/16 20:29:10
Ah ok then. I remembered something like that but I
| |
| 158 .WillByDefault( | |
| 159 Invoke([](uint64_t* memory_total) -> void { NOTREACHED(); })); | |
| 154 } | 160 } |
| 155 ~MockMemoryDumpProvider() override { | 161 ~MockMemoryDumpProvider() override { |
| 156 if (enable_mock_destructor) | 162 if (enable_mock_destructor) |
| 157 Destructor(); | 163 Destructor(); |
| 158 } | 164 } |
| 159 | 165 |
| 160 bool enable_mock_destructor; | 166 bool enable_mock_destructor; |
| 161 }; | 167 }; |
| 162 | 168 |
| 163 class TestSequencedTaskRunner : public SequencedTaskRunner { | 169 class TestSequencedTaskRunner : public SequencedTaskRunner { |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 225 // Turns a Closure into a MemoryDumpCallback, keeping track of the callback | 231 // Turns a Closure into a MemoryDumpCallback, keeping track of the callback |
| 226 // result and taking care of posting the closure on the correct task runner. | 232 // result and taking care of posting the closure on the correct task runner. |
| 227 void DumpCallbackAdapter(scoped_refptr<SingleThreadTaskRunner> task_runner, | 233 void DumpCallbackAdapter(scoped_refptr<SingleThreadTaskRunner> task_runner, |
| 228 Closure closure, | 234 Closure closure, |
| 229 uint64_t dump_guid, | 235 uint64_t dump_guid, |
| 230 bool success) { | 236 bool success) { |
| 231 last_callback_success_ = success; | 237 last_callback_success_ = success; |
| 232 task_runner->PostTask(FROM_HERE, closure); | 238 task_runner->PostTask(FROM_HERE, closure); |
| 233 } | 239 } |
| 234 | 240 |
| 241 void PollFastMemoryTotal(uint64_t* memory_total) { | |
| 242 mdm_->PollFastMemoryTotal(memory_total); | |
| 243 } | |
| 244 | |
| 235 protected: | 245 protected: |
| 236 void InitializeMemoryDumpManager(bool is_coordinator) { | 246 void InitializeMemoryDumpManager(bool is_coordinator) { |
| 237 mdm_->set_dumper_registrations_ignored_for_testing(true); | 247 mdm_->set_dumper_registrations_ignored_for_testing(true); |
| 238 mdm_->Initialize(delegate_.get(), is_coordinator); | 248 mdm_->Initialize(delegate_.get(), is_coordinator); |
| 239 } | 249 } |
| 240 | 250 |
| 241 void RequestGlobalDumpAndWait(MemoryDumpType dump_type, | 251 void RequestGlobalDumpAndWait(MemoryDumpType dump_type, |
| 242 MemoryDumpLevelOfDetail level_of_detail) { | 252 MemoryDumpLevelOfDetail level_of_detail) { |
| 243 RunLoop run_loop; | 253 RunLoop run_loop; |
| 244 MemoryDumpCallback callback = | 254 MemoryDumpCallback callback = |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 261 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } | 271 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } |
| 262 | 272 |
| 263 bool IsPeriodicDumpingEnabled() const { | 273 bool IsPeriodicDumpingEnabled() const { |
| 264 return mdm_->periodic_dump_timer_.IsRunning(); | 274 return mdm_->periodic_dump_timer_.IsRunning(); |
| 265 } | 275 } |
| 266 | 276 |
| 267 int GetMaxConsecutiveFailuresCount() const { | 277 int GetMaxConsecutiveFailuresCount() const { |
| 268 return MemoryDumpManager::kMaxConsecutiveFailuresCount; | 278 return MemoryDumpManager::kMaxConsecutiveFailuresCount; |
| 269 } | 279 } |
| 270 | 280 |
| 281 scoped_refptr<SequencedTaskRunner> GetPollingTaskRunnerUnsafe() { | |
| 282 return mdm_->dump_thread_->task_runner(); | |
| 283 } | |
| 284 | |
| 271 const MemoryDumpProvider::Options kDefaultOptions; | 285 const MemoryDumpProvider::Options kDefaultOptions; |
| 272 std::unique_ptr<MemoryDumpManager> mdm_; | 286 std::unique_ptr<MemoryDumpManager> mdm_; |
| 273 std::unique_ptr<MemoryDumpManagerDelegateForTesting> delegate_; | 287 std::unique_ptr<MemoryDumpManagerDelegateForTesting> delegate_; |
| 274 bool last_callback_success_; | 288 bool last_callback_success_; |
| 275 | 289 |
| 276 private: | 290 private: |
| 277 std::unique_ptr<MessageLoop> message_loop_; | 291 std::unique_ptr<MessageLoop> message_loop_; |
| 278 | 292 |
| 279 // We want our singleton torn down after each test. | 293 // We want our singleton torn down after each test. |
| 280 ShadowingAtExitManager at_exit_manager_; | 294 ShadowingAtExitManager at_exit_manager_; |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 729 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 743 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 730 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); | 744 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); |
| 731 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 745 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 732 MemoryDumpLevelOfDetail::DETAILED); | 746 MemoryDumpLevelOfDetail::DETAILED); |
| 733 ASSERT_EQ(1, on_memory_dump_call_count); | 747 ASSERT_EQ(1, on_memory_dump_call_count); |
| 734 ASSERT_TRUE(last_callback_success_); | 748 ASSERT_TRUE(last_callback_success_); |
| 735 | 749 |
| 736 DisableTracing(); | 750 DisableTracing(); |
| 737 } | 751 } |
| 738 | 752 |
| 753 TEST_F(MemoryDumpManagerTest, TestPollingOnDumpThread) { | |
| 754 InitializeMemoryDumpManager(false /* is_coordinator */); | |
| 755 std::unique_ptr<MockMemoryDumpProvider> mdp1(new MockMemoryDumpProvider()); | |
| 756 std::unique_ptr<MockMemoryDumpProvider> mdp2(new MockMemoryDumpProvider()); | |
| 757 mdp1->enable_mock_destructor = true; | |
| 758 mdp2->enable_mock_destructor = true; | |
| 759 | |
| 760 EXPECT_CALL(*mdp1, SetFastMemoryPollingEnabled(_)).Times(2); | |
| 761 EXPECT_CALL(*mdp2, SetFastMemoryPollingEnabled(_)).Times(2); | |
| 762 EXPECT_CALL(*mdp1, Destructor()); | |
| 763 EXPECT_CALL(*mdp2, Destructor()); | |
| 764 | |
| 765 RunLoop run_loop; | |
| 766 scoped_refptr<SingleThreadTaskRunner> test_task_runner = | |
| 767 ThreadTaskRunnerHandle::Get(); | |
| 768 auto quit_closure = run_loop.QuitClosure(); | |
| 769 | |
| 770 int call_count = 0; | |
| 771 EXPECT_CALL(*mdp1, PollFastMemoryTotal(_)) | |
| 772 .Times(4) | |
| 773 .WillRepeatedly(Invoke([&call_count, &test_task_runner, | |
| 774 quit_closure](uint64_t* total) -> void { | |
| 775 ++call_count; | |
| 776 if (call_count == 4) | |
| 777 test_task_runner->PostTask(FROM_HERE, quit_closure); | |
| 778 })); | |
| 779 | |
| 780 // Depending on the order of PostTask calls the mdp2 might be registered after | |
| 781 // all polls or in between polls. | |
| 782 EXPECT_CALL(*mdp2, PollFastMemoryTotal(_)) | |
| 783 .Times(Between(0, 4)) | |
| 784 .WillRepeatedly(Invoke([](uint64_t* total) -> void {})); | |
|
Primiano Tucci (use gerrit)
2016/12/16 12:34:40
I think you don't need this empty lambda.
Either y
ssid
2016/12/16 18:58:22
Done.
| |
| 785 | |
| 786 MemoryDumpProvider::Options options; | |
| 787 options.is_fast_polling_supported = true; | |
| 788 RegisterDumpProvider(mdp1.get(), nullptr, options); | |
| 789 EnableTracingWithTraceConfig( | |
| 790 TraceConfigMemoryTestUtil::GetTraceConfig_PeakDetectionTrigger(1)); | |
| 791 scoped_refptr<SequencedTaskRunner> polling_task_runner = | |
| 792 GetPollingTaskRunnerUnsafe().get(); | |
| 793 ASSERT_TRUE(polling_task_runner); | |
| 794 | |
| 795 uint64_t value = 0; | |
| 796 for (int i = 0; i < 4; i++) { | |
| 797 if (i == 0) | |
| 798 RegisterDumpProvider(mdp2.get(), nullptr, options); | |
| 799 if (i == 2) | |
| 800 mdm_->UnregisterAndDeleteDumpProviderSoon(std::move(mdp2)); | |
| 801 polling_task_runner->PostTask( | |
| 802 FROM_HERE, Bind(&MemoryDumpManagerTest::PollFastMemoryTotal, | |
| 803 Unretained(this), &value)); | |
| 804 } | |
| 805 | |
| 806 run_loop.Run(); | |
| 807 DisableTracing(); | |
| 808 mdm_->UnregisterAndDeleteDumpProviderSoon(std::move(mdp1)); | |
| 809 } | |
| 810 | |
| 739 // If a thread (with a dump provider living on it) is torn down during a dump | 811 // If a thread (with a dump provider living on it) is torn down during a dump |
| 740 // its dump provider should be skipped but the dump itself should succeed. | 812 // its dump provider should be skipped but the dump itself should succeed. |
| 741 TEST_F(MemoryDumpManagerTest, TearDownThreadWhileDumping) { | 813 TEST_F(MemoryDumpManagerTest, TearDownThreadWhileDumping) { |
| 742 InitializeMemoryDumpManager(false /* is_coordinator */); | 814 InitializeMemoryDumpManager(false /* is_coordinator */); |
| 743 std::vector<std::unique_ptr<TestIOThread>> threads; | 815 std::vector<std::unique_ptr<TestIOThread>> threads; |
| 744 std::vector<std::unique_ptr<MockMemoryDumpProvider>> mdps; | 816 std::vector<std::unique_ptr<MockMemoryDumpProvider>> mdps; |
| 745 | 817 |
| 746 for (int i = 0; i < 2; i++) { | 818 for (int i = 0; i < 2; i++) { |
| 747 threads.push_back( | 819 threads.push_back( |
| 748 WrapUnique(new TestIOThread(TestIOThread::kAutoStart))); | 820 WrapUnique(new TestIOThread(TestIOThread::kAutoStart))); |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1187 MemoryDumpLevelOfDetail::DETAILED); | 1259 MemoryDumpLevelOfDetail::DETAILED); |
| 1188 EXPECT_FALSE(last_callback_success_); | 1260 EXPECT_FALSE(last_callback_success_); |
| 1189 | 1261 |
| 1190 ASSERT_TRUE(IsPeriodicDumpingEnabled()); | 1262 ASSERT_TRUE(IsPeriodicDumpingEnabled()); |
| 1191 run_loop.Run(); | 1263 run_loop.Run(); |
| 1192 DisableTracing(); | 1264 DisableTracing(); |
| 1193 } | 1265 } |
| 1194 | 1266 |
| 1195 } // namespace trace_event | 1267 } // namespace trace_event |
| 1196 } // namespace base | 1268 } // namespace base |
| OLD | NEW |