| OLD | NEW | 
 | (Empty) | 
|    1 #!/usr/bin/env python |  | 
|    2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |  | 
|    3 # Use of this source code is governed by a BSD-style license that can be |  | 
|    4 # found in the LICENSE file. |  | 
|    5  |  | 
|    6 import os |  | 
|    7 import sys |  | 
|    8 import time |  | 
|    9  |  | 
|   10 import pyauto_functional  # Must be imported before pyauto |  | 
|   11 import pyauto |  | 
|   12 import test_utils |  | 
|   13  |  | 
|   14  |  | 
|   15 class MemoryTest(pyauto.PyUITest): |  | 
|   16   """Tests for memory usage of Chrome-related processes. |  | 
|   17  |  | 
|   18   These tests are meant to be used manually, not as part of the continuous |  | 
|   19   test cycle.  This is because each test starts up and periodically |  | 
|   20   measures/records the memory usage of a relevant Chrome process, doing so |  | 
|   21   repeatedly until the test is manually killed.  Currently, this script only |  | 
|   22   works in Linux and ChromeOS, as it uses a Linux shell command to query the |  | 
|   23   system for process memory usage info (test_utils.GetMemoryUsageOfProcess()). |  | 
|   24  |  | 
|   25   The tests in this suite produce the following output files (relative to the |  | 
|   26   current working directory): |  | 
|   27  |  | 
|   28   testTabRendererProcessMemoryUsage: 'renderer_process_mem.txt' |  | 
|   29   testExtensionProcessMemoryUsage:   'extension_process_mem.txt' |  | 
|   30   """ |  | 
|   31  |  | 
|   32   # Constants for all tests in this suite. |  | 
|   33   NUM_SECONDS_BETWEEN_MEASUREMENTS = 10 |  | 
|   34   MEASUREMENT_LOG_MESSAGE_TEMPLATE = '[%s] %.2f MB (pid: %d)' |  | 
|   35   LOG_TO_OUTPUT_FILE = True |  | 
|   36  |  | 
|   37   # Constants for testTabRendererProcessMemoryUsage. |  | 
|   38   RENDERER_PROCESS_URL = 'http://chrome.angrybirds.com' |  | 
|   39   RENDERER_PROCESS_OUTPUT_FILE = 'renderer_process_mem.txt' |  | 
|   40  |  | 
|   41   # Constants for testExtensionProcessMemoryUsage. |  | 
|   42   EXTENSION_LOCATION = os.path.abspath(os.path.join( |  | 
|   43       pyauto.PyUITest.DataDir(), 'extensions', 'google_talk.crx')) |  | 
|   44   EXTENSION_PROCESS_NAME = 'Google Talk' |  | 
|   45   EXTENSION_PROCESS_OUTPUT_FILE = 'extension_process_mem.txt' |  | 
|   46  |  | 
|   47   def _GetPidOfExtensionProcessByName(self, name): |  | 
|   48     """Identifies the process ID of an extension process, given its name. |  | 
|   49  |  | 
|   50     Args: |  | 
|   51       name: The string name of an extension process, as returned by the function |  | 
|   52             GetBrowserInfo(). |  | 
|   53  |  | 
|   54     Returns: |  | 
|   55       The integer process identifier (PID) for the specified process, or |  | 
|   56       None if the PID cannot be identified. |  | 
|   57     """ |  | 
|   58     info = self.GetBrowserInfo()['extension_views'] |  | 
|   59     pid = [x['pid'] for x in info if x['name'] == '%s' % name] |  | 
|   60     if pid: |  | 
|   61       return pid[0] |  | 
|   62     return None |  | 
|   63  |  | 
|   64   def _LogMessage(self, log_file, msg): |  | 
|   65     """Logs a message to the screen, and to a log file if necessary. |  | 
|   66  |  | 
|   67     Args: |  | 
|   68       log_file: The string name of a log file to which to write. |  | 
|   69       msg: The message to log. |  | 
|   70     """ |  | 
|   71     print msg |  | 
|   72     sys.stdout.flush() |  | 
|   73     if self.LOG_TO_OUTPUT_FILE: |  | 
|   74       print >>open(log_file, 'a'), msg |  | 
|   75  |  | 
|   76   def testTabRendererProcessMemoryUsage(self): |  | 
|   77     """Test the memory usage of the renderer process for a tab. |  | 
|   78  |  | 
|   79     This test periodically queries the system for the current memory usage |  | 
|   80     of a tab's renderer process.  The test will take measurements forever; you |  | 
|   81     must manually kill the test to terminate it. |  | 
|   82     """ |  | 
|   83     if (self.LOG_TO_OUTPUT_FILE and |  | 
|   84         os.path.exists(self.RENDERER_PROCESS_OUTPUT_FILE)): |  | 
|   85       os.remove(self.RENDERER_PROCESS_OUTPUT_FILE) |  | 
|   86     self.NavigateToURL(self.RENDERER_PROCESS_URL) |  | 
|   87     self._LogMessage( |  | 
|   88         self.RENDERER_PROCESS_OUTPUT_FILE, |  | 
|   89         'Memory usage for renderer process of a tab navigated to: "%s"' % ( |  | 
|   90             self.RENDERER_PROCESS_URL)) |  | 
|   91  |  | 
|   92     # A user must manually kill this test to terminate the following loop. |  | 
|   93     while True: |  | 
|   94       pid = self.GetBrowserInfo()['windows'][0]['tabs'][0]['renderer_pid'] |  | 
|   95       usage = test_utils.GetMemoryUsageOfProcess(pid) |  | 
|   96       current_time = time.asctime(time.localtime(time.time())) |  | 
|   97       self._LogMessage( |  | 
|   98           self.RENDERER_PROCESS_OUTPUT_FILE, |  | 
|   99           self.MEASUREMENT_LOG_MESSAGE_TEMPLATE % (current_time, usage, pid)) |  | 
|  100       time.sleep(self.NUM_SECONDS_BETWEEN_MEASUREMENTS) |  | 
|  101  |  | 
|  102   def testExtensionProcessMemoryUsage(self): |  | 
|  103     """Test the memory usage of an extension process. |  | 
|  104  |  | 
|  105     This test periodically queries the system for the current memory usage |  | 
|  106     of an extension process.  The test will take measurements forever; you |  | 
|  107     must manually kill the test to terminate it. |  | 
|  108     """ |  | 
|  109     if (self.LOG_TO_OUTPUT_FILE and |  | 
|  110         os.path.exists(self.EXTENSION_PROCESS_OUTPUT_FILE)): |  | 
|  111       os.remove(self.EXTENSION_PROCESS_OUTPUT_FILE) |  | 
|  112     self.InstallExtension(self.EXTENSION_LOCATION) |  | 
|  113     # The PID is 0 until the extension has a chance to start up. |  | 
|  114     self.WaitUntil( |  | 
|  115         lambda: self._GetPidOfExtensionProcessByName( |  | 
|  116                     self.EXTENSION_PROCESS_NAME) not in [0, None]) |  | 
|  117     self._LogMessage( |  | 
|  118         self.EXTENSION_PROCESS_OUTPUT_FILE, |  | 
|  119         'Memory usage for extension process with name: "%s"' % ( |  | 
|  120             self.EXTENSION_PROCESS_NAME)) |  | 
|  121  |  | 
|  122     # A user must manually kill this test to terminate the following loop. |  | 
|  123     while True: |  | 
|  124       pid = self._GetPidOfExtensionProcessByName(self.EXTENSION_PROCESS_NAME) |  | 
|  125       usage = test_utils.GetMemoryUsageOfProcess(pid) |  | 
|  126       current_time = time.asctime(time.localtime(time.time())) |  | 
|  127       self._LogMessage( |  | 
|  128           self.EXTENSION_PROCESS_OUTPUT_FILE, |  | 
|  129           self.MEASUREMENT_LOG_MESSAGE_TEMPLATE % (current_time, usage, pid)) |  | 
|  130       time.sleep(self.NUM_SECONDS_BETWEEN_MEASUREMENTS) |  | 
|  131  |  | 
|  132  |  | 
|  133 if __name__ == '__main__': |  | 
|  134   pyauto_functional.Main() |  | 
| OLD | NEW |