Chromium Code Reviews| 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 unittest | 10 import unittest |
| 11 | 11 |
| 12 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | 12 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
| 13 sys.path.insert(0, ROOT_DIR) | 13 sys.path.insert(0, ROOT_DIR) |
| 14 | 14 |
| 15 import dmprof | 15 import dmprof |
| 16 from dmprof import FUNCTION_ADDRESS, TYPEINFO_ADDRESS | 16 from dmprof import FUNCTION_ADDRESS, TYPEINFO_ADDRESS |
| 17 | 17 |
| 18 | 18 |
| 19 class MockSymbolCache(object): | 19 class SymbolMappingCacheTest(unittest.TestCase): |
| 20 def __init__(self): | 20 class MockBucketSet(object): |
| 21 self._symbol_caches = {FUNCTION_ADDRESS: {}, TYPEINFO_ADDRESS: {}} | 21 def __init__(self, addresses): |
| 22 self._addresses = addresses | |
| 22 | 23 |
| 23 def add(self, address_type, address, symbol): | 24 def iter_addresses(self, address_type): # pylint: disable=W0613 |
| 24 self._symbol_caches[address_type][address] = symbol | 25 for address in self._addresses: |
| 26 yield address | |
| 25 | 27 |
| 26 def lookup(self, address_type, address): | 28 class MockSymbolFinder(object): |
| 27 symbol = self._symbol_caches[address_type].get(address) | 29 def __init__(self, mapping): |
| 28 return symbol if symbol else '0x%016x' % address | 30 self._mapping = mapping |
| 31 | |
| 32 def find(self, address_list): | |
| 33 return [self._mapping[address] for address in address_list] | |
| 34 | |
| 35 _TEST_FUNCTION_CACHE = """1 0x0000000000000001 | |
|
jochen (gone - plz use gerrit)
2012/11/26 09:31:52
what about using textwrap.dedent for multi-line co
Dai Mikurube (NOT FULLTIME)
2012/11/26 09:41:45
Thanks for the good idea. Done.
| |
| 36 7fc33eebcaa4 __gnu_cxx::new_allocator::allocate | |
| 37 7fc33ef69242 void DispatchToMethod | |
| 38 """ | |
| 39 | |
| 40 _EXPECTED_TEST_FUNCTION_CACHE = """1 0x0000000000000001 | |
| 41 7fc33eebcaa4 __gnu_cxx::new_allocator::allocate | |
| 42 7fc33ef69242 void DispatchToMethod | |
| 43 2 0x0000000000000002 | |
| 44 7fc33ef7bc3e std::map::operator[] | |
| 45 7fc34411f9d5 WTF::RefCounted::operator new | |
| 46 """ | |
| 47 | |
| 48 _TEST_FUNCTION_ADDRESS_LIST1 = [ | |
| 49 0x1, 0x7fc33eebcaa4, 0x7fc33ef69242] | |
| 50 | |
| 51 _TEST_FUNCTION_ADDRESS_LIST2 = [ | |
| 52 0x1, 0x2, 0x7fc33eebcaa4, 0x7fc33ef69242, 0x7fc33ef7bc3e, 0x7fc34411f9d5] | |
| 53 | |
| 54 _TEST_FUNCTION_DICT = { | |
| 55 0x1: '0x0000000000000001', | |
| 56 0x2: '0x0000000000000002', | |
| 57 0x7fc33eebcaa4: '__gnu_cxx::new_allocator::allocate', | |
| 58 0x7fc33ef69242: 'void DispatchToMethod', | |
| 59 0x7fc33ef7bc3e: 'std::map::operator[]', | |
| 60 0x7fc34411f9d5: 'WTF::RefCounted::operator new', | |
| 61 } | |
| 62 | |
| 63 def test_update(self): | |
| 64 symbol_mapping_cache = dmprof.SymbolMappingCache() | |
| 65 cache_f = cStringIO.StringIO() | |
| 66 cache_f.write(self._TEST_FUNCTION_CACHE) | |
| 67 | |
| 68 # No update from self._TEST_FUNCTION_CACHE | |
| 69 symbol_mapping_cache.update( | |
| 70 FUNCTION_ADDRESS, | |
| 71 self.MockBucketSet(self._TEST_FUNCTION_ADDRESS_LIST1), | |
| 72 self.MockSymbolFinder(self._TEST_FUNCTION_DICT), cache_f) | |
| 73 for address in self._TEST_FUNCTION_ADDRESS_LIST1: | |
| 74 self.assertEqual(self._TEST_FUNCTION_DICT[address], | |
| 75 symbol_mapping_cache.lookup(FUNCTION_ADDRESS, address)) | |
| 76 self.assertEqual(self._TEST_FUNCTION_CACHE, cache_f.getvalue()) | |
| 77 | |
| 78 # Update to self._TEST_FUNCTION_ADDRESS_LIST2 | |
| 79 symbol_mapping_cache.update( | |
| 80 FUNCTION_ADDRESS, | |
| 81 self.MockBucketSet(self._TEST_FUNCTION_ADDRESS_LIST2), | |
| 82 self.MockSymbolFinder(self._TEST_FUNCTION_DICT), cache_f) | |
| 83 for address in self._TEST_FUNCTION_ADDRESS_LIST2: | |
| 84 self.assertEqual(self._TEST_FUNCTION_DICT[address], | |
| 85 symbol_mapping_cache.lookup(FUNCTION_ADDRESS, address)) | |
| 86 self.assertEqual(self._EXPECTED_TEST_FUNCTION_CACHE, cache_f.getvalue()) | |
| 29 | 87 |
| 30 | 88 |
| 31 class PolicyTest(unittest.TestCase): | 89 class PolicyTest(unittest.TestCase): |
| 90 class MockSymbolMappingCache(object): | |
| 91 def __init__(self): | |
| 92 self._symbol_caches = {FUNCTION_ADDRESS: {}, TYPEINFO_ADDRESS: {}} | |
| 93 | |
| 94 def add(self, address_type, address, symbol): | |
| 95 self._symbol_caches[address_type][address] = symbol | |
| 96 | |
| 97 def lookup(self, address_type, address): | |
| 98 symbol = self._symbol_caches[address_type].get(address) | |
| 99 return symbol if symbol else '0x%016x' % address | |
| 100 | |
| 32 _TEST_POLICY = """{ | 101 _TEST_POLICY = """{ |
| 33 "components": [ | 102 "components": [ |
| 34 "second", | 103 "second", |
| 35 "mmap-v8", | 104 "mmap-v8", |
| 36 "malloc-v8", | 105 "malloc-v8", |
| 37 "malloc-WebKit", | 106 "malloc-WebKit", |
| 38 "mmap-catch-all", | 107 "mmap-catch-all", |
| 39 "malloc-catch-all" | 108 "malloc-catch-all" |
| 40 ], | 109 ], |
| 41 "rules": [ | 110 "rules": [ |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 70 "allocator": "malloc" | 139 "allocator": "malloc" |
| 71 } | 140 } |
| 72 ], | 141 ], |
| 73 "version": "POLICY_DEEP_3" | 142 "version": "POLICY_DEEP_3" |
| 74 } | 143 } |
| 75 """ | 144 """ |
| 76 | 145 |
| 77 def test_load(self): | 146 def test_load(self): |
| 78 policy = dmprof.Policy.parse(cStringIO.StringIO(self._TEST_POLICY), 'json') | 147 policy = dmprof.Policy.parse(cStringIO.StringIO(self._TEST_POLICY), 'json') |
| 79 self.assertTrue(policy) | 148 self.assertTrue(policy) |
| 80 self.assertEqual(policy.version, 'POLICY_DEEP_3') | 149 self.assertEqual('POLICY_DEEP_3', policy.version) |
| 81 | 150 |
| 82 def test_find(self): | 151 def test_find(self): |
| 83 policy = dmprof.Policy.parse(cStringIO.StringIO(self._TEST_POLICY), 'json') | 152 policy = dmprof.Policy.parse(cStringIO.StringIO(self._TEST_POLICY), 'json') |
| 84 self.assertTrue(policy) | 153 self.assertTrue(policy) |
| 85 | 154 |
| 86 symbol_cache = MockSymbolCache() | 155 symbol_mapping_cache = self.MockSymbolMappingCache() |
| 87 symbol_cache.add(FUNCTION_ADDRESS, 0x1212, 'v8::create') | 156 symbol_mapping_cache.add(FUNCTION_ADDRESS, 0x1212, 'v8::create') |
| 88 symbol_cache.add(FUNCTION_ADDRESS, 0x1381, 'WebKit::create') | 157 symbol_mapping_cache.add(FUNCTION_ADDRESS, 0x1381, 'WebKit::create') |
| 89 | 158 |
| 90 bucket1 = dmprof.Bucket([0x1212, 0x013], False, 0x29492, '_Z') | 159 bucket1 = dmprof.Bucket([0x1212, 0x013], False, 0x29492, '_Z') |
| 91 bucket1.symbolize(symbol_cache) | 160 bucket1.symbolize(symbol_mapping_cache) |
| 92 bucket2 = dmprof.Bucket([0x18242, 0x1381], False, 0x9492, '_Z') | 161 bucket2 = dmprof.Bucket([0x18242, 0x1381], False, 0x9492, '_Z') |
| 93 bucket2.symbolize(symbol_cache) | 162 bucket2.symbolize(symbol_mapping_cache) |
| 94 bucket3 = dmprof.Bucket([0x18242, 0x181], False, 0x949, '_Z') | 163 bucket3 = dmprof.Bucket([0x18242, 0x181], False, 0x949, '_Z') |
| 95 bucket3.symbolize(symbol_cache) | 164 bucket3.symbolize(symbol_mapping_cache) |
| 96 | 165 |
| 97 self.assertEqual(policy.find(bucket1), 'malloc-v8') | 166 self.assertEqual('malloc-v8', policy.find(bucket1)) |
| 98 self.assertEqual(policy.find(bucket2), 'malloc-WebKit') | 167 self.assertEqual('malloc-WebKit', policy.find(bucket2)) |
| 99 self.assertEqual(policy.find(bucket3), 'malloc-catch-all') | 168 self.assertEqual('malloc-catch-all', policy.find(bucket3)) |
| 100 | 169 |
| 101 | 170 |
| 102 if __name__ == '__main__': | 171 if __name__ == '__main__': |
| 103 logging.basicConfig( | 172 logging.basicConfig( |
| 104 level=logging.DEBUG if '-v' in sys.argv else logging.ERROR, | 173 level=logging.DEBUG if '-v' in sys.argv else logging.ERROR, |
| 105 format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s') | 174 format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s') |
| 106 unittest.main() | 175 unittest.main() |
| OLD | NEW |