Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2011 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.
      4 
      5 #include "chrome/test/base/chrome_process_util.h"
      6 
      7 #include <string>
      8 #include <vector>
      9 
     10 #include "base/command_line.h"
     11 #include "base/process/launch.h"
     12 #include "base/strings/string_number_conversions.h"
     13 #include "base/strings/string_split.h"
     14 #include "base/strings/string_util.h"
     15 #include "base/strings/stringprintf.h"
     16 
     17 MacChromeProcessInfoList GetRunningMacProcessInfo(
     18     const ChromeProcessList& process_list) {
     19   MacChromeProcessInfoList result;
     20 
     21   // Build up the ps command line
     22   std::vector<std::string> cmdline;
     23   cmdline.push_back("ps");
     24   cmdline.push_back("-o");
     25   cmdline.push_back("pid=,rss=,vsz=");  // fields we need, no headings
     26   ChromeProcessList::const_iterator process_iter;
     27   for (process_iter = process_list.begin();
     28        process_iter != process_list.end();
     29        ++process_iter) {
     30     cmdline.push_back("-p");
     31     cmdline.push_back(base::StringPrintf("%d", *process_iter));
     32   }
     33 
     34   // Invoke it
     35   std::string ps_output;
     36   if (!base::GetAppOutput(CommandLine(cmdline), &ps_output))
     37     return result;  // All the pids might have exited
     38 
     39   // Process the results
     40   std::vector<std::string> ps_output_lines;
     41   base::SplitString(ps_output, '\n', &ps_output_lines);
     42   std::vector<std::string>::const_iterator line_iter;
     43   for (line_iter = ps_output_lines.begin();
     44        line_iter != ps_output_lines.end();
     45        ++line_iter) {
     46     std::string line(CollapseWhitespaceASCII(*line_iter, false));
     47     std::vector<std::string> values;
     48     base::SplitString(line, ' ', &values);
     49     if (values.size() == 3) {
     50       MacChromeProcessInfo proc_info;
     51       int pid;
     52       base::StringToInt(values[0], &pid);
     53       proc_info.pid = pid;
     54       base::StringToInt(values[1], &proc_info.rsz_in_kb);
     55       base::StringToInt(values[2], &proc_info.vsz_in_kb);
     56       if (proc_info.pid && proc_info.rsz_in_kb && proc_info.vsz_in_kb)
     57         result.push_back(proc_info);
     58     }
     59   }
     60 
     61   return result;
     62 }
     63 
     64 // Common interface for fetching memory values from parsed ps output.
     65 // We fill in both values we may get called for, even though our
     66 // callers typically only care about one, just to keep the code
     67 // simple and because this is a test.
     68 static bool GetMemoryValuesHack(uint32 process_id,
     69                           size_t* virtual_size,
     70                           size_t* working_set_size) {
     71   DCHECK(virtual_size && working_set_size);
     72 
     73   std::vector<base::ProcessId> processes;
     74   processes.push_back(process_id);
     75 
     76   MacChromeProcessInfoList process_info = GetRunningMacProcessInfo(processes);
     77   if (process_info.empty())
     78     return false;
     79 
     80   bool found_process = false;
     81   *virtual_size = 0;
     82   *working_set_size = 0;
     83 
     84   MacChromeProcessInfoList::iterator it = process_info.begin();
     85   for (; it != process_info.end(); ++it) {
     86     if (it->pid != static_cast<base::ProcessId>(process_id))
     87       continue;
     88     found_process = true;
     89     *virtual_size = it->vsz_in_kb * 1024;
     90     *working_set_size = it->rsz_in_kb * 1024;
     91     break;
     92   }
     93 
     94   return found_process;
     95 }
     96 
     97 size_t ChromeTestProcessMetrics::GetPagefileUsage() {
     98   size_t virtual_size;
     99   size_t working_set_size;
    100   GetMemoryValuesHack(process_handle_, &virtual_size, &working_set_size);
    101   return virtual_size;
    102 }
    103 
    104 size_t ChromeTestProcessMetrics::GetWorkingSetSize() {
    105   size_t virtual_size;
    106   size_t working_set_size;
    107   GetMemoryValuesHack(process_handle_, &virtual_size, &working_set_size);
    108   return working_set_size;
    109 }
    110