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

Side by Side Diff: content/browser/tracing/memory_tracing_browsertest.cc

Issue 2067793004: [memory-infra] Add support for queueing memory dump requests in the browser process (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <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/synchronization/waitable_event.h"
11 #include "base/threading/thread.h"
10 #include "base/threading/thread_task_runner_handle.h" 12 #include "base/threading/thread_task_runner_handle.h"
11 #include "base/trace_event/memory_dump_manager.h" 13 #include "base/trace_event/memory_dump_manager.h"
12 #include "base/trace_event/memory_dump_provider.h" 14 #include "base/trace_event/memory_dump_provider.h"
13 #include "base/trace_event/memory_dump_request_args.h" 15 #include "base/trace_event/memory_dump_request_args.h"
14 #include "base/trace_event/trace_config_memory_test_util.h" 16 #include "base/trace_event/trace_config_memory_test_util.h"
15 #include "content/public/browser/tracing_controller.h" 17 #include "content/public/browser/tracing_controller.h"
16 #include "content/public/common/content_switches.h" 18 #include "content/public/common/content_switches.h"
17 #include "content/public/test/browser_test_utils.h" 19 #include "content/public/test/browser_test_utils.h"
18 #include "content/public/test/content_browser_test.h" 20 #include "content/public/test/content_browser_test.h"
19 #include "content/public/test/content_browser_test_utils.h" 21 #include "content/public/test/content_browser_test_utils.h"
20 #include "content/shell/browser/shell.h" 22 #include "content/shell/browser/shell.h"
21 #include "testing/gmock/include/gmock/gmock.h" 23 #include "testing/gmock/include/gmock/gmock.h"
22 24
23 using base::trace_event::MemoryDumpArgs; 25 using base::trace_event::MemoryDumpArgs;
24 using base::trace_event::MemoryDumpManager; 26 using base::trace_event::MemoryDumpManager;
25 using base::trace_event::MemoryDumpType; 27 using base::trace_event::MemoryDumpType;
26 using base::trace_event::ProcessMemoryDump; 28 using base::trace_event::ProcessMemoryDump;
27 using testing::_; 29 using testing::_;
30 using testing::DoAll;
28 using testing::Return; 31 using testing::Return;
29 32
30 namespace content { 33 namespace content {
31 34
35 ACTION_P(WaitEvent, event) {
36 event->Wait();
37 }
38
32 // A mock dump provider, used to check that dump requests actually end up 39 // A mock dump provider, used to check that dump requests actually end up
33 // creating memory dumps. 40 // creating memory dumps.
34 class MockDumpProvider : public base::trace_event::MemoryDumpProvider { 41 class MockDumpProvider : public base::trace_event::MemoryDumpProvider {
35 public: 42 public:
36 MOCK_METHOD2(OnMemoryDump, bool(const MemoryDumpArgs& args, 43 MOCK_METHOD2(OnMemoryDump, bool(const MemoryDumpArgs& args,
37 ProcessMemoryDump* pmd)); 44 ProcessMemoryDump* pmd));
38 }; 45 };
39 46
40 class MemoryTracingTest : public ContentBrowserTest { 47 class MemoryTracingTest : public ContentBrowserTest {
41 public: 48 public:
(...skipping 23 matching lines...) Expand all
65 last_callback_success_ = success; 72 last_callback_success_ = success;
66 closure.Run(); 73 closure.Run();
67 } 74 }
68 75
69 protected: 76 protected:
70 void SetUp() override { 77 void SetUp() override {
71 callback_call_count_ = 0; 78 callback_call_count_ = 0;
72 last_callback_dump_guid_ = 0; 79 last_callback_dump_guid_ = 0;
73 last_callback_success_ = false; 80 last_callback_success_ = false;
74 81
82 mock_dump_provider_thread_.reset(
83 new base::Thread("MockDumpProvider thread"));
84 EXPECT_TRUE(mock_dump_provider_thread_->Start());
75 mock_dump_provider_.reset(new MockDumpProvider()); 85 mock_dump_provider_.reset(new MockDumpProvider());
76 MemoryDumpManager::GetInstance()->RegisterDumpProvider( 86 MemoryDumpManager::GetInstance()->RegisterDumpProvider(
77 mock_dump_provider_.get(), "MockDumpProvider", nullptr); 87 mock_dump_provider_.get(), "MockDumpProvider",
88 mock_dump_provider_thread_->task_runner());
78 MemoryDumpManager::GetInstance() 89 MemoryDumpManager::GetInstance()
79 ->set_dumper_registrations_ignored_for_testing(false); 90 ->set_dumper_registrations_ignored_for_testing(false);
80 ContentBrowserTest::SetUp(); 91 ContentBrowserTest::SetUp();
81 } 92 }
82 93
83 void TearDown() override { 94 void TearDown() override {
84 MemoryDumpManager::GetInstance()->UnregisterDumpProvider( 95 MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
85 mock_dump_provider_.get()); 96 mock_dump_provider_.get());
86 mock_dump_provider_.reset(); 97 mock_dump_provider_.reset();
98 mock_dump_provider_thread_.reset();
87 ContentBrowserTest::TearDown(); 99 ContentBrowserTest::TearDown();
88 } 100 }
89 101
90 void EnableMemoryTracing() { 102 void EnableMemoryTracing() {
91 // Enable tracing without periodic dumps. 103 // Enable tracing without periodic dumps.
92 base::trace_event::TraceConfig trace_config( 104 base::trace_event::TraceConfig trace_config(
93 base::trace_event::TraceConfigMemoryTestUtil:: 105 base::trace_event::TraceConfigMemoryTestUtil::
94 GetTraceConfig_EmptyTriggers()); 106 GetTraceConfig_EmptyTriggers());
95 107
96 base::RunLoop run_loop; 108 base::RunLoop run_loop;
97 bool success = TracingController::GetInstance()->StartTracing( 109 bool success = TracingController::GetInstance()->StartTracing(
98 trace_config, run_loop.QuitClosure()); 110 trace_config, run_loop.QuitClosure());
99 EXPECT_TRUE(success); 111 EXPECT_TRUE(success);
100 run_loop.Run(); 112 run_loop.Run();
101 } 113 }
102 114
103 void DisableTracing() { 115 void DisableTracing() {
104 bool success = TracingController::GetInstance()->StopTracing(NULL); 116 bool success = TracingController::GetInstance()->StopTracing(NULL);
105 EXPECT_TRUE(success); 117 EXPECT_TRUE(success);
106 base::RunLoop().RunUntilIdle(); 118 base::RunLoop().RunUntilIdle();
107 } 119 }
108 120
109 void RequestGlobalDumpAndWait(bool from_renderer_thread) { 121 void RequestGlobalDumpWhichQuitsLoop(bool from_renderer_thread,
110 base::RunLoop run_loop; 122 base::RunLoop* run_loop) {
111 base::trace_event::MemoryDumpCallback callback = base::Bind( 123 base::trace_event::MemoryDumpCallback callback = base::Bind(
112 &MemoryTracingTest::OnGlobalMemoryDumpDone, base::Unretained(this), 124 &MemoryTracingTest::OnGlobalMemoryDumpDone, base::Unretained(this),
113 base::ThreadTaskRunnerHandle::Get(), run_loop.QuitClosure()); 125 base::ThreadTaskRunnerHandle::Get(), run_loop->QuitClosure());
114 if (from_renderer_thread) { 126 if (from_renderer_thread) {
115 PostTaskToInProcessRendererAndWait( 127 PostTaskToInProcessRendererAndWait(
116 base::Bind(&MemoryTracingTest::DoRequestGlobalDump, 128 base::Bind(&MemoryTracingTest::DoRequestGlobalDump,
117 base::Unretained(this), callback)); 129 base::Unretained(this), callback));
118 } else { 130 } else {
119 DoRequestGlobalDump(callback); 131 DoRequestGlobalDump(callback);
120 } 132 }
133 }
134
135 void RequestGlobalDumpAndWait(bool from_renderer_thread) {
136 base::RunLoop run_loop;
137 RequestGlobalDumpWhichQuitsLoop(from_renderer_thread, &run_loop);
121 run_loop.Run(); 138 run_loop.Run();
122 } 139 }
123 140
124 void Navigate(Shell* shell) { 141 void Navigate(Shell* shell) {
125 NavigateToURL(shell, GetTestUrl("", "title.html")); 142 NavigateToURL(shell, GetTestUrl("", "title.html"));
126 } 143 }
127 144
128 base::Closure on_memory_dump_complete_closure_; 145 base::Closure on_memory_dump_complete_closure_;
146 std::unique_ptr<base::Thread> mock_dump_provider_thread_;
129 std::unique_ptr<MockDumpProvider> mock_dump_provider_; 147 std::unique_ptr<MockDumpProvider> mock_dump_provider_;
130 uint32_t callback_call_count_; 148 uint32_t callback_call_count_;
131 uint64_t last_callback_dump_guid_; 149 uint64_t last_callback_dump_guid_;
132 bool last_callback_success_; 150 bool last_callback_success_;
133 }; 151 };
134 152
135 // Ignore SingleProcessMemoryTracingTests for Google Chrome builds because 153 // Ignore SingleProcessMemoryTracingTests for Google Chrome builds because
136 // single-process is not supported on those builds. 154 // single-process is not supported on those builds.
137 #if !defined(GOOGLE_CHROME_BUILD) 155 #if !defined(GOOGLE_CHROME_BUILD)
138 156
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 EXPECT_TRUE(last_callback_success_); 217 EXPECT_TRUE(last_callback_success_);
200 218
201 RequestGlobalDumpAndWait(true /* from_renderer_thread */); 219 RequestGlobalDumpAndWait(true /* from_renderer_thread */);
202 EXPECT_EQ(4u, callback_call_count_); 220 EXPECT_EQ(4u, callback_call_count_);
203 EXPECT_NE(0u, last_callback_dump_guid_); 221 EXPECT_NE(0u, last_callback_dump_guid_);
204 EXPECT_TRUE(last_callback_success_); 222 EXPECT_TRUE(last_callback_success_);
205 223
206 DisableTracing(); 224 DisableTracing();
207 } 225 }
208 226
227 IN_PROC_BROWSER_TEST_F(SingleProcessMemoryTracingTest, EnqueuedDumps) {
228 Navigate(shell());
229
230 EnableMemoryTracing();
231
232 base::RunLoop loop1;
Primiano Tucci (use gerrit) 2016/06/16 08:37:23 never seen this pattern, why do you need 4 run loo
petrcermak 2016/06/16 12:08:29 The problem is that I need to do the following:
233 base::RunLoop loop2;
234 base::RunLoop loop3;
235 base::RunLoop loop4;
236
237 // We force all dumps to wait on a waitable event to make sure that they are
238 // indeed queued.
239 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
Primiano Tucci (use gerrit) 2016/06/16 08:37:23 I think you don't need this waitable event if you
petrcermak 2016/06/16 12:08:29 OK. Just to check: Am I guaranteed that a dump doe
240 base::WaitableEvent::InitialState::NOT_SIGNALED);
241 EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_, _))
242 .Times(4)
243 .WillRepeatedly(DoAll(WaitEvent(&event), Return(true)));
244
245 RequestGlobalDumpWhichQuitsLoop(false /* from_renderer_thread */, &loop1);
246 RequestGlobalDumpWhichQuitsLoop(true /* from_renderer_thread */, &loop2);
247 RequestGlobalDumpWhichQuitsLoop(false /* from_renderer_thread */, &loop3);
248 RequestGlobalDumpWhichQuitsLoop(true /* from_renderer_thread */, &loop4);
249 EXPECT_EQ(0u, callback_call_count_);
250
251 event.Signal();
252 loop1.Run();
253 EXPECT_EQ(1u, callback_call_count_);
254 EXPECT_NE(0u, last_callback_dump_guid_);
255 EXPECT_TRUE(last_callback_success_);
256
257 event.Signal();
258 loop2.Run();
259 EXPECT_EQ(2u, callback_call_count_);
260 EXPECT_NE(0u, last_callback_dump_guid_);
261 EXPECT_TRUE(last_callback_success_);
262
263 event.Signal();
264 loop3.Run();
265 EXPECT_EQ(3u, callback_call_count_);
266 EXPECT_NE(0u, last_callback_dump_guid_);
267 EXPECT_TRUE(last_callback_success_);
268
269 event.Signal();
270 loop4.Run();
271 EXPECT_EQ(4u, callback_call_count_);
272 EXPECT_NE(0u, last_callback_dump_guid_);
273 EXPECT_TRUE(last_callback_success_);
274
275 DisableTracing();
276 }
277
209 #endif // !defined(GOOGLE_CHROME_BUILD) 278 #endif // !defined(GOOGLE_CHROME_BUILD)
210 279
211 // Non-deterministic races under TSan. crbug.com/529678 280 // Non-deterministic races under TSan. crbug.com/529678
212 #if defined(THREAD_SANITIZER) 281 #if defined(THREAD_SANITIZER)
213 #define MAYBE_BrowserInitiatedDump DISABLED_BrowserInitiatedDump 282 #define MAYBE_BrowserInitiatedDump DISABLED_BrowserInitiatedDump
214 #else 283 #else
215 #define MAYBE_BrowserInitiatedDump BrowserInitiatedDump 284 #define MAYBE_BrowserInitiatedDump BrowserInitiatedDump
216 #endif 285 #endif
217 // Checks that a memory dump initiated from a the main browser thread ends up in 286 // Checks that a memory dump initiated from a the main browser thread ends up in
218 // a successful dump. 287 // a successful dump.
219 IN_PROC_BROWSER_TEST_F(MemoryTracingTest, MAYBE_BrowserInitiatedDump) { 288 IN_PROC_BROWSER_TEST_F(MemoryTracingTest, MAYBE_BrowserInitiatedDump) {
220 Navigate(shell()); 289 Navigate(shell());
221 290
222 EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_,_)).WillOnce(Return(true)); 291 EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_,_)).WillOnce(Return(true));
223 292
224 EnableMemoryTracing(); 293 EnableMemoryTracing();
225 RequestGlobalDumpAndWait(false /* from_renderer_thread */); 294 RequestGlobalDumpAndWait(false /* from_renderer_thread */);
226 EXPECT_EQ(1u, callback_call_count_); 295 EXPECT_EQ(1u, callback_call_count_);
227 EXPECT_NE(0u, last_callback_dump_guid_); 296 EXPECT_NE(0u, last_callback_dump_guid_);
228 EXPECT_TRUE(last_callback_success_); 297 EXPECT_TRUE(last_callback_success_);
229 DisableTracing(); 298 DisableTracing();
230 } 299 }
231 300
232 } // namespace content 301 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | content/browser/tracing/tracing_controller_impl.h » ('j') | content/browser/tracing/tracing_controller_impl.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698