Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / content / browser / tracing / memory_tracing_browsertest.cc
blob90ddb5bf3b9e121a4b025dde3850f01a246bca86
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
3 // found in the LICENSE file.
5 #include "base/bind.h"
6 #include "base/command_line.h"
7 #include "base/run_loop.h"
8 #include "base/thread_task_runner_handle.h"
9 #include "base/trace_event/memory_dump_manager.h"
10 #include "base/trace_event/memory_dump_provider.h"
11 #include "base/trace_event/memory_dump_request_args.h"
12 #include "content/public/browser/tracing_controller.h"
13 #include "content/public/common/content_switches.h"
14 #include "content/public/test/browser_test_utils.h"
15 #include "content/public/test/content_browser_test.h"
16 #include "content/public/test/content_browser_test_utils.h"
17 #include "content/shell/browser/shell.h"
18 #include "testing/gmock/include/gmock/gmock.h"
20 using base::trace_event::MemoryDumpArgs;
21 using base::trace_event::MemoryDumpManager;
22 using base::trace_event::MemoryDumpType;
23 using base::trace_event::ProcessMemoryDump;
24 using testing::_;
25 using testing::Return;
27 namespace content {
29 // A mock dump provider, used to check that dump requests actually end up
30 // creating memory dumps.
31 class MockDumpProvider : public base::trace_event::MemoryDumpProvider {
32 public:
33 MOCK_METHOD2(OnMemoryDump, bool(const MemoryDumpArgs& args,
34 ProcessMemoryDump* pmd));
37 class MemoryTracingTest : public ContentBrowserTest {
38 public:
39 void DoRequestGlobalDump(const base::trace_event::MemoryDumpCallback& cb) {
40 MemoryDumpArgs dump_args = { MemoryDumpArgs::LevelOfDetail::HIGH };
41 MemoryDumpManager::GetInstance()->RequestGlobalDump(
42 MemoryDumpType::EXPLICITLY_TRIGGERED, dump_args, cb);
45 // Used as callback argument for MemoryDumpManager::RequestGlobalDump():
46 void OnGlobalMemoryDumpDone(
47 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
48 base::Closure closure,
49 uint64 dump_guid,
50 bool success) {
51 // Make sure we run the RunLoop closure on the same thread that originated
52 // the run loop (which is the IN_PROC_BROWSER_TEST_F main thread).
53 if (!task_runner->RunsTasksOnCurrentThread()) {
54 task_runner->PostTask(
55 FROM_HERE, base::Bind(&MemoryTracingTest::OnGlobalMemoryDumpDone,
56 base::Unretained(this), task_runner, closure,
57 dump_guid, success));
58 return;
60 ++callback_call_count_;
61 last_callback_dump_guid_ = dump_guid;
62 last_callback_success_ = success;
63 closure.Run();
66 protected:
67 void SetUp() override {
68 callback_call_count_ = 0;
69 last_callback_dump_guid_ = 0;
70 last_callback_success_ = false;
71 MemoryDumpManager::GetInstance()->Initialize();
72 mock_dump_provider_.reset(new MockDumpProvider());
73 MemoryDumpManager::GetInstance()->RegisterDumpProvider(
74 mock_dump_provider_.get());
75 // TODO(primiano): This should be done via TraceConfig.
76 // See https://goo.gl/5Hj3o0.
77 MemoryDumpManager::GetInstance()->DisablePeriodicDumpsForTesting();
78 ContentBrowserTest::SetUp();
81 void TearDown() override {
82 MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
83 mock_dump_provider_.get());
84 mock_dump_provider_.reset();
85 ContentBrowserTest::TearDown();
88 void EnableMemoryTracing() {
89 base::RunLoop run_loop;
90 std::string category_filter = MemoryDumpManager::kTraceCategory;
91 base::trace_event::TraceConfig trace_config(category_filter, "");
92 bool success = TracingController::GetInstance()->EnableRecording(
93 trace_config, run_loop.QuitClosure());
94 EXPECT_TRUE(success);
95 run_loop.Run();
98 void DisableTracing() {
99 bool success = TracingController::GetInstance()->DisableRecording(NULL);
100 EXPECT_TRUE(success);
101 base::RunLoop().RunUntilIdle();
104 void RequestGlobalDumpAndWait(bool from_renderer_thread) {
105 base::RunLoop run_loop;
106 base::trace_event::MemoryDumpCallback callback = base::Bind(
107 &MemoryTracingTest::OnGlobalMemoryDumpDone, base::Unretained(this),
108 base::ThreadTaskRunnerHandle::Get(), run_loop.QuitClosure());
109 if (from_renderer_thread) {
110 PostTaskToInProcessRendererAndWait(
111 base::Bind(&MemoryTracingTest::DoRequestGlobalDump,
112 base::Unretained(this), callback));
113 } else {
114 DoRequestGlobalDump(callback);
116 run_loop.Run();
119 void Navigate(Shell* shell) {
120 NavigateToURL(shell, GetTestUrl("", "title.html"));
123 base::Closure on_memory_dump_complete_closure_;
124 scoped_ptr<MockDumpProvider> mock_dump_provider_;
125 uint32 callback_call_count_;
126 uint64 last_callback_dump_guid_;
127 bool last_callback_success_;
130 // Ignore SingleProcessMemoryTracingTests for Google Chrome builds because
131 // single-process is not supported on those builds.
132 #if !defined(GOOGLE_CHROME_BUILD)
134 class SingleProcessMemoryTracingTest : public MemoryTracingTest {
135 public:
136 SingleProcessMemoryTracingTest() {}
138 void SetUpCommandLine(base::CommandLine* command_line) override {
139 command_line->AppendSwitch(switches::kSingleProcess);
143 // Checks that a memory dump initiated from a the main browser thread ends up in
144 // a single dump even in single process mode.
145 IN_PROC_BROWSER_TEST_F(SingleProcessMemoryTracingTest,
146 BrowserInitiatedSingleDump) {
147 Navigate(shell());
149 EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_,_)).WillOnce(Return(true));
151 EnableMemoryTracing();
152 RequestGlobalDumpAndWait(false /* from_renderer_thread */);
153 EXPECT_EQ(1u, callback_call_count_);
154 EXPECT_NE(0u, last_callback_dump_guid_);
155 EXPECT_TRUE(last_callback_success_);
156 DisableTracing();
159 // Checks that a memory dump initiated from a renderer thread ends up in a
160 // single dump even in single process mode.
161 IN_PROC_BROWSER_TEST_F(SingleProcessMemoryTracingTest,
162 RendererInitiatedSingleDump) {
163 Navigate(shell());
165 EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_,_)).WillOnce(Return(true));
167 EnableMemoryTracing();
168 RequestGlobalDumpAndWait(true /* from_renderer_thread */);
169 EXPECT_EQ(1u, callback_call_count_);
170 EXPECT_NE(0u, last_callback_dump_guid_);
171 EXPECT_TRUE(last_callback_success_);
172 DisableTracing();
175 IN_PROC_BROWSER_TEST_F(SingleProcessMemoryTracingTest, ManyInterleavedDumps) {
176 Navigate(shell());
178 EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_,_))
179 .Times(4)
180 .WillRepeatedly(Return(true));
182 EnableMemoryTracing();
184 RequestGlobalDumpAndWait(true /* from_renderer_thread */);
185 EXPECT_NE(0u, last_callback_dump_guid_);
186 EXPECT_TRUE(last_callback_success_);
188 RequestGlobalDumpAndWait(false /* from_renderer_thread */);
189 EXPECT_NE(0u, last_callback_dump_guid_);
190 EXPECT_TRUE(last_callback_success_);
192 RequestGlobalDumpAndWait(false /* from_renderer_thread */);
193 EXPECT_NE(0u, last_callback_dump_guid_);
194 EXPECT_TRUE(last_callback_success_);
196 RequestGlobalDumpAndWait(true /* from_renderer_thread */);
197 EXPECT_EQ(4u, callback_call_count_);
198 EXPECT_NE(0u, last_callback_dump_guid_);
199 EXPECT_TRUE(last_callback_success_);
201 DisableTracing();
204 #endif // !defined(GOOGLE_CHROME_BUILD)
206 // Checks that a memory dump initiated from a the main browser thread ends up in
207 // a successful dump.
208 IN_PROC_BROWSER_TEST_F(MemoryTracingTest, BrowserInitiatedDump) {
209 Navigate(shell());
211 EXPECT_CALL(*mock_dump_provider_, OnMemoryDump(_,_)).WillOnce(Return(true));
213 EnableMemoryTracing();
214 RequestGlobalDumpAndWait(false /* from_renderer_thread */);
215 EXPECT_EQ(1u, callback_call_count_);
216 EXPECT_NE(0u, last_callback_dump_guid_);
217 EXPECT_TRUE(last_callback_success_);
218 DisableTracing();
221 } // namespace content