| Index: base/trace_event/memory_dump_manager_unittest.cc
|
| diff --git a/base/trace_event/memory_dump_manager_unittest.cc b/base/trace_event/memory_dump_manager_unittest.cc
|
| deleted file mode 100644
|
| index be20cec238f285294c6822ced380d7367f2071f9..0000000000000000000000000000000000000000
|
| --- a/base/trace_event/memory_dump_manager_unittest.cc
|
| +++ /dev/null
|
| @@ -1,360 +0,0 @@
|
| -// Copyright 2015 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "base/trace_event/memory_dump_manager.h"
|
| -
|
| -#include "base/bind_helpers.h"
|
| -#include "base/memory/scoped_vector.h"
|
| -#include "base/message_loop/message_loop.h"
|
| -#include "base/run_loop.h"
|
| -#include "base/thread_task_runner_handle.h"
|
| -#include "base/threading/thread.h"
|
| -#include "base/trace_event/memory_dump_provider.h"
|
| -#include "base/trace_event/process_memory_dump.h"
|
| -#include "testing/gmock/include/gmock/gmock.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -
|
| -using testing::_;
|
| -using testing::Between;
|
| -using testing::Invoke;
|
| -using testing::Return;
|
| -
|
| -namespace base {
|
| -namespace trace_event {
|
| -
|
| -// Testing MemoryDumpManagerDelegate which short-circuits dump requests locally
|
| -// instead of performing IPC dances.
|
| -class MemoryDumpManagerDelegateForTesting : public MemoryDumpManagerDelegate {
|
| - public:
|
| - void RequestGlobalMemoryDump(const MemoryDumpRequestArgs& args,
|
| - const MemoryDumpCallback& callback) override {
|
| - CreateProcessDump(args, callback);
|
| - }
|
| -
|
| - bool IsCoordinatorProcess() const override { return false; }
|
| -};
|
| -
|
| -class MemoryDumpManagerTest : public testing::Test {
|
| - public:
|
| - void SetUp() override {
|
| - message_loop_.reset(new MessageLoop());
|
| - mdm_.reset(new MemoryDumpManager());
|
| - MemoryDumpManager::SetInstanceForTesting(mdm_.get());
|
| - ASSERT_EQ(mdm_, MemoryDumpManager::GetInstance());
|
| - MemoryDumpManager::GetInstance()->Initialize();
|
| - MemoryDumpManager::GetInstance()->SetDelegate(&delegate_);
|
| - }
|
| -
|
| - void TearDown() override {
|
| - MemoryDumpManager::SetInstanceForTesting(nullptr);
|
| - mdm_.reset();
|
| - message_loop_.reset();
|
| - TraceLog::DeleteForTesting();
|
| - }
|
| -
|
| - void DumpCallbackAdapter(scoped_refptr<SingleThreadTaskRunner> task_runner,
|
| - Closure closure,
|
| - uint64 dump_guid,
|
| - bool success) {
|
| - task_runner->PostTask(FROM_HERE, closure);
|
| - }
|
| -
|
| - protected:
|
| - const char* kTraceCategory = MemoryDumpManager::kTraceCategoryForTesting;
|
| -
|
| - void EnableTracing(const char* category) {
|
| - TraceLog::GetInstance()->SetEnabled(
|
| - TraceConfig(category, ""), TraceLog::RECORDING_MODE);
|
| - }
|
| -
|
| - void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); }
|
| -
|
| - scoped_ptr<MemoryDumpManager> mdm_;
|
| -
|
| - private:
|
| - scoped_ptr<MessageLoop> message_loop_;
|
| - MemoryDumpManagerDelegateForTesting delegate_;
|
| -
|
| - // We want our singleton torn down after each test.
|
| - ShadowingAtExitManager at_exit_manager_;
|
| -};
|
| -
|
| -class MockDumpProvider : public MemoryDumpProvider {
|
| - public:
|
| - MockDumpProvider()
|
| - : dump_provider_to_register_or_unregister(nullptr),
|
| - last_session_state_(nullptr) {}
|
| -
|
| - // Ctor used by the RespectTaskRunnerAffinity test.
|
| - explicit MockDumpProvider(
|
| - const scoped_refptr<SingleThreadTaskRunner>& task_runner)
|
| - : last_session_state_(nullptr), task_runner_(task_runner) {}
|
| -
|
| - virtual ~MockDumpProvider() {}
|
| -
|
| - MOCK_METHOD1(OnMemoryDump, bool(ProcessMemoryDump* pmd));
|
| -
|
| - // OnMemoryDump() override for the RespectTaskRunnerAffinity test.
|
| - bool OnMemoryDump_CheckTaskRunner(ProcessMemoryDump* pmd) {
|
| - EXPECT_TRUE(task_runner_->RunsTasksOnCurrentThread());
|
| - return true;
|
| - }
|
| -
|
| - // OnMemoryDump() override for the SharedSessionState test.
|
| - bool OnMemoryDump_CheckSessionState(ProcessMemoryDump* pmd) {
|
| - MemoryDumpSessionState* cur_session_state = pmd->session_state().get();
|
| - if (last_session_state_)
|
| - EXPECT_EQ(last_session_state_, cur_session_state);
|
| - last_session_state_ = cur_session_state;
|
| - return true;
|
| - }
|
| -
|
| - // OnMemoryDump() override for the RegisterDumperWhileDumping test.
|
| - bool OnMemoryDump_RegisterExtraDumpProvider(ProcessMemoryDump* pmd) {
|
| - MemoryDumpManager::GetInstance()->RegisterDumpProvider(
|
| - dump_provider_to_register_or_unregister);
|
| - return true;
|
| - }
|
| -
|
| - // OnMemoryDump() override for the UnegisterDumperWhileDumping test.
|
| - bool OnMemoryDump_UnregisterDumpProvider(ProcessMemoryDump* pmd) {
|
| - MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
|
| - dump_provider_to_register_or_unregister);
|
| - return true;
|
| - }
|
| -
|
| - // Used by OnMemoryDump_(Un)RegisterExtraDumpProvider.
|
| - MemoryDumpProvider* dump_provider_to_register_or_unregister;
|
| -
|
| - private:
|
| - MemoryDumpSessionState* last_session_state_;
|
| - scoped_refptr<SingleThreadTaskRunner> task_runner_;
|
| -};
|
| -
|
| -TEST_F(MemoryDumpManagerTest, SingleDumper) {
|
| - MockDumpProvider mdp;
|
| - mdm_->RegisterDumpProvider(&mdp);
|
| -
|
| - // Check that the dumper is not called if the memory category is not enabled.
|
| - EnableTracing("foo-and-bar-but-not-memory");
|
| - EXPECT_CALL(mdp, OnMemoryDump(_)).Times(0);
|
| - mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
|
| - DisableTracing();
|
| -
|
| - // Now repeat enabling the memory category and check that the dumper is
|
| - // invoked this time.
|
| - EnableTracing(kTraceCategory);
|
| - EXPECT_CALL(mdp, OnMemoryDump(_)).Times(3).WillRepeatedly(Return(true));
|
| - for (int i = 0; i < 3; ++i)
|
| - mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
|
| - DisableTracing();
|
| -
|
| - mdm_->UnregisterDumpProvider(&mdp);
|
| -
|
| - // Finally check the unregister logic (no calls to the mdp after unregister).
|
| - EnableTracing(kTraceCategory);
|
| - EXPECT_CALL(mdp, OnMemoryDump(_)).Times(0);
|
| - mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
|
| - TraceLog::GetInstance()->SetDisabled();
|
| -}
|
| -
|
| -TEST_F(MemoryDumpManagerTest, SharedSessionState) {
|
| - MockDumpProvider mdp1;
|
| - MockDumpProvider mdp2;
|
| - mdm_->RegisterDumpProvider(&mdp1);
|
| - mdm_->RegisterDumpProvider(&mdp2);
|
| -
|
| - EnableTracing(kTraceCategory);
|
| - EXPECT_CALL(mdp1, OnMemoryDump(_))
|
| - .Times(2)
|
| - .WillRepeatedly(
|
| - Invoke(&mdp1, &MockDumpProvider::OnMemoryDump_CheckSessionState));
|
| - EXPECT_CALL(mdp2, OnMemoryDump(_))
|
| - .Times(2)
|
| - .WillRepeatedly(
|
| - Invoke(&mdp2, &MockDumpProvider::OnMemoryDump_CheckSessionState));
|
| -
|
| - for (int i = 0; i < 2; ++i)
|
| - mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
|
| -
|
| - DisableTracing();
|
| -}
|
| -
|
| -TEST_F(MemoryDumpManagerTest, MultipleDumpers) {
|
| - MockDumpProvider mdp1;
|
| - MockDumpProvider mdp2;
|
| -
|
| - // Enable only mdp1.
|
| - mdm_->RegisterDumpProvider(&mdp1);
|
| - EnableTracing(kTraceCategory);
|
| - EXPECT_CALL(mdp1, OnMemoryDump(_)).Times(1).WillRepeatedly(Return(true));
|
| - EXPECT_CALL(mdp2, OnMemoryDump(_)).Times(0);
|
| - mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
|
| - DisableTracing();
|
| -
|
| - // Invert: enable mdp1 and disable mdp2.
|
| - mdm_->UnregisterDumpProvider(&mdp1);
|
| - mdm_->RegisterDumpProvider(&mdp2);
|
| - EnableTracing(kTraceCategory);
|
| - EXPECT_CALL(mdp1, OnMemoryDump(_)).Times(0);
|
| - EXPECT_CALL(mdp2, OnMemoryDump(_)).Times(1).WillRepeatedly(Return(true));
|
| - mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
|
| - DisableTracing();
|
| -
|
| - // Enable both mdp1 and mdp2.
|
| - mdm_->RegisterDumpProvider(&mdp1);
|
| - EnableTracing(kTraceCategory);
|
| - EXPECT_CALL(mdp1, OnMemoryDump(_)).Times(1).WillRepeatedly(Return(true));
|
| - EXPECT_CALL(mdp2, OnMemoryDump(_)).Times(1).WillRepeatedly(Return(true));
|
| - mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
|
| - DisableTracing();
|
| -}
|
| -
|
| -// Checks that the MemoryDumpManager respects the thread affinity when a
|
| -// MemoryDumpProvider specifies a task_runner(). The test starts creating 8
|
| -// threads and registering a MemoryDumpProvider on each of them. At each
|
| -// iteration, one thread is removed, to check the live unregistration logic.
|
| -TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) {
|
| - const uint32 kNumInitialThreads = 8;
|
| -
|
| - ScopedVector<Thread> threads;
|
| - ScopedVector<MockDumpProvider> mdps;
|
| -
|
| - // Create the threads and setup the expectations. Given that at each iteration
|
| - // we will pop out one thread/MemoryDumpProvider, each MDP is supposed to be
|
| - // invoked a number of times equal to its index.
|
| - for (uint32 i = kNumInitialThreads; i > 0; --i) {
|
| - threads.push_back(new Thread("test thread"));
|
| - threads.back()->Start();
|
| - mdps.push_back(new MockDumpProvider(threads.back()->task_runner()));
|
| - MockDumpProvider* mdp = mdps.back();
|
| - mdm_->RegisterDumpProvider(mdp, threads.back()->task_runner());
|
| - EXPECT_CALL(*mdp, OnMemoryDump(_))
|
| - .Times(i)
|
| - .WillRepeatedly(
|
| - Invoke(mdp, &MockDumpProvider::OnMemoryDump_CheckTaskRunner));
|
| - }
|
| -
|
| - EnableTracing(kTraceCategory);
|
| -
|
| - while (!threads.empty()) {
|
| - {
|
| - RunLoop run_loop;
|
| - MemoryDumpCallback callback =
|
| - Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this),
|
| - MessageLoop::current()->task_runner(), run_loop.QuitClosure());
|
| - mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, callback);
|
| - // This nested message loop (|run_loop|) will be quit if and only if
|
| - // the RequestGlobalDump callback is invoked.
|
| - run_loop.Run();
|
| - }
|
| -
|
| - // Unregister a MDP and destroy one thread at each iteration to check the
|
| - // live unregistration logic. The unregistration needs to happen on the same
|
| - // thread the MDP belongs to.
|
| - {
|
| - RunLoop run_loop;
|
| - Closure unregistration =
|
| - Bind(&MemoryDumpManager::UnregisterDumpProvider,
|
| - Unretained(mdm_.get()), Unretained(mdps.back()));
|
| - threads.back()->task_runner()->PostTaskAndReply(FROM_HERE, unregistration,
|
| - run_loop.QuitClosure());
|
| - run_loop.Run();
|
| - }
|
| - mdps.pop_back();
|
| - threads.back()->Stop();
|
| - threads.pop_back();
|
| - }
|
| -
|
| - DisableTracing();
|
| -}
|
| -
|
| -// Enable both dump providers, make sure that mdp gets disabled after 3 failures
|
| -// and not disabled after 1.
|
| -TEST_F(MemoryDumpManagerTest, DisableFailingDumpers) {
|
| - MockDumpProvider mdp1;
|
| - MockDumpProvider mdp2;
|
| -
|
| - mdm_->RegisterDumpProvider(&mdp1);
|
| - mdm_->RegisterDumpProvider(&mdp2);
|
| - EnableTracing(kTraceCategory);
|
| -
|
| - EXPECT_CALL(mdp1, OnMemoryDump(_))
|
| - .Times(MemoryDumpManager::kMaxConsecutiveFailuresCount)
|
| - .WillRepeatedly(Return(false));
|
| -
|
| - EXPECT_CALL(mdp2, OnMemoryDump(_))
|
| - .Times(1 + MemoryDumpManager::kMaxConsecutiveFailuresCount)
|
| - .WillOnce(Return(false))
|
| - .WillRepeatedly(Return(true));
|
| - for (int i = 0; i < 1 + MemoryDumpManager::kMaxConsecutiveFailuresCount;
|
| - i++) {
|
| - mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
|
| - }
|
| -
|
| - DisableTracing();
|
| -}
|
| -
|
| -// Sneakily register an extra memory dump provider while an existing one is
|
| -// dumping and expect it to take part in the already active tracing session.
|
| -TEST_F(MemoryDumpManagerTest, RegisterDumperWhileDumping) {
|
| - MockDumpProvider mdp1;
|
| - MockDumpProvider mdp2;
|
| -
|
| - mdp1.dump_provider_to_register_or_unregister = &mdp2;
|
| - mdm_->RegisterDumpProvider(&mdp1);
|
| - EnableTracing(kTraceCategory);
|
| -
|
| - EXPECT_CALL(mdp1, OnMemoryDump(_))
|
| - .Times(4)
|
| - .WillOnce(Return(true))
|
| - .WillOnce(Invoke(
|
| - &mdp1, &MockDumpProvider::OnMemoryDump_RegisterExtraDumpProvider))
|
| - .WillRepeatedly(Return(true));
|
| -
|
| - // Depending on the insertion order (before or after mdp1), mdp2 might be
|
| - // called also immediately after it gets registered.
|
| - EXPECT_CALL(mdp2, OnMemoryDump(_))
|
| - .Times(Between(2, 3))
|
| - .WillRepeatedly(Return(true));
|
| -
|
| - for (int i = 0; i < 4; i++) {
|
| - mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
|
| - }
|
| -
|
| - DisableTracing();
|
| -}
|
| -
|
| -// Like the above, but suddenly unregister the dump provider.
|
| -TEST_F(MemoryDumpManagerTest, UnregisterDumperWhileDumping) {
|
| - MockDumpProvider mdp1;
|
| - MockDumpProvider mdp2;
|
| -
|
| - mdm_->RegisterDumpProvider(&mdp1, ThreadTaskRunnerHandle::Get());
|
| - mdm_->RegisterDumpProvider(&mdp2, ThreadTaskRunnerHandle::Get());
|
| - mdp1.dump_provider_to_register_or_unregister = &mdp2;
|
| - EnableTracing(kTraceCategory);
|
| -
|
| - EXPECT_CALL(mdp1, OnMemoryDump(_))
|
| - .Times(4)
|
| - .WillOnce(Return(true))
|
| - .WillOnce(
|
| - Invoke(&mdp1, &MockDumpProvider::OnMemoryDump_UnregisterDumpProvider))
|
| - .WillRepeatedly(Return(true));
|
| -
|
| - // Depending on the insertion order (before or after mdp1), mdp2 might have
|
| - // been already called when OnMemoryDump_UnregisterDumpProvider happens.
|
| - EXPECT_CALL(mdp2, OnMemoryDump(_))
|
| - .Times(Between(1, 2))
|
| - .WillRepeatedly(Return(true));
|
| -
|
| - for (int i = 0; i < 4; i++) {
|
| - mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
|
| - }
|
| -
|
| - DisableTracing();
|
| -}
|
| -
|
| -} // namespace trace_event
|
| -} // namespace base
|
|
|