summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/test/chrome_process_util.h25
-rw-r--r--chrome/test/chrome_process_util_mac.cc45
-rw-r--r--chrome/test/page_cycler/page_cycler_test.cc31
3 files changed, 101 insertions, 0 deletions
diff --git a/chrome/test/chrome_process_util.h b/chrome/test/chrome_process_util.h
index 31f3b5f..576c2e0 100644
--- a/chrome/test/chrome_process_util.h
+++ b/chrome/test/chrome_process_util.h
@@ -23,4 +23,29 @@ ChromeProcessList GetRunningChromeProcesses(const FilePath& data_dir);
// Attempts to terminate all chrome processes associated with |data_dir|.
void TerminateAllChromeProcesses(const FilePath& data_dir);
+#if defined(OS_MACOSX)
+
+// These types and API are here to fetch the information about a set of running
+// processes by ID on the Mac. There are also APIs in base, but fetching the
+// information for another process requires privileges that a normal executable
+// does not have. This API fetches the data by spawning ps (which is setuid so
+// it has the needed privileges) and processing its output. The API is provided
+// here because we don't want code spawning processes like this in base, where
+// someone writing cross platform code might use it without realizing that it's
+// a heavyweight call on the Mac.
+
+struct MacChromeProcessInfo {
+ base::ProcessId pid;
+ int rsz_in_kb;
+ int vsz_in_kb;
+};
+
+typedef std::vector<MacChromeProcessInfo> MacChromeProcessInfoList;
+
+// Any ProcessId that info can't be found for will be left out.
+MacChromeProcessInfoList GetRunningMacProcessInfo(
+ const ChromeProcessList &process_list);
+
+#endif // defined(OS_MACOSX)
+
#endif // CHROME_TEST_CHROME_PROCESS_UTIL_H_
diff --git a/chrome/test/chrome_process_util_mac.cc b/chrome/test/chrome_process_util_mac.cc
index fa587b9..9b12e9c 100644
--- a/chrome/test/chrome_process_util_mac.cc
+++ b/chrome/test/chrome_process_util_mac.cc
@@ -55,3 +55,48 @@ base::ProcessId ChromeBrowserProcessId(const FilePath& data_dir) {
return -1;
}
+
+MacChromeProcessInfoList GetRunningMacProcessInfo(
+ const ChromeProcessList &process_list) {
+ MacChromeProcessInfoList result;
+
+ // Build up the ps command line
+ std::vector<std::string> cmdline;
+ cmdline.push_back("ps");
+ cmdline.push_back("-o");
+ cmdline.push_back("pid=,rsz=,vsz="); // fields we need, no headings
+ ChromeProcessList::const_iterator process_iter;
+ for (process_iter = process_list.begin();
+ process_iter != process_list.end();
+ ++process_iter) {
+ cmdline.push_back("-p");
+ cmdline.push_back(StringPrintf("%d", *process_iter));
+ }
+
+ // Invoke it
+ std::string ps_output;
+ if (!base::GetAppOutput(CommandLine(cmdline), &ps_output))
+ return result; // All the pids might have exited
+
+ // Process the results
+ std::vector<std::string> ps_output_lines;
+ SplitString(ps_output, '\n', &ps_output_lines);
+ std::vector<std::string>::const_iterator line_iter;
+ for (line_iter = ps_output_lines.begin();
+ line_iter != ps_output_lines.end();
+ ++line_iter) {
+ std::string line(CollapseWhitespaceASCII(*line_iter, false));
+ std::vector<std::string> values;
+ SplitString(line, ' ', &values);
+ if (values.size() == 3) {
+ MacChromeProcessInfo proc_info;
+ proc_info.pid = StringToInt(values[0]);
+ proc_info.rsz_in_kb = StringToInt(values[1]);
+ proc_info.vsz_in_kb = StringToInt(values[2]);
+ if (proc_info.pid && proc_info.rsz_in_kb && proc_info.vsz_in_kb)
+ result.push_back(proc_info);
+ }
+ }
+
+ return result;
+}
diff --git a/chrome/test/page_cycler/page_cycler_test.cc b/chrome/test/page_cycler/page_cycler_test.cc
index 04d563c..f8a80d0 100644
--- a/chrome/test/page_cycler/page_cycler_test.cc
+++ b/chrome/test/page_cycler/page_cycler_test.cc
@@ -214,6 +214,7 @@ class PageCyclerTest : public UITest {
int browser_process_pid = ChromeBrowserProcessId(data_dir);
ChromeProcessList chrome_processes(GetRunningChromeProcesses(data_dir));
+#if !defined(OS_MACOSX)
ChromeProcessList::const_iterator it;
for (it = chrome_processes.begin(); it != chrome_processes.end(); ++it) {
base::ProcessHandle process_handle;
@@ -259,6 +260,36 @@ class PageCyclerTest : public UITest {
#endif
base::CloseProcessHandle(process_handle);
}
+
+#else // !defined(OS_MACOSX)
+
+ // There is no way to get memory info from one process on another process
+ // without privileges, this means the base methods for doing this can't be
+ // made to work. Instead we use a helper that invokes ps to collect the
+ // data so we have it for the unittest.
+
+ MacChromeProcessInfoList process_infos(
+ GetRunningMacProcessInfo(chrome_processes));
+ MacChromeProcessInfoList::const_iterator it;
+ for (it = process_infos.begin(); it != process_infos.end(); ++it) {
+ const MacChromeProcessInfo &process_info = *it;
+
+ std::string chrome_name =
+ (process_info.pid == browser_process_pid) ? "_b" : "_r";
+ std::string trace_name(test_name);
+
+ PrintResult("vm_size_final", chrome_name,
+ "vm_size_f" + chrome_name + trace_name,
+ static_cast<size_t>(process_info.vsz_in_kb) * 1024, "bytes",
+ true /* important */);
+ PrintResult("vm_rss_final", chrome_name,
+ "vm_rss_f" + chrome_name + trace_name,
+ static_cast<size_t>(process_info.rsz_in_kb) * 1024, "bytes",
+ true /* important */);
+ }
+
+#endif // !defined(OS_MACOSX)
+
}
// When use_http is true, the test name passed here will be used directly in