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 <stdint.h> | 5 #include <stdint.h> |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
| 10 #include "base/threading/thread_task_runner_handle.h" | 10 #include "base/threading/thread_task_runner_handle.h" |
| 11 #include "base/trace_event/memory_dump_manager.h" | 11 #include "base/trace_event/memory_dump_manager.h" |
| 12 #include "base/trace_event/memory_dump_provider.h" | 12 #include "base/trace_event/memory_dump_provider.h" |
| 13 #include "base/trace_event/memory_dump_request_args.h" | 13 #include "base/trace_event/memory_dump_request_args.h" |
| 14 #include "base/trace_event/trace_config_memory_test_util.h" | 14 #include "base/trace_event/trace_config_memory_test_util.h" |
| 15 #include "content/public/browser/tracing_controller.h" | 15 #include "content/public/browser/tracing_controller.h" |
| 16 #include "content/public/common/content_switches.h" | 16 #include "content/public/common/content_switches.h" |
| 17 #include "content/public/test/browser_test_utils.h" | 17 #include "content/public/test/browser_test_utils.h" |
| 18 #include "content/public/test/content_browser_test.h" | 18 #include "content/public/test/content_browser_test.h" |
| 19 #include "content/public/test/content_browser_test_utils.h" | 19 #include "content/public/test/content_browser_test_utils.h" |
| 20 #include "content/shell/browser/shell.h" | 20 #include "content/shell/browser/shell.h" |
| 21 #include "testing/gmock/include/gmock/gmock.h" | 21 #include "testing/gmock/include/gmock/gmock.h" |
| 22 | 22 |
| 23 using base::trace_event::MemoryDumpArgs; | 23 using base::trace_event::MemoryDumpArgs; |
| 24 using base::trace_event::MemoryDumpLevelOfDetail; | |
| 24 using base::trace_event::MemoryDumpManager; | 25 using base::trace_event::MemoryDumpManager; |
| 25 using base::trace_event::MemoryDumpType; | 26 using base::trace_event::MemoryDumpType; |
| 26 using base::trace_event::ProcessMemoryDump; | 27 using base::trace_event::ProcessMemoryDump; |
| 27 using testing::_; | 28 using testing::_; |
| 28 using testing::Return; | 29 using testing::Return; |
| 29 | 30 |
| 30 namespace content { | 31 namespace content { |
| 31 | 32 |
| 32 // A mock dump provider, used to check that dump requests actually end up | 33 // A mock dump provider, used to check that dump requests actually end up |
| 33 // creating memory dumps. | 34 // creating memory dumps. |
| 34 class MockDumpProvider : public base::trace_event::MemoryDumpProvider { | 35 class MockDumpProvider : public base::trace_event::MemoryDumpProvider { |
| 35 public: | 36 public: |
| 36 MOCK_METHOD2(OnMemoryDump, bool(const MemoryDumpArgs& args, | 37 MOCK_METHOD2(OnMemoryDump, bool(const MemoryDumpArgs& args, |
| 37 ProcessMemoryDump* pmd)); | 38 ProcessMemoryDump* pmd)); |
| 38 }; | 39 }; |
| 39 | 40 |
| 40 class MemoryTracingTest : public ContentBrowserTest { | 41 class MemoryTracingTest : public ContentBrowserTest { |
| 41 public: | 42 public: |
| 42 void DoRequestGlobalDump(const base::trace_event::MemoryDumpCallback& cb) { | 43 void DoRequestGlobalDump(const MemoryDumpType& dump_type, |
| 43 MemoryDumpManager::GetInstance()->RequestGlobalDump( | 44 const MemoryDumpLevelOfDetail& level_of_detail, |
| 44 MemoryDumpType::EXPLICITLY_TRIGGERED, | 45 const base::trace_event::MemoryDumpCallback& cb) { |
| 45 base::trace_event::MemoryDumpLevelOfDetail::DETAILED, cb); | 46 MemoryDumpManager::GetInstance()->RequestGlobalDump(dump_type, |
| 47 level_of_detail, cb); | |
| 46 } | 48 } |
| 47 | 49 |
| 48 // Used as callback argument for MemoryDumpManager::RequestGlobalDump(): | 50 // Used as callback argument for MemoryDumpManager::RequestGlobalDump(): |
| 49 void OnGlobalMemoryDumpDone( | 51 void OnGlobalMemoryDumpDone( |
| 50 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | 52 scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| 51 base::Closure closure, | 53 base::Closure closure, |
| 52 uint64_t dump_guid, | 54 uint64_t dump_guid, |
| 53 bool success) { | 55 bool success) { |
| 54 // Make sure we run the RunLoop closure on the same thread that originated | 56 // Make sure we run the RunLoop closure on the same thread that originated |
| 55 // the run loop (which is the IN_PROC_BROWSER_TEST_F main thread). | 57 // the run loop (which is the IN_PROC_BROWSER_TEST_F main thread). |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 99 EXPECT_TRUE(success); | 101 EXPECT_TRUE(success); |
| 100 run_loop.Run(); | 102 run_loop.Run(); |
| 101 } | 103 } |
| 102 | 104 |
| 103 void DisableTracing() { | 105 void DisableTracing() { |
| 104 bool success = TracingController::GetInstance()->StopTracing(NULL); | 106 bool success = TracingController::GetInstance()->StopTracing(NULL); |
| 105 EXPECT_TRUE(success); | 107 EXPECT_TRUE(success); |
| 106 base::RunLoop().RunUntilIdle(); | 108 base::RunLoop().RunUntilIdle(); |
| 107 } | 109 } |
| 108 | 110 |
| 109 void RequestGlobalDumpAndWait(bool from_renderer_thread) { | 111 std::unique_ptr<base::RunLoop> RequestGlobalDumpWhichQuitsLoop( |
| 110 base::RunLoop run_loop; | 112 bool from_renderer_thread, |
| 113 const MemoryDumpType& dump_type, | |
| 114 const MemoryDumpLevelOfDetail& level_of_detail) { | |
| 115 std::unique_ptr<base::RunLoop> run_loop; | |
| 116 run_loop.reset(new base::RunLoop()); | |
| 111 base::trace_event::MemoryDumpCallback callback = base::Bind( | 117 base::trace_event::MemoryDumpCallback callback = base::Bind( |
| 112 &MemoryTracingTest::OnGlobalMemoryDumpDone, base::Unretained(this), | 118 &MemoryTracingTest::OnGlobalMemoryDumpDone, base::Unretained(this), |
| 113 base::ThreadTaskRunnerHandle::Get(), run_loop.QuitClosure()); | 119 base::ThreadTaskRunnerHandle::Get(), run_loop->QuitClosure()); |
| 114 if (from_renderer_thread) { | 120 if (from_renderer_thread) { |
| 115 PostTaskToInProcessRendererAndWait( | 121 PostTaskToInProcessRendererAndWait(base::Bind( |
| 116 base::Bind(&MemoryTracingTest::DoRequestGlobalDump, | 122 &MemoryTracingTest::DoRequestGlobalDump, base::Unretained(this), |
| 117 base::Unretained(this), callback)); | 123 dump_type, level_of_detail, callback)); |
| 118 } else { | 124 } else { |
| 119 DoRequestGlobalDump(callback); | 125 DoRequestGlobalDump(dump_type, level_of_detail, callback); |
| 120 } | 126 } |
| 121 run_loop.Run(); | 127 return run_loop; |
| 128 } | |
| 129 | |
| 130 void RequestGlobalDumpAndWait(bool from_renderer_thread) { | |
| 131 std::unique_ptr<base::RunLoop> run_loop = RequestGlobalDumpWhichQuitsLoop( | |
| 132 from_renderer_thread, MemoryDumpType::EXPLICITLY_TRIGGERED, | |
| 133 MemoryDumpLevelOfDetail::DETAILED); | |
| 134 run_loop->Run(); | |
| 122 } | 135 } |
| 123 | 136 |
| 124 void Navigate(Shell* shell) { | 137 void Navigate(Shell* shell) { |
| 125 NavigateToURL(shell, GetTestUrl("", "title.html")); | 138 NavigateToURL(shell, GetTestUrl("", "title.html")); |
| 126 } | 139 } |
| 127 | 140 |
| 128 base::Closure on_memory_dump_complete_closure_; | 141 base::Closure on_memory_dump_complete_closure_; |
| 129 std::unique_ptr<MockDumpProvider> mock_dump_provider_; | 142 std::unique_ptr<MockDumpProvider> mock_dump_provider_; |
| 130 uint32_t callback_call_count_; | 143 uint32_t callback_call_count_; |
| 131 uint64_t last_callback_dump_guid_; | 144 uint64_t last_callback_dump_guid_; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 199 EXPECT_TRUE(last_callback_success_); | 212 EXPECT_TRUE(last_callback_success_); |
| 200 | 213 |
| 201 RequestGlobalDumpAndWait(true /* from_renderer_thread */); | 214 RequestGlobalDumpAndWait(true /* from_renderer_thread */); |
| 202 EXPECT_EQ(4u, callback_call_count_); | 215 EXPECT_EQ(4u, callback_call_count_); |
| 203 EXPECT_NE(0u, last_callback_dump_guid_); | 216 EXPECT_NE(0u, last_callback_dump_guid_); |
| 204 EXPECT_TRUE(last_callback_success_); | 217 EXPECT_TRUE(last_callback_success_); |
| 205 | 218 |
| 206 DisableTracing(); | 219 DisableTracing(); |
| 207 } | 220 } |
| 208 | 221 |
| 222 IN_PROC_BROWSER_TEST_F(SingleProcessMemoryTracingTest, QueuedDumps) { | |
|
ssid
2016/06/16 23:12:03
I am removing SingleProcessMemoryTracingTest in th
petrcermak
2016/06/17 08:36:44
Not that I'm aware of, I just followed what the ot
ssid
2016/06/17 18:43:45
Sorry, I got confused with the test files here. Ig
Primiano Tucci (use gerrit)
2016/06/23 11:09:16
Had a chat offline on this. Let's simplify it
Req
petrcermak
2016/06/24 10:49:57
Done (but kept everything in one test).
| |
| 223 Navigate(shell()); | |
| 224 | |
| 225 EnableMemoryTracing(); | |
| 226 | |
| 227 // This test issues the following 6 global memory dump requests: | |
| 228 // | |
| 229 // loop1 (ED) req---------------------------------->ok | |
| 230 // loop2 (PD) req->fail(1) | |
| 231 // loop3 (PL) req-------------------->ok | |
| 232 // loop4 (PL) req->fail(3) | |
| 233 // loop5 (ED) req-------------->ok | |
| 234 // loop6 (PL) req->ok | |
| 235 // | |
| 236 // where P=PERIODIC_INTERVAL, E=EXPLICITLY_TRIGGERED, D=DETAILED and L=LIGHT. | |
| 237 | |
| 238 EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_, _)) | |
| 239 .Times(4) | |
| 240 .WillRepeatedly(Return(true)); | |
| 241 | |
| 242 std::unique_ptr<base::RunLoop> loop1 = RequestGlobalDumpWhichQuitsLoop( | |
| 243 true /* from_renderer_thread */, MemoryDumpType::EXPLICITLY_TRIGGERED, | |
| 244 MemoryDumpLevelOfDetail::DETAILED); | |
| 245 EXPECT_EQ(0u, callback_call_count_); | |
| 246 | |
| 247 // This periodic request should immediately fail because there already is a | |
| 248 // request for a detailed memory dump on the queue (loop1). | |
| 249 std::unique_ptr<base::RunLoop> loop2 = RequestGlobalDumpWhichQuitsLoop( | |
| 250 false /* from_renderer_thread */, MemoryDumpType::PERIODIC_INTERVAL, | |
| 251 MemoryDumpLevelOfDetail::DETAILED); | |
| 252 loop2->Run(); | |
| 253 EXPECT_EQ(1u, callback_call_count_); | |
| 254 EXPECT_FALSE(last_callback_success_); | |
| 255 | |
| 256 std::unique_ptr<base::RunLoop> loop3 = RequestGlobalDumpWhichQuitsLoop( | |
| 257 false /* from_renderer_thread */, MemoryDumpType::PERIODIC_INTERVAL, | |
| 258 MemoryDumpLevelOfDetail::LIGHT); | |
| 259 EXPECT_EQ(1u, callback_call_count_); | |
| 260 | |
| 261 // This periodic request should immediately fail because there already is a | |
| 262 // request for a light memory dump on the queue (loop3). | |
| 263 std::unique_ptr<base::RunLoop> loop4 = RequestGlobalDumpWhichQuitsLoop( | |
| 264 true /* from_renderer_thread */, MemoryDumpType::PERIODIC_INTERVAL, | |
| 265 MemoryDumpLevelOfDetail::LIGHT); | |
| 266 loop4->Run(); | |
| 267 EXPECT_EQ(2u, callback_call_count_); | |
| 268 EXPECT_FALSE(last_callback_success_); | |
| 269 | |
| 270 std::unique_ptr<base::RunLoop> loop5 = RequestGlobalDumpWhichQuitsLoop( | |
| 271 false /* from_renderer_thread */, MemoryDumpType::EXPLICITLY_TRIGGERED, | |
| 272 MemoryDumpLevelOfDetail::DETAILED); | |
| 273 EXPECT_EQ(2u, callback_call_count_); | |
| 274 | |
| 275 loop1->Run(); | |
| 276 EXPECT_EQ(3u, callback_call_count_); | |
| 277 EXPECT_NE(0u, last_callback_dump_guid_); | |
| 278 EXPECT_TRUE(last_callback_success_); | |
| 279 | |
| 280 loop3->Run(); | |
| 281 EXPECT_EQ(4u, callback_call_count_); | |
| 282 EXPECT_NE(0u, last_callback_dump_guid_); | |
| 283 EXPECT_TRUE(last_callback_success_); | |
| 284 | |
| 285 std::unique_ptr<base::RunLoop> loop6 = RequestGlobalDumpWhichQuitsLoop( | |
| 286 false /* from_renderer_thread */, MemoryDumpType::PERIODIC_INTERVAL, | |
| 287 MemoryDumpLevelOfDetail::LIGHT); | |
| 288 | |
| 289 loop5->Run(); | |
| 290 EXPECT_EQ(5u, callback_call_count_); | |
| 291 EXPECT_NE(0u, last_callback_dump_guid_); | |
| 292 EXPECT_TRUE(last_callback_success_); | |
| 293 | |
| 294 loop6->Run(); | |
| 295 EXPECT_EQ(6u, callback_call_count_); | |
| 296 EXPECT_NE(0u, last_callback_dump_guid_); | |
| 297 EXPECT_TRUE(last_callback_success_); | |
| 298 | |
| 299 DisableTracing(); | |
| 300 } | |
| 301 | |
| 209 #endif // !defined(GOOGLE_CHROME_BUILD) | 302 #endif // !defined(GOOGLE_CHROME_BUILD) |
| 210 | 303 |
| 211 // Non-deterministic races under TSan. crbug.com/529678 | 304 // Non-deterministic races under TSan. crbug.com/529678 |
| 212 #if defined(THREAD_SANITIZER) | 305 #if defined(THREAD_SANITIZER) |
| 213 #define MAYBE_BrowserInitiatedDump DISABLED_BrowserInitiatedDump | 306 #define MAYBE_BrowserInitiatedDump DISABLED_BrowserInitiatedDump |
| 214 #else | 307 #else |
| 215 #define MAYBE_BrowserInitiatedDump BrowserInitiatedDump | 308 #define MAYBE_BrowserInitiatedDump BrowserInitiatedDump |
| 216 #endif | 309 #endif |
| 217 // Checks that a memory dump initiated from a the main browser thread ends up in | 310 // Checks that a memory dump initiated from a the main browser thread ends up in |
| 218 // a successful dump. | 311 // a successful dump. |
| 219 IN_PROC_BROWSER_TEST_F(MemoryTracingTest, MAYBE_BrowserInitiatedDump) { | 312 IN_PROC_BROWSER_TEST_F(MemoryTracingTest, MAYBE_BrowserInitiatedDump) { |
| 220 Navigate(shell()); | 313 Navigate(shell()); |
| 221 | 314 |
| 222 EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_,_)).WillOnce(Return(true)); | 315 EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_,_)).WillOnce(Return(true)); |
| 223 | 316 |
| 224 EnableMemoryTracing(); | 317 EnableMemoryTracing(); |
| 225 RequestGlobalDumpAndWait(false /* from_renderer_thread */); | 318 RequestGlobalDumpAndWait(false /* from_renderer_thread */); |
| 226 EXPECT_EQ(1u, callback_call_count_); | 319 EXPECT_EQ(1u, callback_call_count_); |
| 227 EXPECT_NE(0u, last_callback_dump_guid_); | 320 EXPECT_NE(0u, last_callback_dump_guid_); |
| 228 EXPECT_TRUE(last_callback_success_); | 321 EXPECT_TRUE(last_callback_success_); |
| 229 DisableTracing(); | 322 DisableTracing(); |
| 230 } | 323 } |
| 231 | 324 |
| 232 } // namespace content | 325 } // namespace content |
| OLD | NEW |