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 |