| 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 <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <utility> | 10 #include <utility> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
| 14 #include "base/callback.h" | 14 #include "base/callback.h" |
| 15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
| 16 #include "base/memory/ref_counted_memory.h" | 16 #include "base/memory/ref_counted_memory.h" |
| 17 #include "base/message_loop/message_loop.h" | 17 #include "base/message_loop/message_loop.h" |
| 18 #include "base/run_loop.h" | 18 #include "base/run_loop.h" |
| 19 #include "base/single_thread_task_runner.h" | 19 #include "base/single_thread_task_runner.h" |
| 20 #include "base/strings/stringprintf.h" | 20 #include "base/strings/stringprintf.h" |
| 21 #include "base/synchronization/waitable_event.h" | 21 #include "base/synchronization/waitable_event.h" |
| 22 #include "base/test/sequenced_worker_pool_owner.h" | 22 #include "base/test/sequenced_worker_pool_owner.h" |
| 23 #include "base/test/test_io_thread.h" | 23 #include "base/test/test_io_thread.h" |
| 24 #include "base/test/trace_event_analyzer.h" | 24 #include "base/test/trace_event_analyzer.h" |
| 25 #include "base/threading/platform_thread.h" | 25 #include "base/threading/platform_thread.h" |
| 26 #include "base/threading/sequenced_task_runner_handle.h" | 26 #include "base/threading/sequenced_task_runner_handle.h" |
| 27 #include "base/threading/sequenced_worker_pool.h" | 27 #include "base/threading/sequenced_worker_pool.h" |
| 28 #include "base/threading/thread.h" | 28 #include "base/threading/thread.h" |
| 29 #include "base/threading/thread_task_runner_handle.h" | 29 #include "base/threading/thread_task_runner_handle.h" |
| 30 #include "base/trace_event/memory_dump_manager_test_utils.h" |
| 30 #include "base/trace_event/memory_dump_provider.h" | 31 #include "base/trace_event/memory_dump_provider.h" |
| 32 #include "base/trace_event/memory_dump_request_args.h" |
| 31 #include "base/trace_event/memory_dump_scheduler.h" | 33 #include "base/trace_event/memory_dump_scheduler.h" |
| 32 #include "base/trace_event/memory_infra_background_whitelist.h" | 34 #include "base/trace_event/memory_infra_background_whitelist.h" |
| 33 #include "base/trace_event/process_memory_dump.h" | 35 #include "base/trace_event/process_memory_dump.h" |
| 34 #include "base/trace_event/trace_buffer.h" | 36 #include "base/trace_event/trace_buffer.h" |
| 35 #include "base/trace_event/trace_config_memory_test_util.h" | 37 #include "base/trace_event/trace_config_memory_test_util.h" |
| 36 #include "build/build_config.h" | 38 #include "build/build_config.h" |
| 37 #include "testing/gmock/include/gmock/gmock.h" | 39 #include "testing/gmock/include/gmock/gmock.h" |
| 38 #include "testing/gtest/include/gtest/gtest.h" | 40 #include "testing/gtest/include/gtest/gtest.h" |
| 39 | 41 |
| 40 using testing::_; | 42 using testing::_; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 MemoryDumpProvider* mdp, | 94 MemoryDumpProvider* mdp, |
| 93 scoped_refptr<base::SequencedTaskRunner> task_runner, | 95 scoped_refptr<base::SequencedTaskRunner> task_runner, |
| 94 const MemoryDumpProvider::Options& options) { | 96 const MemoryDumpProvider::Options& options) { |
| 95 MemoryDumpManager* mdm = MemoryDumpManager::GetInstance(); | 97 MemoryDumpManager* mdm = MemoryDumpManager::GetInstance(); |
| 96 mdm->set_dumper_registrations_ignored_for_testing(false); | 98 mdm->set_dumper_registrations_ignored_for_testing(false); |
| 97 mdm->RegisterDumpProviderWithSequencedTaskRunner(mdp, kMDPName, task_runner, | 99 mdm->RegisterDumpProviderWithSequencedTaskRunner(mdp, kMDPName, task_runner, |
| 98 options); | 100 options); |
| 99 mdm->set_dumper_registrations_ignored_for_testing(true); | 101 mdm->set_dumper_registrations_ignored_for_testing(true); |
| 100 } | 102 } |
| 101 | 103 |
| 102 void OnTraceDataCollected(Closure quit_closure, | |
| 103 trace_event::TraceResultBuffer* buffer, | |
| 104 const scoped_refptr<RefCountedString>& json, | |
| 105 bool has_more_events) { | |
| 106 buffer->AddFragment(json->data()); | |
| 107 if (!has_more_events) | |
| 108 quit_closure.Run(); | |
| 109 } | |
| 110 | |
| 111 // Posts |task| to |task_runner| and blocks until it is executed. | 104 // Posts |task| to |task_runner| and blocks until it is executed. |
| 112 void PostTaskAndWait(const tracked_objects::Location& from_here, | 105 void PostTaskAndWait(const tracked_objects::Location& from_here, |
| 113 SequencedTaskRunner* task_runner, | 106 SequencedTaskRunner* task_runner, |
| 114 base::OnceClosure task) { | 107 base::OnceClosure task) { |
| 115 base::WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, | 108 base::WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL, |
| 116 WaitableEvent::InitialState::NOT_SIGNALED); | 109 WaitableEvent::InitialState::NOT_SIGNALED); |
| 117 task_runner->PostTask(from_here, std::move(task)); | 110 task_runner->PostTask(from_here, std::move(task)); |
| 118 task_runner->PostTask(FROM_HERE, base::BindOnce(&WaitableEvent::Signal, | 111 task_runner->PostTask(FROM_HERE, base::BindOnce(&WaitableEvent::Signal, |
| 119 base::Unretained(&event))); | 112 base::Unretained(&event))); |
| 120 // The SequencedTaskRunner guarantees that |event| will only be signaled after | 113 // The SequencedTaskRunner guarantees that |event| will only be signaled after |
| 121 // |task| is executed. | 114 // |task| is executed. |
| 122 event.Wait(); | 115 event.Wait(); |
| 123 } | 116 } |
| 124 | 117 |
| 125 // Adapts a ProcessMemoryDumpCallback into a GlobalMemoryDumpCallback | |
| 126 // and keeps around the process-local result. | |
| 127 void ProcessDumpCallbackAdapter( | |
| 128 GlobalMemoryDumpCallback callback, | |
| 129 uint64_t dump_guid, | |
| 130 bool success, | |
| 131 const base::Optional<base::trace_event::MemoryDumpCallbackResult>&) { | |
| 132 callback.Run(dump_guid, success); | |
| 133 } | |
| 134 | |
| 135 // This mocks the RequestGlobalDumpFunction which is typically handled by | |
| 136 // process_local_dump_manager_impl.cc, by short-circuiting dump requests locally | |
| 137 // to the MemoryDumpManager without an actual service. | |
| 138 class GlobalMemoryDumpHandler { | |
| 139 public: | |
| 140 MOCK_METHOD2(RequestGlobalMemoryDump, | |
| 141 void(const MemoryDumpRequestArgs& args, | |
| 142 const GlobalMemoryDumpCallback& callback)); | |
| 143 | |
| 144 GlobalMemoryDumpHandler() { | |
| 145 ON_CALL(*this, RequestGlobalMemoryDump(_, _)) | |
| 146 .WillByDefault(Invoke([this](const MemoryDumpRequestArgs& args, | |
| 147 const GlobalMemoryDumpCallback& callback) { | |
| 148 ProcessMemoryDumpCallback process_callback = | |
| 149 Bind(&ProcessDumpCallbackAdapter, callback); | |
| 150 MemoryDumpManager::GetInstance()->CreateProcessDump(args, | |
| 151 process_callback); | |
| 152 })); | |
| 153 } | |
| 154 }; | |
| 155 | |
| 156 class MockMemoryDumpProvider : public MemoryDumpProvider { | 118 class MockMemoryDumpProvider : public MemoryDumpProvider { |
| 157 public: | 119 public: |
| 158 MOCK_METHOD0(Destructor, void()); | 120 MOCK_METHOD0(Destructor, void()); |
| 159 MOCK_METHOD2(OnMemoryDump, | 121 MOCK_METHOD2(OnMemoryDump, |
| 160 bool(const MemoryDumpArgs& args, ProcessMemoryDump* pmd)); | 122 bool(const MemoryDumpArgs& args, ProcessMemoryDump* pmd)); |
| 161 MOCK_METHOD1(PollFastMemoryTotal, void(uint64_t* memory_total)); | 123 MOCK_METHOD1(PollFastMemoryTotal, void(uint64_t* memory_total)); |
| 162 MOCK_METHOD0(SuspendFastMemoryPolling, void()); | 124 MOCK_METHOD0(SuspendFastMemoryPolling, void()); |
| 163 | 125 |
| 164 MockMemoryDumpProvider() : enable_mock_destructor(false) { | 126 MockMemoryDumpProvider() : enable_mock_destructor(false) { |
| 165 ON_CALL(*this, OnMemoryDump(_, _)) | 127 ON_CALL(*this, OnMemoryDump(_, _)) |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 unsigned num_of_post_tasks_; | 183 unsigned num_of_post_tasks_; |
| 222 }; | 184 }; |
| 223 | 185 |
| 224 std::unique_ptr<trace_analyzer::TraceAnalyzer> GetDeserializedTrace() { | 186 std::unique_ptr<trace_analyzer::TraceAnalyzer> GetDeserializedTrace() { |
| 225 // Flush the trace into JSON. | 187 // Flush the trace into JSON. |
| 226 trace_event::TraceResultBuffer buffer; | 188 trace_event::TraceResultBuffer buffer; |
| 227 TraceResultBuffer::SimpleOutput trace_output; | 189 TraceResultBuffer::SimpleOutput trace_output; |
| 228 buffer.SetOutputCallback(trace_output.GetCallback()); | 190 buffer.SetOutputCallback(trace_output.GetCallback()); |
| 229 RunLoop run_loop; | 191 RunLoop run_loop; |
| 230 buffer.Start(); | 192 buffer.Start(); |
| 231 trace_event::TraceLog::GetInstance()->Flush( | 193 auto on_trace_data_collected = |
| 232 Bind(&OnTraceDataCollected, run_loop.QuitClosure(), Unretained(&buffer))); | 194 [](Closure quit_closure, trace_event::TraceResultBuffer* buffer, |
| 195 const scoped_refptr<RefCountedString>& json, bool has_more_events) { |
| 196 buffer->AddFragment(json->data()); |
| 197 if (!has_more_events) |
| 198 quit_closure.Run(); |
| 199 }; |
| 200 |
| 201 trace_event::TraceLog::GetInstance()->Flush(Bind( |
| 202 on_trace_data_collected, run_loop.QuitClosure(), Unretained(&buffer))); |
| 233 run_loop.Run(); | 203 run_loop.Run(); |
| 234 buffer.Finish(); | 204 buffer.Finish(); |
| 235 | 205 |
| 236 // Analyze the JSON. | 206 // Analyze the JSON. |
| 237 return WrapUnique( | 207 return WrapUnique( |
| 238 trace_analyzer::TraceAnalyzer::Create(trace_output.json_output)); | 208 trace_analyzer::TraceAnalyzer::Create(trace_output.json_output)); |
| 239 } | 209 } |
| 240 | 210 |
| 241 } // namespace | 211 } // namespace |
| 242 | 212 |
| 243 class MemoryDumpManagerTest : public testing::Test { | 213 class MemoryDumpManagerTest : public testing::Test { |
| 244 public: | 214 public: |
| 245 MemoryDumpManagerTest() : testing::Test(), kDefaultOptions() {} | 215 MemoryDumpManagerTest() : testing::Test(), kDefaultOptions() {} |
| 246 | 216 |
| 247 void SetUp() override { | 217 void SetUp() override { |
| 248 last_callback_success_ = false; | |
| 249 message_loop_.reset(new MessageLoop()); | 218 message_loop_.reset(new MessageLoop()); |
| 250 mdm_ = MemoryDumpManager::CreateInstanceForTesting(); | 219 mdm_ = MemoryDumpManager::CreateInstanceForTesting(); |
| 251 ASSERT_EQ(mdm_.get(), MemoryDumpManager::GetInstance()); | 220 ASSERT_EQ(mdm_.get(), MemoryDumpManager::GetInstance()); |
| 252 results_.clear(); | |
| 253 } | 221 } |
| 254 | 222 |
| 255 void TearDown() override { | 223 void TearDown() override { |
| 256 mdm_.reset(); | 224 mdm_.reset(); |
| 257 message_loop_.reset(); | 225 message_loop_.reset(); |
| 258 TraceLog::DeleteForTesting(); | 226 TraceLog::DeleteForTesting(); |
| 259 } | 227 } |
| 260 | 228 |
| 261 // Turns a Closure into a GlobalMemoryDumpCallback, keeping track of the | 229 protected: |
| 262 // callback result and taking care of posting the closure on the correct task | 230 // Blocks the current thread (spinning a nested message loop) until the |
| 263 // runner. | 231 // memory dump is complete. Returns: |
| 264 void GlobalDumpCallbackAdapter( | 232 // - return value: the |success| from the CreateProcessDump() callback. |
| 265 scoped_refptr<SingleThreadTaskRunner> task_runner, | 233 // - (optional) |result|: the summarized metrics for TestSummaryComputation. |
| 266 Closure closure, | 234 bool RequestProcessDumpAndWait( |
| 267 uint64_t dump_guid, | 235 MemoryDumpType dump_type, |
| 268 bool success) { | 236 MemoryDumpLevelOfDetail level_of_detail, |
| 269 last_callback_success_ = success; | 237 Optional<MemoryDumpCallbackResult>* result = nullptr) { |
| 270 task_runner->PostTask(FROM_HERE, closure); | 238 RunLoop run_loop; |
| 271 } | 239 bool success = false; |
| 240 static uint64_t test_guid = 1; |
| 241 test_guid++; |
| 242 MemoryDumpRequestArgs request_args{test_guid, dump_type, level_of_detail}; |
| 272 | 243 |
| 273 protected: | 244 // The signature of the callback delivered by MemoryDumpManager is: |
| 274 void InitializeMemoryDumpManager(bool is_coordinator) { | 245 // void ProcessMemoryDumpCallback(uint64_t dump_guid, |
| 275 mdm_->set_dumper_registrations_ignored_for_testing(true); | 246 // bool success, |
| 276 mdm_->Initialize( | 247 // const Optional<MemoryDumpCallbackResult>&) |
| 277 BindRepeating(&GlobalMemoryDumpHandler::RequestGlobalMemoryDump, | 248 // The extra arguments prepended to the |callback| below (the ones with the |
| 278 Unretained(&global_dump_handler_)), | 249 // "curried_" prefix) are just passed from the Bind(). This is just to get |
| 279 is_coordinator); | 250 // around the limitation of Bind() in supporting only capture-less lambdas. |
| 280 } | 251 ProcessMemoryDumpCallback callback = Bind( |
| 252 [](bool* curried_success, Closure curried_quit_closure, |
| 253 uint64_t curried_expected_guid, |
| 254 Optional<MemoryDumpCallbackResult>* curried_result, |
| 255 uint64_t dump_guid, bool success, |
| 256 const Optional<MemoryDumpCallbackResult>& callback_result) { |
| 257 *curried_success = success; |
| 258 EXPECT_EQ(curried_expected_guid, dump_guid); |
| 259 if (curried_result) |
| 260 *curried_result = callback_result; |
| 261 ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, |
| 262 curried_quit_closure); |
| 263 }, |
| 264 Unretained(&success), run_loop.QuitClosure(), test_guid, result); |
| 281 | 265 |
| 282 void RequestGlobalDumpAndWait(MemoryDumpType dump_type, | 266 mdm_->CreateProcessDump(request_args, callback); |
| 283 MemoryDumpLevelOfDetail level_of_detail) { | |
| 284 RunLoop run_loop; | |
| 285 GlobalMemoryDumpCallback callback = Bind( | |
| 286 &MemoryDumpManagerTest::GlobalDumpCallbackAdapter, Unretained(this), | |
| 287 ThreadTaskRunnerHandle::Get(), run_loop.QuitClosure()); | |
| 288 mdm_->RequestGlobalDump(dump_type, level_of_detail, callback); | |
| 289 run_loop.Run(); | 267 run_loop.Run(); |
| 268 return success; |
| 290 } | 269 } |
| 291 | 270 |
| 292 void EnableTracingWithLegacyCategories(const char* category) { | 271 void EnableTracingWithLegacyCategories(const char* category) { |
| 293 TraceLog::GetInstance()->SetEnabled(TraceConfig(category, ""), | 272 TraceLog::GetInstance()->SetEnabled(TraceConfig(category, ""), |
| 294 TraceLog::RECORDING_MODE); | 273 TraceLog::RECORDING_MODE); |
| 295 } | 274 } |
| 296 | 275 |
| 297 void EnableTracingWithTraceConfig(const std::string& trace_config) { | 276 void EnableTracingWithTraceConfig(const std::string& trace_config) { |
| 298 TraceLog::GetInstance()->SetEnabled(TraceConfig(trace_config), | 277 TraceLog::GetInstance()->SetEnabled(TraceConfig(trace_config), |
| 299 TraceLog::RECORDING_MODE); | 278 TraceLog::RECORDING_MODE); |
| 300 } | 279 } |
| 301 | 280 |
| 302 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } | 281 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } |
| 303 | 282 |
| 304 bool IsPeriodicDumpingEnabled() const { | 283 bool IsPeriodicDumpingEnabled() const { |
| 305 return MemoryDumpScheduler::GetInstance()->is_enabled_for_testing(); | 284 return MemoryDumpScheduler::GetInstance()->is_enabled_for_testing(); |
| 306 } | 285 } |
| 307 | 286 |
| 308 int GetMaxConsecutiveFailuresCount() const { | 287 int GetMaxConsecutiveFailuresCount() const { |
| 309 return MemoryDumpManager::kMaxConsecutiveFailuresCount; | 288 return MemoryDumpManager::kMaxConsecutiveFailuresCount; |
| 310 } | 289 } |
| 311 | 290 |
| 312 const std::vector<MemoryDumpCallbackResult>* GetResults() const { | |
| 313 return &results_; | |
| 314 } | |
| 315 | |
| 316 const MemoryDumpProvider::Options kDefaultOptions; | 291 const MemoryDumpProvider::Options kDefaultOptions; |
| 317 std::unique_ptr<MemoryDumpManager> mdm_; | 292 std::unique_ptr<MemoryDumpManager> mdm_; |
| 318 GlobalMemoryDumpHandler global_dump_handler_; | |
| 319 bool last_callback_success_; | |
| 320 | |
| 321 // Adapts a ProcessMemoryDumpCallback into a GlobalMemoryDumpCallback by | |
| 322 // trimming off the result argument and calling the global callback. | |
| 323 void ProcessDumpRecordingCallbackAdapter( | |
| 324 GlobalMemoryDumpCallback callback, | |
| 325 uint64_t dump_guid, | |
| 326 bool success, | |
| 327 const base::Optional<MemoryDumpCallbackResult>& result) { | |
| 328 if (result.has_value()) { | |
| 329 results_.push_back(result.value()); | |
| 330 } | |
| 331 callback.Run(dump_guid, success); | |
| 332 } | |
| 333 | 293 |
| 334 private: | 294 private: |
| 335 std::unique_ptr<MessageLoop> message_loop_; | 295 std::unique_ptr<MessageLoop> message_loop_; |
| 336 std::vector<MemoryDumpCallbackResult> results_; | |
| 337 | 296 |
| 338 // We want our singleton torn down after each test. | 297 // To tear down the singleton instance after each test. |
| 339 ShadowingAtExitManager at_exit_manager_; | 298 ShadowingAtExitManager at_exit_manager_; |
| 340 }; | 299 }; |
| 341 | 300 |
| 342 // Basic sanity checks. Registers a memory dump provider and checks that it is | 301 // Basic sanity checks. Registers a memory dump provider and checks that it is |
| 343 // called. | 302 // called. |
| 344 TEST_F(MemoryDumpManagerTest, SingleDumper) { | 303 TEST_F(MemoryDumpManagerTest, SingleDumper) { |
| 345 InitializeMemoryDumpManager(false /* is_coordinator */); | 304 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 346 MockMemoryDumpProvider mdp; | 305 MockMemoryDumpProvider mdp; |
| 347 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); | 306 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); |
| 348 | 307 |
| 349 // Now repeat enabling the memory category and check that the dumper is | 308 // Now repeat enabling the memory category and check that the dumper is |
| 350 // invoked this time. | 309 // invoked this time. |
| 351 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 310 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 352 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(3); | 311 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3); |
| 353 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true)); | |
| 354 for (int i = 0; i < 3; ++i) { | 312 for (int i = 0; i < 3; ++i) { |
| 355 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 313 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 356 MemoryDumpLevelOfDetail::DETAILED); | 314 MemoryDumpLevelOfDetail::DETAILED)); |
| 357 } | 315 } |
| 358 DisableTracing(); | 316 DisableTracing(); |
| 359 | 317 |
| 360 mdm_->UnregisterDumpProvider(&mdp); | 318 mdm_->UnregisterDumpProvider(&mdp); |
| 361 | 319 |
| 362 // Finally check the unregister logic: the global dump handler will be invoked | 320 // Finally check the unregister logic: the global dump handler will be invoked |
| 363 // but not the dump provider, as it has been unregistered. | 321 // but not the dump provider, as it has been unregistered. |
| 364 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 322 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 365 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(3); | |
| 366 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); | 323 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
| 367 | |
| 368 for (int i = 0; i < 3; ++i) { | 324 for (int i = 0; i < 3; ++i) { |
| 369 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 325 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 370 MemoryDumpLevelOfDetail::DETAILED); | 326 MemoryDumpLevelOfDetail::DETAILED)); |
| 371 } | 327 } |
| 372 DisableTracing(); | 328 DisableTracing(); |
| 373 } | 329 } |
| 374 | 330 |
| 375 // Checks that requesting dumps with high level of detail actually propagates | 331 // Checks that requesting dumps with high level of detail actually propagates |
| 376 // the level of the detail properly to OnMemoryDump() call on dump providers. | 332 // the level of the detail properly to OnMemoryDump() call on dump providers. |
| 377 TEST_F(MemoryDumpManagerTest, CheckMemoryDumpArgs) { | 333 TEST_F(MemoryDumpManagerTest, CheckMemoryDumpArgs) { |
| 378 InitializeMemoryDumpManager(false /* is_coordinator */); | 334 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 379 MockMemoryDumpProvider mdp; | 335 MockMemoryDumpProvider mdp; |
| 380 | 336 |
| 381 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); | 337 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); |
| 382 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 338 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 383 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1); | 339 EXPECT_CALL(mdp, OnMemoryDump(IsDetailedDump(), _)); |
| 384 EXPECT_CALL(mdp, OnMemoryDump(IsDetailedDump(), _)).WillOnce(Return(true)); | 340 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 385 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 341 MemoryDumpLevelOfDetail::DETAILED)); |
| 386 MemoryDumpLevelOfDetail::DETAILED); | |
| 387 DisableTracing(); | 342 DisableTracing(); |
| 388 mdm_->UnregisterDumpProvider(&mdp); | 343 mdm_->UnregisterDumpProvider(&mdp); |
| 389 | 344 |
| 390 // Check that requesting dumps with low level of detail actually propagates to | 345 // Check that requesting dumps with low level of detail actually propagates to |
| 391 // OnMemoryDump() call on dump providers. | 346 // OnMemoryDump() call on dump providers. |
| 392 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); | 347 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); |
| 393 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 348 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 394 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1); | 349 EXPECT_CALL(mdp, OnMemoryDump(IsLightDump(), _)); |
| 395 EXPECT_CALL(mdp, OnMemoryDump(IsLightDump(), _)).WillOnce(Return(true)); | 350 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 396 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 351 MemoryDumpLevelOfDetail::LIGHT)); |
| 397 MemoryDumpLevelOfDetail::LIGHT); | |
| 398 DisableTracing(); | 352 DisableTracing(); |
| 399 mdm_->UnregisterDumpProvider(&mdp); | 353 mdm_->UnregisterDumpProvider(&mdp); |
| 400 } | 354 } |
| 401 | 355 |
| 402 // Checks that the HeapProfilerSerializationState object is actually | 356 // Checks that the HeapProfilerSerializationState object is actually |
| 403 // shared over time. | 357 // shared over time. |
| 404 TEST_F(MemoryDumpManagerTest, HeapProfilerSerializationState) { | 358 TEST_F(MemoryDumpManagerTest, HeapProfilerSerializationState) { |
| 405 InitializeMemoryDumpManager(false /* is_coordinator */); | 359 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 406 MockMemoryDumpProvider mdp1; | 360 MockMemoryDumpProvider mdp1; |
| 407 MockMemoryDumpProvider mdp2; | 361 MockMemoryDumpProvider mdp2; |
| 408 RegisterDumpProvider(&mdp1, nullptr); | 362 RegisterDumpProvider(&mdp1, nullptr); |
| 409 RegisterDumpProvider(&mdp2, nullptr); | 363 RegisterDumpProvider(&mdp2, nullptr); |
| 410 | 364 |
| 411 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 365 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 412 const HeapProfilerSerializationState* heap_profiler_serialization_state = | 366 const HeapProfilerSerializationState* heap_profiler_serialization_state = |
| 413 mdm_->heap_profiler_serialization_state_for_testing().get(); | 367 mdm_->heap_profiler_serialization_state_for_testing().get(); |
| 414 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(2); | |
| 415 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) | 368 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) |
| 416 .Times(2) | 369 .Times(2) |
| 417 .WillRepeatedly( | 370 .WillRepeatedly( |
| 418 Invoke([heap_profiler_serialization_state]( | 371 Invoke([heap_profiler_serialization_state]( |
| 419 const MemoryDumpArgs&, ProcessMemoryDump* pmd) -> bool { | 372 const MemoryDumpArgs&, ProcessMemoryDump* pmd) -> bool { |
| 420 EXPECT_EQ(heap_profiler_serialization_state, | 373 EXPECT_EQ(heap_profiler_serialization_state, |
| 421 pmd->heap_profiler_serialization_state().get()); | 374 pmd->heap_profiler_serialization_state().get()); |
| 422 return true; | 375 return true; |
| 423 })); | 376 })); |
| 424 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) | 377 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) |
| 425 .Times(2) | 378 .Times(2) |
| 426 .WillRepeatedly( | 379 .WillRepeatedly( |
| 427 Invoke([heap_profiler_serialization_state]( | 380 Invoke([heap_profiler_serialization_state]( |
| 428 const MemoryDumpArgs&, ProcessMemoryDump* pmd) -> bool { | 381 const MemoryDumpArgs&, ProcessMemoryDump* pmd) -> bool { |
| 429 EXPECT_EQ(heap_profiler_serialization_state, | 382 EXPECT_EQ(heap_profiler_serialization_state, |
| 430 pmd->heap_profiler_serialization_state().get()); | 383 pmd->heap_profiler_serialization_state().get()); |
| 431 return true; | 384 return true; |
| 432 })); | 385 })); |
| 433 | 386 |
| 434 for (int i = 0; i < 2; ++i) { | 387 for (int i = 0; i < 2; ++i) { |
| 435 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 388 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 436 MemoryDumpLevelOfDetail::DETAILED); | 389 MemoryDumpLevelOfDetail::DETAILED)); |
| 437 } | 390 } |
| 438 | 391 |
| 439 DisableTracing(); | 392 DisableTracing(); |
| 440 } | 393 } |
| 441 | 394 |
| 442 // Checks that the (Un)RegisterDumpProvider logic behaves sanely. | 395 // Checks that the (Un)RegisterDumpProvider logic behaves sanely. |
| 443 TEST_F(MemoryDumpManagerTest, MultipleDumpers) { | 396 TEST_F(MemoryDumpManagerTest, MultipleDumpers) { |
| 444 InitializeMemoryDumpManager(false /* is_coordinator */); | 397 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 445 MockMemoryDumpProvider mdp1; | 398 MockMemoryDumpProvider mdp1; |
| 446 MockMemoryDumpProvider mdp2; | 399 MockMemoryDumpProvider mdp2; |
| 447 | 400 |
| 448 // Enable only mdp1. | 401 // Enable only mdp1. |
| 449 RegisterDumpProvider(&mdp1, ThreadTaskRunnerHandle::Get()); | 402 RegisterDumpProvider(&mdp1, ThreadTaskRunnerHandle::Get()); |
| 450 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 403 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 451 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1); | 404 EXPECT_CALL(mdp1, OnMemoryDump(_, _)); |
| 452 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).WillOnce(Return(true)); | |
| 453 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(0); | 405 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(0); |
| 454 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 406 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 455 MemoryDumpLevelOfDetail::DETAILED); | 407 MemoryDumpLevelOfDetail::DETAILED)); |
| 456 DisableTracing(); | 408 DisableTracing(); |
| 457 | 409 |
| 458 // Invert: enable mdp1 and disable mdp2. | 410 // Invert: enable mdp2 and disable mdp1. |
| 459 mdm_->UnregisterDumpProvider(&mdp1); | 411 mdm_->UnregisterDumpProvider(&mdp1); |
| 460 RegisterDumpProvider(&mdp2, nullptr); | 412 RegisterDumpProvider(&mdp2, nullptr); |
| 461 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 413 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 462 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1); | |
| 463 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); | 414 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); |
| 464 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).WillOnce(Return(true)); | 415 EXPECT_CALL(mdp2, OnMemoryDump(_, _)); |
| 465 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 416 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 466 MemoryDumpLevelOfDetail::DETAILED); | 417 MemoryDumpLevelOfDetail::DETAILED)); |
| 467 DisableTracing(); | 418 DisableTracing(); |
| 468 | 419 |
| 469 // Enable both mdp1 and mdp2. | 420 // Enable both mdp1 and mdp2. |
| 470 RegisterDumpProvider(&mdp1, nullptr); | 421 RegisterDumpProvider(&mdp1, nullptr); |
| 471 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 422 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 472 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1); | 423 EXPECT_CALL(mdp1, OnMemoryDump(_, _)); |
| 473 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).WillOnce(Return(true)); | 424 EXPECT_CALL(mdp2, OnMemoryDump(_, _)); |
| 474 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).WillOnce(Return(true)); | 425 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 475 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 426 MemoryDumpLevelOfDetail::DETAILED)); |
| 476 MemoryDumpLevelOfDetail::DETAILED); | |
| 477 DisableTracing(); | 427 DisableTracing(); |
| 478 } | 428 } |
| 479 | 429 |
| 480 // Checks that the dump provider invocations depend only on the current | 430 // Checks that the dump provider invocations depend only on the current |
| 481 // registration state and not on previous registrations and dumps. | 431 // registration state and not on previous registrations and dumps. |
| 482 // Flaky on iOS, see crbug.com/706874 | 432 // Flaky on iOS, see crbug.com/706874 |
| 483 #if defined(OS_IOS) | 433 #if defined(OS_IOS) |
| 484 #define MAYBE_RegistrationConsistency DISABLED_RegistrationConsistency | 434 #define MAYBE_RegistrationConsistency DISABLED_RegistrationConsistency |
| 485 #else | 435 #else |
| 486 #define MAYBE_RegistrationConsistency RegistrationConsistency | 436 #define MAYBE_RegistrationConsistency RegistrationConsistency |
| 487 #endif | 437 #endif |
| 488 TEST_F(MemoryDumpManagerTest, MAYBE_RegistrationConsistency) { | 438 TEST_F(MemoryDumpManagerTest, MAYBE_RegistrationConsistency) { |
| 489 InitializeMemoryDumpManager(false /* is_coordinator */); | 439 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 490 MockMemoryDumpProvider mdp; | 440 MockMemoryDumpProvider mdp; |
| 491 | 441 |
| 492 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); | 442 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); |
| 493 | 443 |
| 494 { | 444 { |
| 495 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1); | 445 EXPECT_CALL(mdp, OnMemoryDump(_, _)); |
| 496 EXPECT_CALL(mdp, OnMemoryDump(_, _)).WillOnce(Return(true)); | |
| 497 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 446 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 498 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 447 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 499 MemoryDumpLevelOfDetail::DETAILED); | 448 MemoryDumpLevelOfDetail::DETAILED)); |
| 500 DisableTracing(); | 449 DisableTracing(); |
| 501 } | 450 } |
| 502 | 451 |
| 503 mdm_->UnregisterDumpProvider(&mdp); | 452 mdm_->UnregisterDumpProvider(&mdp); |
| 504 | 453 |
| 505 { | 454 { |
| 506 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1); | |
| 507 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); | 455 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
| 508 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 456 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 509 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 457 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 510 MemoryDumpLevelOfDetail::DETAILED); | 458 MemoryDumpLevelOfDetail::DETAILED)); |
| 511 DisableTracing(); | 459 DisableTracing(); |
| 512 } | 460 } |
| 513 | 461 |
| 514 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); | 462 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); |
| 515 mdm_->UnregisterDumpProvider(&mdp); | 463 mdm_->UnregisterDumpProvider(&mdp); |
| 516 | 464 |
| 517 { | 465 { |
| 518 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1); | |
| 519 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); | 466 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
| 520 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 467 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 521 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 468 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 522 MemoryDumpLevelOfDetail::DETAILED); | 469 MemoryDumpLevelOfDetail::DETAILED)); |
| 523 DisableTracing(); | 470 DisableTracing(); |
| 524 } | 471 } |
| 525 | 472 |
| 526 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); | 473 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); |
| 527 mdm_->UnregisterDumpProvider(&mdp); | 474 mdm_->UnregisterDumpProvider(&mdp); |
| 528 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); | 475 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); |
| 529 | 476 |
| 530 { | 477 { |
| 531 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1); | 478 EXPECT_CALL(mdp, OnMemoryDump(_, _)); |
| 532 EXPECT_CALL(mdp, OnMemoryDump(_, _)).WillOnce(Return(true)); | |
| 533 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 479 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 534 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 480 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 535 MemoryDumpLevelOfDetail::DETAILED); | 481 MemoryDumpLevelOfDetail::DETAILED)); |
| 536 DisableTracing(); | 482 DisableTracing(); |
| 537 } | 483 } |
| 538 } | 484 } |
| 539 | 485 |
| 540 // Checks that the MemoryDumpManager respects the thread affinity when a | 486 // Checks that the MemoryDumpManager respects the thread affinity when a |
| 541 // MemoryDumpProvider specifies a task_runner(). The test starts creating 8 | 487 // MemoryDumpProvider specifies a task_runner(). The test starts creating 8 |
| 542 // threads and registering a MemoryDumpProvider on each of them. At each | 488 // threads and registering a MemoryDumpProvider on each of them. At each |
| 543 // iteration, one thread is removed, to check the live unregistration logic. | 489 // iteration, one thread is removed, to check the live unregistration logic. |
| 544 TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) { | 490 TEST_F(MemoryDumpManagerTest, RespectTaskRunnerAffinity) { |
| 545 InitializeMemoryDumpManager(false /* is_coordinator */); | 491 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 546 const uint32_t kNumInitialThreads = 8; | 492 const uint32_t kNumInitialThreads = 8; |
| 547 | 493 |
| 548 std::vector<std::unique_ptr<Thread>> threads; | 494 std::vector<std::unique_ptr<Thread>> threads; |
| 549 std::vector<std::unique_ptr<MockMemoryDumpProvider>> mdps; | 495 std::vector<std::unique_ptr<MockMemoryDumpProvider>> mdps; |
| 550 | 496 |
| 551 // Create the threads and setup the expectations. Given that at each iteration | 497 // Create the threads and setup the expectations. Given that at each iteration |
| 552 // we will pop out one thread/MemoryDumpProvider, each MDP is supposed to be | 498 // we will pop out one thread/MemoryDumpProvider, each MDP is supposed to be |
| 553 // invoked a number of times equal to its index. | 499 // invoked a number of times equal to its index. |
| 554 for (uint32_t i = kNumInitialThreads; i > 0; --i) { | 500 for (uint32_t i = kNumInitialThreads; i > 0; --i) { |
| 555 threads.push_back(WrapUnique(new Thread("test thread"))); | 501 threads.push_back(WrapUnique(new Thread("test thread"))); |
| 556 auto* thread = threads.back().get(); | 502 auto* thread = threads.back().get(); |
| 557 thread->Start(); | 503 thread->Start(); |
| 558 scoped_refptr<SingleThreadTaskRunner> task_runner = thread->task_runner(); | 504 scoped_refptr<SingleThreadTaskRunner> task_runner = thread->task_runner(); |
| 559 mdps.push_back(WrapUnique(new MockMemoryDumpProvider())); | 505 mdps.push_back(WrapUnique(new MockMemoryDumpProvider())); |
| 560 auto* mdp = mdps.back().get(); | 506 auto* mdp = mdps.back().get(); |
| 561 RegisterDumpProvider(mdp, task_runner, kDefaultOptions); | 507 RegisterDumpProvider(mdp, task_runner, kDefaultOptions); |
| 562 EXPECT_CALL(*mdp, OnMemoryDump(_, _)) | 508 EXPECT_CALL(*mdp, OnMemoryDump(_, _)) |
| 563 .Times(i) | 509 .Times(i) |
| 564 .WillRepeatedly(Invoke( | 510 .WillRepeatedly(Invoke( |
| 565 [task_runner](const MemoryDumpArgs&, ProcessMemoryDump*) -> bool { | 511 [task_runner](const MemoryDumpArgs&, ProcessMemoryDump*) -> bool { |
| 566 EXPECT_TRUE(task_runner->RunsTasksOnCurrentThread()); | 512 EXPECT_TRUE(task_runner->RunsTasksOnCurrentThread()); |
| 567 return true; | 513 return true; |
| 568 })); | 514 })); |
| 569 } | 515 } |
| 570 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 516 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 571 | 517 |
| 572 while (!threads.empty()) { | 518 while (!threads.empty()) { |
| 573 last_callback_success_ = false; | 519 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 574 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1); | 520 MemoryDumpLevelOfDetail::DETAILED)); |
| 575 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | |
| 576 MemoryDumpLevelOfDetail::DETAILED); | |
| 577 EXPECT_TRUE(last_callback_success_); | |
| 578 | 521 |
| 579 // Unregister a MDP and destroy one thread at each iteration to check the | 522 // Unregister a MDP and destroy one thread at each iteration to check the |
| 580 // live unregistration logic. The unregistration needs to happen on the same | 523 // live unregistration logic. The unregistration needs to happen on the same |
| 581 // thread the MDP belongs to. | 524 // thread the MDP belongs to. |
| 582 { | 525 { |
| 583 RunLoop run_loop; | 526 RunLoop run_loop; |
| 584 Closure unregistration = | 527 Closure unregistration = |
| 585 Bind(&MemoryDumpManager::UnregisterDumpProvider, | 528 Bind(&MemoryDumpManager::UnregisterDumpProvider, |
| 586 Unretained(mdm_.get()), Unretained(mdps.back().get())); | 529 Unretained(mdm_.get()), Unretained(mdps.back().get())); |
| 587 threads.back()->task_runner()->PostTaskAndReply(FROM_HERE, unregistration, | 530 threads.back()->task_runner()->PostTaskAndReply(FROM_HERE, unregistration, |
| 588 run_loop.QuitClosure()); | 531 run_loop.QuitClosure()); |
| 589 run_loop.Run(); | 532 run_loop.Run(); |
| 590 } | 533 } |
| 591 mdps.pop_back(); | 534 mdps.pop_back(); |
| 592 threads.back()->Stop(); | 535 threads.back()->Stop(); |
| 593 threads.pop_back(); | 536 threads.pop_back(); |
| 594 } | 537 } |
| 595 | 538 |
| 596 DisableTracing(); | 539 DisableTracing(); |
| 597 } | 540 } |
| 598 | 541 |
| 599 // Check that the memory dump calls are always posted on task runner for | 542 // Check that the memory dump calls are always posted on task runner for |
| 600 // SequencedTaskRunner case and that the dump provider gets disabled when | 543 // SequencedTaskRunner case and that the dump provider gets disabled when |
| 601 // PostTask fails, but the dump still succeeds. | 544 // PostTask fails, but the dump still succeeds. |
| 602 TEST_F(MemoryDumpManagerTest, PostTaskForSequencedTaskRunner) { | 545 TEST_F(MemoryDumpManagerTest, PostTaskForSequencedTaskRunner) { |
| 603 InitializeMemoryDumpManager(false /* is_coordinator */); | 546 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 604 std::vector<MockMemoryDumpProvider> mdps(3); | 547 std::vector<MockMemoryDumpProvider> mdps(3); |
| 605 scoped_refptr<TestSequencedTaskRunner> task_runner1( | 548 scoped_refptr<TestSequencedTaskRunner> task_runner1( |
| 606 make_scoped_refptr(new TestSequencedTaskRunner())); | 549 make_scoped_refptr(new TestSequencedTaskRunner())); |
| 607 scoped_refptr<TestSequencedTaskRunner> task_runner2( | 550 scoped_refptr<TestSequencedTaskRunner> task_runner2( |
| 608 make_scoped_refptr(new TestSequencedTaskRunner())); | 551 make_scoped_refptr(new TestSequencedTaskRunner())); |
| 609 RegisterDumpProviderWithSequencedTaskRunner(&mdps[0], task_runner1, | 552 RegisterDumpProviderWithSequencedTaskRunner(&mdps[0], task_runner1, |
| 610 kDefaultOptions); | 553 kDefaultOptions); |
| 611 RegisterDumpProviderWithSequencedTaskRunner(&mdps[1], task_runner2, | 554 RegisterDumpProviderWithSequencedTaskRunner(&mdps[1], task_runner2, |
| 612 kDefaultOptions); | 555 kDefaultOptions); |
| 613 RegisterDumpProviderWithSequencedTaskRunner(&mdps[2], task_runner2, | 556 RegisterDumpProviderWithSequencedTaskRunner(&mdps[2], task_runner2, |
| 614 kDefaultOptions); | 557 kDefaultOptions); |
| 615 // |mdps[0]| should be disabled permanently after first dump. | 558 // |mdps[0]| should be disabled permanently after first dump. |
| 616 EXPECT_CALL(mdps[0], OnMemoryDump(_, _)).Times(0); | 559 EXPECT_CALL(mdps[0], OnMemoryDump(_, _)).Times(0); |
| 617 EXPECT_CALL(mdps[1], OnMemoryDump(_, _)).Times(2); | 560 EXPECT_CALL(mdps[1], OnMemoryDump(_, _)).Times(2); |
| 618 EXPECT_CALL(mdps[2], OnMemoryDump(_, _)).Times(2); | 561 EXPECT_CALL(mdps[2], OnMemoryDump(_, _)).Times(2); |
| 619 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(2); | |
| 620 | 562 |
| 621 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 563 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 622 | 564 |
| 623 task_runner1->set_enabled(false); | 565 task_runner1->set_enabled(false); |
| 624 last_callback_success_ = false; | 566 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 625 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 567 MemoryDumpLevelOfDetail::DETAILED)); |
| 626 MemoryDumpLevelOfDetail::DETAILED); | |
| 627 // Tasks should be individually posted even if |mdps[1]| and |mdps[2]| belong | 568 // Tasks should be individually posted even if |mdps[1]| and |mdps[2]| belong |
| 628 // to same task runner. | 569 // to same task runner. |
| 629 EXPECT_EQ(1u, task_runner1->no_of_post_tasks()); | 570 EXPECT_EQ(1u, task_runner1->no_of_post_tasks()); |
| 630 EXPECT_EQ(2u, task_runner2->no_of_post_tasks()); | 571 EXPECT_EQ(2u, task_runner2->no_of_post_tasks()); |
| 631 EXPECT_TRUE(last_callback_success_); | |
| 632 | 572 |
| 633 task_runner1->set_enabled(true); | 573 task_runner1->set_enabled(true); |
| 634 last_callback_success_ = false; | 574 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 635 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 575 MemoryDumpLevelOfDetail::DETAILED)); |
| 636 MemoryDumpLevelOfDetail::DETAILED); | |
| 637 EXPECT_EQ(2u, task_runner1->no_of_post_tasks()); | 576 EXPECT_EQ(2u, task_runner1->no_of_post_tasks()); |
| 638 EXPECT_EQ(4u, task_runner2->no_of_post_tasks()); | 577 EXPECT_EQ(4u, task_runner2->no_of_post_tasks()); |
| 639 EXPECT_TRUE(last_callback_success_); | |
| 640 DisableTracing(); | 578 DisableTracing(); |
| 641 } | 579 } |
| 642 | 580 |
| 643 // Checks that providers get disabled after 3 consecutive failures, but not | 581 // Checks that providers get disabled after 3 consecutive failures, but not |
| 644 // otherwise (e.g., if interleaved). | 582 // otherwise (e.g., if interleaved). |
| 645 TEST_F(MemoryDumpManagerTest, DisableFailingDumpers) { | 583 TEST_F(MemoryDumpManagerTest, DisableFailingDumpers) { |
| 646 InitializeMemoryDumpManager(false /* is_coordinator */); | 584 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 647 MockMemoryDumpProvider mdp1; | 585 MockMemoryDumpProvider mdp1; |
| 648 MockMemoryDumpProvider mdp2; | 586 MockMemoryDumpProvider mdp2; |
| 649 | 587 |
| 650 RegisterDumpProvider(&mdp1, nullptr); | 588 RegisterDumpProvider(&mdp1, nullptr); |
| 651 RegisterDumpProvider(&mdp2, nullptr); | 589 RegisterDumpProvider(&mdp2, nullptr); |
| 652 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 590 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 653 | 591 |
| 654 const int kNumDumps = 2 * GetMaxConsecutiveFailuresCount(); | |
| 655 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)) | |
| 656 .Times(kNumDumps); | |
| 657 | |
| 658 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) | 592 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) |
| 659 .Times(GetMaxConsecutiveFailuresCount()) | 593 .Times(GetMaxConsecutiveFailuresCount()) |
| 660 .WillRepeatedly(Return(false)); | 594 .WillRepeatedly(Return(false)); |
| 661 | 595 |
| 662 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) | 596 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) |
| 663 .WillOnce(Return(false)) | 597 .WillOnce(Return(false)) |
| 664 .WillOnce(Return(true)) | 598 .WillOnce(Return(true)) |
| 665 .WillOnce(Return(false)) | 599 .WillOnce(Return(false)) |
| 666 .WillOnce(Return(false)) | 600 .WillOnce(Return(false)) |
| 667 .WillOnce(Return(true)) | 601 .WillOnce(Return(true)) |
| 668 .WillOnce(Return(false)); | 602 .WillOnce(Return(false)); |
| 669 | 603 |
| 604 const int kNumDumps = 2 * GetMaxConsecutiveFailuresCount(); |
| 670 for (int i = 0; i < kNumDumps; i++) { | 605 for (int i = 0; i < kNumDumps; i++) { |
| 671 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 606 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 672 MemoryDumpLevelOfDetail::DETAILED); | 607 MemoryDumpLevelOfDetail::DETAILED)); |
| 673 } | 608 } |
| 674 | 609 |
| 675 DisableTracing(); | 610 DisableTracing(); |
| 676 } | 611 } |
| 677 | 612 |
| 678 // Sneakily registers an extra memory dump provider while an existing one is | 613 // Sneakily registers an extra memory dump provider while an existing one is |
| 679 // dumping and expect it to take part in the already active tracing session. | 614 // dumping and expect it to take part in the already active tracing session. |
| 680 TEST_F(MemoryDumpManagerTest, RegisterDumperWhileDumping) { | 615 TEST_F(MemoryDumpManagerTest, RegisterDumperWhileDumping) { |
| 681 InitializeMemoryDumpManager(false /* is_coordinator */); | 616 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 682 MockMemoryDumpProvider mdp1; | 617 MockMemoryDumpProvider mdp1; |
| 683 MockMemoryDumpProvider mdp2; | 618 MockMemoryDumpProvider mdp2; |
| 684 | 619 |
| 685 RegisterDumpProvider(&mdp1, nullptr); | 620 RegisterDumpProvider(&mdp1, nullptr); |
| 686 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 621 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 687 | 622 |
| 688 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(4); | |
| 689 | |
| 690 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) | 623 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) |
| 691 .Times(4) | 624 .Times(4) |
| 692 .WillOnce(Return(true)) | 625 .WillOnce(Return(true)) |
| 693 .WillOnce( | 626 .WillOnce( |
| 694 Invoke([&mdp2](const MemoryDumpArgs&, ProcessMemoryDump*) -> bool { | 627 Invoke([&mdp2](const MemoryDumpArgs&, ProcessMemoryDump*) -> bool { |
| 695 RegisterDumpProvider(&mdp2, nullptr); | 628 RegisterDumpProvider(&mdp2, nullptr); |
| 696 return true; | 629 return true; |
| 697 })) | 630 })); |
| 698 .WillRepeatedly(Return(true)); | |
| 699 | 631 |
| 700 // Depending on the insertion order (before or after mdp1), mdp2 might be | 632 // Depending on the insertion order (before or after mdp1), mdp2 might be |
| 701 // called also immediately after it gets registered. | 633 // called also immediately after it gets registered. |
| 702 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) | 634 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(Between(2, 3)); |
| 703 .Times(Between(2, 3)) | |
| 704 .WillRepeatedly(Return(true)); | |
| 705 | 635 |
| 706 for (int i = 0; i < 4; i++) { | 636 for (int i = 0; i < 4; i++) { |
| 707 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 637 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 708 MemoryDumpLevelOfDetail::DETAILED); | 638 MemoryDumpLevelOfDetail::DETAILED)); |
| 709 } | 639 } |
| 710 | 640 |
| 711 DisableTracing(); | 641 DisableTracing(); |
| 712 } | 642 } |
| 713 | 643 |
| 714 // Like RegisterDumperWhileDumping, but unregister the dump provider instead. | 644 // Like RegisterDumperWhileDumping, but unregister the dump provider instead. |
| 715 TEST_F(MemoryDumpManagerTest, UnregisterDumperWhileDumping) { | 645 TEST_F(MemoryDumpManagerTest, UnregisterDumperWhileDumping) { |
| 716 InitializeMemoryDumpManager(false /* is_coordinator */); | 646 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 717 MockMemoryDumpProvider mdp1; | 647 MockMemoryDumpProvider mdp1; |
| 718 MockMemoryDumpProvider mdp2; | 648 MockMemoryDumpProvider mdp2; |
| 719 | 649 |
| 720 RegisterDumpProvider(&mdp1, ThreadTaskRunnerHandle::Get(), kDefaultOptions); | 650 RegisterDumpProvider(&mdp1, ThreadTaskRunnerHandle::Get(), kDefaultOptions); |
| 721 RegisterDumpProvider(&mdp2, ThreadTaskRunnerHandle::Get(), kDefaultOptions); | 651 RegisterDumpProvider(&mdp2, ThreadTaskRunnerHandle::Get(), kDefaultOptions); |
| 722 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 652 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 723 | 653 |
| 724 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(4); | |
| 725 | |
| 726 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) | 654 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) |
| 727 .Times(4) | 655 .Times(4) |
| 728 .WillOnce(Return(true)) | 656 .WillOnce(Return(true)) |
| 729 .WillOnce( | 657 .WillOnce( |
| 730 Invoke([&mdp2](const MemoryDumpArgs&, ProcessMemoryDump*) -> bool { | 658 Invoke([&mdp2](const MemoryDumpArgs&, ProcessMemoryDump*) -> bool { |
| 731 MemoryDumpManager::GetInstance()->UnregisterDumpProvider(&mdp2); | 659 MemoryDumpManager::GetInstance()->UnregisterDumpProvider(&mdp2); |
| 732 return true; | 660 return true; |
| 733 })) | 661 })); |
| 734 .WillRepeatedly(Return(true)); | |
| 735 | 662 |
| 736 // Depending on the insertion order (before or after mdp1), mdp2 might have | 663 // Depending on the insertion order (before or after mdp1), mdp2 might have |
| 737 // been already called when UnregisterDumpProvider happens. | 664 // been already called when UnregisterDumpProvider happens. |
| 738 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) | 665 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(Between(1, 2)); |
| 739 .Times(Between(1, 2)) | |
| 740 .WillRepeatedly(Return(true)); | |
| 741 | 666 |
| 742 for (int i = 0; i < 4; i++) { | 667 for (int i = 0; i < 4; i++) { |
| 743 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 668 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 744 MemoryDumpLevelOfDetail::DETAILED); | 669 MemoryDumpLevelOfDetail::DETAILED)); |
| 745 } | 670 } |
| 746 | 671 |
| 747 DisableTracing(); | 672 DisableTracing(); |
| 748 } | 673 } |
| 749 | 674 |
| 750 // Checks that the dump does not abort when unregistering a provider while | 675 // Checks that the dump does not abort when unregistering a provider while |
| 751 // dumping from a different thread than the dumping thread. | 676 // dumping from a different thread than the dumping thread. |
| 752 TEST_F(MemoryDumpManagerTest, UnregisterDumperFromThreadWhileDumping) { | 677 TEST_F(MemoryDumpManagerTest, UnregisterDumperFromThreadWhileDumping) { |
| 753 InitializeMemoryDumpManager(false /* is_coordinator */); | 678 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 754 std::vector<std::unique_ptr<TestIOThread>> threads; | 679 std::vector<std::unique_ptr<TestIOThread>> threads; |
| 755 std::vector<std::unique_ptr<MockMemoryDumpProvider>> mdps; | 680 std::vector<std::unique_ptr<MockMemoryDumpProvider>> mdps; |
| 756 | 681 |
| 757 for (int i = 0; i < 2; i++) { | 682 for (int i = 0; i < 2; i++) { |
| 758 threads.push_back( | 683 threads.push_back( |
| 759 WrapUnique(new TestIOThread(TestIOThread::kAutoStart))); | 684 WrapUnique(new TestIOThread(TestIOThread::kAutoStart))); |
| 760 mdps.push_back(WrapUnique(new MockMemoryDumpProvider())); | 685 mdps.push_back(WrapUnique(new MockMemoryDumpProvider())); |
| 761 RegisterDumpProvider(mdps.back().get(), threads.back()->task_runner(), | 686 RegisterDumpProvider(mdps.back().get(), threads.back()->task_runner(), |
| 762 kDefaultOptions); | 687 kDefaultOptions); |
| 763 } | 688 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 782 return true; | 707 return true; |
| 783 }; | 708 }; |
| 784 | 709 |
| 785 // OnMemoryDump is called once for the provider that dumps first, and zero | 710 // OnMemoryDump is called once for the provider that dumps first, and zero |
| 786 // times for the other provider. | 711 // times for the other provider. |
| 787 EXPECT_CALL(*mdp, OnMemoryDump(_, _)) | 712 EXPECT_CALL(*mdp, OnMemoryDump(_, _)) |
| 788 .Times(AtMost(1)) | 713 .Times(AtMost(1)) |
| 789 .WillOnce(Invoke(on_dump)); | 714 .WillOnce(Invoke(on_dump)); |
| 790 } | 715 } |
| 791 | 716 |
| 792 last_callback_success_ = false; | |
| 793 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 717 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 794 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1); | 718 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 795 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 719 MemoryDumpLevelOfDetail::DETAILED)); |
| 796 MemoryDumpLevelOfDetail::DETAILED); | |
| 797 ASSERT_EQ(1, on_memory_dump_call_count); | 720 ASSERT_EQ(1, on_memory_dump_call_count); |
| 798 ASSERT_TRUE(last_callback_success_); | |
| 799 | 721 |
| 800 DisableTracing(); | 722 DisableTracing(); |
| 801 } | 723 } |
| 802 | 724 |
| 803 TEST_F(MemoryDumpManagerTest, TestPollingOnDumpThread) { | 725 TEST_F(MemoryDumpManagerTest, TestPollingOnDumpThread) { |
| 804 InitializeMemoryDumpManager(false /* is_coordinator */); | 726 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 805 std::unique_ptr<MockMemoryDumpProvider> mdp1(new MockMemoryDumpProvider()); | 727 std::unique_ptr<MockMemoryDumpProvider> mdp1(new MockMemoryDumpProvider()); |
| 806 std::unique_ptr<MockMemoryDumpProvider> mdp2(new MockMemoryDumpProvider()); | 728 std::unique_ptr<MockMemoryDumpProvider> mdp2(new MockMemoryDumpProvider()); |
| 807 mdp1->enable_mock_destructor = true; | 729 mdp1->enable_mock_destructor = true; |
| 808 mdp2->enable_mock_destructor = true; | 730 mdp2->enable_mock_destructor = true; |
| 809 EXPECT_CALL(*mdp1, Destructor()); | 731 EXPECT_CALL(*mdp1, Destructor()); |
| 810 EXPECT_CALL(*mdp2, Destructor()); | 732 EXPECT_CALL(*mdp2, Destructor()); |
| 811 | 733 |
| 812 MemoryDumpProvider::Options options; | 734 MemoryDumpProvider::Options options; |
| 813 options.is_fast_polling_supported = true; | 735 options.is_fast_polling_supported = true; |
| 814 RegisterDumpProvider(mdp1.get(), nullptr, options); | 736 RegisterDumpProvider(mdp1.get(), nullptr, options); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 846 EnableTracingWithTraceConfig( | 768 EnableTracingWithTraceConfig( |
| 847 TraceConfigMemoryTestUtil::GetTraceConfig_PeakDetectionTrigger(1)); | 769 TraceConfigMemoryTestUtil::GetTraceConfig_PeakDetectionTrigger(1)); |
| 848 run_loop.Run(); | 770 run_loop.Run(); |
| 849 DisableTracing(); | 771 DisableTracing(); |
| 850 mdm_->UnregisterAndDeleteDumpProviderSoon(std::move(mdp1)); | 772 mdm_->UnregisterAndDeleteDumpProviderSoon(std::move(mdp1)); |
| 851 } | 773 } |
| 852 | 774 |
| 853 // If a thread (with a dump provider living on it) is torn down during a dump | 775 // If a thread (with a dump provider living on it) is torn down during a dump |
| 854 // its dump provider should be skipped but the dump itself should succeed. | 776 // its dump provider should be skipped but the dump itself should succeed. |
| 855 TEST_F(MemoryDumpManagerTest, TearDownThreadWhileDumping) { | 777 TEST_F(MemoryDumpManagerTest, TearDownThreadWhileDumping) { |
| 856 InitializeMemoryDumpManager(false /* is_coordinator */); | 778 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 857 std::vector<std::unique_ptr<TestIOThread>> threads; | 779 std::vector<std::unique_ptr<TestIOThread>> threads; |
| 858 std::vector<std::unique_ptr<MockMemoryDumpProvider>> mdps; | 780 std::vector<std::unique_ptr<MockMemoryDumpProvider>> mdps; |
| 859 | 781 |
| 860 for (int i = 0; i < 2; i++) { | 782 for (int i = 0; i < 2; i++) { |
| 861 threads.push_back( | 783 threads.push_back( |
| 862 WrapUnique(new TestIOThread(TestIOThread::kAutoStart))); | 784 WrapUnique(new TestIOThread(TestIOThread::kAutoStart))); |
| 863 mdps.push_back(WrapUnique(new MockMemoryDumpProvider())); | 785 mdps.push_back(WrapUnique(new MockMemoryDumpProvider())); |
| 864 RegisterDumpProvider(mdps.back().get(), threads.back()->task_runner(), | 786 RegisterDumpProvider(mdps.back().get(), threads.back()->task_runner(), |
| 865 kDefaultOptions); | 787 kDefaultOptions); |
| 866 } | 788 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 884 return true; | 806 return true; |
| 885 }; | 807 }; |
| 886 | 808 |
| 887 // OnMemoryDump is called once for the provider that dumps first, and zero | 809 // OnMemoryDump is called once for the provider that dumps first, and zero |
| 888 // times for the other provider. | 810 // times for the other provider. |
| 889 EXPECT_CALL(*mdp, OnMemoryDump(_, _)) | 811 EXPECT_CALL(*mdp, OnMemoryDump(_, _)) |
| 890 .Times(AtMost(1)) | 812 .Times(AtMost(1)) |
| 891 .WillOnce(Invoke(on_dump)); | 813 .WillOnce(Invoke(on_dump)); |
| 892 } | 814 } |
| 893 | 815 |
| 894 last_callback_success_ = false; | |
| 895 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 816 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 896 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1); | 817 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 897 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 818 MemoryDumpLevelOfDetail::DETAILED)); |
| 898 MemoryDumpLevelOfDetail::DETAILED); | |
| 899 ASSERT_EQ(1, on_memory_dump_call_count); | 819 ASSERT_EQ(1, on_memory_dump_call_count); |
| 900 ASSERT_TRUE(last_callback_success_); | |
| 901 | 820 |
| 902 DisableTracing(); | 821 DisableTracing(); |
| 903 } | 822 } |
| 904 | 823 |
| 905 // Checks that a NACK callback is invoked if RequestGlobalDump() is called when | 824 // Checks that a NACK callback is invoked if CreateProcessDump() is called when |
| 906 // tracing is not enabled. | 825 // tracing is not enabled. |
| 907 TEST_F(MemoryDumpManagerTest, CallbackCalledOnFailure) { | 826 TEST_F(MemoryDumpManagerTest, CallbackCalledOnFailure) { |
| 908 InitializeMemoryDumpManager(false /* is_coordinator */); | 827 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 909 MockMemoryDumpProvider mdp1; | 828 MockMemoryDumpProvider mdp; |
| 910 RegisterDumpProvider(&mdp1, nullptr); | 829 RegisterDumpProvider(&mdp, nullptr); |
| 911 | 830 EXPECT_CALL(mdp, OnMemoryDump(_, _)); |
| 912 last_callback_success_ = true; | 831 EXPECT_FALSE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 913 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 832 MemoryDumpLevelOfDetail::DETAILED)); |
| 914 MemoryDumpLevelOfDetail::DETAILED); | |
| 915 EXPECT_FALSE(last_callback_success_); | |
| 916 } | 833 } |
| 917 | 834 |
| 918 // Checks that is the MemoryDumpManager is initialized after tracing already | 835 // Checks that is the MemoryDumpManager is initialized after tracing already |
| 919 // began, it will still late-join the party (real use case: startup tracing). | 836 // began, it will still late-join the party (real use case: startup tracing). |
| 920 TEST_F(MemoryDumpManagerTest, InitializedAfterStartOfTracing) { | 837 TEST_F(MemoryDumpManagerTest, InitializedAfterStartOfTracing) { |
| 921 MockMemoryDumpProvider mdp; | 838 MockMemoryDumpProvider mdp; |
| 922 RegisterDumpProvider(&mdp, nullptr); | 839 RegisterDumpProvider(&mdp, nullptr); |
| 923 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 840 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 924 | 841 |
| 925 // First check that a RequestGlobalDump() issued before the MemoryDumpManager | 842 // First check that a CreateProcessDump() issued before the MemoryDumpManager |
| 926 // initialization gets NACK-ed cleanly. | 843 // initialization gets NACK-ed cleanly. |
| 927 { | 844 { |
| 845 testing::InSequence sequence; |
| 928 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); | 846 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
| 929 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 847 EXPECT_FALSE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 930 MemoryDumpLevelOfDetail::DETAILED); | 848 MemoryDumpLevelOfDetail::DETAILED)); |
| 931 EXPECT_FALSE(last_callback_success_); | |
| 932 } | 849 } |
| 933 | 850 |
| 934 // Now late-initialize the MemoryDumpManager and check that the | 851 // Now late-initialize the MemoryDumpManager and check that the |
| 935 // RequestGlobalDump completes successfully. | 852 // CreateProcessDump() completes successfully. |
| 936 { | 853 { |
| 937 InitializeMemoryDumpManager(false /* is_coordinator */); | 854 testing::InSequence sequence; |
| 855 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 938 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(1); | 856 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(1); |
| 939 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1); | 857 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 940 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 858 MemoryDumpLevelOfDetail::DETAILED)); |
| 941 MemoryDumpLevelOfDetail::DETAILED); | |
| 942 EXPECT_TRUE(last_callback_success_); | |
| 943 } | 859 } |
| 944 DisableTracing(); | 860 DisableTracing(); |
| 945 } | 861 } |
| 946 | 862 |
| 947 // This test (and the MemoryDumpManagerTestCoordinator below) crystallizes the | 863 // This test (and the MemoryDumpManagerTestCoordinator below) crystallizes the |
| 948 // expectations of the chrome://tracing UI and chrome telemetry w.r.t. periodic | 864 // expectations of the chrome://tracing UI and chrome telemetry w.r.t. periodic |
| 949 // dumps in memory-infra, handling gracefully the transition between the legacy | 865 // dumps in memory-infra, handling gracefully the transition between the legacy |
| 950 // and the new-style (JSON-based) TraceConfig. | 866 // and the new-style (JSON-based) TraceConfig. |
| 951 TEST_F(MemoryDumpManagerTest, TraceConfigExpectations) { | 867 TEST_F(MemoryDumpManagerTest, TraceConfigExpectations) { |
| 952 InitializeMemoryDumpManager(false /* is_coordinator */); | 868 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 953 | 869 |
| 954 // Don't trigger the default behavior of the global dump handler in this test, | 870 // We don't need to create any dump in this test, only check whether the dumps |
| 955 // which would short-circuit the dump request to the actual | |
| 956 // CreateProcessDump(). | |
| 957 // We don't want to create any dump in this test, only check whether the dumps | |
| 958 // are requested or not. | 871 // are requested or not. |
| 959 ON_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)) | |
| 960 .WillByDefault(Return()); | |
| 961 | 872 |
| 962 // Enabling memory-infra in a non-coordinator process should not trigger any | 873 // Enabling memory-infra in a non-coordinator process should not trigger any |
| 963 // periodic dumps. | 874 // periodic dumps. |
| 964 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 875 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 965 EXPECT_FALSE(IsPeriodicDumpingEnabled()); | 876 EXPECT_FALSE(IsPeriodicDumpingEnabled()); |
| 966 DisableTracing(); | 877 DisableTracing(); |
| 967 | 878 |
| 968 // Enabling memory-infra with the new (JSON) TraceConfig in a non-coordinator | 879 // Enabling memory-infra with the new (JSON) TraceConfig in a non-coordinator |
| 969 // process with a fully defined trigger config should NOT enable any periodic | 880 // process with a fully defined trigger config should NOT enable any periodic |
| 970 // dumps. | 881 // dumps. |
| 971 EnableTracingWithTraceConfig( | 882 EnableTracingWithTraceConfig( |
| 972 TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers(1, 5)); | 883 TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers(1, 5)); |
| 973 EXPECT_FALSE(IsPeriodicDumpingEnabled()); | 884 EXPECT_FALSE(IsPeriodicDumpingEnabled()); |
| 974 DisableTracing(); | 885 DisableTracing(); |
| 975 } | 886 } |
| 976 | 887 |
| 977 TEST_F(MemoryDumpManagerTest, TraceConfigExpectationsWhenIsCoordinator) { | 888 TEST_F(MemoryDumpManagerTest, TraceConfigExpectationsWhenIsCoordinator) { |
| 978 InitializeMemoryDumpManager(true /* is_coordinator */); | 889 InitializeMemoryDumpManagerForInProcessTesting(true /* is_coordinator */); |
| 979 ON_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)) | |
| 980 .WillByDefault(Return()); | |
| 981 | 890 |
| 982 // Enabling memory-infra with the legacy TraceConfig (category filter) in | 891 // Enabling memory-infra with the legacy TraceConfig (category filter) in |
| 983 // a coordinator process should not enable periodic dumps. | 892 // a coordinator process should not enable periodic dumps. |
| 984 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 893 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 985 EXPECT_FALSE(IsPeriodicDumpingEnabled()); | 894 EXPECT_FALSE(IsPeriodicDumpingEnabled()); |
| 986 DisableTracing(); | 895 DisableTracing(); |
| 987 | 896 |
| 988 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator | 897 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator |
| 989 // process while specifying a "memory_dump_config" section should enable | 898 // process while specifying a "memory_dump_config" section should enable |
| 990 // periodic dumps. This is to preserve the behavior chrome://tracing UI, that | 899 // periodic dumps. This is to preserve the behavior chrome://tracing UI, that |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1006 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator | 915 // Enabling memory-infra with the new (JSON) TraceConfig in a coordinator |
| 1007 // process with a fully defined trigger config should cause periodic dumps to | 916 // process with a fully defined trigger config should cause periodic dumps to |
| 1008 // be performed in the correct order. | 917 // be performed in the correct order. |
| 1009 RunLoop run_loop; | 918 RunLoop run_loop; |
| 1010 auto test_task_runner = ThreadTaskRunnerHandle::Get(); | 919 auto test_task_runner = ThreadTaskRunnerHandle::Get(); |
| 1011 auto quit_closure = run_loop.QuitClosure(); | 920 auto quit_closure = run_loop.QuitClosure(); |
| 1012 | 921 |
| 1013 const int kHeavyDumpRate = 5; | 922 const int kHeavyDumpRate = 5; |
| 1014 const int kLightDumpPeriodMs = 1; | 923 const int kLightDumpPeriodMs = 1; |
| 1015 const int kHeavyDumpPeriodMs = kHeavyDumpRate * kLightDumpPeriodMs; | 924 const int kHeavyDumpPeriodMs = kHeavyDumpRate * kLightDumpPeriodMs; |
| 925 |
| 1016 // The expected sequence with light=1ms, heavy=5ms is H,L,L,L,L,H,... | 926 // The expected sequence with light=1ms, heavy=5ms is H,L,L,L,L,H,... |
| 927 MockMemoryDumpProvider mdp; |
| 928 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); |
| 929 |
| 1017 testing::InSequence sequence; | 930 testing::InSequence sequence; |
| 1018 EXPECT_CALL(global_dump_handler_, | 931 EXPECT_CALL(mdp, OnMemoryDump(IsDetailedDump(), _)); |
| 1019 RequestGlobalMemoryDump(IsDetailedDump(), _)); | 932 EXPECT_CALL(mdp, OnMemoryDump(IsLightDump(), _)).Times(kHeavyDumpRate - 1); |
| 1020 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(IsLightDump(), _)) | 933 EXPECT_CALL(mdp, OnMemoryDump(IsDetailedDump(), _)); |
| 1021 .Times(kHeavyDumpRate - 1); | 934 EXPECT_CALL(mdp, OnMemoryDump(IsLightDump(), _)).Times(kHeavyDumpRate - 2); |
| 1022 EXPECT_CALL(global_dump_handler_, | 935 EXPECT_CALL(mdp, OnMemoryDump(IsLightDump(), _)) |
| 1023 RequestGlobalMemoryDump(IsDetailedDump(), _)); | 936 .WillOnce(Invoke([test_task_runner, quit_closure](const MemoryDumpArgs&, |
| 1024 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(IsLightDump(), _)) | 937 ProcessMemoryDump*) { |
| 1025 .Times(kHeavyDumpRate - 2); | |
| 1026 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(IsLightDump(), _)) | |
| 1027 .WillOnce(Invoke([test_task_runner, quit_closure]( | |
| 1028 const MemoryDumpRequestArgs& args, | |
| 1029 const GlobalMemoryDumpCallback& callback) { | |
| 1030 test_task_runner->PostTask(FROM_HERE, quit_closure); | 938 test_task_runner->PostTask(FROM_HERE, quit_closure); |
| 939 return true; |
| 1031 })); | 940 })); |
| 1032 | 941 |
| 1033 // Swallow all the final spurious calls until tracing gets disabled. | 942 // Swallow all the final spurious calls until tracing gets disabled. |
| 1034 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)) | 943 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(AnyNumber()); |
| 1035 .Times(AnyNumber()); | |
| 1036 | 944 |
| 1037 EnableTracingWithTraceConfig( | 945 EnableTracingWithTraceConfig( |
| 1038 TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers( | 946 TraceConfigMemoryTestUtil::GetTraceConfig_PeriodicTriggers( |
| 1039 kLightDumpPeriodMs, kHeavyDumpPeriodMs)); | 947 kLightDumpPeriodMs, kHeavyDumpPeriodMs)); |
| 1040 run_loop.Run(); | 948 run_loop.Run(); |
| 1041 DisableTracing(); | 949 DisableTracing(); |
| 1042 } | 950 } |
| 1043 | 951 |
| 1044 TEST_F(MemoryDumpManagerTest, DumpOnBehalfOfOtherProcess) { | 952 TEST_F(MemoryDumpManagerTest, DumpOnBehalfOfOtherProcess) { |
| 1045 using trace_analyzer::Query; | 953 using trace_analyzer::Query; |
| 1046 | 954 |
| 1047 InitializeMemoryDumpManager(false /* is_coordinator */); | 955 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 1048 | 956 |
| 1049 // Standard provider with default options (create dump for current process). | 957 // Standard provider with default options (create dump for current process). |
| 1050 MemoryDumpProvider::Options options; | 958 MemoryDumpProvider::Options options; |
| 1051 MockMemoryDumpProvider mdp1; | 959 MockMemoryDumpProvider mdp1; |
| 1052 RegisterDumpProvider(&mdp1, nullptr, options); | 960 RegisterDumpProvider(&mdp1, nullptr, options); |
| 1053 | 961 |
| 1054 // Provider with out-of-process dumping. | 962 // Provider with out-of-process dumping. |
| 1055 MockMemoryDumpProvider mdp2; | 963 MockMemoryDumpProvider mdp2; |
| 1056 options.target_pid = 123; | 964 options.target_pid = 123; |
| 1057 RegisterDumpProvider(&mdp2, nullptr, options); | 965 RegisterDumpProvider(&mdp2, nullptr, options); |
| 1058 | 966 |
| 1059 // Another provider with out-of-process dumping. | 967 // Another provider with out-of-process dumping. |
| 1060 MockMemoryDumpProvider mdp3; | 968 MockMemoryDumpProvider mdp3; |
| 1061 options.target_pid = 456; | 969 options.target_pid = 456; |
| 1062 RegisterDumpProvider(&mdp3, nullptr, options); | 970 RegisterDumpProvider(&mdp3, nullptr, options); |
| 1063 | 971 |
| 1064 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 972 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 1065 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1); | 973 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1); |
| 1066 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); | 974 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1); |
| 1067 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); | 975 EXPECT_CALL(mdp3, OnMemoryDump(_, _)).Times(1); |
| 1068 EXPECT_CALL(mdp3, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); | 976 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 1069 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 977 MemoryDumpLevelOfDetail::DETAILED)); |
| 1070 MemoryDumpLevelOfDetail::DETAILED); | |
| 1071 DisableTracing(); | 978 DisableTracing(); |
| 1072 | 979 |
| 1073 std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer = | 980 std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer = |
| 1074 GetDeserializedTrace(); | 981 GetDeserializedTrace(); |
| 1075 trace_analyzer::TraceEventVector events; | 982 trace_analyzer::TraceEventVector events; |
| 1076 analyzer->FindEvents(Query::EventPhaseIs(TRACE_EVENT_PHASE_MEMORY_DUMP), | 983 analyzer->FindEvents(Query::EventPhaseIs(TRACE_EVENT_PHASE_MEMORY_DUMP), |
| 1077 &events); | 984 &events); |
| 1078 | 985 |
| 1079 ASSERT_EQ(3u, events.size()); | 986 ASSERT_EQ(3u, events.size()); |
| 1080 ASSERT_EQ(1u, trace_analyzer::CountMatches(events, Query::EventPidIs(123))); | 987 ASSERT_EQ(1u, trace_analyzer::CountMatches(events, Query::EventPidIs(123))); |
| 1081 ASSERT_EQ(1u, trace_analyzer::CountMatches(events, Query::EventPidIs(456))); | 988 ASSERT_EQ(1u, trace_analyzer::CountMatches(events, Query::EventPidIs(456))); |
| 1082 ASSERT_EQ(1u, trace_analyzer::CountMatches( | 989 ASSERT_EQ(1u, trace_analyzer::CountMatches( |
| 1083 events, Query::EventPidIs(GetCurrentProcId()))); | 990 events, Query::EventPidIs(GetCurrentProcId()))); |
| 1084 ASSERT_EQ(events[0]->id, events[1]->id); | 991 ASSERT_EQ(events[0]->id, events[1]->id); |
| 1085 ASSERT_EQ(events[0]->id, events[2]->id); | 992 ASSERT_EQ(events[0]->id, events[2]->id); |
| 1086 } | 993 } |
| 1087 | 994 |
| 1088 TEST_F(MemoryDumpManagerTest, SummaryOnlyWhitelisting) { | 995 TEST_F(MemoryDumpManagerTest, SummaryOnlyWhitelisting) { |
| 1089 InitializeMemoryDumpManager(false /* is_coordinator */); | 996 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 997 |
| 1090 // Summary only MDPs are a subset of background MDPs. | 998 // Summary only MDPs are a subset of background MDPs. |
| 1091 SetDumpProviderWhitelistForTesting(kTestMDPWhitelist); | 999 SetDumpProviderWhitelistForTesting(kTestMDPWhitelist); |
| 1092 SetDumpProviderSummaryWhitelistForTesting(kTestMDPWhitelistForSummary); | 1000 SetDumpProviderSummaryWhitelistForTesting(kTestMDPWhitelistForSummary); |
| 1093 | 1001 |
| 1094 // Standard provider with default options (create dump for current process). | 1002 // Standard provider with default options (create dump for current process). |
| 1095 MockMemoryDumpProvider summaryMdp; | 1003 MockMemoryDumpProvider summaryMdp; |
| 1096 RegisterDumpProvider(&summaryMdp, nullptr, kDefaultOptions, | 1004 RegisterDumpProvider(&summaryMdp, nullptr, kDefaultOptions, |
| 1097 kWhitelistedMDPName); | 1005 kWhitelistedMDPName); |
| 1098 MockMemoryDumpProvider backgroundMdp; | 1006 MockMemoryDumpProvider backgroundMdp; |
| 1099 RegisterDumpProvider(&backgroundMdp, nullptr, kDefaultOptions, | 1007 RegisterDumpProvider(&backgroundMdp, nullptr, kDefaultOptions, |
| 1100 kBackgroundButNotSummaryWhitelistedMDPName); | 1008 kBackgroundButNotSummaryWhitelistedMDPName); |
| 1101 | 1009 |
| 1102 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 1010 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 1103 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1); | 1011 |
| 1104 EXPECT_CALL(backgroundMdp, OnMemoryDump(_, _)).Times(0); | 1012 EXPECT_CALL(backgroundMdp, OnMemoryDump(_, _)).Times(0); |
| 1105 EXPECT_CALL(summaryMdp, OnMemoryDump(_, _)).Times(1); | 1013 EXPECT_CALL(summaryMdp, OnMemoryDump(_, _)).Times(1); |
| 1106 RequestGlobalDumpAndWait(MemoryDumpType::SUMMARY_ONLY, | 1014 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::SUMMARY_ONLY, |
| 1107 MemoryDumpLevelOfDetail::BACKGROUND); | 1015 MemoryDumpLevelOfDetail::BACKGROUND)); |
| 1108 DisableTracing(); | 1016 DisableTracing(); |
| 1109 } | 1017 } |
| 1110 | 1018 |
| 1111 TEST_F(MemoryDumpManagerTest, SummaryOnlyDumpsArentAddedToTrace) { | 1019 TEST_F(MemoryDumpManagerTest, SummaryOnlyDumpsArentAddedToTrace) { |
| 1112 using trace_analyzer::Query; | 1020 using trace_analyzer::Query; |
| 1113 | 1021 |
| 1114 InitializeMemoryDumpManager(false /* is_coordinator */); | 1022 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 1115 SetDumpProviderSummaryWhitelistForTesting(kTestMDPWhitelistForSummary); | 1023 SetDumpProviderSummaryWhitelistForTesting(kTestMDPWhitelistForSummary); |
| 1116 SetDumpProviderWhitelistForTesting(kTestMDPWhitelist); | 1024 SetDumpProviderWhitelistForTesting(kTestMDPWhitelist); |
| 1117 | 1025 |
| 1118 // Standard provider with default options (create dump for current process). | 1026 // Standard provider with default options (create dump for current process). |
| 1119 MockMemoryDumpProvider mdp; | 1027 MockMemoryDumpProvider mdp; |
| 1120 RegisterDumpProvider(&mdp, nullptr, kDefaultOptions, kWhitelistedMDPName); | 1028 RegisterDumpProvider(&mdp, nullptr, kDefaultOptions, kWhitelistedMDPName); |
| 1121 | 1029 |
| 1122 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 1030 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 1123 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(2); | 1031 |
| 1124 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(2).WillRepeatedly(Return(true)); | 1032 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(2); |
| 1125 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 1033 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 1126 MemoryDumpLevelOfDetail::BACKGROUND); | 1034 MemoryDumpLevelOfDetail::BACKGROUND)); |
| 1127 RequestGlobalDumpAndWait(MemoryDumpType::SUMMARY_ONLY, | 1035 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::SUMMARY_ONLY, |
| 1128 MemoryDumpLevelOfDetail::BACKGROUND); | 1036 MemoryDumpLevelOfDetail::BACKGROUND)); |
| 1129 DisableTracing(); | 1037 DisableTracing(); |
| 1130 | 1038 |
| 1131 std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer = | 1039 std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer = |
| 1132 GetDeserializedTrace(); | 1040 GetDeserializedTrace(); |
| 1133 trace_analyzer::TraceEventVector events; | 1041 trace_analyzer::TraceEventVector events; |
| 1134 analyzer->FindEvents(Query::EventPhaseIs(TRACE_EVENT_PHASE_MEMORY_DUMP), | 1042 analyzer->FindEvents(Query::EventPhaseIs(TRACE_EVENT_PHASE_MEMORY_DUMP), |
| 1135 &events); | 1043 &events); |
| 1136 | 1044 |
| 1137 ASSERT_EQ(1u, events.size()); | 1045 ASSERT_EQ(1u, events.size()); |
| 1138 ASSERT_TRUE(trace_analyzer::CountMatches( | 1046 ASSERT_TRUE(trace_analyzer::CountMatches( |
| 1139 events, Query::EventNameIs(MemoryDumpTypeToString( | 1047 events, Query::EventNameIs(MemoryDumpTypeToString( |
| 1140 MemoryDumpType::EXPLICITLY_TRIGGERED)))); | 1048 MemoryDumpType::EXPLICITLY_TRIGGERED)))); |
| 1141 } | 1049 } |
| 1142 | 1050 |
| 1143 // Tests the basics of the UnregisterAndDeleteDumpProviderSoon(): the | 1051 // Tests the basics of the UnregisterAndDeleteDumpProviderSoon(): the |
| 1144 // unregistration should actually delete the providers and not leak them. | 1052 // unregistration should actually delete the providers and not leak them. |
| 1145 TEST_F(MemoryDumpManagerTest, UnregisterAndDeleteDumpProviderSoon) { | 1053 TEST_F(MemoryDumpManagerTest, UnregisterAndDeleteDumpProviderSoon) { |
| 1146 InitializeMemoryDumpManager(false /* is_coordinator */); | 1054 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 1147 static const int kNumProviders = 3; | 1055 static const int kNumProviders = 3; |
| 1148 int dtor_count = 0; | 1056 int dtor_count = 0; |
| 1149 std::vector<std::unique_ptr<MemoryDumpProvider>> mdps; | 1057 std::vector<std::unique_ptr<MemoryDumpProvider>> mdps; |
| 1150 for (int i = 0; i < kNumProviders; ++i) { | 1058 for (int i = 0; i < kNumProviders; ++i) { |
| 1151 std::unique_ptr<MockMemoryDumpProvider> mdp(new MockMemoryDumpProvider); | 1059 std::unique_ptr<MockMemoryDumpProvider> mdp(new MockMemoryDumpProvider); |
| 1152 mdp->enable_mock_destructor = true; | 1060 mdp->enable_mock_destructor = true; |
| 1153 EXPECT_CALL(*mdp, Destructor()) | 1061 EXPECT_CALL(*mdp, Destructor()) |
| 1154 .WillOnce(Invoke([&dtor_count]() { dtor_count++; })); | 1062 .WillOnce(Invoke([&dtor_count]() { dtor_count++; })); |
| 1155 RegisterDumpProvider(mdp.get(), nullptr, kDefaultOptions); | 1063 RegisterDumpProvider(mdp.get(), nullptr, kDefaultOptions); |
| 1156 mdps.push_back(std::move(mdp)); | 1064 mdps.push_back(std::move(mdp)); |
| 1157 } | 1065 } |
| 1158 | 1066 |
| 1159 while (!mdps.empty()) { | 1067 while (!mdps.empty()) { |
| 1160 mdm_->UnregisterAndDeleteDumpProviderSoon(std::move(mdps.back())); | 1068 mdm_->UnregisterAndDeleteDumpProviderSoon(std::move(mdps.back())); |
| 1161 mdps.pop_back(); | 1069 mdps.pop_back(); |
| 1162 } | 1070 } |
| 1163 | 1071 |
| 1164 ASSERT_EQ(kNumProviders, dtor_count); | 1072 ASSERT_EQ(kNumProviders, dtor_count); |
| 1165 } | 1073 } |
| 1166 | 1074 |
| 1167 // This test checks against races when unregistering an unbound dump provider | 1075 // This test checks against races when unregistering an unbound dump provider |
| 1168 // from another thread while dumping. It registers one MDP and, when | 1076 // from another thread while dumping. It registers one MDP and, when |
| 1169 // OnMemoryDump() is called, it invokes UnregisterAndDeleteDumpProviderSoon() | 1077 // OnMemoryDump() is called, it invokes UnregisterAndDeleteDumpProviderSoon() |
| 1170 // from another thread. The OnMemoryDump() and the dtor call are expected to | 1078 // from another thread. The OnMemoryDump() and the dtor call are expected to |
| 1171 // happen on the same thread (the MemoryDumpManager utility thread). | 1079 // happen on the same thread (the MemoryDumpManager utility thread). |
| 1172 TEST_F(MemoryDumpManagerTest, UnregisterAndDeleteDumpProviderSoonDuringDump) { | 1080 TEST_F(MemoryDumpManagerTest, UnregisterAndDeleteDumpProviderSoonDuringDump) { |
| 1173 InitializeMemoryDumpManager(false /* is_coordinator */); | 1081 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 1174 std::unique_ptr<MockMemoryDumpProvider> mdp(new MockMemoryDumpProvider); | 1082 std::unique_ptr<MockMemoryDumpProvider> mdp(new MockMemoryDumpProvider); |
| 1175 mdp->enable_mock_destructor = true; | 1083 mdp->enable_mock_destructor = true; |
| 1176 RegisterDumpProvider(mdp.get(), nullptr, kDefaultOptions); | 1084 RegisterDumpProvider(mdp.get(), nullptr, kDefaultOptions); |
| 1177 | 1085 |
| 1178 base::PlatformThreadRef thread_ref; | 1086 base::PlatformThreadRef thread_ref; |
| 1179 auto self_unregister_from_another_thread = [&mdp, &thread_ref]( | 1087 auto self_unregister_from_another_thread = [&mdp, &thread_ref]( |
| 1180 const MemoryDumpArgs&, ProcessMemoryDump*) -> bool { | 1088 const MemoryDumpArgs&, ProcessMemoryDump*) -> bool { |
| 1181 thread_ref = PlatformThread::CurrentRef(); | 1089 thread_ref = PlatformThread::CurrentRef(); |
| 1182 TestIOThread thread_for_unregistration(TestIOThread::kAutoStart); | 1090 TestIOThread thread_for_unregistration(TestIOThread::kAutoStart); |
| 1183 PostTaskAndWait( | 1091 PostTaskAndWait( |
| 1184 FROM_HERE, thread_for_unregistration.task_runner().get(), | 1092 FROM_HERE, thread_for_unregistration.task_runner().get(), |
| 1185 base::BindOnce( | 1093 base::BindOnce( |
| 1186 &MemoryDumpManager::UnregisterAndDeleteDumpProviderSoon, | 1094 &MemoryDumpManager::UnregisterAndDeleteDumpProviderSoon, |
| 1187 base::Unretained(MemoryDumpManager::GetInstance()), | 1095 base::Unretained(MemoryDumpManager::GetInstance()), |
| 1188 base::Passed(std::unique_ptr<MemoryDumpProvider>(std::move(mdp))))); | 1096 base::Passed(std::unique_ptr<MemoryDumpProvider>(std::move(mdp))))); |
| 1189 thread_for_unregistration.Stop(); | 1097 thread_for_unregistration.Stop(); |
| 1190 return true; | 1098 return true; |
| 1191 }; | 1099 }; |
| 1192 EXPECT_CALL(*mdp, OnMemoryDump(_, _)) | 1100 EXPECT_CALL(*mdp, OnMemoryDump(_, _)) |
| 1193 .Times(1) | 1101 .Times(1) |
| 1194 .WillOnce(Invoke(self_unregister_from_another_thread)); | 1102 .WillOnce(Invoke(self_unregister_from_another_thread)); |
| 1195 EXPECT_CALL(*mdp, Destructor()) | 1103 EXPECT_CALL(*mdp, Destructor()) |
| 1196 .Times(1) | 1104 .Times(1) |
| 1197 .WillOnce(Invoke([&thread_ref]() { | 1105 .WillOnce(Invoke([&thread_ref]() { |
| 1198 EXPECT_EQ(thread_ref, PlatformThread::CurrentRef()); | 1106 EXPECT_EQ(thread_ref, PlatformThread::CurrentRef()); |
| 1199 })); | 1107 })); |
| 1200 | 1108 |
| 1201 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 1109 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 1202 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(2); | |
| 1203 for (int i = 0; i < 2; ++i) { | 1110 for (int i = 0; i < 2; ++i) { |
| 1204 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 1111 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 1205 MemoryDumpLevelOfDetail::DETAILED); | 1112 MemoryDumpLevelOfDetail::DETAILED)); |
| 1206 } | 1113 } |
| 1207 DisableTracing(); | 1114 DisableTracing(); |
| 1208 } | 1115 } |
| 1209 | 1116 |
| 1210 TEST_F(MemoryDumpManagerTest, TestWhitelistingMDP) { | 1117 TEST_F(MemoryDumpManagerTest, TestWhitelistingMDP) { |
| 1211 InitializeMemoryDumpManager(false /* is_coordinator */); | 1118 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 1212 SetDumpProviderWhitelistForTesting(kTestMDPWhitelist); | 1119 SetDumpProviderWhitelistForTesting(kTestMDPWhitelist); |
| 1213 std::unique_ptr<MockMemoryDumpProvider> mdp1(new MockMemoryDumpProvider); | 1120 std::unique_ptr<MockMemoryDumpProvider> mdp1(new MockMemoryDumpProvider); |
| 1214 RegisterDumpProvider(mdp1.get(), nullptr); | 1121 RegisterDumpProvider(mdp1.get(), nullptr); |
| 1215 std::unique_ptr<MockMemoryDumpProvider> mdp2(new MockMemoryDumpProvider); | 1122 std::unique_ptr<MockMemoryDumpProvider> mdp2(new MockMemoryDumpProvider); |
| 1216 RegisterDumpProvider(mdp2.get(), nullptr, kDefaultOptions, | 1123 RegisterDumpProvider(mdp2.get(), nullptr, kDefaultOptions, |
| 1217 kWhitelistedMDPName); | 1124 kWhitelistedMDPName); |
| 1218 | 1125 |
| 1219 EXPECT_CALL(*mdp1, OnMemoryDump(_, _)).Times(0); | 1126 EXPECT_CALL(*mdp1, OnMemoryDump(_, _)).Times(0); |
| 1220 EXPECT_CALL(*mdp2, OnMemoryDump(_, _)).Times(1).WillOnce(Return(true)); | 1127 EXPECT_CALL(*mdp2, OnMemoryDump(_, _)).Times(1); |
| 1221 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(1); | |
| 1222 | 1128 |
| 1223 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 1129 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 1224 EXPECT_FALSE(IsPeriodicDumpingEnabled()); | 1130 EXPECT_FALSE(IsPeriodicDumpingEnabled()); |
| 1225 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 1131 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 1226 MemoryDumpLevelOfDetail::BACKGROUND); | 1132 MemoryDumpLevelOfDetail::BACKGROUND)); |
| 1227 DisableTracing(); | 1133 DisableTracing(); |
| 1228 } | 1134 } |
| 1229 | 1135 |
| 1136 // Configures periodic dumps with MemoryDumpLevelOfDetail::BACKGROUND triggers |
| 1137 // and tests that only BACKGROUND are added to the trace, but not LIGHT or |
| 1138 // DETAILED, even if requested explicitly. |
| 1230 TEST_F(MemoryDumpManagerTest, TestBackgroundTracingSetup) { | 1139 TEST_F(MemoryDumpManagerTest, TestBackgroundTracingSetup) { |
| 1231 InitializeMemoryDumpManager(true /* is_coordinator */); | 1140 InitializeMemoryDumpManagerForInProcessTesting(true /* is_coordinator */); |
| 1232 | 1141 |
| 1233 // We now need an MDP to hit the code path where the dump will be rejected | 1142 SetDumpProviderWhitelistForTesting(kTestMDPWhitelist); |
| 1234 // since this happens at the point you try to serialize a process dump. | 1143 auto mdp = MakeUnique<MockMemoryDumpProvider>(); |
| 1235 MockMemoryDumpProvider mdp; | 1144 RegisterDumpProvider(&*mdp, nullptr, kDefaultOptions, kWhitelistedMDPName); |
| 1236 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); | |
| 1237 | 1145 |
| 1238 RunLoop run_loop; | 1146 RunLoop run_loop; |
| 1239 auto test_task_runner = ThreadTaskRunnerHandle::Get(); | 1147 auto test_task_runner = ThreadTaskRunnerHandle::Get(); |
| 1240 auto quit_closure = run_loop.QuitClosure(); | 1148 auto quit_closure = run_loop.QuitClosure(); |
| 1241 | 1149 |
| 1242 testing::InSequence sequence; | 1150 { |
| 1243 EXPECT_CALL(global_dump_handler_, | 1151 testing::InSequence sequence; |
| 1244 RequestGlobalMemoryDump(IsBackgroundDump(), _)) | 1152 EXPECT_CALL(*mdp, OnMemoryDump(IsBackgroundDump(), _)).Times(3); |
| 1245 .Times(5); | 1153 EXPECT_CALL(*mdp, OnMemoryDump(IsBackgroundDump(), _)) |
| 1246 EXPECT_CALL(global_dump_handler_, | 1154 .WillOnce(Invoke([test_task_runner, quit_closure](const MemoryDumpArgs&, |
| 1247 RequestGlobalMemoryDump(IsBackgroundDump(), _)) | 1155 ProcessMemoryDump*) { |
| 1248 .WillOnce(Invoke([test_task_runner, quit_closure]( | 1156 test_task_runner->PostTask(FROM_HERE, quit_closure); |
| 1249 const MemoryDumpRequestArgs& args, | 1157 return true; |
| 1250 const GlobalMemoryDumpCallback& callback) { | 1158 })); |
| 1251 test_task_runner->PostTask(FROM_HERE, quit_closure); | 1159 EXPECT_CALL(*mdp, OnMemoryDump(IsBackgroundDump(), _)).Times(AnyNumber()); |
| 1252 })); | 1160 } |
| 1253 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)) | |
| 1254 .Times(AnyNumber()); | |
| 1255 | 1161 |
| 1256 EnableTracingWithTraceConfig( | 1162 EnableTracingWithTraceConfig( |
| 1257 TraceConfigMemoryTestUtil::GetTraceConfig_BackgroundTrigger( | 1163 TraceConfigMemoryTestUtil::GetTraceConfig_BackgroundTrigger( |
| 1258 1 /* period_ms */)); | 1164 1 /* period_ms */)); |
| 1259 | 1165 |
| 1260 run_loop.Run(); | 1166 run_loop.Run(); |
| 1261 | 1167 |
| 1262 // Only background mode dumps should be allowed with the trace config. | 1168 // When requesting non-BACKGROUND dumps the MDP will be invoked but the |
| 1263 last_callback_success_ = false; | 1169 // data is expected to be dropped on the floor, hence the EXPECT_FALSE. |
| 1264 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 1170 EXPECT_CALL(*mdp, OnMemoryDump(IsLightDump(), _)); |
| 1265 MemoryDumpLevelOfDetail::LIGHT); | 1171 EXPECT_FALSE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 1266 EXPECT_FALSE(last_callback_success_); | 1172 MemoryDumpLevelOfDetail::LIGHT)); |
| 1267 last_callback_success_ = false; | 1173 |
| 1268 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 1174 EXPECT_CALL(*mdp, OnMemoryDump(IsDetailedDump(), _)); |
| 1269 MemoryDumpLevelOfDetail::DETAILED); | 1175 EXPECT_FALSE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 1270 EXPECT_FALSE(last_callback_success_); | 1176 MemoryDumpLevelOfDetail::DETAILED)); |
| 1271 | 1177 |
| 1272 ASSERT_TRUE(IsPeriodicDumpingEnabled()); | 1178 ASSERT_TRUE(IsPeriodicDumpingEnabled()); |
| 1273 DisableTracing(); | 1179 DisableTracing(); |
| 1180 mdm_->UnregisterAndDeleteDumpProviderSoon(std::move(mdp)); |
| 1274 } | 1181 } |
| 1275 | 1182 |
| 1276 // Tests that we can manually take a dump without enabling tracing. | 1183 // Tests that the MemoryDumpProvider(s) are invoked even if tracing has not |
| 1277 TEST_F(MemoryDumpManagerTest, DumpWithTracingDisabled) { | 1184 // been initialized. |
| 1278 InitializeMemoryDumpManager(false /* is_coordinator */); | 1185 TEST_F(MemoryDumpManagerTest, DumpWithoutInitializingTracing) { |
| 1186 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 1187 MockMemoryDumpProvider mdp; |
| 1188 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); |
| 1189 DisableTracing(); |
| 1190 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3); |
| 1191 for (int i = 0; i < 3; ++i) { |
| 1192 // The callback result will be false for the moment. true result means that |
| 1193 // as well as the dump being successful we also managed to add the dump to |
| 1194 // the trace. But the latter won't happen here. |
| 1195 EXPECT_FALSE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 1196 MemoryDumpLevelOfDetail::DETAILED)); |
| 1197 } |
| 1198 mdm_->UnregisterDumpProvider(&mdp); |
| 1199 } |
| 1200 |
| 1201 // Similar to DumpWithoutInitializingTracing. Tracing is initialized but not |
| 1202 // enabled. |
| 1203 TEST_F(MemoryDumpManagerTest, DumpWithTracingInitializedButDisabled) { |
| 1204 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 1279 MockMemoryDumpProvider mdp; | 1205 MockMemoryDumpProvider mdp; |
| 1280 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); | 1206 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); |
| 1281 | 1207 |
| 1282 DisableTracing(); | 1208 DisableTracing(); |
| 1283 | 1209 |
| 1284 const TraceConfig& trace_config = | 1210 const TraceConfig& trace_config = |
| 1285 TraceConfig(TraceConfigMemoryTestUtil::GetTraceConfig_NoTriggers()); | 1211 TraceConfig(TraceConfigMemoryTestUtil::GetTraceConfig_NoTriggers()); |
| 1286 const TraceConfig::MemoryDumpConfig& memory_dump_config = | 1212 const TraceConfig::MemoryDumpConfig& memory_dump_config = |
| 1287 trace_config.memory_dump_config(); | 1213 trace_config.memory_dump_config(); |
| 1288 | |
| 1289 mdm_->SetupForTracing(memory_dump_config); | 1214 mdm_->SetupForTracing(memory_dump_config); |
| 1290 | 1215 |
| 1291 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(3); | 1216 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3); |
| 1292 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true)); | 1217 for (int i = 0; i < 3; ++i) { |
| 1293 last_callback_success_ = true; | 1218 // Same as the above. Even if the MDP(s) are invoked, this will return false |
| 1294 for (int i = 0; i < 3; ++i) | 1219 // while attempting to add the dump into the trace. |
| 1295 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 1220 EXPECT_FALSE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 1296 MemoryDumpLevelOfDetail::DETAILED); | 1221 MemoryDumpLevelOfDetail::DETAILED)); |
| 1297 // The callback result should actually be false since (for the moment at | 1222 } |
| 1298 // least) a true result means that as well as the dump generally being | |
| 1299 // successful we also managed to add the dump to the trace. | |
| 1300 EXPECT_FALSE(last_callback_success_); | |
| 1301 | |
| 1302 mdm_->TeardownForTracing(); | 1223 mdm_->TeardownForTracing(); |
| 1303 | |
| 1304 mdm_->UnregisterDumpProvider(&mdp); | |
| 1305 } | |
| 1306 | |
| 1307 // Tests that we can do a dump without enabling/disabling. | |
| 1308 TEST_F(MemoryDumpManagerTest, DumpWithoutTracing) { | |
| 1309 InitializeMemoryDumpManager(false /* is_coordinator */); | |
| 1310 MockMemoryDumpProvider mdp; | |
| 1311 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); | |
| 1312 | |
| 1313 DisableTracing(); | |
| 1314 | |
| 1315 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)).Times(3); | |
| 1316 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true)); | |
| 1317 last_callback_success_ = true; | |
| 1318 for (int i = 0; i < 3; ++i) | |
| 1319 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | |
| 1320 MemoryDumpLevelOfDetail::DETAILED); | |
| 1321 // The callback result should be false since (for the moment at | |
| 1322 // least) a true result means that as well as the dump being | |
| 1323 // successful we also managed to add the dump to the trace which shouldn't | |
| 1324 // happen when tracing is not enabled. | |
| 1325 EXPECT_FALSE(last_callback_success_); | |
| 1326 | |
| 1327 mdm_->UnregisterDumpProvider(&mdp); | 1224 mdm_->UnregisterDumpProvider(&mdp); |
| 1328 } | 1225 } |
| 1329 | 1226 |
| 1330 TEST_F(MemoryDumpManagerTest, TestSummaryComputation) { | 1227 TEST_F(MemoryDumpManagerTest, TestSummaryComputation) { |
| 1331 InitializeMemoryDumpManager(false /* is_coordinator */); | 1228 InitializeMemoryDumpManagerForInProcessTesting(false /* is_coordinator */); |
| 1332 MockMemoryDumpProvider mdp; | 1229 MockMemoryDumpProvider mdp; |
| 1333 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); | 1230 RegisterDumpProvider(&mdp, ThreadTaskRunnerHandle::Get()); |
| 1334 | 1231 |
| 1335 const HeapProfilerSerializationState* heap_profiler_serialization_state = | |
| 1336 mdm_->heap_profiler_serialization_state_for_testing().get(); | |
| 1337 | |
| 1338 EXPECT_CALL(global_dump_handler_, RequestGlobalMemoryDump(_, _)) | |
| 1339 .WillOnce(Invoke([this](const MemoryDumpRequestArgs& args, | |
| 1340 const GlobalMemoryDumpCallback& callback) { | |
| 1341 ProcessMemoryDumpCallback process_callback = | |
| 1342 Bind(&MemoryDumpManagerTest_TestSummaryComputation_Test:: | |
| 1343 ProcessDumpRecordingCallbackAdapter, | |
| 1344 Unretained(this), callback); | |
| 1345 mdm_->CreateProcessDump(args, process_callback); | |
| 1346 })); | |
| 1347 | |
| 1348 EXPECT_CALL(mdp, OnMemoryDump(_, _)) | 1232 EXPECT_CALL(mdp, OnMemoryDump(_, _)) |
| 1349 .Times(1) | 1233 .WillOnce(Invoke([](const MemoryDumpArgs&, |
| 1350 .WillRepeatedly(Invoke([heap_profiler_serialization_state]( | 1234 ProcessMemoryDump* pmd) -> bool { |
| 1351 const MemoryDumpArgs&, | |
| 1352 ProcessMemoryDump* pmd) -> bool { | |
| 1353 auto* size = MemoryAllocatorDump::kNameSize; | 1235 auto* size = MemoryAllocatorDump::kNameSize; |
| 1354 auto* bytes = MemoryAllocatorDump::kUnitsBytes; | 1236 auto* bytes = MemoryAllocatorDump::kUnitsBytes; |
| 1355 const uint32_t kB = 1024; | 1237 const uint32_t kB = 1024; |
| 1356 | 1238 |
| 1357 pmd->CreateAllocatorDump("malloc")->AddScalar(size, bytes, 1 * kB); | 1239 pmd->CreateAllocatorDump("malloc")->AddScalar(size, bytes, 1 * kB); |
| 1358 pmd->CreateAllocatorDump("malloc/ignored") | 1240 pmd->CreateAllocatorDump("malloc/ignored") |
| 1359 ->AddScalar(size, bytes, 99 * kB); | 1241 ->AddScalar(size, bytes, 99 * kB); |
| 1360 | 1242 |
| 1361 pmd->CreateAllocatorDump("blink_gc")->AddScalar(size, bytes, 2 * kB); | 1243 pmd->CreateAllocatorDump("blink_gc")->AddScalar(size, bytes, 2 * kB); |
| 1362 pmd->CreateAllocatorDump("blink_gc/ignored") | 1244 pmd->CreateAllocatorDump("blink_gc/ignored") |
| 1363 ->AddScalar(size, bytes, 99 * kB); | 1245 ->AddScalar(size, bytes, 99 * kB); |
| 1364 | 1246 |
| 1365 pmd->CreateAllocatorDump("v8/foo")->AddScalar(size, bytes, 1 * kB); | 1247 pmd->CreateAllocatorDump("v8/foo")->AddScalar(size, bytes, 1 * kB); |
| 1366 pmd->CreateAllocatorDump("v8/bar")->AddScalar(size, bytes, 2 * kB); | 1248 pmd->CreateAllocatorDump("v8/bar")->AddScalar(size, bytes, 2 * kB); |
| 1367 pmd->CreateAllocatorDump("v8")->AddScalar(size, bytes, 99 * kB); | 1249 pmd->CreateAllocatorDump("v8")->AddScalar(size, bytes, 99 * kB); |
| 1368 | 1250 |
| 1251 // All the 99 KB values here are expected to be ignored. |
| 1369 pmd->CreateAllocatorDump("partition_alloc") | 1252 pmd->CreateAllocatorDump("partition_alloc") |
| 1370 ->AddScalar(size, bytes, 99 * kB); | 1253 ->AddScalar(size, bytes, 99 * kB); |
| 1371 pmd->CreateAllocatorDump("partition_alloc/allocated_objects") | 1254 pmd->CreateAllocatorDump("partition_alloc/allocated_objects") |
| 1372 ->AddScalar(size, bytes, 99 * kB); | 1255 ->AddScalar(size, bytes, 99 * kB); |
| 1373 pmd->CreateAllocatorDump("partition_alloc/allocated_objects/ignored") | 1256 pmd->CreateAllocatorDump("partition_alloc/allocated_objects/ignored") |
| 1374 ->AddScalar(size, bytes, 99 * kB); | 1257 ->AddScalar(size, bytes, 99 * kB); |
| 1375 pmd->CreateAllocatorDump("partition_alloc/partitions") | 1258 pmd->CreateAllocatorDump("partition_alloc/partitions") |
| 1376 ->AddScalar(size, bytes, 99 * kB); | 1259 ->AddScalar(size, bytes, 99 * kB); |
| 1377 pmd->CreateAllocatorDump("partition_alloc/partitions/foo") | 1260 pmd->CreateAllocatorDump("partition_alloc/partitions/not_ignored_1") |
| 1378 ->AddScalar(size, bytes, 2 * kB); | 1261 ->AddScalar(size, bytes, 2 * kB); |
| 1379 pmd->CreateAllocatorDump("partition_alloc/partitions/bar") | 1262 pmd->CreateAllocatorDump("partition_alloc/partitions/not_ignored_2") |
| 1380 ->AddScalar(size, bytes, 2 * kB); | 1263 ->AddScalar(size, bytes, 2 * kB); |
| 1381 pmd->process_totals()->set_resident_set_bytes(5 * kB); | 1264 pmd->process_totals()->set_resident_set_bytes(5 * kB); |
| 1382 pmd->set_has_process_totals(); | 1265 pmd->set_has_process_totals(); |
| 1383 return true; | 1266 return true; |
| 1384 })); | 1267 })); |
| 1385 | 1268 |
| 1386 last_callback_success_ = false; | |
| 1387 | |
| 1388 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); | 1269 EnableTracingWithLegacyCategories(MemoryDumpManager::kTraceCategory); |
| 1389 RequestGlobalDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, | 1270 Optional<MemoryDumpCallbackResult> result; |
| 1390 MemoryDumpLevelOfDetail::LIGHT); | 1271 EXPECT_TRUE(RequestProcessDumpAndWait(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 1272 MemoryDumpLevelOfDetail::LIGHT, |
| 1273 &result)); |
| 1391 DisableTracing(); | 1274 DisableTracing(); |
| 1392 | 1275 |
| 1393 // We shouldn't see any of the 99 values from above. | 1276 ASSERT_TRUE(result); |
| 1394 EXPECT_TRUE(last_callback_success_); | 1277 |
| 1395 ASSERT_EQ(1u, GetResults()->size()); | |
| 1396 MemoryDumpCallbackResult result = GetResults()->front(); | |
| 1397 // For malloc we only count the root "malloc" not children "malloc/*". | 1278 // For malloc we only count the root "malloc" not children "malloc/*". |
| 1398 EXPECT_EQ(1u, result.chrome_dump.malloc_total_kb); | 1279 EXPECT_EQ(1u, result->chrome_dump.malloc_total_kb); |
| 1280 |
| 1399 // For blink_gc we only count the root "blink_gc" not children "blink_gc/*". | 1281 // For blink_gc we only count the root "blink_gc" not children "blink_gc/*". |
| 1400 EXPECT_EQ(2u, result.chrome_dump.blink_gc_total_kb); | 1282 EXPECT_EQ(2u, result->chrome_dump.blink_gc_total_kb); |
| 1283 |
| 1401 // For v8 we count the children ("v8/*") as the root total is not given. | 1284 // For v8 we count the children ("v8/*") as the root total is not given. |
| 1402 EXPECT_EQ(3u, result.chrome_dump.v8_total_kb); | 1285 EXPECT_EQ(3u, result->chrome_dump.v8_total_kb); |
| 1286 |
| 1403 // partition_alloc has partition_alloc/allocated_objects/* which is a subset | 1287 // partition_alloc has partition_alloc/allocated_objects/* which is a subset |
| 1404 // of partition_alloc/partitions/* so we only count the latter. | 1288 // of partition_alloc/partitions/* so we only count the latter. |
| 1405 EXPECT_EQ(4u, result.chrome_dump.partition_alloc_total_kb); | 1289 EXPECT_EQ(4u, result->chrome_dump.partition_alloc_total_kb); |
| 1290 |
| 1406 // resident_set_kb should read from process_totals. | 1291 // resident_set_kb should read from process_totals. |
| 1407 EXPECT_EQ(5u, result.os_dump.resident_set_kb); | 1292 EXPECT_EQ(5u, result->os_dump.resident_set_kb); |
| 1408 }; | 1293 }; |
| 1409 | 1294 |
| 1410 } // namespace trace_event | 1295 } // namespace trace_event |
| 1411 } // namespace base | 1296 } // namespace base |
| OLD | NEW |