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
3 // found in the LICENSE file.
5 #include "base/trace_event/memory_dump_manager.h"
7 #include "base/trace_event/memory_dump_provider.h"
8 #include "base/trace_event/process_memory_dump.h"
9 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h"
13 using testing::Invoke
;
14 using testing::Return
;
17 namespace trace_event
{
19 // Testing MemoryDumpManagerDelegate which short-circuits dump requests locally
20 // instead of performing IPC dances.
21 class MemoryDumpManagerDelegateForTesting
: public MemoryDumpManagerDelegate
{
23 void RequestGlobalMemoryDump(
24 const base::trace_event::MemoryDumpRequestArgs
& args
,
25 const MemoryDumpCallback
& callback
) override
{
26 MemoryDumpManager::GetInstance()->CreateProcessDump(args
);
30 class MemoryDumpManagerTest
: public testing::Test
{
32 void SetUp() override
{
33 mdm_
.reset(new MemoryDumpManager());
34 MemoryDumpManager::SetInstanceForTesting(mdm_
.get());
35 ASSERT_EQ(mdm_
, MemoryDumpManager::GetInstance());
36 MemoryDumpManager::GetInstance()->Initialize();
37 MemoryDumpManager::GetInstance()->SetDelegate(&delegate_
);
40 void TearDown() override
{
41 MemoryDumpManager::SetInstanceForTesting(nullptr);
43 TraceLog::DeleteForTesting();
47 const char* const kTraceCategory
= MemoryDumpManager::kTraceCategory
;
49 void EnableTracing(const char* category
) {
50 TraceLog::GetInstance()->SetEnabled(
51 CategoryFilter(category
), TraceLog::RECORDING_MODE
, TraceOptions());
54 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); }
56 scoped_ptr
<MemoryDumpManager
> mdm_
;
59 MemoryDumpManagerDelegateForTesting delegate_
;
61 // We want our singleton torn down after each test.
62 ShadowingAtExitManager at_exit_manager_
;
65 class MockDumpProvider
: public MemoryDumpProvider
{
67 MOCK_METHOD1(DumpInto
, bool(ProcessMemoryDump
* pmd
));
69 // DumpInto() override for the ActiveDumpProviderConsistency test,
70 bool DumpIntoAndCheckDumpProviderCurrentlyActive(ProcessMemoryDump
* pmd
) {
73 MemoryDumpManager::GetInstance()->dump_provider_currently_active());
77 const char* GetFriendlyName() const override
{ return "MockDumpProvider"; }
80 TEST_F(MemoryDumpManagerTest
, SingleDumper
) {
82 mdm_
->RegisterDumpProvider(&mdp
);
84 // Check that the dumper is not called if the memory category is not enabled.
85 EnableTracing("foo-and-bar-but-not-memory");
86 EXPECT_CALL(mdp
, DumpInto(_
)).Times(0);
87 mdm_
->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED
);
90 // Now repeat enabling the memory category and check that the dumper is
92 EnableTracing(kTraceCategory
);
93 EXPECT_CALL(mdp
, DumpInto(_
)).Times(3).WillRepeatedly(Return(true));
94 for (int i
= 0; i
< 3; ++i
)
95 mdm_
->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED
);
98 mdm_
->UnregisterDumpProvider(&mdp
);
100 // Finally check the unregister logic (no calls to the mdp after unregister).
101 EnableTracing(kTraceCategory
);
102 EXPECT_CALL(mdp
, DumpInto(_
)).Times(0);
103 mdm_
->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED
);
104 TraceLog::GetInstance()->SetDisabled();
107 TEST_F(MemoryDumpManagerTest
, UnregisterDumperWhileTracing
) {
108 MockDumpProvider mdp
;
109 mdm_
->RegisterDumpProvider(&mdp
);
111 EnableTracing(kTraceCategory
);
112 EXPECT_CALL(mdp
, DumpInto(_
)).Times(1).WillRepeatedly(Return(true));
113 mdm_
->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED
);
115 mdm_
->UnregisterDumpProvider(&mdp
);
116 EXPECT_CALL(mdp
, DumpInto(_
)).Times(0);
117 mdm_
->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED
);
122 TEST_F(MemoryDumpManagerTest
, MultipleDumpers
) {
123 MockDumpProvider mdp1
;
124 MockDumpProvider mdp2
;
127 mdm_
->RegisterDumpProvider(&mdp1
);
128 EnableTracing(kTraceCategory
);
129 EXPECT_CALL(mdp1
, DumpInto(_
)).Times(1).WillRepeatedly(Return(true));
130 EXPECT_CALL(mdp2
, DumpInto(_
)).Times(0);
131 mdm_
->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED
);
134 // Invert: enable mdp1 and disable mdp2.
135 mdm_
->UnregisterDumpProvider(&mdp1
);
136 mdm_
->RegisterDumpProvider(&mdp2
);
137 EnableTracing(kTraceCategory
);
138 EXPECT_CALL(mdp1
, DumpInto(_
)).Times(0);
139 EXPECT_CALL(mdp2
, DumpInto(_
)).Times(1).WillRepeatedly(Return(true));
140 mdm_
->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED
);
143 // Enable both mdp1 and mdp2.
144 mdm_
->RegisterDumpProvider(&mdp1
);
145 EnableTracing(kTraceCategory
);
146 EXPECT_CALL(mdp1
, DumpInto(_
)).Times(1).WillRepeatedly(Return(true));
147 EXPECT_CALL(mdp2
, DumpInto(_
)).Times(1).WillRepeatedly(Return(true));
148 mdm_
->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED
);
152 // Enable both dump providers, make mdp1 fail and assert that only mdp2 is
153 // invoked the 2nd time.
154 // FIXME(primiano): remove once crbug.com/461788 gets fixed.
155 TEST_F(MemoryDumpManagerTest
, DisableFailingDumpers
) {
156 MockDumpProvider mdp1
;
157 MockDumpProvider mdp2
;
159 mdm_
->RegisterDumpProvider(&mdp1
);
160 mdm_
->RegisterDumpProvider(&mdp2
);
161 EnableTracing(kTraceCategory
);
163 EXPECT_CALL(mdp1
, DumpInto(_
)).Times(1).WillRepeatedly(Return(false));
164 EXPECT_CALL(mdp2
, DumpInto(_
)).Times(1).WillRepeatedly(Return(true));
165 mdm_
->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED
);
167 EXPECT_CALL(mdp1
, DumpInto(_
)).Times(0);
168 EXPECT_CALL(mdp2
, DumpInto(_
)).Times(1).WillRepeatedly(Return(false));
169 mdm_
->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED
);
174 // TODO(primiano): remove once crbug.com/466121 gets fixed.
175 // Ascertains that calls to MDM::dump_provider_currently_active() actually
176 // returns the MemoryDumpProvider currently active during the DumpInto() call.
177 TEST_F(MemoryDumpManagerTest
, ActiveDumpProviderConsistency
) {
178 MockDumpProvider mdp1
;
179 MockDumpProvider mdp2
;
181 mdm_
->RegisterDumpProvider(&mdp1
);
182 mdm_
->RegisterDumpProvider(&mdp2
);
183 EnableTracing(kTraceCategory
);
184 EXPECT_CALL(mdp1
, DumpInto(_
))
186 .WillRepeatedly(Invoke(
188 &MockDumpProvider::DumpIntoAndCheckDumpProviderCurrentlyActive
));
189 EXPECT_CALL(mdp2
, DumpInto(_
))
191 .WillRepeatedly(Invoke(
193 &MockDumpProvider::DumpIntoAndCheckDumpProviderCurrentlyActive
));
194 mdm_
->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED
);
195 mdm_
->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED
);
199 } // namespace trace_event