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 class MemoryDumpManagerTest
: public testing::Test
{
21 void SetUp() override
{
22 mdm_
.reset(new MemoryDumpManager());
23 MemoryDumpManager::SetInstanceForTesting(mdm_
.get());
24 ASSERT_EQ(mdm_
, MemoryDumpManager::GetInstance());
25 MemoryDumpManager::GetInstance()->Initialize();
28 void TearDown() override
{
29 MemoryDumpManager::SetInstanceForTesting(nullptr);
31 TraceLog::DeleteForTesting();
35 const char* const kTraceCategory
= MemoryDumpManager::kTraceCategory
;
37 void EnableTracing(const char* category
) {
38 TraceLog::GetInstance()->SetEnabled(
39 CategoryFilter(category
), TraceLog::RECORDING_MODE
, TraceOptions());
42 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); }
44 scoped_ptr
<MemoryDumpManager
> mdm_
;
47 // We want our singleton torn down after each test.
48 ShadowingAtExitManager at_exit_manager_
;
51 class MockDumpProvider
: public MemoryDumpProvider
{
53 MOCK_METHOD1(DumpInto
, bool(ProcessMemoryDump
* pmd
));
55 // DumpInto() override for the ActiveDumpProviderConsistency test,
56 bool DumpIntoAndCheckDumpProviderCurrentlyActive(ProcessMemoryDump
* pmd
) {
59 MemoryDumpManager::GetInstance()->dump_provider_currently_active());
63 const char* GetFriendlyName() const override
{ return "MockDumpProvider"; }
66 TEST_F(MemoryDumpManagerTest
, SingleDumper
) {
68 mdm_
->RegisterDumpProvider(&mdp
);
70 // Check that the dumper is not called if the memory category is not enabled.
71 EnableTracing("foo-and-bar-but-not-memory");
72 EXPECT_CALL(mdp
, DumpInto(_
)).Times(0);
73 mdm_
->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED
);
76 // Now repeat enabling the memory category and check that the dumper is
78 EnableTracing(kTraceCategory
);
79 EXPECT_CALL(mdp
, DumpInto(_
)).Times(3).WillRepeatedly(Return(true));
80 for (int i
= 0; i
< 3; ++i
)
81 mdm_
->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED
);
84 mdm_
->UnregisterDumpProvider(&mdp
);
86 // Finally check the unregister logic (no calls to the mdp after unregister).
87 EnableTracing(kTraceCategory
);
88 EXPECT_CALL(mdp
, DumpInto(_
)).Times(0);
89 mdm_
->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED
);
90 TraceLog::GetInstance()->SetDisabled();
93 TEST_F(MemoryDumpManagerTest
, UnregisterDumperWhileTracing
) {
95 mdm_
->RegisterDumpProvider(&mdp
);
97 EnableTracing(kTraceCategory
);
98 EXPECT_CALL(mdp
, DumpInto(_
)).Times(1).WillRepeatedly(Return(true));
99 mdm_
->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED
);
101 mdm_
->UnregisterDumpProvider(&mdp
);
102 EXPECT_CALL(mdp
, DumpInto(_
)).Times(0);
103 mdm_
->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED
);
108 TEST_F(MemoryDumpManagerTest
, MultipleDumpers
) {
109 MockDumpProvider mdp1
;
110 MockDumpProvider mdp2
;
113 mdm_
->RegisterDumpProvider(&mdp1
);
114 EnableTracing(kTraceCategory
);
115 EXPECT_CALL(mdp1
, DumpInto(_
)).Times(1).WillRepeatedly(Return(true));
116 EXPECT_CALL(mdp2
, DumpInto(_
)).Times(0);
117 mdm_
->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED
);
120 // Invert: enable mdp1 and disable mdp2.
121 mdm_
->UnregisterDumpProvider(&mdp1
);
122 mdm_
->RegisterDumpProvider(&mdp2
);
123 EnableTracing(kTraceCategory
);
124 EXPECT_CALL(mdp1
, DumpInto(_
)).Times(0);
125 EXPECT_CALL(mdp2
, DumpInto(_
)).Times(1).WillRepeatedly(Return(true));
126 mdm_
->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED
);
129 // Enable both mdp1 and mdp2.
130 mdm_
->RegisterDumpProvider(&mdp1
);
131 EnableTracing(kTraceCategory
);
132 EXPECT_CALL(mdp1
, DumpInto(_
)).Times(1).WillRepeatedly(Return(true));
133 EXPECT_CALL(mdp2
, DumpInto(_
)).Times(1).WillRepeatedly(Return(true));
134 mdm_
->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED
);
138 // Enable both dump providers, make mdp1 fail and assert that only mdp2 is
139 // invoked the 2nd time.
140 // FIXME(primiano): remove once crbug.com/461788 gets fixed.
141 TEST_F(MemoryDumpManagerTest
, DisableFailingDumpers
) {
142 MockDumpProvider mdp1
;
143 MockDumpProvider mdp2
;
145 mdm_
->RegisterDumpProvider(&mdp1
);
146 mdm_
->RegisterDumpProvider(&mdp2
);
147 EnableTracing(kTraceCategory
);
149 EXPECT_CALL(mdp1
, DumpInto(_
)).Times(1).WillRepeatedly(Return(false));
150 EXPECT_CALL(mdp2
, DumpInto(_
)).Times(1).WillRepeatedly(Return(true));
151 mdm_
->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED
);
153 EXPECT_CALL(mdp1
, DumpInto(_
)).Times(0);
154 EXPECT_CALL(mdp2
, DumpInto(_
)).Times(1).WillRepeatedly(Return(false));
155 mdm_
->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED
);
160 // TODO(primiano): remove once crbug.com/466121 gets fixed.
161 // Ascertains that calls to MDM::dump_provider_currently_active() actually
162 // returns the MemoryDumpProvider currently active during the DumpInto() call.
163 TEST_F(MemoryDumpManagerTest
, ActiveDumpProviderConsistency
) {
164 MockDumpProvider mdp1
;
165 MockDumpProvider mdp2
;
167 mdm_
->RegisterDumpProvider(&mdp1
);
168 mdm_
->RegisterDumpProvider(&mdp2
);
169 EnableTracing(kTraceCategory
);
170 EXPECT_CALL(mdp1
, DumpInto(_
))
172 .WillRepeatedly(Invoke(
174 &MockDumpProvider::DumpIntoAndCheckDumpProviderCurrentlyActive
));
175 EXPECT_CALL(mdp2
, DumpInto(_
))
177 .WillRepeatedly(Invoke(
179 &MockDumpProvider::DumpIntoAndCheckDumpProviderCurrentlyActive
));
180 mdm_
->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED
);
181 mdm_
->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED
);
185 } // namespace trace_event