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 |