1 // Copyright (c) 2012 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 "chrome/test/base/tracing.h"
7 #include "base/command_line.h"
8 #include "base/location.h"
9 #include "base/run_loop.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "base/trace_event/memory_dump_manager.h"
13 #include "base/trace_event/trace_event.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/tabs/tab_strip_model.h"
16 #include "chrome/test/base/in_process_browser_test.h"
17 #include "chrome/test/base/ui_test_utils.h"
18 #include "content/public/browser/render_view_host.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/common/content_switches.h"
21 #include "content/public/test/browser_test_utils.h"
22 #include "testing/gtest/include/gtest/gtest.h"
26 using base::trace_event::MemoryDumpManager
;
27 using base::trace_event::MemoryDumpType
;
28 using tracing::BeginTracingWithWatch
;
29 using tracing::WaitForWatchEvent
;
30 using tracing::EndTracing
;
32 const char g_category
[] = "test_tracing";
33 const char g_event
[] = "TheEvent";
35 class TracingBrowserTest
: public InProcessBrowserTest
{
37 // Execute some no-op javascript on the current tab - this triggers a trace
38 // event in RenderFrameImpl::OnJavaScriptExecuteRequestForTests (from the
40 void ExecuteJavascriptOnCurrentTab() {
41 content::RenderViewHost
* rvh
= browser()->tab_strip_model()->
42 GetActiveWebContents()->GetRenderViewHost();
44 ASSERT_TRUE(content::ExecuteScript(rvh
, ";"));
47 void PerformDumpMemoryTestActions() {
48 std::string json_events
;
49 base::TimeDelta no_timeout
;
51 GURL
url1("about:blank");
52 ui_test_utils::NavigateToURLWithDisposition(
53 browser(), url1
, NEW_FOREGROUND_TAB
,
54 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
55 ASSERT_NO_FATAL_FAILURE(ExecuteJavascriptOnCurrentTab());
57 // Begin tracing and watch for multiple periodic dump trace events.
58 std::string event_name
= base::trace_event::MemoryDumpTypeToString(
59 MemoryDumpType::PERIODIC_INTERVAL
);
60 ASSERT_TRUE(BeginTracingWithWatch(MemoryDumpManager::kTraceCategory
,
61 MemoryDumpManager::kTraceCategory
,
64 GURL
url2("chrome://credits/");
65 ui_test_utils::NavigateToURLWithDisposition(
66 browser(), url2
, NEW_FOREGROUND_TAB
,
67 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
68 ASSERT_NO_FATAL_FAILURE(ExecuteJavascriptOnCurrentTab());
70 EXPECT_TRUE(WaitForWatchEvent(no_timeout
));
71 ASSERT_TRUE(EndTracing(&json_events
));
73 // Expect the basic memory dumps to be present in the trace.
74 EXPECT_NE(std::string::npos
, json_events
.find("process_totals"));
76 EXPECT_NE(std::string::npos
, json_events
.find("v8"));
77 EXPECT_NE(std::string::npos
, json_events
.find("blink_gc"));
81 class SingleProcessTracingBrowserTest
: public TracingBrowserTest
{
83 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
84 InProcessBrowserTest::SetUpCommandLine(command_line
);
85 command_line
->AppendSwitch(switches::kSingleProcess
);
89 void AddEvents(int num
) {
90 for (int i
= 0; i
< num
; ++i
)
91 TRACE_EVENT_INSTANT0(g_category
, g_event
, TRACE_EVENT_SCOPE_THREAD
);
94 IN_PROC_BROWSER_TEST_F(TracingBrowserTest
, BeginTracingWithWatch
) {
95 base::TimeDelta no_timeout
;
96 base::TimeDelta short_timeout
= base::TimeDelta::FromMilliseconds(5);
97 std::string json_events
;
99 // One event before wait.
100 ASSERT_TRUE(BeginTracingWithWatch(g_category
, g_category
, g_event
, 1));
102 EXPECT_TRUE(WaitForWatchEvent(no_timeout
));
103 ASSERT_TRUE(EndTracing(&json_events
));
105 // One event after wait.
106 ASSERT_TRUE(BeginTracingWithWatch(g_category
, g_category
, g_event
, 1));
107 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
,
108 base::Bind(&AddEvents
, 1));
109 EXPECT_TRUE(WaitForWatchEvent(no_timeout
));
110 ASSERT_TRUE(EndTracing(&json_events
));
112 // Not enough events timeout.
113 ASSERT_TRUE(BeginTracingWithWatch(g_category
, g_category
, g_event
, 2));
115 EXPECT_FALSE(WaitForWatchEvent(short_timeout
));
116 ASSERT_TRUE(EndTracing(&json_events
));
118 // Multi event before wait.
119 ASSERT_TRUE(BeginTracingWithWatch(g_category
, g_category
, g_event
, 5));
121 EXPECT_TRUE(WaitForWatchEvent(no_timeout
));
122 ASSERT_TRUE(EndTracing(&json_events
));
124 // Multi event after wait.
125 ASSERT_TRUE(BeginTracingWithWatch(g_category
, g_category
, g_event
, 5));
126 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE
,
127 base::Bind(&AddEvents
, 5));
128 EXPECT_TRUE(WaitForWatchEvent(no_timeout
));
129 ASSERT_TRUE(EndTracing(&json_events
));
131 // Child process events from same process.
132 ASSERT_TRUE(BeginTracingWithWatch(g_category
, g_category
,
133 "OnJavaScriptExecuteRequestForTests", 2));
134 ASSERT_NO_FATAL_FAILURE(ExecuteJavascriptOnCurrentTab());
135 ASSERT_NO_FATAL_FAILURE(ExecuteJavascriptOnCurrentTab());
136 EXPECT_TRUE(WaitForWatchEvent(no_timeout
));
137 ASSERT_TRUE(EndTracing(&json_events
));
139 // Child process events from different processes.
140 GURL
url1("chrome://tracing/");
141 GURL
url2("chrome://credits/");
142 ASSERT_TRUE(BeginTracingWithWatch(g_category
, g_category
,
143 "OnJavaScriptExecuteRequestForTests", 2));
144 // Open two tabs to different URLs to encourage two separate renderer
145 // processes. Each will fire an event that will be counted towards the total.
146 ui_test_utils::NavigateToURLWithDisposition(browser(), url1
,
147 NEW_FOREGROUND_TAB
, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
148 ASSERT_NO_FATAL_FAILURE(ExecuteJavascriptOnCurrentTab());
149 ui_test_utils::NavigateToURLWithDisposition(browser(), url2
,
150 NEW_FOREGROUND_TAB
, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
151 ASSERT_NO_FATAL_FAILURE(ExecuteJavascriptOnCurrentTab());
152 EXPECT_TRUE(WaitForWatchEvent(no_timeout
));
153 ASSERT_TRUE(EndTracing(&json_events
));
156 // Multi-process mode.
157 IN_PROC_BROWSER_TEST_F(TracingBrowserTest
, TestMemoryInfra
) {
158 PerformDumpMemoryTestActions();
161 // Single-process mode.
162 IN_PROC_BROWSER_TEST_F(SingleProcessTracingBrowserTest
, TestMemoryInfra
) {
163 PerformDumpMemoryTestActions();