OLD | NEW |
---|---|
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" | 7 #include "base/bind_helpers.h" |
8 #include "base/memory/scoped_vector.h" | 8 #include "base/memory/scoped_vector.h" |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
11 #include "base/test/test_io_thread.h" | 11 #include "base/test/test_io_thread.h" |
12 #include "base/thread_task_runner_handle.h" | 12 #include "base/thread_task_runner_handle.h" |
13 #include "base/threading/thread.h" | 13 #include "base/threading/thread.h" |
14 #include "base/trace_event/memory_dump_provider.h" | 14 #include "base/trace_event/memory_dump_provider.h" |
15 #include "base/trace_event/process_memory_dump.h" | 15 #include "base/trace_event/process_memory_dump.h" |
16 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
18 | 18 |
19 using testing::_; | 19 using testing::_; |
20 using testing::AtMost; | 20 using testing::AtMost; |
21 using testing::Between; | 21 using testing::Between; |
22 using testing::Invoke; | 22 using testing::Invoke; |
23 using testing::Return; | 23 using testing::Return; |
24 | 24 |
25 namespace base { | 25 namespace base { |
26 namespace trace_event { | 26 namespace trace_event { |
27 namespace { | 27 namespace { |
28 MemoryDumpArgs high_detail_args = {MemoryDumpArgs::LevelOfDetail::HIGH}; | 28 MemoryDumpArgs g_high_detail_args = {MemoryDumpArgs::LevelOfDetail::HIGH}; |
29 MemoryDumpArgs low_detail_args = {MemoryDumpArgs::LevelOfDetail::LOW}; | 29 MemoryDumpArgs g_low_detail_args = {MemoryDumpArgs::LevelOfDetail::LOW}; |
30 } | 30 } |
31 | 31 |
32 // Testing MemoryDumpManagerDelegate which short-circuits dump requests locally | 32 // Testing MemoryDumpManagerDelegate which short-circuits dump requests locally |
33 // instead of performing IPC dances. | 33 // instead of performing IPC dances. |
34 class MemoryDumpManagerDelegateForTesting : public MemoryDumpManagerDelegate { | 34 class MemoryDumpManagerDelegateForTesting : public MemoryDumpManagerDelegate { |
35 public: | 35 public: |
36 void RequestGlobalMemoryDump(const MemoryDumpRequestArgs& args, | 36 void RequestGlobalMemoryDump(const MemoryDumpRequestArgs& args, |
37 const MemoryDumpCallback& callback) override { | 37 const MemoryDumpCallback& callback) override { |
38 CreateProcessDump(args, callback); | 38 CreateProcessDump(args, callback); |
39 } | 39 } |
40 | 40 |
41 bool IsCoordinatorProcess() const override { return false; } | 41 bool IsCoordinatorProcess() const override { return false; } |
42 uint64 GetTracingProcessId() const override { | 42 uint64 GetTracingProcessId() const override { |
43 return MemoryDumpManager::kInvalidTracingProcessId; | 43 return MemoryDumpManager::kInvalidTracingProcessId; |
44 } | 44 } |
45 }; | 45 }; |
46 | 46 |
47 class MemoryDumpManagerDelegateForPeriodicDumpTest | |
48 : public MemoryDumpManagerDelegateForTesting { | |
Primiano Tucci (use gerrit)
2015/09/03 22:44:51
Ah also why doesn't this inherit just from MemoryD
ssid
2015/09/04 10:43:47
Because the delegate objects are owned by MemoryDu
| |
49 public: | |
50 MemoryDumpManagerDelegateForPeriodicDumpTest(int dump_calls_to_quit, | |
51 int expected_high_dump_ratio, | |
52 base::Closure quit_closure) | |
53 : dump_call_count_(0), | |
54 dump_calls_to_quit_(dump_calls_to_quit), | |
55 expected_high_dump_ratio_(expected_high_dump_ratio), | |
56 quit_closure_(quit_closure) {} | |
57 | |
58 ~MemoryDumpManagerDelegateForPeriodicDumpTest() override {} | |
59 | |
60 MOCK_METHOD2(RequestGlobalMemoryDump, | |
61 void(const MemoryDumpRequestArgs& args, | |
62 const MemoryDumpCallback& callback)); | |
63 | |
64 // RequestGlobalMemoryDump override for SchedulePeriodicDumpsFromTraceConfig | |
65 // test. | |
66 void RequestGlobalMemoryDump_QuitAfterCalls( | |
67 const MemoryDumpRequestArgs& args, | |
68 const MemoryDumpCallback& callback) { | |
69 CreateProcessDump(args, callback); | |
Primiano Tucci (use gerrit)
2015/09/03 22:44:13
No need to create any process dump
ssid
2015/09/04 10:43:47
Done.
| |
70 if (dump_call_count_ % expected_high_dump_ratio_ == 0) { | |
Primiano Tucci (use gerrit)
2015/09/03 22:44:13
I don't think you need all this logic here. You ca
ssid
2015/09/04 10:43:47
No, I cannot do that. I can define only one expect
| |
71 EXPECT_EQ(MemoryDumpArgs::LevelOfDetail::HIGH, | |
72 args.dump_args.level_of_detail); | |
73 } else { | |
74 EXPECT_EQ(MemoryDumpArgs::LevelOfDetail::LOW, | |
75 args.dump_args.level_of_detail); | |
76 } | |
77 if (++dump_call_count_ == dump_calls_to_quit_) { | |
78 TraceLog::GetInstance()->SetDisabled(); | |
79 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, quit_closure_); | |
80 } | |
81 } | |
82 | |
83 bool IsCoordinatorProcess() const override { return true; } | |
84 | |
85 private: | |
86 int dump_call_count_; | |
87 int dump_calls_to_quit_; | |
88 int expected_high_dump_ratio_; | |
89 base::Closure quit_closure_; | |
90 }; | |
91 | |
47 class MemoryDumpManagerTest : public testing::Test { | 92 class MemoryDumpManagerTest : public testing::Test { |
48 public: | 93 public: |
49 void SetUp() override { | 94 void SetUp() override { |
50 last_callback_success_ = false; | 95 last_callback_success_ = false; |
51 message_loop_.reset(new MessageLoop()); | 96 message_loop_.reset(new MessageLoop()); |
52 mdm_.reset(new MemoryDumpManager()); | 97 mdm_.reset(new MemoryDumpManager()); |
53 MemoryDumpManager::SetInstanceForTesting(mdm_.get()); | 98 MemoryDumpManager::SetInstanceForTesting(mdm_.get()); |
54 ASSERT_EQ(mdm_, MemoryDumpManager::GetInstance()); | 99 ASSERT_EQ(mdm_, MemoryDumpManager::GetInstance()); |
55 MemoryDumpManager::GetInstance()->Initialize(); | 100 MemoryDumpManager::GetInstance()->Initialize(); |
56 MemoryDumpManager::GetInstance()->SetDelegate(&delegate_); | |
57 } | 101 } |
58 | 102 |
59 void TearDown() override { | 103 void TearDown() override { |
60 MemoryDumpManager::SetInstanceForTesting(nullptr); | 104 MemoryDumpManager::SetInstanceForTesting(nullptr); |
61 mdm_.reset(); | 105 mdm_.reset(); |
62 message_loop_.reset(); | 106 message_loop_.reset(); |
63 TraceLog::DeleteForTesting(); | 107 TraceLog::DeleteForTesting(); |
64 } | 108 } |
65 | 109 |
66 void DumpCallbackAdapter(scoped_refptr<SingleThreadTaskRunner> task_runner, | 110 void DumpCallbackAdapter(scoped_refptr<SingleThreadTaskRunner> task_runner, |
67 Closure closure, | 111 Closure closure, |
68 uint64 dump_guid, | 112 uint64 dump_guid, |
69 bool success) { | 113 bool success) { |
70 last_callback_success_ = success; | 114 last_callback_success_ = success; |
71 task_runner->PostTask(FROM_HERE, closure); | 115 task_runner->PostTask(FROM_HERE, closure); |
72 } | 116 } |
73 | 117 |
74 protected: | 118 protected: |
119 // This enalbes tracing using the legacy category filter string. | |
75 void EnableTracing(const char* category) { | 120 void EnableTracing(const char* category) { |
121 delegate_.reset(new MemoryDumpManagerDelegateForTesting()); | |
122 MemoryDumpManager::GetInstance()->SetDelegate(delegate_.get()); | |
76 TraceLog::GetInstance()->SetEnabled( | 123 TraceLog::GetInstance()->SetEnabled( |
77 TraceConfig(category, ""), TraceLog::RECORDING_MODE); | 124 TraceConfig(category, ""), TraceLog::RECORDING_MODE); |
78 } | 125 } |
79 | 126 |
127 void SetDelegate(scoped_ptr<MemoryDumpManagerDelegateForTesting> delegate) { | |
128 delegate_ = delegate.Pass(); | |
129 MemoryDumpManager::GetInstance()->SetDelegate(delegate_.get()); | |
130 } | |
131 | |
132 void EnableTracingWithTraceConfig(const char* trace_config) { | |
133 DCHECK(delegate_); | |
134 TraceConfig tc(trace_config); | |
135 TraceLog::GetInstance()->SetEnabled(tc, TraceLog::RECORDING_MODE); | |
136 } | |
137 | |
80 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } | 138 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } |
81 | 139 |
82 scoped_ptr<MemoryDumpManager> mdm_; | 140 scoped_ptr<MemoryDumpManager> mdm_; |
83 bool last_callback_success_; | 141 bool last_callback_success_; |
142 scoped_ptr<MemoryDumpManagerDelegateForTesting> delegate_; | |
84 | 143 |
85 private: | 144 private: |
86 scoped_ptr<MessageLoop> message_loop_; | 145 scoped_ptr<MessageLoop> message_loop_; |
87 MemoryDumpManagerDelegateForTesting delegate_; | |
88 | 146 |
89 // We want our singleton torn down after each test. | 147 // We want our singleton torn down after each test. |
90 ShadowingAtExitManager at_exit_manager_; | 148 ShadowingAtExitManager at_exit_manager_; |
91 }; | 149 }; |
92 | 150 |
93 class MockDumpProvider : public MemoryDumpProvider { | 151 class MockDumpProvider : public MemoryDumpProvider { |
94 public: | 152 public: |
95 MockDumpProvider() | 153 MockDumpProvider() |
96 : dump_provider_to_register_or_unregister(nullptr), | 154 : dump_provider_to_register_or_unregister(nullptr), |
97 last_session_state_(nullptr), | 155 last_session_state_(nullptr), |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
163 }; | 221 }; |
164 | 222 |
165 TEST_F(MemoryDumpManagerTest, SingleDumper) { | 223 TEST_F(MemoryDumpManagerTest, SingleDumper) { |
166 MockDumpProvider mdp; | 224 MockDumpProvider mdp; |
167 mdm_->RegisterDumpProvider(&mdp); | 225 mdm_->RegisterDumpProvider(&mdp); |
168 | 226 |
169 // Check that the dumper is not called if the memory category is not enabled. | 227 // Check that the dumper is not called if the memory category is not enabled. |
170 EnableTracing("foo-and-bar-but-not-memory"); | 228 EnableTracing("foo-and-bar-but-not-memory"); |
171 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); | 229 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
172 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 230 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
173 high_detail_args); | 231 g_high_detail_args); |
174 DisableTracing(); | 232 DisableTracing(); |
175 | 233 |
176 // Now repeat enabling the memory category and check that the dumper is | 234 // Now repeat enabling the memory category and check that the dumper is |
177 // invoked this time. | 235 // invoked this time. |
178 EnableTracing(MemoryDumpManager::kTraceCategory); | 236 EnableTracing(MemoryDumpManager::kTraceCategory); |
179 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true)); | 237 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true)); |
180 for (int i = 0; i < 3; ++i) | 238 for (int i = 0; i < 3; ++i) |
181 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 239 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
182 high_detail_args); | 240 g_high_detail_args); |
183 DisableTracing(); | 241 DisableTracing(); |
184 | 242 |
185 mdm_->UnregisterDumpProvider(&mdp); | 243 mdm_->UnregisterDumpProvider(&mdp); |
186 | 244 |
187 // Finally check the unregister logic (no calls to the mdp after unregister). | 245 // Finally check the unregister logic (no calls to the mdp after unregister). |
188 EnableTracing(MemoryDumpManager::kTraceCategory); | 246 EnableTracing(MemoryDumpManager::kTraceCategory); |
189 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); | 247 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
190 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 248 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
191 high_detail_args); | 249 g_high_detail_args); |
192 TraceLog::GetInstance()->SetDisabled(); | 250 TraceLog::GetInstance()->SetDisabled(); |
193 } | 251 } |
194 | 252 |
195 TEST_F(MemoryDumpManagerTest, CheckMemoryDumpArgs) { | 253 TEST_F(MemoryDumpManagerTest, CheckMemoryDumpArgs) { |
196 // Check that requesting dumps with high level of detail actually propagates | 254 // Check that requesting dumps with high level of detail actually propagates |
197 // to OnMemoryDump() call on dump providers. | 255 // to OnMemoryDump() call on dump providers. |
198 MockDumpProvider mdp_high_detail(MemoryDumpArgs::LevelOfDetail::HIGH); | 256 MockDumpProvider mdp_high_detail(MemoryDumpArgs::LevelOfDetail::HIGH); |
199 mdm_->RegisterDumpProvider(&mdp_high_detail); | 257 mdm_->RegisterDumpProvider(&mdp_high_detail); |
200 | 258 |
201 EnableTracing(MemoryDumpManager::kTraceCategory); | 259 EnableTracing(MemoryDumpManager::kTraceCategory); |
202 EXPECT_CALL(mdp_high_detail, OnMemoryDump(_, _)) | 260 EXPECT_CALL(mdp_high_detail, OnMemoryDump(_, _)) |
203 .Times(1) | 261 .Times(1) |
204 .WillRepeatedly( | 262 .WillRepeatedly( |
205 Invoke(&mdp_high_detail, | 263 Invoke(&mdp_high_detail, |
206 &MockDumpProvider::OnMemoryDump_CheckMemoryDumpArgs)); | 264 &MockDumpProvider::OnMemoryDump_CheckMemoryDumpArgs)); |
207 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 265 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
208 high_detail_args); | 266 g_high_detail_args); |
209 DisableTracing(); | 267 DisableTracing(); |
210 mdm_->UnregisterDumpProvider(&mdp_high_detail); | 268 mdm_->UnregisterDumpProvider(&mdp_high_detail); |
211 | 269 |
212 // Check that requesting dumps with low level of detail actually propagates to | 270 // Check that requesting dumps with low level of detail actually propagates to |
213 // OnMemoryDump() call on dump providers. | 271 // OnMemoryDump() call on dump providers. |
214 MockDumpProvider mdp_low_detail(MemoryDumpArgs::LevelOfDetail::LOW); | 272 MockDumpProvider mdp_low_detail(MemoryDumpArgs::LevelOfDetail::LOW); |
215 mdm_->RegisterDumpProvider(&mdp_low_detail); | 273 mdm_->RegisterDumpProvider(&mdp_low_detail); |
216 | 274 |
217 EnableTracing(MemoryDumpManager::kTraceCategory); | 275 EnableTracing(MemoryDumpManager::kTraceCategory); |
218 EXPECT_CALL(mdp_low_detail, OnMemoryDump(_, _)) | 276 EXPECT_CALL(mdp_low_detail, OnMemoryDump(_, _)) |
219 .Times(1) | 277 .Times(1) |
220 .WillRepeatedly( | 278 .WillRepeatedly( |
221 Invoke(&mdp_low_detail, | 279 Invoke(&mdp_low_detail, |
222 &MockDumpProvider::OnMemoryDump_CheckMemoryDumpArgs)); | 280 &MockDumpProvider::OnMemoryDump_CheckMemoryDumpArgs)); |
223 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 281 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
224 low_detail_args); | 282 g_low_detail_args); |
225 DisableTracing(); | 283 DisableTracing(); |
226 mdm_->UnregisterDumpProvider(&mdp_low_detail); | 284 mdm_->UnregisterDumpProvider(&mdp_low_detail); |
227 } | 285 } |
228 | 286 |
229 TEST_F(MemoryDumpManagerTest, SharedSessionState) { | 287 TEST_F(MemoryDumpManagerTest, SharedSessionState) { |
230 MockDumpProvider mdp1; | 288 MockDumpProvider mdp1; |
231 MockDumpProvider mdp2; | 289 MockDumpProvider mdp2; |
232 mdm_->RegisterDumpProvider(&mdp1); | 290 mdm_->RegisterDumpProvider(&mdp1); |
233 mdm_->RegisterDumpProvider(&mdp2); | 291 mdm_->RegisterDumpProvider(&mdp2); |
234 | 292 |
235 EnableTracing(MemoryDumpManager::kTraceCategory); | 293 EnableTracing(MemoryDumpManager::kTraceCategory); |
236 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) | 294 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) |
237 .Times(2) | 295 .Times(2) |
238 .WillRepeatedly( | 296 .WillRepeatedly( |
239 Invoke(&mdp1, &MockDumpProvider::OnMemoryDump_CheckSessionState)); | 297 Invoke(&mdp1, &MockDumpProvider::OnMemoryDump_CheckSessionState)); |
240 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) | 298 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) |
241 .Times(2) | 299 .Times(2) |
242 .WillRepeatedly( | 300 .WillRepeatedly( |
243 Invoke(&mdp2, &MockDumpProvider::OnMemoryDump_CheckSessionState)); | 301 Invoke(&mdp2, &MockDumpProvider::OnMemoryDump_CheckSessionState)); |
244 | 302 |
245 for (int i = 0; i < 2; ++i) | 303 for (int i = 0; i < 2; ++i) |
246 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 304 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
247 high_detail_args); | 305 g_high_detail_args); |
248 | 306 |
249 DisableTracing(); | 307 DisableTracing(); |
250 } | 308 } |
251 | 309 |
252 TEST_F(MemoryDumpManagerTest, MultipleDumpers) { | 310 TEST_F(MemoryDumpManagerTest, MultipleDumpers) { |
253 MockDumpProvider mdp1; | 311 MockDumpProvider mdp1; |
254 MockDumpProvider mdp2; | 312 MockDumpProvider mdp2; |
255 | 313 |
256 // Enable only mdp1. | 314 // Enable only mdp1. |
257 mdm_->RegisterDumpProvider(&mdp1); | 315 mdm_->RegisterDumpProvider(&mdp1); |
258 EnableTracing(MemoryDumpManager::kTraceCategory); | 316 EnableTracing(MemoryDumpManager::kTraceCategory); |
259 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); | 317 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); |
260 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(0); | 318 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(0); |
261 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 319 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
262 high_detail_args); | 320 g_high_detail_args); |
263 DisableTracing(); | 321 DisableTracing(); |
264 | 322 |
265 // Invert: enable mdp1 and disable mdp2. | 323 // Invert: enable mdp1 and disable mdp2. |
266 mdm_->UnregisterDumpProvider(&mdp1); | 324 mdm_->UnregisterDumpProvider(&mdp1); |
267 mdm_->RegisterDumpProvider(&mdp2); | 325 mdm_->RegisterDumpProvider(&mdp2); |
268 EnableTracing(MemoryDumpManager::kTraceCategory); | 326 EnableTracing(MemoryDumpManager::kTraceCategory); |
269 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); | 327 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); |
270 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); | 328 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); |
271 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 329 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
272 high_detail_args); | 330 g_high_detail_args); |
273 DisableTracing(); | 331 DisableTracing(); |
274 | 332 |
275 // Enable both mdp1 and mdp2. | 333 // Enable both mdp1 and mdp2. |
276 mdm_->RegisterDumpProvider(&mdp1); | 334 mdm_->RegisterDumpProvider(&mdp1); |
277 EnableTracing(MemoryDumpManager::kTraceCategory); | 335 EnableTracing(MemoryDumpManager::kTraceCategory); |
278 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); | 336 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); |
279 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); | 337 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); |
280 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 338 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
281 high_detail_args); | 339 g_high_detail_args); |
282 DisableTracing(); | 340 DisableTracing(); |
283 } | 341 } |
284 | 342 |
285 // Verify that whether OnMemoryDump is called depends only on the current | 343 // Verify that whether OnMemoryDump is called depends only on the current |
286 // registration state and not on previous registrations and dumps. | 344 // registration state and not on previous registrations and dumps. |
287 TEST_F(MemoryDumpManagerTest, RegistrationConsistency) { | 345 TEST_F(MemoryDumpManagerTest, RegistrationConsistency) { |
288 MockDumpProvider mdp; | 346 MockDumpProvider mdp; |
289 | 347 |
290 mdm_->RegisterDumpProvider(&mdp); | 348 mdm_->RegisterDumpProvider(&mdp); |
291 | 349 |
292 { | 350 { |
293 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(1); | 351 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(1); |
294 EnableTracing(MemoryDumpManager::kTraceCategory); | 352 EnableTracing(MemoryDumpManager::kTraceCategory); |
295 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 353 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
296 high_detail_args); | 354 g_high_detail_args); |
297 DisableTracing(); | 355 DisableTracing(); |
298 } | 356 } |
299 | 357 |
300 mdm_->UnregisterDumpProvider(&mdp); | 358 mdm_->UnregisterDumpProvider(&mdp); |
301 | 359 |
302 { | 360 { |
303 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); | 361 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
304 EnableTracing(MemoryDumpManager::kTraceCategory); | 362 EnableTracing(MemoryDumpManager::kTraceCategory); |
305 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 363 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
306 high_detail_args); | 364 g_high_detail_args); |
307 DisableTracing(); | 365 DisableTracing(); |
308 } | 366 } |
309 | 367 |
310 mdm_->RegisterDumpProvider(&mdp); | 368 mdm_->RegisterDumpProvider(&mdp); |
311 mdm_->UnregisterDumpProvider(&mdp); | 369 mdm_->UnregisterDumpProvider(&mdp); |
312 | 370 |
313 { | 371 { |
314 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); | 372 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
315 EnableTracing(MemoryDumpManager::kTraceCategory); | 373 EnableTracing(MemoryDumpManager::kTraceCategory); |
316 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 374 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
317 high_detail_args); | 375 g_high_detail_args); |
318 DisableTracing(); | 376 DisableTracing(); |
319 } | 377 } |
320 | 378 |
321 mdm_->RegisterDumpProvider(&mdp); | 379 mdm_->RegisterDumpProvider(&mdp); |
322 mdm_->UnregisterDumpProvider(&mdp); | 380 mdm_->UnregisterDumpProvider(&mdp); |
323 mdm_->RegisterDumpProvider(&mdp); | 381 mdm_->RegisterDumpProvider(&mdp); |
324 | 382 |
325 { | 383 { |
326 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(1); | 384 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(1); |
327 EnableTracing(MemoryDumpManager::kTraceCategory); | 385 EnableTracing(MemoryDumpManager::kTraceCategory); |
328 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 386 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
329 high_detail_args); | 387 g_high_detail_args); |
330 DisableTracing(); | 388 DisableTracing(); |
331 } | 389 } |
332 } | 390 } |
333 | 391 |
334 // Checks that the MemoryDumpManager respects the thread affinity when a | 392 // Checks that the MemoryDumpManager respects the thread affinity when a |
335 // MemoryDumpProvider specifies a task_runner(). The test starts creating 8 | 393 // MemoryDumpProvider specifies a task_runner(). The test starts creating 8 |
336 // threads and registering a MemoryDumpProvider on each of them. At each | 394 // threads and registering a MemoryDumpProvider on each of them. At each |
337 // iteration, one thread is removed, to check the live unregistration logic. | 395 // iteration, one thread is removed, to check the live unregistration logic. |
338 TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) { | 396 TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) { |
339 const uint32 kNumInitialThreads = 8; | 397 const uint32 kNumInitialThreads = 8; |
(...skipping 19 matching lines...) Expand all Loading... | |
359 EnableTracing(MemoryDumpManager::kTraceCategory); | 417 EnableTracing(MemoryDumpManager::kTraceCategory); |
360 | 418 |
361 while (!threads.empty()) { | 419 while (!threads.empty()) { |
362 last_callback_success_ = false; | 420 last_callback_success_ = false; |
363 { | 421 { |
364 RunLoop run_loop; | 422 RunLoop run_loop; |
365 MemoryDumpCallback callback = | 423 MemoryDumpCallback callback = |
366 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), | 424 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), |
367 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); | 425 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); |
368 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 426 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
369 high_detail_args, callback); | 427 g_high_detail_args, callback); |
370 // This nested message loop (|run_loop|) will be quit if and only if | 428 // This nested message loop (|run_loop|) will be quit if and only if |
371 // the RequestGlobalDump callback is invoked. | 429 // the RequestGlobalDump callback is invoked. |
372 run_loop.Run(); | 430 run_loop.Run(); |
373 } | 431 } |
374 EXPECT_TRUE(last_callback_success_); | 432 EXPECT_TRUE(last_callback_success_); |
375 | 433 |
376 // Unregister a MDP and destroy one thread at each iteration to check the | 434 // Unregister a MDP and destroy one thread at each iteration to check the |
377 // live unregistration logic. The unregistration needs to happen on the same | 435 // live unregistration logic. The unregistration needs to happen on the same |
378 // thread the MDP belongs to. | 436 // thread the MDP belongs to. |
379 { | 437 { |
(...skipping 27 matching lines...) Expand all Loading... | |
407 .Times(MemoryDumpManager::kMaxConsecutiveFailuresCount) | 465 .Times(MemoryDumpManager::kMaxConsecutiveFailuresCount) |
408 .WillRepeatedly(Return(false)); | 466 .WillRepeatedly(Return(false)); |
409 | 467 |
410 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) | 468 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) |
411 .Times(1 + MemoryDumpManager::kMaxConsecutiveFailuresCount) | 469 .Times(1 + MemoryDumpManager::kMaxConsecutiveFailuresCount) |
412 .WillOnce(Return(false)) | 470 .WillOnce(Return(false)) |
413 .WillRepeatedly(Return(true)); | 471 .WillRepeatedly(Return(true)); |
414 for (int i = 0; i < 1 + MemoryDumpManager::kMaxConsecutiveFailuresCount; | 472 for (int i = 0; i < 1 + MemoryDumpManager::kMaxConsecutiveFailuresCount; |
415 i++) { | 473 i++) { |
416 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 474 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
417 high_detail_args); | 475 g_high_detail_args); |
418 } | 476 } |
419 | 477 |
420 DisableTracing(); | 478 DisableTracing(); |
421 } | 479 } |
422 | 480 |
423 // Sneakily register an extra memory dump provider while an existing one is | 481 // Sneakily register an extra memory dump provider while an existing one is |
424 // dumping and expect it to take part in the already active tracing session. | 482 // dumping and expect it to take part in the already active tracing session. |
425 TEST_F(MemoryDumpManagerTest, RegisterDumperWhileDumping) { | 483 TEST_F(MemoryDumpManagerTest, RegisterDumperWhileDumping) { |
426 MockDumpProvider mdp1; | 484 MockDumpProvider mdp1; |
427 MockDumpProvider mdp2; | 485 MockDumpProvider mdp2; |
(...skipping 10 matching lines...) Expand all Loading... | |
438 .WillRepeatedly(Return(true)); | 496 .WillRepeatedly(Return(true)); |
439 | 497 |
440 // Depending on the insertion order (before or after mdp1), mdp2 might be | 498 // Depending on the insertion order (before or after mdp1), mdp2 might be |
441 // called also immediately after it gets registered. | 499 // called also immediately after it gets registered. |
442 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) | 500 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) |
443 .Times(Between(2, 3)) | 501 .Times(Between(2, 3)) |
444 .WillRepeatedly(Return(true)); | 502 .WillRepeatedly(Return(true)); |
445 | 503 |
446 for (int i = 0; i < 4; i++) { | 504 for (int i = 0; i < 4; i++) { |
447 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 505 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
448 high_detail_args); | 506 g_high_detail_args); |
449 } | 507 } |
450 | 508 |
451 DisableTracing(); | 509 DisableTracing(); |
452 } | 510 } |
453 | 511 |
454 // Like the above, but suddenly unregister the dump provider. | 512 // Like the above, but suddenly unregister the dump provider. |
455 TEST_F(MemoryDumpManagerTest, UnregisterDumperWhileDumping) { | 513 TEST_F(MemoryDumpManagerTest, UnregisterDumperWhileDumping) { |
456 MockDumpProvider mdp1; | 514 MockDumpProvider mdp1; |
457 MockDumpProvider mdp2; | 515 MockDumpProvider mdp2; |
458 | 516 |
(...skipping 10 matching lines...) Expand all Loading... | |
469 .WillRepeatedly(Return(true)); | 527 .WillRepeatedly(Return(true)); |
470 | 528 |
471 // Depending on the insertion order (before or after mdp1), mdp2 might have | 529 // Depending on the insertion order (before or after mdp1), mdp2 might have |
472 // been already called when OnMemoryDump_UnregisterDumpProvider happens. | 530 // been already called when OnMemoryDump_UnregisterDumpProvider happens. |
473 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) | 531 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) |
474 .Times(Between(1, 2)) | 532 .Times(Between(1, 2)) |
475 .WillRepeatedly(Return(true)); | 533 .WillRepeatedly(Return(true)); |
476 | 534 |
477 for (int i = 0; i < 4; i++) { | 535 for (int i = 0; i < 4; i++) { |
478 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 536 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
479 high_detail_args); | 537 g_high_detail_args); |
480 } | 538 } |
481 | 539 |
482 DisableTracing(); | 540 DisableTracing(); |
483 } | 541 } |
484 | 542 |
485 // Verify that the dump does not abort when unregistering a provider while | 543 // Verify that the dump does not abort when unregistering a provider while |
486 // dumping from a different thread than the dumping thread. | 544 // dumping from a different thread than the dumping thread. |
487 TEST_F(MemoryDumpManagerTest, UnregisterDumperFromThreadWhileDumping) { | 545 TEST_F(MemoryDumpManagerTest, UnregisterDumperFromThreadWhileDumping) { |
488 ScopedVector<TestIOThread> threads; | 546 ScopedVector<TestIOThread> threads; |
489 ScopedVector<MockDumpProvider> mdps; | 547 ScopedVector<MockDumpProvider> mdps; |
(...skipping 29 matching lines...) Expand all Loading... | |
519 .WillOnce(Invoke(on_dump)); | 577 .WillOnce(Invoke(on_dump)); |
520 } | 578 } |
521 | 579 |
522 last_callback_success_ = false; | 580 last_callback_success_ = false; |
523 MemoryDumpCallback callback = | 581 MemoryDumpCallback callback = |
524 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), | 582 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), |
525 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); | 583 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); |
526 | 584 |
527 EnableTracing(MemoryDumpManager::kTraceCategory); | 585 EnableTracing(MemoryDumpManager::kTraceCategory); |
528 MemoryDumpRequestArgs request_args = {0, MemoryDumpType::EXPLICITLY_TRIGGERED, | 586 MemoryDumpRequestArgs request_args = {0, MemoryDumpType::EXPLICITLY_TRIGGERED, |
529 high_detail_args}; | 587 g_high_detail_args}; |
530 mdm_->CreateProcessDump(request_args, callback); | 588 mdm_->CreateProcessDump(request_args, callback); |
531 | 589 |
532 run_loop.Run(); | 590 run_loop.Run(); |
533 | 591 |
534 ASSERT_EQ(1, on_memory_dump_call_count); | 592 ASSERT_EQ(1, on_memory_dump_call_count); |
535 ASSERT_EQ(true, last_callback_success_); | 593 ASSERT_EQ(true, last_callback_success_); |
536 | 594 |
537 DisableTracing(); | 595 DisableTracing(); |
538 } | 596 } |
539 | 597 |
540 // Ensures that a NACK callback is invoked if RequestGlobalDump is called when | 598 // Ensures that a NACK callback is invoked if RequestGlobalDump is called when |
541 // tracing is not enabled. | 599 // tracing is not enabled. |
542 TEST_F(MemoryDumpManagerTest, CallbackCalledOnFailure) { | 600 TEST_F(MemoryDumpManagerTest, CallbackCalledOnFailure) { |
543 MockDumpProvider mdp1; | 601 MockDumpProvider mdp1; |
544 | 602 |
545 mdm_->RegisterDumpProvider(&mdp1); | 603 mdm_->RegisterDumpProvider(&mdp1); |
546 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); | 604 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); |
547 | 605 |
548 last_callback_success_ = true; | 606 last_callback_success_ = true; |
549 { | 607 { |
550 RunLoop run_loop; | 608 RunLoop run_loop; |
551 MemoryDumpCallback callback = | 609 MemoryDumpCallback callback = |
552 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), | 610 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), |
553 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); | 611 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); |
554 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 612 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
555 high_detail_args, callback); | 613 g_high_detail_args, callback); |
556 run_loop.Run(); | 614 run_loop.Run(); |
557 } | 615 } |
558 EXPECT_FALSE(last_callback_success_); | 616 EXPECT_FALSE(last_callback_success_); |
559 } | 617 } |
560 | 618 |
619 TEST_F(MemoryDumpManagerTest, SchedulePeriodicDumpsFromTraceConfig) { | |
620 const char kMemoryDumpTraceConfigString[] = | |
621 "{" | |
622 "\"included_categories\":[" | |
623 "\"disabled-by-default-memory-infra\"" | |
624 "]," | |
625 "\"memory_dump_config\":{" | |
626 "\"triggers\":[" | |
627 "{" | |
628 "\"mode\":\"light\"," | |
629 "\"periodic_interval_ms\":1" | |
630 "}," | |
631 "{" | |
632 "\"mode\":\"detailed\"," | |
633 "\"periodic_interval_ms\":3" | |
634 "}" | |
635 "]" | |
636 "}" | |
637 "}"; | |
638 | |
639 RunLoop run_loop; | |
640 scoped_ptr<MemoryDumpManagerDelegateForPeriodicDumpTest> delegate( | |
641 new MemoryDumpManagerDelegateForPeriodicDumpTest( | |
642 5 /* dump_calls_to_quit */, 3 /* expected_high_dump_ratio */, | |
643 run_loop.QuitClosure())); | |
644 EXPECT_CALL(*delegate.get(), RequestGlobalMemoryDump(_, _)) | |
645 .Times(5) | |
646 .WillRepeatedly( | |
647 Invoke(delegate.get(), &MemoryDumpManagerDelegateForPeriodicDumpTest:: | |
648 RequestGlobalMemoryDump_QuitAfterCalls)); | |
649 SetDelegate(delegate.Pass()); | |
650 EnableTracingWithTraceConfig(kMemoryDumpTraceConfigString); | |
651 | |
652 run_loop.Run(); | |
653 } | |
654 | |
561 } // namespace trace_event | 655 } // namespace trace_event |
562 } // namespace base | 656 } // namespace base |
OLD | NEW |