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/thread_task_runner_handle.h" |
11 #include "base/threading/thread.h" | 12 #include "base/threading/thread.h" |
12 #include "base/trace_event/memory_dump_provider.h" | 13 #include "base/trace_event/memory_dump_provider.h" |
13 #include "base/trace_event/process_memory_dump.h" | 14 #include "base/trace_event/process_memory_dump.h" |
14 #include "testing/gmock/include/gmock/gmock.h" | 15 #include "testing/gmock/include/gmock/gmock.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
16 | 17 |
17 using testing::_; | 18 using testing::_; |
| 19 using testing::Between; |
18 using testing::Invoke; | 20 using testing::Invoke; |
19 using testing::Return; | 21 using testing::Return; |
20 | 22 |
21 namespace base { | 23 namespace base { |
22 namespace trace_event { | 24 namespace trace_event { |
23 | 25 |
24 // Testing MemoryDumpManagerDelegate which short-circuits dump requests locally | 26 // Testing MemoryDumpManagerDelegate which short-circuits dump requests locally |
25 // instead of performing IPC dances. | 27 // instead of performing IPC dances. |
26 class MemoryDumpManagerDelegateForTesting : public MemoryDumpManagerDelegate { | 28 class MemoryDumpManagerDelegateForTesting : public MemoryDumpManagerDelegate { |
27 public: | 29 public: |
28 void RequestGlobalMemoryDump( | 30 void RequestGlobalMemoryDump(const MemoryDumpRequestArgs& args, |
29 const base::trace_event::MemoryDumpRequestArgs& args, | 31 const MemoryDumpCallback& callback) override { |
30 const MemoryDumpCallback& callback) override { | |
31 CreateProcessDump(args, callback); | 32 CreateProcessDump(args, callback); |
32 } | 33 } |
33 | 34 |
34 bool IsCoordinatorProcess() const override { return false; } | 35 bool IsCoordinatorProcess() const override { return false; } |
35 }; | 36 }; |
36 | 37 |
37 class MemoryDumpManagerTest : public testing::Test { | 38 class MemoryDumpManagerTest : public testing::Test { |
38 public: | 39 public: |
39 void SetUp() override { | 40 void SetUp() override { |
40 message_loop_.reset(new MessageLoop()); | 41 message_loop_.reset(new MessageLoop()); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 private: | 75 private: |
75 scoped_ptr<MessageLoop> message_loop_; | 76 scoped_ptr<MessageLoop> message_loop_; |
76 MemoryDumpManagerDelegateForTesting delegate_; | 77 MemoryDumpManagerDelegateForTesting delegate_; |
77 | 78 |
78 // We want our singleton torn down after each test. | 79 // We want our singleton torn down after each test. |
79 ShadowingAtExitManager at_exit_manager_; | 80 ShadowingAtExitManager at_exit_manager_; |
80 }; | 81 }; |
81 | 82 |
82 class MockDumpProvider : public MemoryDumpProvider { | 83 class MockDumpProvider : public MemoryDumpProvider { |
83 public: | 84 public: |
84 MockDumpProvider() : last_session_state_(nullptr) {} | 85 MockDumpProvider() |
| 86 : dump_provider_to_register_or_unregister(nullptr), |
| 87 last_session_state_(nullptr) {} |
85 | 88 |
86 // Ctor used by the RespectTaskRunnerAffinity test. | 89 // Ctor used by the RespectTaskRunnerAffinity test. |
87 explicit MockDumpProvider( | 90 explicit MockDumpProvider( |
88 const scoped_refptr<SingleThreadTaskRunner>& task_runner) | 91 const scoped_refptr<SingleThreadTaskRunner>& task_runner) |
89 : last_session_state_(nullptr), task_runner_(task_runner) {} | 92 : last_session_state_(nullptr), task_runner_(task_runner) {} |
90 | 93 |
91 virtual ~MockDumpProvider() {} | 94 virtual ~MockDumpProvider() {} |
92 | 95 |
93 MOCK_METHOD1(OnMemoryDump, bool(ProcessMemoryDump* pmd)); | 96 MOCK_METHOD1(OnMemoryDump, bool(ProcessMemoryDump* pmd)); |
94 | 97 |
95 // OnMemoryDump() override for the RespectTaskRunnerAffinity test. | 98 // OnMemoryDump() override for the RespectTaskRunnerAffinity test. |
96 bool OnMemoryDump_CheckTaskRunner(ProcessMemoryDump* pmd) { | 99 bool OnMemoryDump_CheckTaskRunner(ProcessMemoryDump* pmd) { |
97 EXPECT_TRUE(task_runner_->RunsTasksOnCurrentThread()); | 100 EXPECT_TRUE(task_runner_->RunsTasksOnCurrentThread()); |
98 return true; | 101 return true; |
99 } | 102 } |
100 | 103 |
101 // OnMemoryDump() override for the SharedSessionState test. | 104 // OnMemoryDump() override for the SharedSessionState test. |
102 bool OnMemoryDump_CheckSessionState(ProcessMemoryDump* pmd) { | 105 bool OnMemoryDump_CheckSessionState(ProcessMemoryDump* pmd) { |
103 MemoryDumpSessionState* cur_session_state = pmd->session_state().get(); | 106 MemoryDumpSessionState* cur_session_state = pmd->session_state().get(); |
104 if (last_session_state_) | 107 if (last_session_state_) |
105 EXPECT_EQ(last_session_state_, cur_session_state); | 108 EXPECT_EQ(last_session_state_, cur_session_state); |
106 last_session_state_ = cur_session_state; | 109 last_session_state_ = cur_session_state; |
107 return true; | 110 return true; |
108 } | 111 } |
109 | 112 |
| 113 // OnMemoryDump() override for the RegisterDumperWhileDumping test. |
| 114 bool OnMemoryDump_RegisterExtraDumpProvider(ProcessMemoryDump* pmd) { |
| 115 MemoryDumpManager::GetInstance()->RegisterDumpProvider( |
| 116 dump_provider_to_register_or_unregister); |
| 117 return true; |
| 118 } |
| 119 |
| 120 // OnMemoryDump() override for the UnegisterDumperWhileDumping test. |
| 121 bool OnMemoryDump_UnregisterDumpProvider(ProcessMemoryDump* pmd) { |
| 122 MemoryDumpManager::GetInstance()->UnregisterDumpProvider( |
| 123 dump_provider_to_register_or_unregister); |
| 124 return true; |
| 125 } |
| 126 |
| 127 // Used by OnMemoryDump_(Un)RegisterExtraDumpProvider. |
| 128 MemoryDumpProvider* dump_provider_to_register_or_unregister; |
| 129 |
110 private: | 130 private: |
111 MemoryDumpSessionState* last_session_state_; | 131 MemoryDumpSessionState* last_session_state_; |
112 scoped_refptr<SingleThreadTaskRunner> task_runner_; | 132 scoped_refptr<SingleThreadTaskRunner> task_runner_; |
113 }; | 133 }; |
114 | 134 |
115 TEST_F(MemoryDumpManagerTest, SingleDumper) { | 135 TEST_F(MemoryDumpManagerTest, SingleDumper) { |
116 MockDumpProvider mdp; | 136 MockDumpProvider mdp; |
117 mdm_->RegisterDumpProvider(&mdp); | 137 mdm_->RegisterDumpProvider(&mdp); |
118 | 138 |
119 // Check that the dumper is not called if the memory category is not enabled. | 139 // Check that the dumper is not called if the memory category is not enabled. |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 MockDumpProvider mdp1; | 276 MockDumpProvider mdp1; |
257 MockDumpProvider mdp2; | 277 MockDumpProvider mdp2; |
258 | 278 |
259 mdm_->RegisterDumpProvider(&mdp1); | 279 mdm_->RegisterDumpProvider(&mdp1); |
260 mdm_->RegisterDumpProvider(&mdp2); | 280 mdm_->RegisterDumpProvider(&mdp2); |
261 EnableTracing(kTraceCategory); | 281 EnableTracing(kTraceCategory); |
262 | 282 |
263 EXPECT_CALL(mdp1, OnMemoryDump(_)) | 283 EXPECT_CALL(mdp1, OnMemoryDump(_)) |
264 .Times(MemoryDumpManager::kMaxConsecutiveFailuresCount) | 284 .Times(MemoryDumpManager::kMaxConsecutiveFailuresCount) |
265 .WillRepeatedly(Return(false)); | 285 .WillRepeatedly(Return(false)); |
| 286 |
266 EXPECT_CALL(mdp2, OnMemoryDump(_)) | 287 EXPECT_CALL(mdp2, OnMemoryDump(_)) |
267 .Times(1 + MemoryDumpManager::kMaxConsecutiveFailuresCount) | 288 .Times(1 + MemoryDumpManager::kMaxConsecutiveFailuresCount) |
268 .WillOnce(Return(false)) | 289 .WillOnce(Return(false)) |
269 .WillRepeatedly(Return(true)); | 290 .WillRepeatedly(Return(true)); |
270 for (int i = 0; i < 1 + MemoryDumpManager::kMaxConsecutiveFailuresCount; | 291 for (int i = 0; i < 1 + MemoryDumpManager::kMaxConsecutiveFailuresCount; |
271 i++) { | 292 i++) { |
272 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); | 293 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
273 } | 294 } |
274 | 295 |
275 DisableTracing(); | 296 DisableTracing(); |
276 } | 297 } |
277 | 298 |
| 299 // Sneakily register an extra memory dump provider while an existing one is |
| 300 // dumping and expect it to take part in the already active tracing session. |
| 301 TEST_F(MemoryDumpManagerTest, RegisterDumperWhileDumping) { |
| 302 MockDumpProvider mdp1; |
| 303 MockDumpProvider mdp2; |
| 304 |
| 305 mdp1.dump_provider_to_register_or_unregister = &mdp2; |
| 306 mdm_->RegisterDumpProvider(&mdp1); |
| 307 EnableTracing(kTraceCategory); |
| 308 |
| 309 EXPECT_CALL(mdp1, OnMemoryDump(_)) |
| 310 .Times(4) |
| 311 .WillOnce(Return(true)) |
| 312 .WillOnce(Invoke( |
| 313 &mdp1, &MockDumpProvider::OnMemoryDump_RegisterExtraDumpProvider)) |
| 314 .WillRepeatedly(Return(true)); |
| 315 |
| 316 // Depending on the insertion order (before or after mdp1), mdp2 might be |
| 317 // called also immediately after it gets registered. |
| 318 EXPECT_CALL(mdp2, OnMemoryDump(_)) |
| 319 .Times(Between(2, 3)) |
| 320 .WillRepeatedly(Return(true)); |
| 321 |
| 322 for (int i = 0; i < 4; i++) { |
| 323 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 324 } |
| 325 |
| 326 DisableTracing(); |
| 327 } |
| 328 |
| 329 // Like the above, but suddenly unregister the dump provider. |
| 330 TEST_F(MemoryDumpManagerTest, UnregisterDumperWhileDumping) { |
| 331 MockDumpProvider mdp1; |
| 332 MockDumpProvider mdp2; |
| 333 |
| 334 mdm_->RegisterDumpProvider(&mdp1, ThreadTaskRunnerHandle::Get()); |
| 335 mdm_->RegisterDumpProvider(&mdp2, ThreadTaskRunnerHandle::Get()); |
| 336 mdp1.dump_provider_to_register_or_unregister = &mdp2; |
| 337 EnableTracing(kTraceCategory); |
| 338 |
| 339 EXPECT_CALL(mdp1, OnMemoryDump(_)) |
| 340 .Times(4) |
| 341 .WillOnce(Return(true)) |
| 342 .WillOnce(Invoke(&mdp1, |
| 343 &MockDumpProvider::OnMemoryDump_UnregisterDumpProvider)) |
| 344 .WillRepeatedly(Return(true)); |
| 345 |
| 346 // Depending on the insertion order (before or after mdp1), mdp2 might have |
| 347 // been already called when OnMemoryDump_UnregisterDumpProvider happens. |
| 348 EXPECT_CALL(mdp2, OnMemoryDump(_)) |
| 349 .Times(Between(1, 2)) |
| 350 .WillRepeatedly(Return(true)); |
| 351 |
| 352 for (int i = 0; i < 4; i++) { |
| 353 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 354 } |
| 355 |
| 356 DisableTracing(); |
| 357 } |
| 358 |
278 } // namespace trace_event | 359 } // namespace trace_event |
279 } // namespace base | 360 } // namespace base |
OLD | NEW |