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

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

Issue 1618703004: [MemoryInfra] Support dump providers running on SequencedTaskRunner (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Split ContinueAsyncProcessDump. Created 4 years, 10 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
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 <stdint.h> 7 #include <stdint.h>
8 8
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
14 #include "base/run_loop.h" 14 #include "base/run_loop.h"
15 #include "base/strings/stringprintf.h" 15 #include "base/strings/stringprintf.h"
16 #include "base/synchronization/waitable_event.h" 16 #include "base/synchronization/waitable_event.h"
17 #include "base/test/test_io_thread.h" 17 #include "base/test/test_io_thread.h"
18 #include "base/test/trace_event_analyzer.h" 18 #include "base/test/trace_event_analyzer.h"
19 #include "base/thread_task_runner_handle.h" 19 #include "base/thread_task_runner_handle.h"
20 #include "base/threading/platform_thread.h" 20 #include "base/threading/platform_thread.h"
21 #include "base/threading/sequenced_worker_pool.h"
21 #include "base/threading/thread.h" 22 #include "base/threading/thread.h"
22 #include "base/trace_event/memory_dump_provider.h" 23 #include "base/trace_event/memory_dump_provider.h"
23 #include "base/trace_event/process_memory_dump.h" 24 #include "base/trace_event/process_memory_dump.h"
24 #include "base/trace_event/trace_buffer.h" 25 #include "base/trace_event/trace_buffer.h"
25 #include "base/trace_event/trace_config_memory_test_util.h" 26 #include "base/trace_event/trace_config_memory_test_util.h"
26 #include "testing/gmock/include/gmock/gmock.h" 27 #include "testing/gmock/include/gmock/gmock.h"
27 #include "testing/gtest/include/gtest/gtest.h" 28 #include "testing/gtest/include/gtest/gtest.h"
28 29
29 using testing::_; 30 using testing::_;
30 using testing::AnyNumber; 31 using testing::AnyNumber;
(...skipping 23 matching lines...) Expand all
54 MemoryDumpManager* mdm = MemoryDumpManager::GetInstance(); 55 MemoryDumpManager* mdm = MemoryDumpManager::GetInstance();
55 mdm->set_dumper_registrations_ignored_for_testing(false); 56 mdm->set_dumper_registrations_ignored_for_testing(false);
56 mdm->RegisterDumpProvider(mdp, "TestDumpProvider", task_runner, options); 57 mdm->RegisterDumpProvider(mdp, "TestDumpProvider", task_runner, options);
57 mdm->set_dumper_registrations_ignored_for_testing(true); 58 mdm->set_dumper_registrations_ignored_for_testing(true);
58 } 59 }
59 60
60 void RegisterDumpProvider(MemoryDumpProvider* mdp) { 61 void RegisterDumpProvider(MemoryDumpProvider* mdp) {
61 RegisterDumpProvider(mdp, nullptr, MemoryDumpProvider::Options()); 62 RegisterDumpProvider(mdp, nullptr, MemoryDumpProvider::Options());
62 } 63 }
63 64
65 void RegisterDumpProviderWithSequencedTaskRunner(
Primiano Tucci (use gerrit) 2016/02/08 12:03:15 this seems a copy-paste of the above. Maybe you wa
ssid 2016/02/11 01:45:03 Done.
66 MemoryDumpProvider* mdp,
67 const scoped_refptr<base::SequencedTaskRunner>& task_runner,
68 const MemoryDumpProvider::Options& options) {
69 MemoryDumpManager* mdm = MemoryDumpManager::GetInstance();
70 mdm->set_dumper_registrations_ignored_for_testing(false);
71 mdm->RegisterDumpProviderWithSequencedTaskRunner(mdp, "TestDumpProvider",
72 task_runner, options);
73 mdm->set_dumper_registrations_ignored_for_testing(true);
74 }
75
64 void OnTraceDataCollected(Closure quit_closure, 76 void OnTraceDataCollected(Closure quit_closure,
65 trace_event::TraceResultBuffer* buffer, 77 trace_event::TraceResultBuffer* buffer,
66 const scoped_refptr<RefCountedString>& json, 78 const scoped_refptr<RefCountedString>& json,
67 bool has_more_events) { 79 bool has_more_events) {
68 buffer->AddFragment(json->data()); 80 buffer->AddFragment(json->data());
69 if (!has_more_events) 81 if (!has_more_events)
70 quit_closure.Run(); 82 quit_closure.Run();
71 } 83 }
72 84
73 } // namespace 85 } // namespace
(...skipping 29 matching lines...) Expand all
103 115
104 MockMemoryDumpProvider() : enable_mock_destructor(false) {} 116 MockMemoryDumpProvider() : enable_mock_destructor(false) {}
105 ~MockMemoryDumpProvider() override { 117 ~MockMemoryDumpProvider() override {
106 if (enable_mock_destructor) 118 if (enable_mock_destructor)
107 Destructor(); 119 Destructor();
108 } 120 }
109 121
110 bool enable_mock_destructor; 122 bool enable_mock_destructor;
111 }; 123 };
112 124
125 class TestSequencedTaskRunner : public SequencedTaskRunner {
Primiano Tucci (use gerrit) 2016/02/08 12:03:15 why do you need to create your own SeqTaskRunner?
ssid 2016/02/11 01:45:03 There seems to be no SeqTaskRunner implementation
126 public:
127 TestSequencedTaskRunner()
128 : worker_pool_(
129 new SequencedWorkerPool(2 /* max_threads */, "Test Task Runner")),
130 disabled_(false),
131 no_of_post_tasks_(0) {}
132
133 void set_enabled() { disabled_ = false; }
134 void set_disabled() { disabled_ = true; }
135 unsigned no_of_post_tasks() const { return no_of_post_tasks_; }
136
137 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
138 const Closure& task,
139 TimeDelta delay) override {
140 NOTREACHED();
141 return false;
142 }
143
144 bool PostDelayedTask(const tracked_objects::Location& from_here,
145 const Closure& task,
146 TimeDelta delay) override {
147 EXPECT_EQ(TimeDelta(), delay);
148 no_of_post_tasks_++;
149 if (disabled_)
150 return false;
151 return worker_pool_->PostSequencedWorkerTask(token_, from_here, task);
152 }
153
154 bool RunsTasksOnCurrentThread() const override {
155 return worker_pool_->IsRunningSequenceOnCurrentThread(token_);
156 }
157
158 private:
159 ~TestSequencedTaskRunner() override {}
160
161 scoped_refptr<SequencedWorkerPool> worker_pool_;
162 const SequencedWorkerPool::SequenceToken token_;
163 bool disabled_;
164 unsigned no_of_post_tasks_;
165 };
166
113 class MemoryDumpManagerTest : public testing::Test { 167 class MemoryDumpManagerTest : public testing::Test {
114 public: 168 public:
115 MemoryDumpManagerTest() : testing::Test(), kDefaultOptions() {} 169 MemoryDumpManagerTest() : testing::Test(), kDefaultOptions() {}
116 170
117 void SetUp() override { 171 void SetUp() override {
118 last_callback_success_ = false; 172 last_callback_success_ = false;
119 message_loop_.reset(new MessageLoop()); 173 message_loop_.reset(new MessageLoop());
120 mdm_.reset(new MemoryDumpManager()); 174 mdm_.reset(new MemoryDumpManager());
121 MemoryDumpManager::SetInstanceForTesting(mdm_.get()); 175 MemoryDumpManager::SetInstanceForTesting(mdm_.get());
122 ASSERT_EQ(mdm_.get(), MemoryDumpManager::GetInstance()); 176 ASSERT_EQ(mdm_.get(), MemoryDumpManager::GetInstance());
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 { 429 {
376 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); 430 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1);
377 EXPECT_CALL(mdp, OnMemoryDump(_, _)).WillOnce(Return(true)); 431 EXPECT_CALL(mdp, OnMemoryDump(_, _)).WillOnce(Return(true));
378 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); 432 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
379 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, 433 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
380 MemoryDumpLevelOfDetail::DETAILED); 434 MemoryDumpLevelOfDetail::DETAILED);
381 DisableTracing(); 435 DisableTracing();
382 } 436 }
383 } 437 }
384 438
385 // Checks that the MemoryDumpManager respects the thread affinity when a 439 // Checks that the MemoryDumpManager respects the task runner affinity when a
386 // MemoryDumpProvider specifies a task_runner(). The test starts creating 8 440 // MemoryDumpProvider specifies task runner. The test starts creating 8 threads
387 // threads and registering a MemoryDumpProvider on each of them. At each 441 // and sequenced task runners and registering a MemoryDumpProvider on each of
388 // iteration, one thread is removed, to check the live unregistration logic. 442 // them. At each iteration, one task runner of each kind is removed, to check
443 // the live unregistration logic.
389 TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) { 444 TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) {
390 InitializeMemoryDumpManager(false /* is_coordinator */); 445 InitializeMemoryDumpManager(false /* is_coordinator */);
391 const uint32_t kNumInitialThreads = 8; 446 const uint32_t kNumTaskRunners = 8;
392 447
393 std::vector<scoped_ptr<Thread>> threads; 448 std::vector<scoped_ptr<Thread>> threads;
394 std::vector<scoped_ptr<MockMemoryDumpProvider>> mdps; 449 std::vector<scoped_refptr<TestSequencedTaskRunner>> sequenced_task_runners;
450 std::vector<scoped_ptr<MockMemoryDumpProvider>> thread_mdps;
Primiano Tucci (use gerrit) 2016/02/08 12:03:15 I'd call them threaded_mdps and sequenced_mdps
ssid 2016/02/11 01:45:03 Done.
451 std::vector<scoped_ptr<MockMemoryDumpProvider>> sequenced_runner_mdps;
395 452
396 // Create the threads and setup the expectations. Given that at each iteration 453 // Create the threads and setup the expectations. Given that at each iteration
397 // we will pop out one thread/MemoryDumpProvider, each MDP is supposed to be 454 // we will pop out one task runner of each kind and it's MDP, each MDP is
398 // invoked a number of times equal to its index. 455 // supposed to be invoked a number of times equal to its index.
399 for (uint32_t i = kNumInitialThreads; i > 0; --i) { 456 for (uint32_t i = kNumTaskRunners; i > 0; --i) {
400 threads.push_back(make_scoped_ptr(new Thread("test thread"))); 457 threads.push_back(make_scoped_ptr(new Thread("test thread")));
401 auto thread = threads.back().get(); 458 auto thread = threads.back().get();
402 thread->Start(); 459 thread->Start();
403 scoped_refptr<SingleThreadTaskRunner> task_runner = thread->task_runner(); 460 scoped_refptr<SingleThreadTaskRunner> thread_task_runner =
404 mdps.push_back(make_scoped_ptr(new MockMemoryDumpProvider())); 461 thread->task_runner();
405 auto mdp = mdps.back().get(); 462 sequenced_task_runners.push_back(
406 RegisterDumpProvider(mdp, task_runner, kDefaultOptions); 463 make_scoped_refptr(new TestSequencedTaskRunner()));
407 EXPECT_CALL(*mdp, OnMemoryDump(_, _)) 464 auto sequenced_task_runner = sequenced_task_runners.back().get();
465
466 thread_mdps.push_back(make_scoped_ptr(new MockMemoryDumpProvider()));
467 auto thread_mdp = thread_mdps.back().get();
468 sequenced_runner_mdps.push_back(
469 make_scoped_ptr(new MockMemoryDumpProvider()));
470 auto sequenced_runner_mdp = sequenced_runner_mdps.back().get();
471
472 RegisterDumpProvider(thread_mdp, thread_task_runner, kDefaultOptions);
473 RegisterDumpProviderWithSequencedTaskRunner(
474 sequenced_runner_mdp, sequenced_task_runner, kDefaultOptions);
475
476 EXPECT_CALL(*thread_mdp, OnMemoryDump(_, _))
408 .Times(i) 477 .Times(i)
409 .WillRepeatedly(Invoke( 478 .WillRepeatedly(
410 [task_runner](const MemoryDumpArgs&, ProcessMemoryDump*) -> bool { 479 Invoke([thread_task_runner](const MemoryDumpArgs&,
411 EXPECT_TRUE(task_runner->RunsTasksOnCurrentThread()); 480 ProcessMemoryDump*) -> bool {
481 EXPECT_TRUE(thread_task_runner->RunsTasksOnCurrentThread());
412 return true; 482 return true;
413 })); 483 }));
484
485 EXPECT_CALL(*sequenced_runner_mdp, OnMemoryDump(_, _))
486 .Times(i)
487 .WillRepeatedly(Invoke([sequenced_task_runner](
488 const MemoryDumpArgs&,
489 ProcessMemoryDump* pmd) -> bool {
490 EXPECT_TRUE(
491 SequencedWorkerPool::GetSequenceTokenForCurrentThread().Equals(
492 SequencedWorkerPool::SequenceToken()));
493 EXPECT_TRUE(sequenced_task_runner->RunsTasksOnCurrentThread());
494 return true;
495 }));
414 } 496 }
415 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); 497 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
416 498
417 while (!threads.empty()) { 499 for (uint32_t i = 1; i <= kNumTaskRunners; ++i) {
418 last_callback_success_ = false; 500 last_callback_success_ = false;
419 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1); 501 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(1);
420 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, 502 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
421 MemoryDumpLevelOfDetail::DETAILED); 503 MemoryDumpLevelOfDetail::DETAILED);
422 EXPECT_TRUE(last_callback_success_); 504 EXPECT_TRUE(last_callback_success_);
505 // Check that each dump call was posted for the last sequenced task runner.
506 EXPECT_EQ(i, sequenced_task_runners.back()->no_of_post_tasks());
423 507
424 // Unregister a MDP and destroy one thread at each iteration to check the 508 // Destroy one thread and one sequenced task runner and their corresponding
425 // live unregistration logic. The unregistration needs to happen on the same 509 // MDPs at each iteration to check the live unregistration logic. The
426 // thread the MDP belongs to. 510 // unregistration needs to happen on the same task runner the MDP belongs
511 // to.
427 { 512 {
428 RunLoop run_loop; 513 RunLoop run_loop;
429 Closure unregistration = 514 Closure unregistration1 =
430 Bind(&MemoryDumpManager::UnregisterDumpProvider, 515 Bind(&MemoryDumpManager::UnregisterDumpProvider,
431 Unretained(mdm_.get()), Unretained(mdps.back().get())); 516 Unretained(mdm_.get()), Unretained(thread_mdps.back().get()));
432 threads.back()->task_runner()->PostTaskAndReply(FROM_HERE, unregistration, 517 Closure unregistration2 = Bind(
433 run_loop.QuitClosure()); 518 &MemoryDumpManager::UnregisterDumpProvider, Unretained(mdm_.get()),
519 Unretained(sequenced_runner_mdps.back().get()));
520 threads.back()->task_runner()->PostTask(FROM_HERE, unregistration1);
521 sequenced_task_runners.back()->PostTaskAndReply(
522 FROM_HERE, unregistration2, run_loop.QuitClosure());
434 run_loop.Run(); 523 run_loop.Run();
435 } 524 }
436 mdps.pop_back(); 525
526 thread_mdps.pop_back();
527 sequenced_runner_mdps.pop_back();
437 threads.back()->Stop(); 528 threads.back()->Stop();
529 sequenced_task_runners.pop_back();
438 threads.pop_back(); 530 threads.pop_back();
439 } 531 }
440 532
441 DisableTracing(); 533 DisableTracing();
442 } 534 }
443 535
536 // Check that the memory dump calls are always posted on task runner for
537 // SequencedTaskRunner case and that the dump provider gets disabled when
538 // PostTask fails, but the dump still succeeds.
539 TEST_F(MemoryDumpManagerTest, PostTaskForSequencedTaskRunner) {
540 InitializeMemoryDumpManager(false /* is_coordinator */);
541 std::vector<MockMemoryDumpProvider> mdps(3);
542 scoped_refptr<TestSequencedTaskRunner> task_runner1(
543 make_scoped_refptr(new TestSequencedTaskRunner()));
544 scoped_refptr<TestSequencedTaskRunner> task_runner2(
545 make_scoped_refptr(new TestSequencedTaskRunner()));
546 RegisterDumpProviderWithSequencedTaskRunner(&mdps[0], task_runner1,
547 kDefaultOptions);
548 RegisterDumpProviderWithSequencedTaskRunner(&mdps[1], task_runner2,
549 kDefaultOptions);
550 RegisterDumpProviderWithSequencedTaskRunner(&mdps[2], task_runner2,
551 kDefaultOptions);
552 task_runner1->set_disabled();
553 EXPECT_CALL(mdps[0], OnMemoryDump(_, _)).Times(0);
554 EXPECT_CALL(mdps[1], OnMemoryDump(_, _)).Times(2);
555 EXPECT_CALL(mdps[2], OnMemoryDump(_, _)).Times(2);
556 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(2);
557
558 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
559 last_callback_success_ = false;
560 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
561 MemoryDumpLevelOfDetail::DETAILED);
562 // Tasks should be posted even if |mdps[1]| and |mdps[2]| belong to same task
563 // runner.
564 EXPECT_EQ(1u, task_runner1->no_of_post_tasks());
565 EXPECT_EQ(2u, task_runner2->no_of_post_tasks());
566 EXPECT_TRUE(last_callback_success_);
567
568 // Check that |mdps[0]|'s OnMemoryDump is not called even if the task runner
569 // is enabled since |mdps[0]| was disabled previously.
570 task_runner1->set_enabled();
571 last_callback_success_ = false;
572 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
573 MemoryDumpLevelOfDetail::DETAILED);
574 EXPECT_EQ(2u, task_runner1->no_of_post_tasks());
575 EXPECT_EQ(4u, task_runner2->no_of_post_tasks());
576 EXPECT_TRUE(last_callback_success_);
577 DisableTracing();
578 }
579
444 // Checks that providers get disabled after 3 consecutive failures, but not 580 // Checks that providers get disabled after 3 consecutive failures, but not
445 // otherwise (e.g., if interleaved). 581 // otherwise (e.g., if interleaved).
446 TEST_F(MemoryDumpManagerTest, DisableFailingDumpers) { 582 TEST_F(MemoryDumpManagerTest, DisableFailingDumpers) {
447 InitializeMemoryDumpManager(false /* is_coordinator */); 583 InitializeMemoryDumpManager(false /* is_coordinator */);
448 MockMemoryDumpProvider mdp1; 584 MockMemoryDumpProvider mdp1;
449 MockMemoryDumpProvider mdp2; 585 MockMemoryDumpProvider mdp2;
450 586
451 RegisterDumpProvider(&mdp1); 587 RegisterDumpProvider(&mdp1);
452 RegisterDumpProvider(&mdp2); 588 RegisterDumpProvider(&mdp2);
453 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); 589 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory);
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after
973 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(2); 1109 EXPECT_CALL(*delegate_, RequestGlobalMemoryDump(_, _)).Times(2);
974 for (int i = 0; i < 2; ++i) { 1110 for (int i = 0; i < 2; ++i) {
975 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, 1111 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED,
976 MemoryDumpLevelOfDetail::DETAILED); 1112 MemoryDumpLevelOfDetail::DETAILED);
977 } 1113 }
978 DisableTracing(); 1114 DisableTracing();
979 } 1115 }
980 1116
981 } // namespace trace_event 1117 } // namespace trace_event
982 } // namespace base 1118 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698