diff options
-rw-r--r-- | chrome/test/chrome_process_util.h | 25 | ||||
-rw-r--r-- | chrome/test/chrome_process_util_mac.cc | 45 | ||||
-rw-r--r-- | chrome/test/page_cycler/page_cycler_test.cc | 31 |
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 |