OLD | NEW |
---|---|
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """PyAuto: Python Interface to Chromium's Automation Proxy. | 6 """PyAuto: Python Interface to Chromium's Automation Proxy. |
7 | 7 |
8 PyAuto uses swig to expose Automation Proxy interfaces to Python. | 8 PyAuto uses swig to expose Automation Proxy interfaces to Python. |
9 For complete documentation on the functionality available, | 9 For complete documentation on the functionality available, |
10 run pydoc on this file. | 10 run pydoc on this file. |
(...skipping 4909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4920 A user needs to be logged-in as a precondition. Note that the UI is not | 4920 A user needs to be logged-in as a precondition. Note that the UI is not |
4921 destroyed afterwards, a browser restart is necessary if you want | 4921 destroyed afterwards, a browser restart is necessary if you want |
4922 to interact with the browser after this call in the same test case. | 4922 to interact with the browser after this call in the same test case. |
4923 | 4923 |
4924 Raises: | 4924 Raises: |
4925 pyauto_errors.JSONInterfaceError if the automation call returns an error. | 4925 pyauto_errors.JSONInterfaceError if the automation call returns an error. |
4926 """ | 4926 """ |
4927 cmd_dict = { 'command': 'CaptureProfilePhoto' } | 4927 cmd_dict = { 'command': 'CaptureProfilePhoto' } |
4928 return self._GetResultFromJSONRequest(cmd_dict) | 4928 return self._GetResultFromJSONRequest(cmd_dict) |
4929 | 4929 |
4930 def GetCrosMemoryStats(self, duration): | |
Nirnimesh
2012/04/30 22:30:46
I recommend GetMemoryStatsonChromeOS
it's easier t
dennis_jeffrey
2012/04/30 22:37:43
Done - though I removed the "on" from the suggeste
| |
4931 """Identifies and returns different kinds of current memory usage stats. | |
4932 | |
4933 This function samples values each second for |duration| seconds, then | |
4934 outputs the min, max, and ending values for each measurement type. | |
4935 | |
4936 Args: | |
4937 duration: The number of seconds to sample data before outputting the | |
4938 minimum, maximum, and ending values for each measurement type. | |
4939 | |
4940 Returns: | |
4941 A dictionary containing memory usage information. Each measurement type | |
4942 is associated with the min, max, and ending values from among all | |
4943 sampled values. Values are specified in KB. | |
4944 { | |
4945 'gem_obj': { # GPU memory usage. | |
4946 'min': ..., | |
4947 'max': ..., | |
4948 'end': ..., | |
4949 }, | |
4950 'gtt': { ... }, # GPU memory usage (graphics translation table). | |
4951 'mem_free': { ... }, # CPU free memory. | |
4952 'mem_available': { ... }, # CPU available memory. | |
4953 'mem_shared': { ... }, # CPU shared memory. | |
4954 'mem_cached': { ... }, # CPU cached memory. | |
4955 'mem_anon': { ... }, # CPU anon memory (active + inactive). | |
4956 'mem_file': { ... }, # CPU file memory (active + inactive). | |
4957 'mem_slab': { ... }, # CPU slab memory. | |
4958 'browser_priv': { ... }, # Chrome browser private memory. | |
4959 'browser_shared': { ... }, # Chrome browser shared memory. | |
4960 'gpu_priv': { ... }, # Chrome GPU private memory. | |
4961 'gpu_shared': { ... }, # Chrome GPU shared memory. | |
4962 'renderer_priv': { ... }, # Total private memory of all renderers. | |
4963 'renderer_shared': { ... }, # Total shared memory of all renderers. | |
4964 } | |
4965 """ | |
4966 logging.debug('Sampling memory information for %d seconds...' % duration) | |
4967 stats = {} | |
4968 | |
4969 for _ in xrange(duration): | |
4970 # GPU memory. | |
4971 gem_obj_path = '/sys/kernel/debug/dri/0/i915_gem_objects' | |
4972 if os.path.exists(gem_obj_path): | |
4973 p = subprocess.Popen('grep bytes %s' % gem_obj_path, | |
4974 stdout=subprocess.PIPE, shell=True) | |
4975 stdout = p.communicate()[0] | |
4976 | |
4977 gem_obj = re.search( | |
4978 '\d+ objects, (\d+) bytes\n', stdout).group(1) | |
4979 if 'gem_obj' not in stats: | |
4980 stats['gem_obj'] = [] | |
4981 stats['gem_obj'].append(int(gem_obj) / 1024.0) | |
4982 | |
4983 gtt_path = '/sys/kernel/debug/dri/0/i915_gem_gtt' | |
4984 if os.path.exists(gtt_path): | |
4985 p = subprocess.Popen('grep bytes %s' % gtt_path, | |
4986 stdout=subprocess.PIPE, shell=True) | |
4987 stdout = p.communicate()[0] | |
4988 | |
4989 gtt = re.search( | |
4990 'Total [\d]+ objects, ([\d]+) bytes', stdout).group(1) | |
4991 if 'gtt' not in stats: | |
4992 stats['gtt'] = [] | |
4993 stats['gtt'].append(int(gtt) / 1024.0) | |
4994 | |
4995 # CPU memory. | |
4996 stdout = '' | |
4997 with open('/proc/meminfo') as f: | |
4998 stdout = f.read() | |
4999 mem_free = re.search('MemFree:\s*([\d]+) kB', stdout).group(1) | |
5000 | |
5001 if 'mem_free' not in stats: | |
5002 stats['mem_free'] = [] | |
5003 stats['mem_free'].append(int(mem_free)) | |
5004 | |
5005 mem_dirty = re.search('Dirty:\s*([\d]+) kB', stdout).group(1) | |
5006 mem_active_file = re.search( | |
5007 'Active\(file\):\s*([\d]+) kB', stdout).group(1) | |
5008 mem_inactive_file = re.search( | |
5009 'Inactive\(file\):\s*([\d]+) kB', stdout).group(1) | |
5010 | |
5011 with open('/proc/sys/vm/min_filelist_kbytes') as f: | |
5012 mem_min_file = f.read() | |
5013 | |
5014 # Available memory = | |
5015 # MemFree + ActiveFile + InactiveFile - DirtyMem - MinFileMem | |
5016 if 'mem_available' not in stats: | |
5017 stats['mem_available'] = [] | |
5018 stats['mem_available'].append( | |
5019 int(mem_free) + int(mem_active_file) + int(mem_inactive_file) - | |
5020 int(mem_dirty) - int(mem_min_file)) | |
5021 | |
5022 mem_shared = re.search('Shmem:\s*([\d]+) kB', stdout).group(1) | |
5023 if 'mem_shared' not in stats: | |
5024 stats['mem_shared'] = [] | |
5025 stats['mem_shared'].append(int(mem_shared)) | |
5026 | |
5027 mem_cached = re.search('Cached:\s*([\d]+) kB', stdout).group(1) | |
5028 if 'mem_cached' not in stats: | |
5029 stats['mem_cached'] = [] | |
5030 stats['mem_cached'].append(int(mem_cached)) | |
5031 | |
5032 mem_anon_active = re.search('Active\(anon\):\s*([\d]+) kB', | |
5033 stdout).group(1) | |
5034 mem_anon_inactive = re.search('Inactive\(anon\):\s*([\d]+) kB', | |
5035 stdout).group(1) | |
5036 if 'mem_anon' not in stats: | |
5037 stats['mem_anon'] = [] | |
5038 stats['mem_anon'].append(int(mem_anon_active) + int(mem_anon_inactive)) | |
5039 | |
5040 mem_file_active = re.search('Active\(file\):\s*([\d]+) kB', | |
5041 stdout).group(1) | |
5042 mem_file_inactive = re.search('Inactive\(file\):\s*([\d]+) kB', | |
5043 stdout).group(1) | |
5044 if 'mem_file' not in stats: | |
5045 stats['mem_file'] = [] | |
5046 stats['mem_file'].append(int(mem_file_active) + int(mem_file_inactive)) | |
5047 | |
5048 mem_slab = re.search('Slab:\s*([\d]+) kB', stdout).group(1) | |
5049 if 'mem_slab' not in stats: | |
5050 stats['mem_slab'] = [] | |
5051 stats['mem_slab'].append(int(mem_slab)) | |
5052 | |
5053 # Chrome process memory. | |
5054 pinfo = self.GetProcessInfo()['browsers'][0]['processes'] | |
5055 total_renderer_priv = 0 | |
5056 total_renderer_shared = 0 | |
5057 for process in pinfo: | |
5058 mem_priv = process['working_set_mem']['priv'] | |
5059 mem_shared = process['working_set_mem']['shared'] | |
5060 if process['child_process_type'] == 'Browser': | |
5061 if 'browser_priv' not in stats: | |
5062 stats['browser_priv'] = [] | |
5063 stats['browser_priv'].append(int(mem_priv)) | |
5064 if 'browser_shared' not in stats: | |
5065 stats['browser_shared'] = [] | |
5066 stats['browser_shared'].append(int(mem_shared)) | |
5067 elif process['child_process_type'] == 'GPU': | |
5068 if 'gpu_priv' not in stats: | |
5069 stats['gpu_priv'] = [] | |
5070 stats['gpu_priv'].append(int(mem_priv)) | |
5071 if 'gpu_shared' not in stats: | |
5072 stats['gpu_shared'] = [] | |
5073 stats['gpu_shared'].append(int(mem_shared)) | |
5074 elif process['child_process_type'] == 'Tab': | |
5075 # Sum the memory of all renderer processes. | |
5076 total_renderer_priv += int(mem_priv) | |
5077 total_renderer_shared += int(mem_shared) | |
5078 if 'renderer_priv' not in stats: | |
5079 stats['renderer_priv'] = [] | |
5080 stats['renderer_priv'].append(int(total_renderer_priv)) | |
5081 if 'renderer_shared' not in stats: | |
5082 stats['renderer_shared'] = [] | |
5083 stats['renderer_shared'].append(int(total_renderer_shared)) | |
5084 | |
5085 time.sleep(1) | |
5086 | |
5087 # Compute min, max, and ending values to return. | |
5088 result = {} | |
5089 for measurement_type in stats: | |
5090 values = stats[measurement_type] | |
5091 result[measurement_type] = { | |
5092 'min': min(values), | |
5093 'max': max(values), | |
5094 'end': values[-1], | |
5095 } | |
5096 | |
5097 return result | |
5098 | |
4930 ## ChromeOS section -- end | 5099 ## ChromeOS section -- end |
4931 | 5100 |
4932 | 5101 |
4933 class ExtraBrowser(PyUITest): | 5102 class ExtraBrowser(PyUITest): |
4934 """Launches a new browser with some extra flags. | 5103 """Launches a new browser with some extra flags. |
4935 | 5104 |
4936 The new browser is launched with its own fresh profile. | 5105 The new browser is launched with its own fresh profile. |
4937 This class does not apply to ChromeOS. | 5106 This class does not apply to ChromeOS. |
4938 """ | 5107 """ |
4939 def __init__(self, chrome_flags=[], methodName='runTest', **kwargs): | 5108 def __init__(self, chrome_flags=[], methodName='runTest', **kwargs): |
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5496 successful = result.wasSuccessful() | 5665 successful = result.wasSuccessful() |
5497 if not successful: | 5666 if not successful: |
5498 pyauto_tests_file = os.path.join(self.TestsDir(), self._tests_filename) | 5667 pyauto_tests_file = os.path.join(self.TestsDir(), self._tests_filename) |
5499 print >>sys.stderr, 'Tests can be disabled by editing %s. ' \ | 5668 print >>sys.stderr, 'Tests can be disabled by editing %s. ' \ |
5500 'Ref: %s' % (pyauto_tests_file, _PYAUTO_DOC_URL) | 5669 'Ref: %s' % (pyauto_tests_file, _PYAUTO_DOC_URL) |
5501 sys.exit(not successful) | 5670 sys.exit(not successful) |
5502 | 5671 |
5503 | 5672 |
5504 if __name__ == '__main__': | 5673 if __name__ == '__main__': |
5505 Main() | 5674 Main() |
OLD | NEW |