| 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/thread_task_runner_handle.h" |
| 12 #include "base/threading/thread.h" | 12 #include "base/threading/thread.h" |
| 13 #include "base/trace_event/memory_dump_provider.h" | 13 #include "base/trace_event/memory_dump_provider.h" |
| 14 #include "base/trace_event/process_memory_dump.h" | 14 #include "base/trace_event/process_memory_dump.h" |
| 15 #include "testing/gmock/include/gmock/gmock.h" | 15 #include "testing/gmock/include/gmock/gmock.h" |
| 16 #include "testing/gtest/include/gtest/gtest.h" | 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 | 17 |
| 18 using testing::_; | 18 using testing::_; |
| 19 using testing::Between; | 19 using testing::Between; |
| 20 using testing::Invoke; | 20 using testing::Invoke; |
| 21 using testing::Return; | 21 using testing::Return; |
| 22 | 22 |
| 23 namespace base { | 23 namespace base { |
| 24 namespace trace_event { | 24 namespace trace_event { |
| 25 namespace { | |
| 26 MemoryDumpArgs high_detail_args = {MemoryDumpArgs::LEVEL_OF_DETAIL_HIGH}; | |
| 27 MemoryDumpArgs low_detail_args = {MemoryDumpArgs::LEVEL_OF_DETAIL_LOW}; | |
| 28 } | |
| 29 | 25 |
| 30 // Testing MemoryDumpManagerDelegate which short-circuits dump requests locally | 26 // Testing MemoryDumpManagerDelegate which short-circuits dump requests locally |
| 31 // instead of performing IPC dances. | 27 // instead of performing IPC dances. |
| 32 class MemoryDumpManagerDelegateForTesting : public MemoryDumpManagerDelegate { | 28 class MemoryDumpManagerDelegateForTesting : public MemoryDumpManagerDelegate { |
| 33 public: | 29 public: |
| 34 void RequestGlobalMemoryDump(const MemoryDumpRequestArgs& args, | 30 void RequestGlobalMemoryDump(const MemoryDumpRequestArgs& args, |
| 35 const MemoryDumpCallback& callback) override { | 31 const MemoryDumpCallback& callback) override { |
| 36 CreateProcessDump(args, callback); | 32 CreateProcessDump(args, callback); |
| 37 } | 33 } |
| 38 | 34 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 MemoryDumpManagerDelegateForTesting delegate_; | 83 MemoryDumpManagerDelegateForTesting delegate_; |
| 88 | 84 |
| 89 // We want our singleton torn down after each test. | 85 // We want our singleton torn down after each test. |
| 90 ShadowingAtExitManager at_exit_manager_; | 86 ShadowingAtExitManager at_exit_manager_; |
| 91 }; | 87 }; |
| 92 | 88 |
| 93 class MockDumpProvider : public MemoryDumpProvider { | 89 class MockDumpProvider : public MemoryDumpProvider { |
| 94 public: | 90 public: |
| 95 MockDumpProvider() | 91 MockDumpProvider() |
| 96 : dump_provider_to_register_or_unregister(nullptr), | 92 : dump_provider_to_register_or_unregister(nullptr), |
| 97 last_session_state_(nullptr), | 93 last_session_state_(nullptr) {} |
| 98 level_of_detail_(MemoryDumpArgs::LEVEL_OF_DETAIL_HIGH) {} | |
| 99 | 94 |
| 100 // Ctor used by the RespectTaskRunnerAffinity test. | 95 // Ctor used by the RespectTaskRunnerAffinity test. |
| 101 explicit MockDumpProvider( | 96 explicit MockDumpProvider( |
| 102 const scoped_refptr<SingleThreadTaskRunner>& task_runner) | 97 const scoped_refptr<SingleThreadTaskRunner>& task_runner) |
| 103 : last_session_state_(nullptr), | 98 : last_session_state_(nullptr), task_runner_(task_runner) {} |
| 104 task_runner_(task_runner), | |
| 105 level_of_detail_(MemoryDumpArgs::LEVEL_OF_DETAIL_HIGH) {} | |
| 106 | |
| 107 // Ctor used by CheckMemoryDumpArgs test. | |
| 108 explicit MockDumpProvider(const MemoryDumpArgs::LevelOfDetail level_of_detail) | |
| 109 : last_session_state_(nullptr), level_of_detail_(level_of_detail) {} | |
| 110 | 99 |
| 111 virtual ~MockDumpProvider() {} | 100 virtual ~MockDumpProvider() {} |
| 112 | 101 |
| 113 MOCK_METHOD2(OnMemoryDump, | 102 MOCK_METHOD2(OnMemoryDump, |
| 114 bool(const MemoryDumpArgs& args, ProcessMemoryDump* pmd)); | 103 bool(const MemoryDumpArgs& args, ProcessMemoryDump* pmd)); |
| 115 | 104 |
| 116 // OnMemoryDump() override for the RespectTaskRunnerAffinity test. | 105 // OnMemoryDump() override for the RespectTaskRunnerAffinity test. |
| 117 bool OnMemoryDump_CheckTaskRunner(const MemoryDumpArgs& args, | 106 bool OnMemoryDump_CheckTaskRunner(const MemoryDumpArgs& args, |
| 118 ProcessMemoryDump* pmd) { | 107 ProcessMemoryDump* pmd) { |
| 119 EXPECT_TRUE(task_runner_->RunsTasksOnCurrentThread()); | 108 EXPECT_TRUE(task_runner_->RunsTasksOnCurrentThread()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 139 } | 128 } |
| 140 | 129 |
| 141 // OnMemoryDump() override for the UnegisterDumperWhileDumping test. | 130 // OnMemoryDump() override for the UnegisterDumperWhileDumping test. |
| 142 bool OnMemoryDump_UnregisterDumpProvider(const MemoryDumpArgs& args, | 131 bool OnMemoryDump_UnregisterDumpProvider(const MemoryDumpArgs& args, |
| 143 ProcessMemoryDump* pmd) { | 132 ProcessMemoryDump* pmd) { |
| 144 MemoryDumpManager::GetInstance()->UnregisterDumpProvider( | 133 MemoryDumpManager::GetInstance()->UnregisterDumpProvider( |
| 145 dump_provider_to_register_or_unregister); | 134 dump_provider_to_register_or_unregister); |
| 146 return true; | 135 return true; |
| 147 } | 136 } |
| 148 | 137 |
| 149 // OnMemoryDump() override for the CheckMemoryDumpArgs test. | |
| 150 bool OnMemoryDump_CheckMemoryDumpArgs(const MemoryDumpArgs& args, | |
| 151 ProcessMemoryDump* pmd) { | |
| 152 EXPECT_EQ(level_of_detail_, args.level_of_detail); | |
| 153 return true; | |
| 154 } | |
| 155 | |
| 156 // Used by OnMemoryDump_(Un)RegisterExtraDumpProvider. | 138 // Used by OnMemoryDump_(Un)RegisterExtraDumpProvider. |
| 157 MemoryDumpProvider* dump_provider_to_register_or_unregister; | 139 MemoryDumpProvider* dump_provider_to_register_or_unregister; |
| 158 | 140 |
| 159 private: | 141 private: |
| 160 MemoryDumpSessionState* last_session_state_; | 142 MemoryDumpSessionState* last_session_state_; |
| 161 scoped_refptr<SingleThreadTaskRunner> task_runner_; | 143 scoped_refptr<SingleThreadTaskRunner> task_runner_; |
| 162 const MemoryDumpArgs::LevelOfDetail level_of_detail_; | |
| 163 }; | 144 }; |
| 164 | 145 |
| 165 TEST_F(MemoryDumpManagerTest, SingleDumper) { | 146 TEST_F(MemoryDumpManagerTest, SingleDumper) { |
| 166 MockDumpProvider mdp; | 147 MockDumpProvider mdp; |
| 167 mdm_->RegisterDumpProvider(&mdp); | 148 mdm_->RegisterDumpProvider(&mdp); |
| 168 | 149 |
| 169 // Check that the dumper is not called if the memory category is not enabled. | 150 // Check that the dumper is not called if the memory category is not enabled. |
| 170 EnableTracing("foo-and-bar-but-not-memory"); | 151 EnableTracing("foo-and-bar-but-not-memory"); |
| 171 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); | 152 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
| 172 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 153 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 173 high_detail_args); | |
| 174 DisableTracing(); | 154 DisableTracing(); |
| 175 | 155 |
| 176 // Now repeat enabling the memory category and check that the dumper is | 156 // Now repeat enabling the memory category and check that the dumper is |
| 177 // invoked this time. | 157 // invoked this time. |
| 178 EnableTracing(kTraceCategory); | 158 EnableTracing(kTraceCategory); |
| 179 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true)); | 159 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true)); |
| 180 for (int i = 0; i < 3; ++i) | 160 for (int i = 0; i < 3; ++i) |
| 181 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 161 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 182 high_detail_args); | |
| 183 DisableTracing(); | 162 DisableTracing(); |
| 184 | 163 |
| 185 mdm_->UnregisterDumpProvider(&mdp); | 164 mdm_->UnregisterDumpProvider(&mdp); |
| 186 | 165 |
| 187 // Finally check the unregister logic (no calls to the mdp after unregister). | 166 // Finally check the unregister logic (no calls to the mdp after unregister). |
| 188 EnableTracing(kTraceCategory); | 167 EnableTracing(kTraceCategory); |
| 189 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); | 168 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
| 190 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 169 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 191 high_detail_args); | |
| 192 TraceLog::GetInstance()->SetDisabled(); | 170 TraceLog::GetInstance()->SetDisabled(); |
| 193 } | 171 } |
| 194 | 172 |
| 195 TEST_F(MemoryDumpManagerTest, CheckMemoryDumpArgs) { | |
| 196 // Check that requesting dumps with high level of detail actually propagates | |
| 197 // to OnMemoryDump() call on dump providers. | |
| 198 MockDumpProvider mdp_high_detail(MemoryDumpArgs::LEVEL_OF_DETAIL_HIGH); | |
| 199 mdm_->RegisterDumpProvider(&mdp_high_detail); | |
| 200 | |
| 201 EnableTracing(kTraceCategory); | |
| 202 EXPECT_CALL(mdp_high_detail, OnMemoryDump(_, _)) | |
| 203 .Times(1) | |
| 204 .WillRepeatedly( | |
| 205 Invoke(&mdp_high_detail, | |
| 206 &MockDumpProvider::OnMemoryDump_CheckMemoryDumpArgs)); | |
| 207 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | |
| 208 high_detail_args); | |
| 209 DisableTracing(); | |
| 210 mdm_->UnregisterDumpProvider(&mdp_high_detail); | |
| 211 | |
| 212 // Check that requesting dumps with low level of detail actually propagates to | |
| 213 // OnMemoryDump() call on dump providers. | |
| 214 MockDumpProvider mdp_low_detail(MemoryDumpArgs::LEVEL_OF_DETAIL_LOW); | |
| 215 mdm_->RegisterDumpProvider(&mdp_low_detail); | |
| 216 | |
| 217 EnableTracing(kTraceCategory); | |
| 218 EXPECT_CALL(mdp_low_detail, OnMemoryDump(_, _)) | |
| 219 .Times(1) | |
| 220 .WillRepeatedly( | |
| 221 Invoke(&mdp_low_detail, | |
| 222 &MockDumpProvider::OnMemoryDump_CheckMemoryDumpArgs)); | |
| 223 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | |
| 224 low_detail_args); | |
| 225 DisableTracing(); | |
| 226 mdm_->UnregisterDumpProvider(&mdp_low_detail); | |
| 227 } | |
| 228 | |
| 229 TEST_F(MemoryDumpManagerTest, SharedSessionState) { | 173 TEST_F(MemoryDumpManagerTest, SharedSessionState) { |
| 230 MockDumpProvider mdp1; | 174 MockDumpProvider mdp1; |
| 231 MockDumpProvider mdp2; | 175 MockDumpProvider mdp2; |
| 232 mdm_->RegisterDumpProvider(&mdp1); | 176 mdm_->RegisterDumpProvider(&mdp1); |
| 233 mdm_->RegisterDumpProvider(&mdp2); | 177 mdm_->RegisterDumpProvider(&mdp2); |
| 234 | 178 |
| 235 EnableTracing(kTraceCategory); | 179 EnableTracing(kTraceCategory); |
| 236 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) | 180 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) |
| 237 .Times(2) | 181 .Times(2) |
| 238 .WillRepeatedly( | 182 .WillRepeatedly( |
| 239 Invoke(&mdp1, &MockDumpProvider::OnMemoryDump_CheckSessionState)); | 183 Invoke(&mdp1, &MockDumpProvider::OnMemoryDump_CheckSessionState)); |
| 240 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) | 184 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) |
| 241 .Times(2) | 185 .Times(2) |
| 242 .WillRepeatedly( | 186 .WillRepeatedly( |
| 243 Invoke(&mdp2, &MockDumpProvider::OnMemoryDump_CheckSessionState)); | 187 Invoke(&mdp2, &MockDumpProvider::OnMemoryDump_CheckSessionState)); |
| 244 | 188 |
| 245 for (int i = 0; i < 2; ++i) | 189 for (int i = 0; i < 2; ++i) |
| 246 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 190 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 247 high_detail_args); | |
| 248 | 191 |
| 249 DisableTracing(); | 192 DisableTracing(); |
| 250 } | 193 } |
| 251 | 194 |
| 252 TEST_F(MemoryDumpManagerTest, MultipleDumpers) { | 195 TEST_F(MemoryDumpManagerTest, MultipleDumpers) { |
| 253 MockDumpProvider mdp1; | 196 MockDumpProvider mdp1; |
| 254 MockDumpProvider mdp2; | 197 MockDumpProvider mdp2; |
| 255 | 198 |
| 256 // Enable only mdp1. | 199 // Enable only mdp1. |
| 257 mdm_->RegisterDumpProvider(&mdp1); | 200 mdm_->RegisterDumpProvider(&mdp1); |
| 258 EnableTracing(kTraceCategory); | 201 EnableTracing(kTraceCategory); |
| 259 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); | 202 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); |
| 260 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(0); | 203 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(0); |
| 261 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 204 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 262 high_detail_args); | |
| 263 DisableTracing(); | 205 DisableTracing(); |
| 264 | 206 |
| 265 // Invert: enable mdp1 and disable mdp2. | 207 // Invert: enable mdp1 and disable mdp2. |
| 266 mdm_->UnregisterDumpProvider(&mdp1); | 208 mdm_->UnregisterDumpProvider(&mdp1); |
| 267 mdm_->RegisterDumpProvider(&mdp2); | 209 mdm_->RegisterDumpProvider(&mdp2); |
| 268 EnableTracing(kTraceCategory); | 210 EnableTracing(kTraceCategory); |
| 269 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); | 211 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); |
| 270 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); | 212 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); |
| 271 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 213 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 272 high_detail_args); | |
| 273 DisableTracing(); | 214 DisableTracing(); |
| 274 | 215 |
| 275 // Enable both mdp1 and mdp2. | 216 // Enable both mdp1 and mdp2. |
| 276 mdm_->RegisterDumpProvider(&mdp1); | 217 mdm_->RegisterDumpProvider(&mdp1); |
| 277 EnableTracing(kTraceCategory); | 218 EnableTracing(kTraceCategory); |
| 278 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); | 219 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); |
| 279 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); | 220 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); |
| 280 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 221 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 281 high_detail_args); | |
| 282 DisableTracing(); | 222 DisableTracing(); |
| 283 } | 223 } |
| 284 | 224 |
| 285 // Checks that the MemoryDumpManager respects the thread affinity when a | 225 // Checks that the MemoryDumpManager respects the thread affinity when a |
| 286 // MemoryDumpProvider specifies a task_runner(). The test starts creating 8 | 226 // MemoryDumpProvider specifies a task_runner(). The test starts creating 8 |
| 287 // threads and registering a MemoryDumpProvider on each of them. At each | 227 // threads and registering a MemoryDumpProvider on each of them. At each |
| 288 // iteration, one thread is removed, to check the live unregistration logic. | 228 // iteration, one thread is removed, to check the live unregistration logic. |
| 289 TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) { | 229 TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) { |
| 290 const uint32 kNumInitialThreads = 8; | 230 const uint32 kNumInitialThreads = 8; |
| 291 | 231 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 309 | 249 |
| 310 EnableTracing(kTraceCategory); | 250 EnableTracing(kTraceCategory); |
| 311 | 251 |
| 312 while (!threads.empty()) { | 252 while (!threads.empty()) { |
| 313 last_callback_success_ = false; | 253 last_callback_success_ = false; |
| 314 { | 254 { |
| 315 RunLoop run_loop; | 255 RunLoop run_loop; |
| 316 MemoryDumpCallback callback = | 256 MemoryDumpCallback callback = |
| 317 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), | 257 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), |
| 318 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); | 258 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); |
| 319 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 259 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, callback); |
| 320 high_detail_args, callback); | |
| 321 // This nested message loop (|run_loop|) will be quit if and only if | 260 // This nested message loop (|run_loop|) will be quit if and only if |
| 322 // the RequestGlobalDump callback is invoked. | 261 // the RequestGlobalDump callback is invoked. |
| 323 run_loop.Run(); | 262 run_loop.Run(); |
| 324 } | 263 } |
| 325 EXPECT_TRUE(last_callback_success_); | 264 EXPECT_TRUE(last_callback_success_); |
| 326 | 265 |
| 327 // Unregister a MDP and destroy one thread at each iteration to check the | 266 // Unregister a MDP and destroy one thread at each iteration to check the |
| 328 // live unregistration logic. The unregistration needs to happen on the same | 267 // live unregistration logic. The unregistration needs to happen on the same |
| 329 // thread the MDP belongs to. | 268 // thread the MDP belongs to. |
| 330 { | 269 { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 357 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) | 296 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) |
| 358 .Times(MemoryDumpManager::kMaxConsecutiveFailuresCount) | 297 .Times(MemoryDumpManager::kMaxConsecutiveFailuresCount) |
| 359 .WillRepeatedly(Return(false)); | 298 .WillRepeatedly(Return(false)); |
| 360 | 299 |
| 361 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) | 300 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) |
| 362 .Times(1 + MemoryDumpManager::kMaxConsecutiveFailuresCount) | 301 .Times(1 + MemoryDumpManager::kMaxConsecutiveFailuresCount) |
| 363 .WillOnce(Return(false)) | 302 .WillOnce(Return(false)) |
| 364 .WillRepeatedly(Return(true)); | 303 .WillRepeatedly(Return(true)); |
| 365 for (int i = 0; i < 1 + MemoryDumpManager::kMaxConsecutiveFailuresCount; | 304 for (int i = 0; i < 1 + MemoryDumpManager::kMaxConsecutiveFailuresCount; |
| 366 i++) { | 305 i++) { |
| 367 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 306 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 368 high_detail_args); | |
| 369 } | 307 } |
| 370 | 308 |
| 371 DisableTracing(); | 309 DisableTracing(); |
| 372 } | 310 } |
| 373 | 311 |
| 374 // Sneakily register an extra memory dump provider while an existing one is | 312 // Sneakily register an extra memory dump provider while an existing one is |
| 375 // dumping and expect it to take part in the already active tracing session. | 313 // dumping and expect it to take part in the already active tracing session. |
| 376 TEST_F(MemoryDumpManagerTest, RegisterDumperWhileDumping) { | 314 TEST_F(MemoryDumpManagerTest, RegisterDumperWhileDumping) { |
| 377 MockDumpProvider mdp1; | 315 MockDumpProvider mdp1; |
| 378 MockDumpProvider mdp2; | 316 MockDumpProvider mdp2; |
| 379 | 317 |
| 380 mdp1.dump_provider_to_register_or_unregister = &mdp2; | 318 mdp1.dump_provider_to_register_or_unregister = &mdp2; |
| 381 mdm_->RegisterDumpProvider(&mdp1); | 319 mdm_->RegisterDumpProvider(&mdp1); |
| 382 EnableTracing(kTraceCategory); | 320 EnableTracing(kTraceCategory); |
| 383 | 321 |
| 384 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) | 322 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) |
| 385 .Times(4) | 323 .Times(4) |
| 386 .WillOnce(Return(true)) | 324 .WillOnce(Return(true)) |
| 387 .WillOnce(Invoke( | 325 .WillOnce(Invoke( |
| 388 &mdp1, &MockDumpProvider::OnMemoryDump_RegisterExtraDumpProvider)) | 326 &mdp1, &MockDumpProvider::OnMemoryDump_RegisterExtraDumpProvider)) |
| 389 .WillRepeatedly(Return(true)); | 327 .WillRepeatedly(Return(true)); |
| 390 | 328 |
| 391 // Depending on the insertion order (before or after mdp1), mdp2 might be | 329 // Depending on the insertion order (before or after mdp1), mdp2 might be |
| 392 // called also immediately after it gets registered. | 330 // called also immediately after it gets registered. |
| 393 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) | 331 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) |
| 394 .Times(Between(2, 3)) | 332 .Times(Between(2, 3)) |
| 395 .WillRepeatedly(Return(true)); | 333 .WillRepeatedly(Return(true)); |
| 396 | 334 |
| 397 for (int i = 0; i < 4; i++) { | 335 for (int i = 0; i < 4; i++) { |
| 398 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 336 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 399 high_detail_args); | |
| 400 } | 337 } |
| 401 | 338 |
| 402 DisableTracing(); | 339 DisableTracing(); |
| 403 } | 340 } |
| 404 | 341 |
| 405 // Like the above, but suddenly unregister the dump provider. | 342 // Like the above, but suddenly unregister the dump provider. |
| 406 TEST_F(MemoryDumpManagerTest, UnregisterDumperWhileDumping) { | 343 TEST_F(MemoryDumpManagerTest, UnregisterDumperWhileDumping) { |
| 407 MockDumpProvider mdp1; | 344 MockDumpProvider mdp1; |
| 408 MockDumpProvider mdp2; | 345 MockDumpProvider mdp2; |
| 409 | 346 |
| 410 mdm_->RegisterDumpProvider(&mdp1, ThreadTaskRunnerHandle::Get()); | 347 mdm_->RegisterDumpProvider(&mdp1, ThreadTaskRunnerHandle::Get()); |
| 411 mdm_->RegisterDumpProvider(&mdp2, ThreadTaskRunnerHandle::Get()); | 348 mdm_->RegisterDumpProvider(&mdp2, ThreadTaskRunnerHandle::Get()); |
| 412 mdp1.dump_provider_to_register_or_unregister = &mdp2; | 349 mdp1.dump_provider_to_register_or_unregister = &mdp2; |
| 413 EnableTracing(kTraceCategory); | 350 EnableTracing(kTraceCategory); |
| 414 | 351 |
| 415 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) | 352 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) |
| 416 .Times(4) | 353 .Times(4) |
| 417 .WillOnce(Return(true)) | 354 .WillOnce(Return(true)) |
| 418 .WillOnce( | 355 .WillOnce( |
| 419 Invoke(&mdp1, &MockDumpProvider::OnMemoryDump_UnregisterDumpProvider)) | 356 Invoke(&mdp1, &MockDumpProvider::OnMemoryDump_UnregisterDumpProvider)) |
| 420 .WillRepeatedly(Return(true)); | 357 .WillRepeatedly(Return(true)); |
| 421 | 358 |
| 422 // Depending on the insertion order (before or after mdp1), mdp2 might have | 359 // Depending on the insertion order (before or after mdp1), mdp2 might have |
| 423 // been already called when OnMemoryDump_UnregisterDumpProvider happens. | 360 // been already called when OnMemoryDump_UnregisterDumpProvider happens. |
| 424 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) | 361 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) |
| 425 .Times(Between(1, 2)) | 362 .Times(Between(1, 2)) |
| 426 .WillRepeatedly(Return(true)); | 363 .WillRepeatedly(Return(true)); |
| 427 | 364 |
| 428 for (int i = 0; i < 4; i++) { | 365 for (int i = 0; i < 4; i++) { |
| 429 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 366 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED); |
| 430 high_detail_args); | |
| 431 } | 367 } |
| 432 | 368 |
| 433 DisableTracing(); | 369 DisableTracing(); |
| 434 } | 370 } |
| 435 | 371 |
| 436 // Ensures that a NACK callback is invoked if RequestGlobalDump is called when | 372 // Ensures that a NACK callback is invoked if RequestGlobalDump is called when |
| 437 // tracing is not enabled. | 373 // tracing is not enabled. |
| 438 TEST_F(MemoryDumpManagerTest, CallbackCalledOnFailure) { | 374 TEST_F(MemoryDumpManagerTest, CallbackCalledOnFailure) { |
| 439 MockDumpProvider mdp1; | 375 MockDumpProvider mdp1; |
| 440 | 376 |
| 441 mdm_->RegisterDumpProvider(&mdp1); | 377 mdm_->RegisterDumpProvider(&mdp1); |
| 442 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); | 378 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); |
| 443 | 379 |
| 444 last_callback_success_ = true; | 380 last_callback_success_ = true; |
| 445 { | 381 { |
| 446 RunLoop run_loop; | 382 RunLoop run_loop; |
| 447 MemoryDumpCallback callback = | 383 MemoryDumpCallback callback = |
| 448 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), | 384 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), |
| 449 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); | 385 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); |
| 450 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 386 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, callback); |
| 451 high_detail_args, callback); | |
| 452 run_loop.Run(); | 387 run_loop.Run(); |
| 453 } | 388 } |
| 454 EXPECT_FALSE(last_callback_success_); | 389 EXPECT_FALSE(last_callback_success_); |
| 455 } | 390 } |
| 456 | 391 |
| 457 } // namespace trace_event | 392 } // namespace trace_event |
| 458 } // namespace base | 393 } // namespace base |
| OLD | NEW |