Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/trace_event/memory_dump_manager.h" | 5 #include "base/trace_event/memory_dump_manager.h" |
| 6 | 6 |
| 7 #include "base/bind_helpers.h" | 7 #include "base/bind_helpers.h" |
| 8 #include "base/memory/scoped_vector.h" | 8 #include "base/memory/scoped_vector.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/run_loop.h" | 10 #include "base/run_loop.h" |
| 11 #include "base/test/test_io_thread.h" | 11 #include "base/test/test_io_thread.h" |
| 12 #include "base/thread_task_runner_handle.h" | 12 #include "base/thread_task_runner_handle.h" |
| 13 #include "base/threading/thread.h" | 13 #include "base/threading/thread.h" |
| 14 #include "base/trace_event/memory_dump_provider.h" | 14 #include "base/trace_event/memory_dump_provider.h" |
| 15 #include "base/trace_event/process_memory_dump.h" | 15 #include "base/trace_event/process_memory_dump.h" |
| 16 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 18 |
| 19 using testing::_; | 19 using testing::_; |
| 20 using testing::AtMost; | 20 using testing::AtMost; |
| 21 using testing::Between; | 21 using testing::Between; |
| 22 using testing::Invoke; | 22 using testing::Invoke; |
| 23 using testing::Return; | 23 using testing::Return; |
| 24 | 24 |
| 25 namespace base { | 25 namespace base { |
| 26 namespace trace_event { | 26 namespace trace_event { |
| 27 namespace { | 27 namespace { |
| 28 MemoryDumpArgs high_detail_args = {MemoryDumpArgs::LevelOfDetail::HIGH}; | 28 MemoryDumpArgs g_high_detail_args = {MemoryDumpArgs::LevelOfDetail::HIGH}; |
| 29 MemoryDumpArgs low_detail_args = {MemoryDumpArgs::LevelOfDetail::LOW}; | 29 MemoryDumpArgs g_low_detail_args = {MemoryDumpArgs::LevelOfDetail::LOW}; |
| 30 } | 30 |
| 31 const char kMemoryDumpTraceConfigString[] = | |
| 32 "{" | |
| 33 "\"included_categories\":[" | |
| 34 "\"disabled-by-default-memory-infra\"" | |
|
Primiano Tucci (use gerrit)
2015/08/26 10:25:07
I don't think you want the "disabled-by-default-me
| |
| 35 "]," | |
| 36 "\"memory_dump_config\":{" | |
| 37 "\"triggers\":[" | |
| 38 "{" | |
| 39 "\"level_of_detail\":\"low\"," | |
| 40 "\"periodic_interval_ms\":50" | |
| 41 "}," | |
| 42 "{" | |
| 43 "\"level_of_detail\":\"high\"," | |
| 44 "\"periodic_interval_ms\":100" | |
| 45 "}," | |
| 46 "{" | |
| 47 "\"level_of_detail\":\"high\"," | |
| 48 "\"periodic_interval_ms\":150" | |
| 49 "}" | |
| 50 "]" | |
| 51 "}" | |
| 52 "}"; | |
| 53 | |
| 54 } // namespace | |
| 31 | 55 |
| 32 // Testing MemoryDumpManagerDelegate which short-circuits dump requests locally | 56 // Testing MemoryDumpManagerDelegate which short-circuits dump requests locally |
| 33 // instead of performing IPC dances. | 57 // instead of performing IPC dances. |
| 34 class MemoryDumpManagerDelegateForTesting : public MemoryDumpManagerDelegate { | 58 class MemoryDumpManagerDelegateForTesting : public MemoryDumpManagerDelegate { |
| 35 public: | 59 public: |
| 36 void RequestGlobalMemoryDump(const MemoryDumpRequestArgs& args, | 60 void RequestGlobalMemoryDump(const MemoryDumpRequestArgs& args, |
| 37 const MemoryDumpCallback& callback) override { | 61 const MemoryDumpCallback& callback) override { |
| 38 CreateProcessDump(args, callback); | 62 CreateProcessDump(args, callback); |
| 39 } | 63 } |
| 40 | 64 |
| 41 bool IsCoordinatorProcess() const override { return false; } | 65 bool IsCoordinatorProcess() const override { return false; } |
| 42 uint64 GetTracingProcessId() const override { | 66 uint64 GetTracingProcessId() const override { |
| 43 return MemoryDumpManager::kInvalidTracingProcessId; | 67 return MemoryDumpManager::kInvalidTracingProcessId; |
| 44 } | 68 } |
| 45 }; | 69 }; |
| 46 | 70 |
| 71 class CoordinatorMemoryDumpManagerDelegateForTesting | |
|
Primiano Tucci (use gerrit)
2015/08/26 10:25:07
Can you Just add a static public boolean to Memory
| |
| 72 : public MemoryDumpManagerDelegateForTesting { | |
| 73 bool IsCoordinatorProcess() const override { return true; } | |
| 74 }; | |
| 75 | |
| 47 class MemoryDumpManagerTest : public testing::Test { | 76 class MemoryDumpManagerTest : public testing::Test { |
| 48 public: | 77 public: |
| 49 void SetUp() override { | 78 void SetUp() override { |
| 50 last_callback_success_ = false; | 79 last_callback_success_ = false; |
| 51 message_loop_.reset(new MessageLoop()); | 80 message_loop_.reset(new MessageLoop()); |
| 52 mdm_.reset(new MemoryDumpManager()); | 81 mdm_.reset(new MemoryDumpManager()); |
| 53 MemoryDumpManager::SetInstanceForTesting(mdm_.get()); | 82 MemoryDumpManager::SetInstanceForTesting(mdm_.get()); |
| 54 ASSERT_EQ(mdm_, MemoryDumpManager::GetInstance()); | 83 ASSERT_EQ(mdm_, MemoryDumpManager::GetInstance()); |
| 55 MemoryDumpManager::GetInstance()->Initialize(); | 84 MemoryDumpManager::GetInstance()->Initialize(); |
| 56 MemoryDumpManager::GetInstance()->SetDelegate(&delegate_); | |
| 57 } | 85 } |
| 58 | 86 |
| 59 void TearDown() override { | 87 void TearDown() override { |
| 60 MemoryDumpManager::SetInstanceForTesting(nullptr); | 88 MemoryDumpManager::SetInstanceForTesting(nullptr); |
| 61 mdm_.reset(); | 89 mdm_.reset(); |
| 62 message_loop_.reset(); | 90 message_loop_.reset(); |
| 63 TraceLog::DeleteForTesting(); | 91 TraceLog::DeleteForTesting(); |
| 64 } | 92 } |
| 65 | 93 |
| 66 void DumpCallbackAdapter(scoped_refptr<SingleThreadTaskRunner> task_runner, | 94 void DumpCallbackAdapter(scoped_refptr<SingleThreadTaskRunner> task_runner, |
| 67 Closure closure, | 95 Closure closure, |
| 68 uint64 dump_guid, | 96 uint64 dump_guid, |
| 69 bool success) { | 97 bool success) { |
| 70 last_callback_success_ = success; | 98 last_callback_success_ = success; |
| 71 task_runner->PostTask(FROM_HERE, closure); | 99 task_runner->PostTask(FROM_HERE, closure); |
| 72 } | 100 } |
| 73 | 101 |
| 74 protected: | 102 protected: |
| 75 void EnableTracing(const char* category) { | 103 void EnableTracing(const char* category) { |
|
Primiano Tucci (use gerrit)
2015/08/26 10:25:07
I think at this point you don't need the char* arg
| |
| 104 delegate_.reset(new MemoryDumpManagerDelegateForTesting()); | |
| 105 MemoryDumpManager::GetInstance()->SetDelegate(delegate_.get()); | |
| 76 TraceLog::GetInstance()->SetEnabled( | 106 TraceLog::GetInstance()->SetEnabled( |
| 77 TraceConfig(category, ""), TraceLog::RECORDING_MODE); | 107 TraceConfig(category, ""), TraceLog::RECORDING_MODE); |
| 78 } | 108 } |
| 79 | 109 |
| 110 void EnableTracingWithTriggers() { | |
|
Primiano Tucci (use gerrit)
2015/08/26 10:25:07
Rename this to EnableTracingWithTraceConfig(const
| |
| 111 delegate_.reset(new CoordinatorMemoryDumpManagerDelegateForTesting()); | |
| 112 MemoryDumpManager::GetInstance()->SetDelegate(delegate_.get()); | |
| 113 TraceConfig tc(kMemoryDumpTraceConfigString); | |
| 114 TraceLog::GetInstance()->SetEnabled(tc, TraceLog::RECORDING_MODE); | |
| 115 } | |
| 116 | |
| 80 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } | 117 void DisableTracing() { TraceLog::GetInstance()->SetDisabled(); } |
| 81 | 118 |
| 82 scoped_ptr<MemoryDumpManager> mdm_; | 119 scoped_ptr<MemoryDumpManager> mdm_; |
| 83 bool last_callback_success_; | 120 bool last_callback_success_; |
| 84 | 121 |
| 85 private: | 122 private: |
| 86 scoped_ptr<MessageLoop> message_loop_; | 123 scoped_ptr<MessageLoop> message_loop_; |
| 87 MemoryDumpManagerDelegateForTesting delegate_; | 124 scoped_ptr<MemoryDumpManagerDelegateForTesting> delegate_; |
| 88 | 125 |
| 89 // We want our singleton torn down after each test. | 126 // We want our singleton torn down after each test. |
| 90 ShadowingAtExitManager at_exit_manager_; | 127 ShadowingAtExitManager at_exit_manager_; |
| 91 }; | 128 }; |
| 92 | 129 |
| 93 class MockDumpProvider : public MemoryDumpProvider { | 130 class MockDumpProvider : public MemoryDumpProvider { |
| 94 public: | 131 public: |
| 95 MockDumpProvider() | 132 MockDumpProvider() |
| 96 : dump_provider_to_register_or_unregister(nullptr), | 133 : MockDumpProvider(nullptr, MemoryDumpArgs::LevelOfDetail::HIGH, 0) {} |
| 97 last_session_state_(nullptr), | |
| 98 level_of_detail_(MemoryDumpArgs::LevelOfDetail::HIGH) {} | |
| 99 | 134 |
| 100 // Ctor used by the RespectTaskRunnerAffinity test. | 135 // Ctor used by the RespectTaskRunnerAffinity test. |
| 101 explicit MockDumpProvider( | 136 explicit MockDumpProvider( |
| 102 const scoped_refptr<SingleThreadTaskRunner>& task_runner) | 137 const scoped_refptr<SingleThreadTaskRunner>& task_runner) |
| 103 : last_session_state_(nullptr), | 138 : MockDumpProvider(task_runner, MemoryDumpArgs::LevelOfDetail::HIGH, 0) {} |
| 104 task_runner_(task_runner), | |
| 105 level_of_detail_(MemoryDumpArgs::LevelOfDetail::HIGH) {} | |
| 106 | 139 |
| 107 // Ctor used by CheckMemoryDumpArgs test. | 140 // Ctor used by CheckMemoryDumpArgs test. |
| 108 explicit MockDumpProvider(const MemoryDumpArgs::LevelOfDetail level_of_detail) | 141 explicit MockDumpProvider(const MemoryDumpArgs::LevelOfDetail level_of_detail) |
| 109 : last_session_state_(nullptr), level_of_detail_(level_of_detail) {} | 142 : MockDumpProvider(nullptr, level_of_detail, 0) {} |
| 143 | |
| 144 // Ctor used by TraceConfigTriggers test. | |
| 145 explicit MockDumpProvider(int dump_calls_to_disable_tracing) | |
| 146 : MockDumpProvider(nullptr, | |
| 147 MemoryDumpArgs::LevelOfDetail::HIGH, | |
| 148 dump_calls_to_disable_tracing) {} | |
| 149 | |
| 150 MockDumpProvider(const scoped_refptr<SingleThreadTaskRunner>& task_runner, | |
| 151 const MemoryDumpArgs::LevelOfDetail level_of_detail, | |
| 152 int dump_calls_to_disable_tracing) | |
| 153 : dump_provider_to_register_or_unregister(nullptr), | |
| 154 last_session_state_(nullptr), | |
| 155 level_of_detail_(level_of_detail), | |
| 156 on_memory_dump_calls_(0), | |
| 157 dump_calls_to_disable_tracing_(dump_calls_to_disable_tracing) {} | |
| 110 | 158 |
| 111 virtual ~MockDumpProvider() {} | 159 virtual ~MockDumpProvider() {} |
| 112 | 160 |
| 113 MOCK_METHOD2(OnMemoryDump, | 161 MOCK_METHOD2(OnMemoryDump, |
| 114 bool(const MemoryDumpArgs& args, ProcessMemoryDump* pmd)); | 162 bool(const MemoryDumpArgs& args, ProcessMemoryDump* pmd)); |
| 115 | 163 |
| 116 // OnMemoryDump() override for the RespectTaskRunnerAffinity test. | 164 // OnMemoryDump() override for the RespectTaskRunnerAffinity test. |
| 117 bool OnMemoryDump_CheckTaskRunner(const MemoryDumpArgs& args, | 165 bool OnMemoryDump_CheckTaskRunner(const MemoryDumpArgs& args, |
| 118 ProcessMemoryDump* pmd) { | 166 ProcessMemoryDump* pmd) { |
| 119 EXPECT_TRUE(task_runner_->RunsTasksOnCurrentThread()); | 167 EXPECT_TRUE(task_runner_->RunsTasksOnCurrentThread()); |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 146 return true; | 194 return true; |
| 147 } | 195 } |
| 148 | 196 |
| 149 // OnMemoryDump() override for the CheckMemoryDumpArgs test. | 197 // OnMemoryDump() override for the CheckMemoryDumpArgs test. |
| 150 bool OnMemoryDump_CheckMemoryDumpArgs(const MemoryDumpArgs& args, | 198 bool OnMemoryDump_CheckMemoryDumpArgs(const MemoryDumpArgs& args, |
| 151 ProcessMemoryDump* pmd) { | 199 ProcessMemoryDump* pmd) { |
| 152 EXPECT_EQ(level_of_detail_, args.level_of_detail); | 200 EXPECT_EQ(level_of_detail_, args.level_of_detail); |
| 153 return true; | 201 return true; |
| 154 } | 202 } |
| 155 | 203 |
| 204 // OnMemoryDump() override for the TraceConfigTriggers test. | |
| 205 bool OnMemoryDump_TraceConfigTriggers(const MemoryDumpArgs& args, | |
| 206 ProcessMemoryDump* pmd) { | |
| 207 if (on_memory_dump_calls_ % 2 == 0 || on_memory_dump_calls_ % 3 == 0) | |
|
Primiano Tucci (use gerrit)
2015/08/26 10:25:06
I don't think you need all this logic, just use th
| |
| 208 EXPECT_EQ(args.level_of_detail, MemoryDumpArgs::LevelOfDetail::HIGH); | |
| 209 else | |
| 210 EXPECT_EQ(args.level_of_detail, MemoryDumpArgs::LevelOfDetail::LOW); | |
| 211 | |
| 212 on_memory_dump_calls_++; | |
| 213 if (on_memory_dump_calls_ == dump_calls_to_disable_tracing_) { | |
| 214 TraceLog::GetInstance()->SetDisabled(); | |
| 215 MemoryDumpManager::GetInstance()->UnregisterDumpProvider(this); | |
| 216 } | |
| 217 return true; | |
| 218 } | |
| 219 | |
| 156 // Used by OnMemoryDump_(Un)RegisterExtraDumpProvider. | 220 // Used by OnMemoryDump_(Un)RegisterExtraDumpProvider. |
| 157 MemoryDumpProvider* dump_provider_to_register_or_unregister; | 221 MemoryDumpProvider* dump_provider_to_register_or_unregister; |
| 158 | 222 |
| 159 private: | 223 private: |
| 160 MemoryDumpSessionState* last_session_state_; | 224 MemoryDumpSessionState* last_session_state_; |
| 161 scoped_refptr<SingleThreadTaskRunner> task_runner_; | 225 scoped_refptr<SingleThreadTaskRunner> task_runner_; |
| 162 const MemoryDumpArgs::LevelOfDetail level_of_detail_; | 226 const MemoryDumpArgs::LevelOfDetail level_of_detail_; |
| 227 int on_memory_dump_calls_; | |
| 228 int dump_calls_to_disable_tracing_; | |
| 163 }; | 229 }; |
| 164 | 230 |
| 165 TEST_F(MemoryDumpManagerTest, SingleDumper) { | 231 TEST_F(MemoryDumpManagerTest, SingleDumper) { |
| 166 MockDumpProvider mdp; | 232 MockDumpProvider mdp; |
| 167 mdm_->RegisterDumpProvider(&mdp); | 233 mdm_->RegisterDumpProvider(&mdp); |
| 168 | 234 |
| 169 // Check that the dumper is not called if the memory category is not enabled. | 235 // Check that the dumper is not called if the memory category is not enabled. |
| 170 EnableTracing("foo-and-bar-but-not-memory"); | 236 EnableTracing("foo-and-bar-but-not-memory"); |
| 171 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); | 237 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
| 172 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 238 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 173 high_detail_args); | 239 g_high_detail_args); |
| 174 DisableTracing(); | 240 DisableTracing(); |
| 175 | 241 |
| 176 // Now repeat enabling the memory category and check that the dumper is | 242 // Now repeat enabling the memory category and check that the dumper is |
| 177 // invoked this time. | 243 // invoked this time. |
| 178 EnableTracing(MemoryDumpManager::kTraceCategory); | 244 EnableTracing(MemoryDumpManager::kTraceCategory); |
| 179 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true)); | 245 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(3).WillRepeatedly(Return(true)); |
| 180 for (int i = 0; i < 3; ++i) | 246 for (int i = 0; i < 3; ++i) |
| 181 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 247 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 182 high_detail_args); | 248 g_high_detail_args); |
| 183 DisableTracing(); | 249 DisableTracing(); |
| 184 | 250 |
| 185 mdm_->UnregisterDumpProvider(&mdp); | 251 mdm_->UnregisterDumpProvider(&mdp); |
| 186 | 252 |
| 187 // Finally check the unregister logic (no calls to the mdp after unregister). | 253 // Finally check the unregister logic (no calls to the mdp after unregister). |
| 188 EnableTracing(MemoryDumpManager::kTraceCategory); | 254 EnableTracing(MemoryDumpManager::kTraceCategory); |
| 189 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); | 255 EXPECT_CALL(mdp, OnMemoryDump(_, _)).Times(0); |
| 190 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 256 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 191 high_detail_args); | 257 g_high_detail_args); |
| 192 TraceLog::GetInstance()->SetDisabled(); | 258 TraceLog::GetInstance()->SetDisabled(); |
| 193 } | 259 } |
| 194 | 260 |
| 195 TEST_F(MemoryDumpManagerTest, CheckMemoryDumpArgs) { | 261 TEST_F(MemoryDumpManagerTest, CheckMemoryDumpArgs) { |
| 196 // Check that requesting dumps with high level of detail actually propagates | 262 // Check that requesting dumps with high level of detail actually propagates |
| 197 // to OnMemoryDump() call on dump providers. | 263 // to OnMemoryDump() call on dump providers. |
| 198 MockDumpProvider mdp_high_detail(MemoryDumpArgs::LevelOfDetail::HIGH); | 264 MockDumpProvider mdp_high_detail(MemoryDumpArgs::LevelOfDetail::HIGH); |
| 199 mdm_->RegisterDumpProvider(&mdp_high_detail); | 265 mdm_->RegisterDumpProvider(&mdp_high_detail); |
| 200 | 266 |
| 201 EnableTracing(MemoryDumpManager::kTraceCategory); | 267 EnableTracing(MemoryDumpManager::kTraceCategory); |
| 202 EXPECT_CALL(mdp_high_detail, OnMemoryDump(_, _)) | 268 EXPECT_CALL(mdp_high_detail, OnMemoryDump(_, _)) |
| 203 .Times(1) | 269 .Times(1) |
| 204 .WillRepeatedly( | 270 .WillRepeatedly( |
| 205 Invoke(&mdp_high_detail, | 271 Invoke(&mdp_high_detail, |
| 206 &MockDumpProvider::OnMemoryDump_CheckMemoryDumpArgs)); | 272 &MockDumpProvider::OnMemoryDump_CheckMemoryDumpArgs)); |
| 207 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 273 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 208 high_detail_args); | 274 g_high_detail_args); |
| 209 DisableTracing(); | 275 DisableTracing(); |
| 210 mdm_->UnregisterDumpProvider(&mdp_high_detail); | 276 mdm_->UnregisterDumpProvider(&mdp_high_detail); |
| 211 | 277 |
| 212 // Check that requesting dumps with low level of detail actually propagates to | 278 // Check that requesting dumps with low level of detail actually propagates to |
| 213 // OnMemoryDump() call on dump providers. | 279 // OnMemoryDump() call on dump providers. |
| 214 MockDumpProvider mdp_low_detail(MemoryDumpArgs::LevelOfDetail::LOW); | 280 MockDumpProvider mdp_low_detail(MemoryDumpArgs::LevelOfDetail::LOW); |
| 215 mdm_->RegisterDumpProvider(&mdp_low_detail); | 281 mdm_->RegisterDumpProvider(&mdp_low_detail); |
| 216 | 282 |
| 217 EnableTracing(MemoryDumpManager::kTraceCategory); | 283 EnableTracing(MemoryDumpManager::kTraceCategory); |
| 218 EXPECT_CALL(mdp_low_detail, OnMemoryDump(_, _)) | 284 EXPECT_CALL(mdp_low_detail, OnMemoryDump(_, _)) |
| 219 .Times(1) | 285 .Times(1) |
| 220 .WillRepeatedly( | 286 .WillRepeatedly( |
| 221 Invoke(&mdp_low_detail, | 287 Invoke(&mdp_low_detail, |
| 222 &MockDumpProvider::OnMemoryDump_CheckMemoryDumpArgs)); | 288 &MockDumpProvider::OnMemoryDump_CheckMemoryDumpArgs)); |
| 223 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 289 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 224 low_detail_args); | 290 g_low_detail_args); |
| 225 DisableTracing(); | 291 DisableTracing(); |
| 226 mdm_->UnregisterDumpProvider(&mdp_low_detail); | 292 mdm_->UnregisterDumpProvider(&mdp_low_detail); |
| 227 } | 293 } |
| 228 | 294 |
| 229 TEST_F(MemoryDumpManagerTest, SharedSessionState) { | 295 TEST_F(MemoryDumpManagerTest, SharedSessionState) { |
| 230 MockDumpProvider mdp1; | 296 MockDumpProvider mdp1; |
| 231 MockDumpProvider mdp2; | 297 MockDumpProvider mdp2; |
| 232 mdm_->RegisterDumpProvider(&mdp1); | 298 mdm_->RegisterDumpProvider(&mdp1); |
| 233 mdm_->RegisterDumpProvider(&mdp2); | 299 mdm_->RegisterDumpProvider(&mdp2); |
| 234 | 300 |
| 235 EnableTracing(MemoryDumpManager::kTraceCategory); | 301 EnableTracing(MemoryDumpManager::kTraceCategory); |
| 236 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) | 302 EXPECT_CALL(mdp1, OnMemoryDump(_, _)) |
| 237 .Times(2) | 303 .Times(2) |
| 238 .WillRepeatedly( | 304 .WillRepeatedly( |
| 239 Invoke(&mdp1, &MockDumpProvider::OnMemoryDump_CheckSessionState)); | 305 Invoke(&mdp1, &MockDumpProvider::OnMemoryDump_CheckSessionState)); |
| 240 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) | 306 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) |
| 241 .Times(2) | 307 .Times(2) |
| 242 .WillRepeatedly( | 308 .WillRepeatedly( |
| 243 Invoke(&mdp2, &MockDumpProvider::OnMemoryDump_CheckSessionState)); | 309 Invoke(&mdp2, &MockDumpProvider::OnMemoryDump_CheckSessionState)); |
| 244 | 310 |
| 245 for (int i = 0; i < 2; ++i) | 311 for (int i = 0; i < 2; ++i) |
| 246 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 312 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 247 high_detail_args); | 313 g_high_detail_args); |
| 248 | 314 |
| 249 DisableTracing(); | 315 DisableTracing(); |
| 250 } | 316 } |
| 251 | 317 |
| 252 TEST_F(MemoryDumpManagerTest, MultipleDumpers) { | 318 TEST_F(MemoryDumpManagerTest, MultipleDumpers) { |
| 253 MockDumpProvider mdp1; | 319 MockDumpProvider mdp1; |
| 254 MockDumpProvider mdp2; | 320 MockDumpProvider mdp2; |
| 255 | 321 |
| 256 // Enable only mdp1. | 322 // Enable only mdp1. |
| 257 mdm_->RegisterDumpProvider(&mdp1); | 323 mdm_->RegisterDumpProvider(&mdp1); |
| 258 EnableTracing(MemoryDumpManager::kTraceCategory); | 324 EnableTracing(MemoryDumpManager::kTraceCategory); |
| 259 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); | 325 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); |
| 260 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(0); | 326 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(0); |
| 261 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 327 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 262 high_detail_args); | 328 g_high_detail_args); |
| 263 DisableTracing(); | 329 DisableTracing(); |
| 264 | 330 |
| 265 // Invert: enable mdp1 and disable mdp2. | 331 // Invert: enable mdp1 and disable mdp2. |
| 266 mdm_->UnregisterDumpProvider(&mdp1); | 332 mdm_->UnregisterDumpProvider(&mdp1); |
| 267 mdm_->RegisterDumpProvider(&mdp2); | 333 mdm_->RegisterDumpProvider(&mdp2); |
| 268 EnableTracing(MemoryDumpManager::kTraceCategory); | 334 EnableTracing(MemoryDumpManager::kTraceCategory); |
| 269 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); | 335 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); |
| 270 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); | 336 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); |
| 271 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 337 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 272 high_detail_args); | 338 g_high_detail_args); |
| 273 DisableTracing(); | 339 DisableTracing(); |
| 274 | 340 |
| 275 // Enable both mdp1 and mdp2. | 341 // Enable both mdp1 and mdp2. |
| 276 mdm_->RegisterDumpProvider(&mdp1); | 342 mdm_->RegisterDumpProvider(&mdp1); |
| 277 EnableTracing(MemoryDumpManager::kTraceCategory); | 343 EnableTracing(MemoryDumpManager::kTraceCategory); |
| 278 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); | 344 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); |
| 279 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); | 345 EXPECT_CALL(mdp2, OnMemoryDump(_, _)).Times(1).WillRepeatedly(Return(true)); |
| 280 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 346 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 281 high_detail_args); | 347 g_high_detail_args); |
| 282 DisableTracing(); | 348 DisableTracing(); |
| 283 } | 349 } |
| 284 | 350 |
| 285 // Verify that whether OnMemoryDump is called depends only on the current | 351 // Verify that whether OnMemoryDump is called depends only on the current |
| 286 // registration state and not on previous registrations and dumps. | 352 // registration state and not on previous registrations and dumps. |
| 287 TEST_F(MemoryDumpManagerTest, RegistrationConsistency) { | 353 TEST_F(MemoryDumpManagerTest, RegistrationConsistency) { |
| 288 MockDumpProvider mdp; | 354 MockDumpProvider mdp; |
| 289 | 355 |
| 290 mdm_->RegisterDumpProvider(&mdp); | 356 mdm_->RegisterDumpProvider(&mdp); |
| 291 | 357 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 359 EnableTracing(MemoryDumpManager::kTraceCategory); | 425 EnableTracing(MemoryDumpManager::kTraceCategory); |
| 360 | 426 |
| 361 while (!threads.empty()) { | 427 while (!threads.empty()) { |
| 362 last_callback_success_ = false; | 428 last_callback_success_ = false; |
| 363 { | 429 { |
| 364 RunLoop run_loop; | 430 RunLoop run_loop; |
| 365 MemoryDumpCallback callback = | 431 MemoryDumpCallback callback = |
| 366 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), | 432 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), |
| 367 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); | 433 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); |
| 368 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 434 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 369 high_detail_args, callback); | 435 g_high_detail_args, callback); |
| 370 // This nested message loop (|run_loop|) will be quit if and only if | 436 // This nested message loop (|run_loop|) will be quit if and only if |
| 371 // the RequestGlobalDump callback is invoked. | 437 // the RequestGlobalDump callback is invoked. |
| 372 run_loop.Run(); | 438 run_loop.Run(); |
| 373 } | 439 } |
| 374 EXPECT_TRUE(last_callback_success_); | 440 EXPECT_TRUE(last_callback_success_); |
| 375 | 441 |
| 376 // Unregister a MDP and destroy one thread at each iteration to check the | 442 // Unregister a MDP and destroy one thread at each iteration to check the |
| 377 // live unregistration logic. The unregistration needs to happen on the same | 443 // live unregistration logic. The unregistration needs to happen on the same |
| 378 // thread the MDP belongs to. | 444 // thread the MDP belongs to. |
| 379 { | 445 { |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 407 .Times(MemoryDumpManager::kMaxConsecutiveFailuresCount) | 473 .Times(MemoryDumpManager::kMaxConsecutiveFailuresCount) |
| 408 .WillRepeatedly(Return(false)); | 474 .WillRepeatedly(Return(false)); |
| 409 | 475 |
| 410 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) | 476 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) |
| 411 .Times(1 + MemoryDumpManager::kMaxConsecutiveFailuresCount) | 477 .Times(1 + MemoryDumpManager::kMaxConsecutiveFailuresCount) |
| 412 .WillOnce(Return(false)) | 478 .WillOnce(Return(false)) |
| 413 .WillRepeatedly(Return(true)); | 479 .WillRepeatedly(Return(true)); |
| 414 for (int i = 0; i < 1 + MemoryDumpManager::kMaxConsecutiveFailuresCount; | 480 for (int i = 0; i < 1 + MemoryDumpManager::kMaxConsecutiveFailuresCount; |
| 415 i++) { | 481 i++) { |
| 416 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 482 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 417 high_detail_args); | 483 g_high_detail_args); |
| 418 } | 484 } |
| 419 | 485 |
| 420 DisableTracing(); | 486 DisableTracing(); |
| 421 } | 487 } |
| 422 | 488 |
| 423 // Sneakily register an extra memory dump provider while an existing one is | 489 // Sneakily register an extra memory dump provider while an existing one is |
| 424 // dumping and expect it to take part in the already active tracing session. | 490 // dumping and expect it to take part in the already active tracing session. |
| 425 TEST_F(MemoryDumpManagerTest, RegisterDumperWhileDumping) { | 491 TEST_F(MemoryDumpManagerTest, RegisterDumperWhileDumping) { |
| 426 MockDumpProvider mdp1; | 492 MockDumpProvider mdp1; |
| 427 MockDumpProvider mdp2; | 493 MockDumpProvider mdp2; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 438 .WillRepeatedly(Return(true)); | 504 .WillRepeatedly(Return(true)); |
| 439 | 505 |
| 440 // Depending on the insertion order (before or after mdp1), mdp2 might be | 506 // Depending on the insertion order (before or after mdp1), mdp2 might be |
| 441 // called also immediately after it gets registered. | 507 // called also immediately after it gets registered. |
| 442 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) | 508 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) |
| 443 .Times(Between(2, 3)) | 509 .Times(Between(2, 3)) |
| 444 .WillRepeatedly(Return(true)); | 510 .WillRepeatedly(Return(true)); |
| 445 | 511 |
| 446 for (int i = 0; i < 4; i++) { | 512 for (int i = 0; i < 4; i++) { |
| 447 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 513 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 448 high_detail_args); | 514 g_high_detail_args); |
| 449 } | 515 } |
| 450 | 516 |
| 451 DisableTracing(); | 517 DisableTracing(); |
| 452 } | 518 } |
| 453 | 519 |
| 454 // Like the above, but suddenly unregister the dump provider. | 520 // Like the above, but suddenly unregister the dump provider. |
| 455 TEST_F(MemoryDumpManagerTest, UnregisterDumperWhileDumping) { | 521 TEST_F(MemoryDumpManagerTest, UnregisterDumperWhileDumping) { |
| 456 MockDumpProvider mdp1; | 522 MockDumpProvider mdp1; |
| 457 MockDumpProvider mdp2; | 523 MockDumpProvider mdp2; |
| 458 | 524 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 469 .WillRepeatedly(Return(true)); | 535 .WillRepeatedly(Return(true)); |
| 470 | 536 |
| 471 // Depending on the insertion order (before or after mdp1), mdp2 might have | 537 // Depending on the insertion order (before or after mdp1), mdp2 might have |
| 472 // been already called when OnMemoryDump_UnregisterDumpProvider happens. | 538 // been already called when OnMemoryDump_UnregisterDumpProvider happens. |
| 473 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) | 539 EXPECT_CALL(mdp2, OnMemoryDump(_, _)) |
| 474 .Times(Between(1, 2)) | 540 .Times(Between(1, 2)) |
| 475 .WillRepeatedly(Return(true)); | 541 .WillRepeatedly(Return(true)); |
| 476 | 542 |
| 477 for (int i = 0; i < 4; i++) { | 543 for (int i = 0; i < 4; i++) { |
| 478 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 544 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 479 high_detail_args); | 545 g_high_detail_args); |
| 480 } | 546 } |
| 481 | 547 |
| 482 DisableTracing(); | 548 DisableTracing(); |
| 483 } | 549 } |
| 484 | 550 |
| 485 // Verify that the dump does not abort when unregistering a provider while | 551 // Verify that the dump does not abort when unregistering a provider while |
| 486 // dumping from a different thread than the dumping thread. | 552 // dumping from a different thread than the dumping thread. |
| 487 TEST_F(MemoryDumpManagerTest, UnregisterDumperFromThreadWhileDumping) { | 553 TEST_F(MemoryDumpManagerTest, UnregisterDumperFromThreadWhileDumping) { |
| 488 ScopedVector<TestIOThread> threads; | 554 ScopedVector<TestIOThread> threads; |
| 489 ScopedVector<MockDumpProvider> mdps; | 555 ScopedVector<MockDumpProvider> mdps; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 545 mdm_->RegisterDumpProvider(&mdp1); | 611 mdm_->RegisterDumpProvider(&mdp1); |
| 546 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); | 612 EXPECT_CALL(mdp1, OnMemoryDump(_, _)).Times(0); |
| 547 | 613 |
| 548 last_callback_success_ = true; | 614 last_callback_success_ = true; |
| 549 { | 615 { |
| 550 RunLoop run_loop; | 616 RunLoop run_loop; |
| 551 MemoryDumpCallback callback = | 617 MemoryDumpCallback callback = |
| 552 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), | 618 Bind(&MemoryDumpManagerTest::DumpCallbackAdapter, Unretained(this), |
| 553 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); | 619 MessageLoop::current()->task_runner(), run_loop.QuitClosure()); |
| 554 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, | 620 mdm_->RequestGlobalDump(MemoryDumpType::EXPLICITLY_TRIGGERED, |
| 555 high_detail_args, callback); | 621 g_high_detail_args, callback); |
| 556 run_loop.Run(); | 622 run_loop.Run(); |
| 557 } | 623 } |
| 558 EXPECT_FALSE(last_callback_success_); | 624 EXPECT_FALSE(last_callback_success_); |
| 559 } | 625 } |
| 560 | 626 |
| 627 TEST_F(MemoryDumpManagerTest, TraceConfigTriggers) { | |
|
Primiano Tucci (use gerrit)
2015/08/26 10:25:06
The name here (TraceConfigTriggers) should reflect
| |
| 628 MockDumpProvider mdp; | |
| 629 mdm_->RegisterDumpProvider(&mdp); | |
| 630 const int kTestDumpCount = 10; | |
| 631 RunLoop run_loop; | |
| 632 EnableTracingWithTriggers(); | |
| 633 EXPECT_CALL(mdp, OnMemoryDump(_, _)) | |
| 634 .Times(kTestDumpCount) | |
| 635 .WillRepeatedly( | |
| 636 Invoke(&mdp, &MockDumpProvider::OnMemoryDump_TraceConfigTriggers)); | |
| 637 | |
| 638 // 50 ms is the shortest interval given in the kMemoryDumpTraceConfigString. | |
|
Primiano Tucci (use gerrit)
2015/08/26 10:25:06
Please don't have tests based on timings as they a
| |
| 639 // kTestDumpCount * 50 is time taken for kTestDumpCount "OnMemoryDump" calls. | |
| 640 const uint32 test_runtime = kTestDumpCount * 50 + 25; | |
| 641 MessageLoop::current()->task_runner()->PostDelayedTask( | |
| 642 FROM_HERE, run_loop.QuitClosure(), | |
| 643 base::TimeDelta::FromMilliseconds(test_runtime)); | |
| 644 run_loop.Run(); | |
| 645 } | |
|
Primiano Tucci (use gerrit)
2015/08/26 10:25:07
Also you should have a test to make sure that if y
ssid
2015/08/28 12:34:48
This test is not needed here since, all we test he
| |
| 646 | |
| 561 } // namespace trace_event | 647 } // namespace trace_event |
| 562 } // namespace base | 648 } // namespace base |
| OLD | NEW |