summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-10 05:11:33 +0000
committerdmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-10 05:11:33 +0000
commita10518617a875aaea9ed572c0d794b2581a05603 (patch)
treed4ccec67def04b7fc0335dc3f38c479ab5a34064
parentf9907e347b6f3ef2c747ec3e46278f41d72faa2e (diff)
downloadchromium_src-a10518617a875aaea9ed572c0d794b2581a05603.zip
chromium_src-a10518617a875aaea9ed572c0d794b2581a05603.tar.gz
chromium_src-a10518617a875aaea9ed572c0d794b2581a05603.tar.bz2
Add a WebDriver API function HeapProrilerDump.
BUG=123751 TEST=none Review URL: https://chromiumcodereview.appspot.com/10161020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@136242 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/test/automation/automation_json_requests.cc17
-rw-r--r--chrome/test/automation/automation_json_requests.h10
-rwxr-xr-xchrome/test/pyautolib/pyauto.py10
-rw-r--r--chrome/test/webdriver/commands/chrome_commands.cc27
-rw-r--r--chrome/test/webdriver/commands/chrome_commands.h17
-rw-r--r--chrome/test/webdriver/test/chromedriver.py30
-rw-r--r--chrome/test/webdriver/webdriver_automation.cc17
-rw-r--r--chrome/test/webdriver/webdriver_automation.h6
-rw-r--r--chrome/test/webdriver/webdriver_server.cc4
-rw-r--r--chrome/test/webdriver/webdriver_session.cc14
-rw-r--r--chrome/test/webdriver/webdriver_session.h3
11 files changed, 147 insertions, 8 deletions
diff --git a/chrome/test/automation/automation_json_requests.cc b/chrome/test/automation/automation_json_requests.cc
index 059c11e..3a6fb95 100644
--- a/chrome/test/automation/automation_json_requests.cc
+++ b/chrome/test/automation/automation_json_requests.cc
@@ -359,6 +359,23 @@ bool SendCaptureEntirePageJSONRequest(
return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
}
+#if !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
+bool SendHeapProfilerDumpJSONRequest(
+ AutomationMessageSender* sender,
+ const WebViewLocator& locator,
+ const std::string& reason,
+ Error* error) {
+ DictionaryValue dict;
+ dict.SetString("command", "HeapProfilerDump");
+ dict.SetString("process_type", "renderer");
+ dict.SetString("reason", reason);
+ locator.UpdateDictionary(&dict, "auto_id");
+ DictionaryValue reply_dict;
+
+ return SendAutomationJSONRequest(sender, dict, &reply_dict, error);
+}
+#endif // !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
+
bool SendGetCookiesJSONRequest(
AutomationMessageSender* sender,
const std::string& url,
diff --git a/chrome/test/automation/automation_json_requests.h b/chrome/test/automation/automation_json_requests.h
index 5fc2c14..22fb858 100644
--- a/chrome/test/automation/automation_json_requests.h
+++ b/chrome/test/automation/automation_json_requests.h
@@ -248,6 +248,16 @@ bool SendCaptureEntirePageJSONRequest(
const FilePath& path,
automation::Error* error) WARN_UNUSED_RESULT;
+#if !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
+// Requests a heap profile dump.
+// Returns true on success.
+bool SendHeapProfilerDumpJSONRequest(
+ AutomationMessageSender* sender,
+ const WebViewLocator& locator,
+ const std::string& reason,
+ automation::Error* error) WARN_UNUSED_RESULT;
+#endif // !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
+
// Requests all the cookies for the given URL. On success returns true and
// caller takes ownership of |cookies|, which is a list of all the cookies in
// dictionary format.
diff --git a/chrome/test/pyautolib/pyauto.py b/chrome/test/pyautolib/pyauto.py
index ce70de1..0eb5765 100755
--- a/chrome/test/pyautolib/pyauto.py
+++ b/chrome/test/pyautolib/pyauto.py
@@ -3486,11 +3486,11 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase):
def HeapProfilerDump(self, process_type, reason, tab_index=0, windex=0):
"""Dumps a heap profile. It works only on Linux and ChromeOS.
- We need an environment variable "HEAPPROFILE" set to a directory and a
- filename prefix, for example, "/tmp/prof". In a case of this example,
- heap profiles will be dumped into "/tmp/prof.(pid).0002.heap",
- "/tmp/prof.(pid).0003.heap", and so on. Nothing happens when this
- function is called without the env.
+ We need an environment variable "HEAPPROFILE" set to a directory and a
+ filename prefix, for example, "/tmp/prof". In a case of this example,
+ heap profiles will be dumped into "/tmp/prof.(pid).0002.heap",
+ "/tmp/prof.(pid).0003.heap", and so on. Nothing happens when this
+ function is called without the env.
Args:
process_type: A string which is one of 'browser' or 'renderer'.
diff --git a/chrome/test/webdriver/commands/chrome_commands.cc b/chrome/test/webdriver/commands/chrome_commands.cc
index d12e071..88d7b78 100644
--- a/chrome/test/webdriver/commands/chrome_commands.cc
+++ b/chrome/test/webdriver/commands/chrome_commands.cc
@@ -255,4 +255,31 @@ void ViewsCommand::ExecuteGet(Response* const response) {
response->SetValue(views_list);
}
+#if !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
+HeapProfilerDumpCommand::HeapProfilerDumpCommand(
+ const std::vector<std::string>& ps,
+ const DictionaryValue* const parameters)
+ : WebDriverCommand(ps, parameters) {}
+
+HeapProfilerDumpCommand::~HeapProfilerDumpCommand() {}
+
+bool HeapProfilerDumpCommand::DoesPost() {
+ return true;
+}
+
+void HeapProfilerDumpCommand::ExecutePost(Response* const response) {
+ std::string reason;
+ if (!GetStringParameter("reason", &reason)) {
+ response->SetError(new Error(kBadRequest, "'reason' missing or invalid"));
+ return;
+ }
+
+ Error* error = session_->HeapProfilerDump(reason);
+ if (error) {
+ response->SetError(error);
+ return;
+ }
+}
+#endif // !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
+
} // namespace webdriver
diff --git a/chrome/test/webdriver/commands/chrome_commands.h b/chrome/test/webdriver/commands/chrome_commands.h
index c84f5d4..7fc7993 100644
--- a/chrome/test/webdriver/commands/chrome_commands.h
+++ b/chrome/test/webdriver/commands/chrome_commands.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -83,6 +83,21 @@ class ViewsCommand : public WebDriverCommand {
DISALLOW_COPY_AND_ASSIGN(ViewsCommand);
};
+#if !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
+class HeapProfilerDumpCommand : public WebDriverCommand {
+ public:
+ HeapProfilerDumpCommand(const std::vector<std::string>& path_segments,
+ const base::DictionaryValue* const parameters);
+ virtual ~HeapProfilerDumpCommand();
+
+ virtual bool DoesPost() OVERRIDE;
+ virtual void ExecutePost(Response* const response) OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(HeapProfilerDumpCommand);
+};
+#endif // !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
+
} // namespace webdriver
#endif // CHROME_TEST_WEBDRIVER_COMMANDS_CHROME_COMMANDS_H_
diff --git a/chrome/test/webdriver/test/chromedriver.py b/chrome/test/webdriver/test/chromedriver.py
index b26e736..a22680d 100644
--- a/chrome/test/webdriver/test/chromedriver.py
+++ b/chrome/test/webdriver/test/chromedriver.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -12,6 +12,7 @@ since this module will eventually be moved into the webdriver codebase, the
code follows WebDriver naming conventions for functions.
"""
+from selenium.common.exceptions import WebDriverException
from selenium.webdriver.remote.webdriver import WebDriver as RemoteWebDriver
@@ -38,6 +39,7 @@ class WebDriver(RemoteWebDriver):
_CHROME_MODIFY_EXTENSION = "chrome.setExtensionState"
_CHROME_UNINSTALL_EXTENSION = "chrome.uninstallExtension"
_CHROME_GET_VIEW_HANDLES = "chrome.getViewHandles"
+ _CHROME_DUMP_HEAP_PROFILE = "chrome.dumpHeapProfile"
def __init__(self, url, desired_capabilities={}):
"""Creates a WebDriver that controls Chrome via ChromeDriver.
@@ -64,7 +66,9 @@ class WebDriver(RemoteWebDriver):
WebDriver._CHROME_UNINSTALL_EXTENSION:
('DELETE', '/session/$sessionId/chrome/extension/$id'),
WebDriver._CHROME_GET_VIEW_HANDLES:
- ('GET', '/session/$sessionId/chrome/views')
+ ('GET', '/session/$sessionId/chrome/views'),
+ WebDriver._CHROME_DUMP_HEAP_PROFILE:
+ ('POST', '/session/$sessionId/chrome/heapprofilerdump')
}
self.command_executor._commands.update(custom_commands)
@@ -88,6 +92,28 @@ class WebDriver(RemoteWebDriver):
self, WebDriver._CHROME_INSTALL_EXTENSION, params)['value']
return Extension(self, id)
+ def dump_heap_profile(self, reason):
+ """Dumps a heap profile. It works only on Linux and ChromeOS.
+
+ We need an environment variable "HEAPPROFILE" set to a directory and a
+ filename prefix, for example, "/tmp/prof". In a case of this example,
+ heap profiles will be dumped into "/tmp/prof.(pid).0002.heap",
+ "/tmp/prof.(pid).0003.heap", and so on. Nothing happens when this
+ function is called without the env.
+
+ Args:
+ reason: A string which describes the reason for dumping a heap profile.
+ The reason will be included in the logged message.
+ Examples:
+ 'To check memory leaking'
+ 'For WebDriver tests'
+ """
+ if self.IsLinux(): # IsLinux() also implies IsChromeOS().
+ params = {'reason': reason}
+ RemoteWebDriver.execute(self, WebDriver._CHROME_DUMP_HEAP_PROFILE, params)
+ else:
+ raise WebDriverException('Heap-profiling is not supported in this OS.')
+
class Extension(object):
"""Represents a Chrome extension/app."""
diff --git a/chrome/test/webdriver/webdriver_automation.cc b/chrome/test/webdriver/webdriver_automation.cc
index 05addd1..f64bf37 100644
--- a/chrome/test/webdriver/webdriver_automation.cc
+++ b/chrome/test/webdriver/webdriver_automation.cc
@@ -561,6 +561,23 @@ void Automation::CaptureEntirePageAsPNG(const WebViewId& view_id,
}
}
+#if !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
+void Automation::HeapProfilerDump(const WebViewId& view_id,
+ const std::string& reason,
+ Error** error) {
+ WebViewLocator view_locator;
+ *error = ConvertViewIdToLocator(view_id, &view_locator);
+ if (*error)
+ return;
+
+ automation::Error auto_error;
+ if (!SendHeapProfilerDumpJSONRequest(
+ automation(), view_locator, reason, &auto_error)) {
+ *error = Error::FromAutomationError(auto_error);
+ }
+}
+#endif // !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
+
void Automation::NavigateToURL(const WebViewId& view_id,
const std::string& url,
Error** error) {
diff --git a/chrome/test/webdriver/webdriver_automation.h b/chrome/test/webdriver/webdriver_automation.h
index 312ef14..13d4775 100644
--- a/chrome/test/webdriver/webdriver_automation.h
+++ b/chrome/test/webdriver/webdriver_automation.h
@@ -119,6 +119,12 @@ class Automation {
void CaptureEntirePageAsPNG(
const WebViewId& view_id, const FilePath& path, Error** error);
+#if !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
+ // Dumps a heap profile of the process of the tab.
+ void HeapProfilerDump(
+ const WebViewId& view_id, const std::string& reason, Error** error);
+#endif // !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
+
void NavigateToURL(
const WebViewId& view_id, const std::string& url, Error** error);
void NavigateToURLAsync(
diff --git a/chrome/test/webdriver/webdriver_server.cc b/chrome/test/webdriver/webdriver_server.cc
index ac7b716..6587bac 100644
--- a/chrome/test/webdriver/webdriver_server.cc
+++ b/chrome/test/webdriver/webdriver_server.cc
@@ -163,6 +163,10 @@ void InitCallbacks(Dispatcher* dispatcher,
dispatcher->Add<ExtensionsCommand>("/session/*/chrome/extensions");
dispatcher->Add<ExtensionCommand>("/session/*/chrome/extension/*");
dispatcher->Add<ViewsCommand>("/session/*/chrome/views");
+#if !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
+ dispatcher->Add<HeapProfilerDumpCommand>(
+ "/session/*/chrome/heapprofilerdump");
+#endif // !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
// HTML5 functions.
dispatcher->Add<HTML5LocationCommand>("/session/*/location");
diff --git a/chrome/test/webdriver/webdriver_session.cc b/chrome/test/webdriver/webdriver_session.cc
index 9e30b9b..4e704c8 100644
--- a/chrome/test/webdriver/webdriver_session.cc
+++ b/chrome/test/webdriver/webdriver_session.cc
@@ -1835,6 +1835,20 @@ Error* Session::GetScreenShot(std::string* png) {
return NULL;
}
+#if !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
+Error* Session::HeapProfilerDump(const std::string& reason) {
+ // TODO(dmikurube): Support browser processes.
+ Error* error = NULL;
+ RunSessionTask(base::Bind(
+ &Automation::HeapProfilerDump,
+ base::Unretained(automation_.get()),
+ current_target_.view_id,
+ reason,
+ &error));
+ return error;
+}
+#endif // !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
+
Error* Session::PostBrowserStartInit() {
Error* error = NULL;
if (!capabilities_.no_website_testing_defaults)
diff --git a/chrome/test/webdriver/webdriver_session.h b/chrome/test/webdriver/webdriver_session.h
index ff53cca..71e53e6 100644
--- a/chrome/test/webdriver/webdriver_session.h
+++ b/chrome/test/webdriver/webdriver_session.h
@@ -140,6 +140,9 @@ class Session {
Error* GetURL(std::string* url);
Error* GetTitle(std::string* tab_title);
Error* GetScreenShot(std::string* png);
+#if !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
+ Error* HeapProfilerDump(const std::string& reason);
+#endif // !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
Error* GetCookies(const std::string& url, base::ListValue** cookies);
Error* DeleteCookie(const std::string& url, const std::string& cookie_name);
Error* SetCookie(const std::string& url, base::DictionaryValue* cookie_dict);