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 import cStringIO | 6 import cStringIO |
7 import logging | 7 import logging |
8 import os | 8 import os |
9 import sys | 9 import sys |
10 import textwrap | 10 import textwrap |
11 import unittest | 11 import unittest |
12 | 12 |
13 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | 13 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
14 sys.path.insert(0, ROOT_DIR) | 14 sys.path.insert(0, ROOT_DIR) |
15 | 15 |
| 16 try: |
| 17 from collections import OrderedDict # pylint: disable=E0611 |
| 18 except ImportError: |
| 19 SIMPLEJSON_PATH = os.path.join(ROOT_DIR, os.pardir, os.pardir, 'third_party') |
| 20 sys.path.insert(0, SIMPLEJSON_PATH) |
| 21 from simplejson import OrderedDict |
| 22 |
16 import dmprof | 23 import dmprof |
17 from dmprof import FUNCTION_ADDRESS, TYPEINFO_ADDRESS | 24 from find_runtime_symbols import FUNCTION_SYMBOLS |
| 25 from find_runtime_symbols import SOURCEFILE_SYMBOLS |
| 26 from find_runtime_symbols import TYPEINFO_SYMBOLS |
18 | 27 |
19 | 28 |
20 class SymbolMappingCacheTest(unittest.TestCase): | 29 class SymbolMappingCacheTest(unittest.TestCase): |
21 class MockBucketSet(object): | 30 class MockBucketSet(object): |
22 def __init__(self, addresses): | 31 def __init__(self, addresses): |
23 self._addresses = addresses | 32 self._addresses = addresses |
24 | 33 |
25 def iter_addresses(self, address_type): # pylint: disable=W0613 | 34 def iter_addresses(self, symbol_type): # pylint: disable=W0613 |
26 for address in self._addresses: | 35 for address in self._addresses: |
27 yield address | 36 yield address |
28 | 37 |
29 class MockSymbolFinder(object): | 38 class MockSymbolFinder(object): |
30 def __init__(self, mapping): | 39 def __init__(self, mapping): |
31 self._mapping = mapping | 40 self._mapping = mapping |
32 | 41 |
33 def find(self, address_list): | 42 def find(self, address_list): |
34 return [self._mapping[address] for address in address_list] | 43 result = OrderedDict() |
| 44 for address in address_list: |
| 45 result[address] = self._mapping[address] |
| 46 return result |
35 | 47 |
36 _TEST_FUNCTION_CACHE = textwrap.dedent("""\ | 48 _TEST_FUNCTION_CACHE = textwrap.dedent("""\ |
37 1 0x0000000000000001 | 49 1 0x0000000000000001 |
38 7fc33eebcaa4 __gnu_cxx::new_allocator::allocate | 50 7fc33eebcaa4 __gnu_cxx::new_allocator::allocate |
39 7fc33ef69242 void DispatchToMethod | 51 7fc33ef69242 void DispatchToMethod |
40 """) | 52 """) |
41 | 53 |
42 _EXPECTED_TEST_FUNCTION_CACHE = textwrap.dedent("""\ | 54 _EXPECTED_TEST_FUNCTION_CACHE = textwrap.dedent("""\ |
43 1 0x0000000000000001 | 55 1 0x0000000000000001 |
44 7fc33eebcaa4 __gnu_cxx::new_allocator::allocate | 56 7fc33eebcaa4 __gnu_cxx::new_allocator::allocate |
(...skipping 18 matching lines...) Expand all Loading... |
63 0x7fc34411f9d5: 'WTF::RefCounted::operator new', | 75 0x7fc34411f9d5: 'WTF::RefCounted::operator new', |
64 } | 76 } |
65 | 77 |
66 def test_update(self): | 78 def test_update(self): |
67 symbol_mapping_cache = dmprof.SymbolMappingCache() | 79 symbol_mapping_cache = dmprof.SymbolMappingCache() |
68 cache_f = cStringIO.StringIO() | 80 cache_f = cStringIO.StringIO() |
69 cache_f.write(self._TEST_FUNCTION_CACHE) | 81 cache_f.write(self._TEST_FUNCTION_CACHE) |
70 | 82 |
71 # No update from self._TEST_FUNCTION_CACHE | 83 # No update from self._TEST_FUNCTION_CACHE |
72 symbol_mapping_cache.update( | 84 symbol_mapping_cache.update( |
73 FUNCTION_ADDRESS, | 85 FUNCTION_SYMBOLS, |
74 self.MockBucketSet(self._TEST_FUNCTION_ADDRESS_LIST1), | 86 self.MockBucketSet(self._TEST_FUNCTION_ADDRESS_LIST1), |
75 self.MockSymbolFinder(self._TEST_FUNCTION_DICT), cache_f) | 87 self.MockSymbolFinder(self._TEST_FUNCTION_DICT), cache_f) |
76 for address in self._TEST_FUNCTION_ADDRESS_LIST1: | 88 for address in self._TEST_FUNCTION_ADDRESS_LIST1: |
77 self.assertEqual(self._TEST_FUNCTION_DICT[address], | 89 self.assertEqual(self._TEST_FUNCTION_DICT[address], |
78 symbol_mapping_cache.lookup(FUNCTION_ADDRESS, address)) | 90 symbol_mapping_cache.lookup(FUNCTION_SYMBOLS, address)) |
79 self.assertEqual(self._TEST_FUNCTION_CACHE, cache_f.getvalue()) | 91 self.assertEqual(self._TEST_FUNCTION_CACHE, cache_f.getvalue()) |
80 | 92 |
81 # Update to self._TEST_FUNCTION_ADDRESS_LIST2 | 93 # Update to self._TEST_FUNCTION_ADDRESS_LIST2 |
82 symbol_mapping_cache.update( | 94 symbol_mapping_cache.update( |
83 FUNCTION_ADDRESS, | 95 FUNCTION_SYMBOLS, |
84 self.MockBucketSet(self._TEST_FUNCTION_ADDRESS_LIST2), | 96 self.MockBucketSet(self._TEST_FUNCTION_ADDRESS_LIST2), |
85 self.MockSymbolFinder(self._TEST_FUNCTION_DICT), cache_f) | 97 self.MockSymbolFinder(self._TEST_FUNCTION_DICT), cache_f) |
86 for address in self._TEST_FUNCTION_ADDRESS_LIST2: | 98 for address in self._TEST_FUNCTION_ADDRESS_LIST2: |
87 self.assertEqual(self._TEST_FUNCTION_DICT[address], | 99 self.assertEqual(self._TEST_FUNCTION_DICT[address], |
88 symbol_mapping_cache.lookup(FUNCTION_ADDRESS, address)) | 100 symbol_mapping_cache.lookup(FUNCTION_SYMBOLS, address)) |
89 self.assertEqual(self._EXPECTED_TEST_FUNCTION_CACHE, cache_f.getvalue()) | 101 self.assertEqual(self._EXPECTED_TEST_FUNCTION_CACHE, cache_f.getvalue()) |
90 | 102 |
91 | 103 |
92 class PolicyTest(unittest.TestCase): | 104 class PolicyTest(unittest.TestCase): |
93 class MockSymbolMappingCache(object): | 105 class MockSymbolMappingCache(object): |
94 def __init__(self): | 106 def __init__(self): |
95 self._symbol_caches = {FUNCTION_ADDRESS: {}, TYPEINFO_ADDRESS: {}} | 107 self._symbol_caches = { |
| 108 FUNCTION_SYMBOLS: {}, |
| 109 SOURCEFILE_SYMBOLS: {}, |
| 110 TYPEINFO_SYMBOLS: {}, |
| 111 } |
96 | 112 |
97 def add(self, address_type, address, symbol): | 113 def add(self, symbol_type, address, symbol): |
98 self._symbol_caches[address_type][address] = symbol | 114 self._symbol_caches[symbol_type][address] = symbol |
99 | 115 |
100 def lookup(self, address_type, address): | 116 def lookup(self, symbol_type, address): |
101 symbol = self._symbol_caches[address_type].get(address) | 117 symbol = self._symbol_caches[symbol_type].get(address) |
102 return symbol if symbol else '0x%016x' % address | 118 return symbol if symbol else '0x%016x' % address |
103 | 119 |
104 _TEST_POLICY = textwrap.dedent("""\ | 120 _TEST_POLICY = textwrap.dedent("""\ |
105 { | 121 { |
106 "components": [ | 122 "components": [ |
107 "second", | 123 "second", |
108 "mmap-v8", | 124 "mmap-v8", |
109 "malloc-v8", | 125 "malloc-v8", |
110 "malloc-WebKit", | 126 "malloc-WebKit", |
111 "mmap-catch-all", | 127 "mmap-catch-all", |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 def test_load(self): | 166 def test_load(self): |
151 policy = dmprof.Policy.parse(cStringIO.StringIO(self._TEST_POLICY), 'json') | 167 policy = dmprof.Policy.parse(cStringIO.StringIO(self._TEST_POLICY), 'json') |
152 self.assertTrue(policy) | 168 self.assertTrue(policy) |
153 self.assertEqual('POLICY_DEEP_3', policy.version) | 169 self.assertEqual('POLICY_DEEP_3', policy.version) |
154 | 170 |
155 def test_find(self): | 171 def test_find(self): |
156 policy = dmprof.Policy.parse(cStringIO.StringIO(self._TEST_POLICY), 'json') | 172 policy = dmprof.Policy.parse(cStringIO.StringIO(self._TEST_POLICY), 'json') |
157 self.assertTrue(policy) | 173 self.assertTrue(policy) |
158 | 174 |
159 symbol_mapping_cache = self.MockSymbolMappingCache() | 175 symbol_mapping_cache = self.MockSymbolMappingCache() |
160 symbol_mapping_cache.add(FUNCTION_ADDRESS, 0x1212, 'v8::create') | 176 symbol_mapping_cache.add(FUNCTION_SYMBOLS, 0x1212, 'v8::create') |
161 symbol_mapping_cache.add(FUNCTION_ADDRESS, 0x1381, 'WebKit::create') | 177 symbol_mapping_cache.add(FUNCTION_SYMBOLS, 0x1381, 'WebKit::create') |
162 | 178 |
163 bucket1 = dmprof.Bucket([0x1212, 0x013], False, 0x29492, '_Z') | 179 bucket1 = dmprof.Bucket([0x1212, 0x013], False, 0x29492, '_Z') |
164 bucket1.symbolize(symbol_mapping_cache) | 180 bucket1.symbolize(symbol_mapping_cache) |
165 bucket2 = dmprof.Bucket([0x18242, 0x1381], False, 0x9492, '_Z') | 181 bucket2 = dmprof.Bucket([0x18242, 0x1381], False, 0x9492, '_Z') |
166 bucket2.symbolize(symbol_mapping_cache) | 182 bucket2.symbolize(symbol_mapping_cache) |
167 bucket3 = dmprof.Bucket([0x18242, 0x181], False, 0x949, '_Z') | 183 bucket3 = dmprof.Bucket([0x18242, 0x181], False, 0x949, '_Z') |
168 bucket3.symbolize(symbol_mapping_cache) | 184 bucket3.symbolize(symbol_mapping_cache) |
169 | 185 |
170 self.assertEqual('malloc-v8', policy.find(bucket1)) | 186 self.assertEqual('malloc-v8', policy.find(bucket1)) |
171 self.assertEqual('malloc-WebKit', policy.find(bucket2)) | 187 self.assertEqual('malloc-WebKit', policy.find(bucket2)) |
(...skipping 10 matching lines...) Expand all Loading... |
182 os.path.join(ROOT_DIR, 'tests', 'data', 'heap.01234.0001.heap'), | 198 os.path.join(ROOT_DIR, 'tests', 'data', 'heap.01234.0001.heap'), |
183 'gs://test-storage/']) | 199 'gs://test-storage/']) |
184 self.assertEqual(0, returncode) | 200 self.assertEqual(0, returncode) |
185 | 201 |
186 | 202 |
187 if __name__ == '__main__': | 203 if __name__ == '__main__': |
188 logging.basicConfig( | 204 logging.basicConfig( |
189 level=logging.DEBUG if '-v' in sys.argv else logging.ERROR, | 205 level=logging.DEBUG if '-v' in sys.argv else logging.ERROR, |
190 format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s') | 206 format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s') |
191 unittest.main() | 207 unittest.main() |
OLD | NEW |