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