Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: base/trace_event/memory_dump_manager_unittest.cc

Issue 1289793007: Allow unregistering MemoryDumpProviders during dump (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Replace auto with explicit types Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/trace_event/memory_dump_manager.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/test/test_io_thread.h"
11 #include "base/thread_task_runner_handle.h" 12 #include "base/thread_task_runner_handle.h"
12 #include "base/threading/thread.h" 13 #include "base/threading/thread.h"
13 #include "base/trace_event/memory_dump_provider.h" 14 #include "base/trace_event/memory_dump_provider.h"
14 #include "base/trace_event/process_memory_dump.h" 15 #include "base/trace_event/process_memory_dump.h"
15 #include "testing/gmock/include/gmock/gmock.h" 16 #include "testing/gmock/include/gmock/gmock.h"
16 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/gtest/include/gtest/gtest.h"
17 18
18 using testing::_; 19 using testing::_;
20 using testing::AtMost;
19 using testing::Between; 21 using testing::Between;
20 using testing::Invoke; 22 using testing::Invoke;
21 using testing::Return; 23 using testing::Return;
22 24
23 namespace base { 25 namespace base {
24 namespace trace_event { 26 namespace trace_event {
25 namespace { 27 namespace {
26 MemoryDumpArgs high_detail_args = {MemoryDumpArgs::LevelOfDetail::HIGH}; 28 MemoryDumpArgs high_detail_args = {MemoryDumpArgs::LevelOfDetail::HIGH};
27 MemoryDumpArgs low_detail_args = {MemoryDumpArgs::LevelOfDetail::LOW}; 29 MemoryDumpArgs low_detail_args = {MemoryDumpArgs::LevelOfDetail::LOW};
28 } 30 }
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 // Enable both mdp1 and mdp2. 277 // Enable both mdp1 and mdp2.
276 mdm_->RegisterDumpProvider(&mdp1); 278 mdm_->RegisterDumpProvider(&mdp1);
277 EnableTracing(kTraceCategory); 279 EnableTracing(kTraceCategory);
278 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); 280 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true));
279 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); 281 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true));
280 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, 282 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED,
281 high_detail_args); 283 high_detail_args);
282 DisableTracing(); 284 DisableTracing();
283 } 285 }
284 286
287 // Verify that whether OnMemoryDump is called depends only on the current
288 // registration state and not on previous registrations and dumps.
289 TEST_F(MemoryDumpManagerTest, RegistrationConsistency) {
290 MockDumpProvider mdp;
291
292 mdm_->RegisterDumpProvider(&mdp);
293
294 {
295 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(1);
296 EnableTracing(kTraceCategory);
297 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED,
298 high_detail_args);
299 DisableTracing();
300 }
301
302 mdm_->UnregisterDumpProvider(&mdp);
303
304 {
305 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0);
306 EnableTracing(kTraceCategory);
307 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED,
308 high_detail_args);
309 DisableTracing();
310 }
311
312 mdm_->RegisterDumpProvider(&mdp);
313 mdm_->UnregisterDumpProvider(&mdp);
314
315 {
316 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0);
317 EnableTracing(kTraceCategory);
318 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED,
319 high_detail_args);
320 DisableTracing();
321 }
322
323 mdm_->RegisterDumpProvider(&mdp);
324 mdm_->UnregisterDumpProvider(&mdp);
325 mdm_->RegisterDumpProvider(&mdp);
326
327 {
328 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(1);
329 EnableTracing(kTraceCategory);
330 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED,
331 high_detail_args);
332 DisableTracing();
333 }
334 }
335
285 // Checks that the MemoryDumpManager respects the thread affinity when a 336 // Checks that the MemoryDumpManager respects the thread affinity when a
286 // MemoryDumpProvider specifies a task_runner(). The test starts creating 8 337 // MemoryDumpProvider specifies a task_runner(). The test starts creating 8
287 // threads and registering a MemoryDumpProvider on each of them. At each 338 // threads and registering a MemoryDumpProvider on each of them. At each
288 // iteration, one thread is removed, to check the live unregistration logic. 339 // iteration, one thread is removed, to check the live unregistration logic.
289 TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) { 340 TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) {
290 const uint32 kNumInitialThreads = 8; 341 const uint32 kNumInitialThreads = 8;
291 342
292 ScopedVector<Thread> threads; 343 ScopedVector<Thread> threads;
293 ScopedVector<MockDumpProvider> mdps; 344 ScopedVector<MockDumpProvider> mdps;
294 345
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 .WillRepeatedly(Return(true)); 477 .WillRepeatedly(Return(true));
427 478
428 for (int i = 0; i < 4; i++) { 479 for (int i = 0; i < 4; i++) {
429 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, 480 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED,
430 high_detail_args); 481 high_detail_args);
431 } 482 }
432 483
433 DisableTracing(); 484 DisableTracing();
434 } 485 }
435 486
487 // Verify that the dump does not abort when unregistering a provider while
488 // dumping from a different thread than the dumping thread.
489 TEST_F(MemoryDumpManagerTest, UnregisterDumperFromThreadWhileDumping) {
490 ScopedVector<TestIOThread> threads;
491 ScopedVector<MockDumpProvider> mdps;
492
493 for (int i = 0; i < 2; i++) {
494 threads.push_back(new TestIOThread(TestIOThread::kAutoStart));
495 mdps.push_back(new MockDumpProvider(threads.back()->task_runner()));
496 mdm_->RegisterDumpProvider(mdps.back(), threads.back()->task_runner());
497 }
498
499 int on_memory_dump_call_count = 0;
500 RunLoop run_loop;
501
502 // When OnMemoryDump is called on either of the dump providers, it will
503 // unregister the other one.
504 for (MockDumpProvider* mdp : mdps) {
505 int other_idx = (mdps.front() == mdp);
506 TestIOThread* other_thread = threads[other_idx];
507 MockDumpProvider* other_mdp = mdps[other_idx];
508 auto on_dump = [this, other_thread, other_mdp, &on_memory_dump_call_count](
509 const MemoryDumpArgs& args, ProcessMemoryDump* pmd) {
510 other_thread->PostTaskAndWait(
511 FROM_HERE, base::Bind(&MemoryDumpManager::UnregisterDumpProvider,
512 base::Unretained(&*mdm_), other_mdp));
513 on_memory_dump_call_count++;
514 return true;
515 };
516
517 // OnMemoryDump is called once for the provider that dumps first, and zero
518 // times for the other provider.
519 EXPECT_CALL(*mdp, OnMemoryDump(_, _))
520 .Times(AtMost(1))
521 .WillOnce(Invoke(on_dump));
522 }
523
524 last_callback_success_ = false;
525 MemoryDumpCallback callback =
526 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this),
527 MessageLoop::current()->task_runner(), run_loop.QuitClosure());
528
529 EnableTracing(kTraceCategory);
530 MemoryDumpRequestArgs request_args = {0, MemoryDumpType::EXPLICITLY_TRIGGERED,
531 high_detail_args};
532 mdm_->CreateProcessDump(request_args, callback);
533
534 run_loop.Run();
535
536 ASSERT_EQ(1, on_memory_dump_call_count);
537 ASSERT_EQ(true, last_callback_success_);
538
539 DisableTracing();
540 }
541
436 // Ensures that a NACK callback is invoked if RequestGlobalDump is called when 542 // Ensures that a NACK callback is invoked if RequestGlobalDump is called when
437 // tracing is not enabled. 543 // tracing is not enabled.
438 TEST_F(MemoryDumpManagerTest, CallbackCalledOnFailure) { 544 TEST_F(MemoryDumpManagerTest, CallbackCalledOnFailure) {
439 MockDumpProvider mdp1; 545 MockDumpProvider mdp1;
440 546
441 mdm_->RegisterDumpProvider(&mdp1); 547 mdm_->RegisterDumpProvider(&mdp1);
442 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); 548 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0);
443 549
444 last_callback_success_ = true; 550 last_callback_success_ = true;
445 { 551 {
446 RunLoop run_loop; 552 RunLoop run_loop;
447 MemoryDumpCallback callback = 553 MemoryDumpCallback callback =
448 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), 554 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this),
449 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); 555 MessageLoop::current()->task_runner(), run_loop.QuitClosure());
450 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, 556 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED,
451 high_detail_args, callback); 557 high_detail_args, callback);
452 run_loop.Run(); 558 run_loop.Run();
453 } 559 }
454 EXPECT_FALSE(last_callback_success_); 560 EXPECT_FALSE(last_callback_success_);
455 } 561 }
456 562
457 } // namespace trace_event 563 } // namespace trace_event
458 } // namespace base 564 } // namespace base
OLDNEW
« no previous file with comments | « base/trace_event/memory_dump_manager.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698