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

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

Issue 1124763003: Update from https://crrev.com/327068 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: update nacl, buildtools, fix display_change_notifier_unittest Created 5 years, 7 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 "base/bind_helpers.h"
8 #include "base/memory/scoped_vector.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/run_loop.h"
11 #include "base/threading/thread.h"
7 #include "base/trace_event/memory_dump_provider.h" 12 #include "base/trace_event/memory_dump_provider.h"
8 #include "base/trace_event/process_memory_dump.h" 13 #include "base/trace_event/process_memory_dump.h"
9 #include "testing/gmock/include/gmock/gmock.h" 14 #include "testing/gmock/include/gmock/gmock.h"
10 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
11 16
12 using testing::_; 17 using testing::_;
13 using testing::Invoke; 18 using testing::Invoke;
14 using testing::Return; 19 using testing::Return;
15 20
16 namespace base { 21 namespace base {
17 namespace trace_event { 22 namespace trace_event {
18 23
24 // Testing MemoryDumpManagerDelegate which short-circuits dump requests locally
25 // instead of performing IPC dances.
26 class MemoryDumpManagerDelegateForTesting : public MemoryDumpManagerDelegate {
27 public:
28 void RequestGlobalMemoryDump(
29 const base::trace_event::MemoryDumpRequestArgs& args,
30 const MemoryDumpCallback& callback) override {
31 CreateProcessDump(args, callback);
32 }
33
34 bool IsCoordinatorProcess() const override { return false; }
35 };
36
19 class MemoryDumpManagerTest : public testing::Test { 37 class MemoryDumpManagerTest : public testing::Test {
20 public: 38 public:
21 void SetUp() override { 39 void SetUp() override {
40 message_loop_.reset(new MessageLoop());
22 mdm_.reset(new MemoryDumpManager()); 41 mdm_.reset(new MemoryDumpManager());
23 MemoryDumpManager::SetInstanceForTesting(mdm_.get()); 42 MemoryDumpManager::SetInstanceForTesting(mdm_.get());
24 ASSERT_EQ(mdm_, MemoryDumpManager::GetInstance()); 43 ASSERT_EQ(mdm_, MemoryDumpManager::GetInstance());
25 MemoryDumpManager::GetInstance()->Initialize(); 44 MemoryDumpManager::GetInstance()->Initialize();
45 MemoryDumpManager::GetInstance()->SetDelegate(&delegate_);
26 } 46 }
27 47
28 void TearDown() override { 48 void TearDown() override {
29 MemoryDumpManager::SetInstanceForTesting(nullptr); 49 MemoryDumpManager::SetInstanceForTesting(nullptr);
30 mdm_.reset(); 50 mdm_.reset();
51 message_loop_.reset();
31 TraceLog::DeleteForTesting(); 52 TraceLog::DeleteForTesting();
32 } 53 }
33 54
55 void DumpCallbackAdapter(scoped_refptr<SingleThreadTaskRunner> task_runner,
56 Closure closure,
57 uint64 dump_guid,
58 bool success) {
59 task_runner->PostTask(FROM_HERE, closure);
60 }
61
34 protected: 62 protected:
35 const char* const kTraceCategory = MemoryDumpManager::kTraceCategory; 63 const char* kTraceCategory = MemoryDumpManager::kTraceCategoryForTesting;
36 64
37 void EnableTracing(const char* category) { 65 void EnableTracing(const char* category) {
38 TraceLog::GetInstance()->SetEnabled( 66 TraceLog::GetInstance()->SetEnabled(
39 CategoryFilter(category), TraceLog::RECORDING_MODE, TraceOptions()); 67 CategoryFilter(category), TraceLog::RECORDING_MODE, TraceOptions());
40 } 68 }
41 69
42 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } 70 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); }
43 71
44 scoped_ptr<MemoryDumpManager> mdm_; 72 scoped_ptr<MemoryDumpManager> mdm_;
45 73
46 private: 74 private:
75 scoped_ptr<MessageLoop> message_loop_;
76 MemoryDumpManagerDelegateForTesting delegate_;
77
47 // We want our singleton torn down after each test. 78 // We want our singleton torn down after each test.
48 ShadowingAtExitManager at_exit_manager_; 79 ShadowingAtExitManager at_exit_manager_;
49 }; 80 };
50 81
51 class MockDumpProvider : public MemoryDumpProvider { 82 class MockDumpProvider : public MemoryDumpProvider {
52 public: 83 public:
84 MockDumpProvider() {}
85
86 explicit MockDumpProvider(
87 const scoped_refptr<SingleThreadTaskRunner>& task_runner)
88 : MemoryDumpProvider(task_runner) {}
89
90 // Ctor for the SharedSessionState test.
91 explicit MockDumpProvider(const std::string& id) {
92 DeclareAllocatorAttribute("allocator" + id, "attr" + id, "type" + id);
93 }
94
53 MOCK_METHOD1(DumpInto, bool(ProcessMemoryDump* pmd)); 95 MOCK_METHOD1(DumpInto, bool(ProcessMemoryDump* pmd));
54 96
55 // DumpInto() override for the ActiveDumpProviderConsistency test, 97 // DumpInto() override for the ActiveDumpProviderConsistency test.
56 bool DumpIntoAndCheckDumpProviderCurrentlyActive(ProcessMemoryDump* pmd) { 98 bool DumpIntoAndCheckDumpProviderCurrentlyActive(ProcessMemoryDump* pmd) {
57 EXPECT_EQ( 99 EXPECT_EQ(
58 this, 100 this,
59 MemoryDumpManager::GetInstance()->dump_provider_currently_active()); 101 MemoryDumpManager::GetInstance()->dump_provider_currently_active());
60 return true; 102 return true;
61 } 103 }
62 104
105 // DumpInto() override for the RespectTaskRunnerAffinity test.
106 bool DumpIntoAndCheckTaskRunner(ProcessMemoryDump* pmd) {
107 EXPECT_TRUE(task_runner()->RunsTasksOnCurrentThread());
108 return true;
109 }
110
111 // DumpInto() override for the SharedSessionState test.
112 bool DumpIntoAndCheckSessionState(ProcessMemoryDump* pmd) {
113 EXPECT_TRUE(pmd->session_state());
114 const auto& attrs_type_info =
115 pmd->session_state()->allocators_attributes_type_info;
116 EXPECT_TRUE(attrs_type_info.Exists("allocator1", "attr1"));
117 EXPECT_TRUE(attrs_type_info.Exists("allocator2", "attr2"));
118 return true;
119 }
120
63 const char* GetFriendlyName() const override { return "MockDumpProvider"; } 121 const char* GetFriendlyName() const override { return "MockDumpProvider"; }
64 }; 122 };
65 123
66 TEST_F(MemoryDumpManagerTest, SingleDumper) { 124 TEST_F(MemoryDumpManagerTest, SingleDumper) {
67 MockDumpProvider mdp; 125 MockDumpProvider mdp;
68 mdm_->RegisterDumpProvider(&mdp); 126 mdm_->RegisterDumpProvider(&mdp);
69 127
70 // Check that the dumper is not called if the memory category is not enabled. 128 // Check that the dumper is not called if the memory category is not enabled.
71 EnableTracing("foo-and-bar-but-not-memory"); 129 EnableTracing("foo-and-bar-but-not-memory");
72 EXPECT_CALL(mdp, DumpInto(_)).Times(0); 130 EXPECT_CALL(mdp, DumpInto(_)).Times(0);
73 mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED); 131 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
74 DisableTracing(); 132 DisableTracing();
75 133
76 // Now repeat enabling the memory category and check that the dumper is 134 // Now repeat enabling the memory category and check that the dumper is
77 // invoked this time. 135 // invoked this time.
78 EnableTracing(kTraceCategory); 136 EnableTracing(kTraceCategory);
79 EXPECT_CALL(mdp, DumpInto(_)).Times(3).WillRepeatedly(Return(true)); 137 EXPECT_CALL(mdp, DumpInto(_)).Times(3).WillRepeatedly(Return(true));
80 for (int i = 0; i < 3; ++i) 138 for (int i = 0; i < 3; ++i)
81 mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED); 139 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
82 DisableTracing(); 140 DisableTracing();
83 141
84 mdm_->UnregisterDumpProvider(&mdp); 142 mdm_->UnregisterDumpProvider(&mdp);
85 143
86 // Finally check the unregister logic (no calls to the mdp after unregister). 144 // Finally check the unregister logic (no calls to the mdp after unregister).
87 EnableTracing(kTraceCategory); 145 EnableTracing(kTraceCategory);
88 EXPECT_CALL(mdp, DumpInto(_)).Times(0); 146 EXPECT_CALL(mdp, DumpInto(_)).Times(0);
89 mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED); 147 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
90 TraceLog::GetInstance()->SetDisabled(); 148 TraceLog::GetInstance()->SetDisabled();
91 } 149 }
92 150
93 TEST_F(MemoryDumpManagerTest, UnregisterDumperWhileTracing) { 151 TEST_F(MemoryDumpManagerTest, SharedSessionState) {
94 MockDumpProvider mdp; 152 MockDumpProvider mdp1("1"); // Will declare an allocator property "attr1".
95 mdm_->RegisterDumpProvider(&mdp); 153 MockDumpProvider mdp2("2"); // Will declare an allocator property "attr2".
154 mdm_->RegisterDumpProvider(&mdp1);
155 mdm_->RegisterDumpProvider(&mdp2);
96 156
97 EnableTracing(kTraceCategory); 157 EnableTracing(kTraceCategory);
98 EXPECT_CALL(mdp, DumpInto(_)).Times(1).WillRepeatedly(Return(true)); 158 EXPECT_CALL(mdp1, DumpInto(_)).Times(2).WillRepeatedly(
99 mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED); 159 Invoke(&mdp1, &MockDumpProvider::DumpIntoAndCheckSessionState));
160 EXPECT_CALL(mdp2, DumpInto(_)).Times(2).WillRepeatedly(
161 Invoke(&mdp2, &MockDumpProvider::DumpIntoAndCheckSessionState));
100 162
101 mdm_->UnregisterDumpProvider(&mdp); 163 for (int i = 0; i < 2; ++i)
102 EXPECT_CALL(mdp, DumpInto(_)).Times(0); 164 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
103 mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED);
104 165
105 DisableTracing(); 166 DisableTracing();
106 } 167 }
107 168
108 TEST_F(MemoryDumpManagerTest, MultipleDumpers) { 169 TEST_F(MemoryDumpManagerTest, MultipleDumpers) {
109 MockDumpProvider mdp1; 170 MockDumpProvider mdp1;
110 MockDumpProvider mdp2; 171 MockDumpProvider mdp2;
111 172
112 // Enable only mdp1. 173 // Enable only mdp1.
113 mdm_->RegisterDumpProvider(&mdp1); 174 mdm_->RegisterDumpProvider(&mdp1);
114 EnableTracing(kTraceCategory); 175 EnableTracing(kTraceCategory);
115 EXPECT_CALL(mdp1, DumpInto(_)).Times(1).WillRepeatedly(Return(true)); 176 EXPECT_CALL(mdp1, DumpInto(_)).Times(1).WillRepeatedly(Return(true));
116 EXPECT_CALL(mdp2, DumpInto(_)).Times(0); 177 EXPECT_CALL(mdp2, DumpInto(_)).Times(0);
117 mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED); 178 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
118 DisableTracing(); 179 DisableTracing();
119 180
120 // Invert: enable mdp1 and disable mdp2. 181 // Invert: enable mdp1 and disable mdp2.
121 mdm_->UnregisterDumpProvider(&mdp1); 182 mdm_->UnregisterDumpProvider(&mdp1);
122 mdm_->RegisterDumpProvider(&mdp2); 183 mdm_->RegisterDumpProvider(&mdp2);
123 EnableTracing(kTraceCategory); 184 EnableTracing(kTraceCategory);
124 EXPECT_CALL(mdp1, DumpInto(_)).Times(0); 185 EXPECT_CALL(mdp1, DumpInto(_)).Times(0);
125 EXPECT_CALL(mdp2, DumpInto(_)).Times(1).WillRepeatedly(Return(true)); 186 EXPECT_CALL(mdp2, DumpInto(_)).Times(1).WillRepeatedly(Return(true));
126 mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED); 187 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
127 DisableTracing(); 188 DisableTracing();
128 189
129 // Enable both mdp1 and mdp2. 190 // Enable both mdp1 and mdp2.
130 mdm_->RegisterDumpProvider(&mdp1); 191 mdm_->RegisterDumpProvider(&mdp1);
131 EnableTracing(kTraceCategory); 192 EnableTracing(kTraceCategory);
132 EXPECT_CALL(mdp1, DumpInto(_)).Times(1).WillRepeatedly(Return(true)); 193 EXPECT_CALL(mdp1, DumpInto(_)).Times(1).WillRepeatedly(Return(true));
133 EXPECT_CALL(mdp2, DumpInto(_)).Times(1).WillRepeatedly(Return(true)); 194 EXPECT_CALL(mdp2, DumpInto(_)).Times(1).WillRepeatedly(Return(true));
134 mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED); 195 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
135 DisableTracing(); 196 DisableTracing();
136 } 197 }
137 198
199 // Checks that the MemoryDumpManager respects the thread affinity when a
200 // MemoryDumpProvider specifies a task_runner(). The test starts creating 8
201 // threads and registering a MemoryDumpProvider on each of them. At each
202 // iteration, one thread is removed, to check the live unregistration logic.
203 TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) {
204 const uint32 kNumInitialThreads = 8;
205
206 ScopedVector<Thread> threads;
207 ScopedVector<MockDumpProvider> mdps;
208
209 // Create the threads and setup the expectations. Given that at each iteration
210 // we will pop out one thread/MemoryDumpProvider, each MDP is supposed to be
211 // invoked a number of times equal to its index.
212 for (uint32 i = kNumInitialThreads; i > 0; --i) {
213 threads.push_back(new Thread("test thread"));
214 threads.back()->Start();
215 mdps.push_back(new MockDumpProvider(threads.back()->task_runner()));
216 MockDumpProvider* mdp = mdps.back();
217 mdm_->RegisterDumpProvider(mdp);
218 EXPECT_CALL(*mdp, DumpInto(_))
219 .Times(i)
220 .WillRepeatedly(
221 Invoke(mdp, &MockDumpProvider::DumpIntoAndCheckTaskRunner));
222 }
223
224 EnableTracing(kTraceCategory);
225
226 while (!threads.empty()) {
227 {
228 RunLoop run_loop;
229 MemoryDumpCallback callback =
230 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this),
231 MessageLoop::current()->task_runner(), run_loop.QuitClosure());
232 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, callback);
233 // This nested message loop (|run_loop|) will be quit if and only if
234 // the RequestGlobalDump callback is invoked.
235 run_loop.Run();
236 }
237
238 // Unregister a MDP and destroy one thread at each iteration to check the
239 // live unregistration logic. The unregistration needs to happen on the same
240 // thread the MDP belongs to.
241 {
242 RunLoop run_loop;
243 Closure unregistration =
244 Bind(&MemoryDumpManager::UnregisterDumpProvider,
245 Unretained(mdm_.get()), Unretained(mdps.back()));
246 threads.back()->task_runner()->PostTaskAndReply(FROM_HERE, unregistration,
247 run_loop.QuitClosure());
248 run_loop.Run();
249 }
250 mdps.pop_back();
251 threads.back()->Stop();
252 threads.pop_back();
253 }
254
255 DisableTracing();
256 }
257
138 // Enable both dump providers, make mdp1 fail and assert that only mdp2 is 258 // Enable both dump providers, make mdp1 fail and assert that only mdp2 is
139 // invoked the 2nd time. 259 // invoked the 2nd time.
140 // FIXME(primiano): remove once crbug.com/461788 gets fixed. 260 // FIXME(primiano): remove once crbug.com/461788 gets fixed.
141 TEST_F(MemoryDumpManagerTest, DisableFailingDumpers) { 261 TEST_F(MemoryDumpManagerTest, DisableFailingDumpers) {
142 MockDumpProvider mdp1; 262 MockDumpProvider mdp1;
143 MockDumpProvider mdp2; 263 MockDumpProvider mdp2;
144 264
145 mdm_->RegisterDumpProvider(&mdp1); 265 mdm_->RegisterDumpProvider(&mdp1);
146 mdm_->RegisterDumpProvider(&mdp2); 266 mdm_->RegisterDumpProvider(&mdp2);
147 EnableTracing(kTraceCategory); 267 EnableTracing(kTraceCategory);
148 268
149 EXPECT_CALL(mdp1, DumpInto(_)).Times(1).WillRepeatedly(Return(false)); 269 EXPECT_CALL(mdp1, DumpInto(_)).Times(1).WillRepeatedly(Return(false));
150 EXPECT_CALL(mdp2, DumpInto(_)).Times(1).WillRepeatedly(Return(true)); 270 EXPECT_CALL(mdp2, DumpInto(_)).Times(1).WillRepeatedly(Return(true));
151 mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED); 271 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
152 272
153 EXPECT_CALL(mdp1, DumpInto(_)).Times(0); 273 EXPECT_CALL(mdp1, DumpInto(_)).Times(0);
154 EXPECT_CALL(mdp2, DumpInto(_)).Times(1).WillRepeatedly(Return(false)); 274 EXPECT_CALL(mdp2, DumpInto(_)).Times(1).WillRepeatedly(Return(false));
155 mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED); 275 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
156 276
157 DisableTracing(); 277 DisableTracing();
158 } 278 }
159 279
160 // TODO(primiano): remove once crbug.com/466121 gets fixed. 280 // TODO(primiano): remove once crbug.com/466121 gets fixed.
161 // Ascertains that calls to MDM::dump_provider_currently_active() actually 281 // Ascertains that calls to MDM::dump_provider_currently_active() actually
162 // returns the MemoryDumpProvider currently active during the DumpInto() call. 282 // returns the MemoryDumpProvider currently active during the DumpInto() call.
163 TEST_F(MemoryDumpManagerTest, ActiveDumpProviderConsistency) { 283 TEST_F(MemoryDumpManagerTest, ActiveDumpProviderConsistency) {
164 MockDumpProvider mdp1; 284 MockDumpProvider mdp1;
165 MockDumpProvider mdp2; 285 MockDumpProvider mdp2;
166 286
167 mdm_->RegisterDumpProvider(&mdp1); 287 mdm_->RegisterDumpProvider(&mdp1);
168 mdm_->RegisterDumpProvider(&mdp2); 288 mdm_->RegisterDumpProvider(&mdp2);
169 EnableTracing(kTraceCategory); 289 EnableTracing(kTraceCategory);
170 EXPECT_CALL(mdp1, DumpInto(_)) 290 EXPECT_CALL(mdp1, DumpInto(_))
171 .Times(2) 291 .Times(2)
172 .WillRepeatedly(Invoke( 292 .WillRepeatedly(Invoke(
173 &mdp1, 293 &mdp1,
174 &MockDumpProvider::DumpIntoAndCheckDumpProviderCurrentlyActive)); 294 &MockDumpProvider::DumpIntoAndCheckDumpProviderCurrentlyActive));
175 EXPECT_CALL(mdp2, DumpInto(_)) 295 EXPECT_CALL(mdp2, DumpInto(_))
176 .Times(2) 296 .Times(2)
177 .WillRepeatedly(Invoke( 297 .WillRepeatedly(Invoke(
178 &mdp2, 298 &mdp2,
179 &MockDumpProvider::DumpIntoAndCheckDumpProviderCurrentlyActive)); 299 &MockDumpProvider::DumpIntoAndCheckDumpProviderCurrentlyActive));
180 mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED); 300 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
181 mdm_->RequestDumpPoint(DumpPointType::EXPLICITLY_TRIGGERED); 301 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED);
182 DisableTracing(); 302 DisableTracing();
183 } 303 }
184 304
185 } // namespace trace_event 305 } // namespace trace_event
186 } // namespace base 306 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698