- add sources.
[platform/framework/web/crosswalk.git] / src / tools / deep_memory_profiler / tests / dmprof_test.py
1 #!/usr/bin/env python
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
4 # found in the LICENSE file.
5
6 import cStringIO
7 import logging
8 import os
9 import sys
10 import textwrap
11 import unittest
12
13 BASE_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
14 sys.path.append(BASE_PATH)
15
16 from lib.bucket import Bucket
17 from lib.ordered_dict import OrderedDict
18 from lib.policy import Policy
19 from lib.symbol import SymbolMappingCache
20 from lib.symbol import FUNCTION_SYMBOLS, SOURCEFILE_SYMBOLS, TYPEINFO_SYMBOLS
21
22 import subcommands
23
24
25 class SymbolMappingCacheTest(unittest.TestCase):
26   class MockBucketSet(object):
27     def __init__(self, addresses):
28       self._addresses = addresses
29
30     def iter_addresses(self, symbol_type):  # pylint: disable=W0613
31       for address in self._addresses:
32         yield address
33
34   class MockSymbolFinder(object):
35     def __init__(self, mapping):
36       self._mapping = mapping
37
38     def find(self, address_list):
39       result = OrderedDict()
40       for address in address_list:
41         result[address] = self._mapping[address]
42       return result
43
44   _TEST_FUNCTION_CACHE = textwrap.dedent("""\
45       1 0x0000000000000001
46       7fc33eebcaa4 __gnu_cxx::new_allocator::allocate
47       7fc33ef69242 void DispatchToMethod
48       """)
49
50   _EXPECTED_TEST_FUNCTION_CACHE = textwrap.dedent("""\
51       1 0x0000000000000001
52       7fc33eebcaa4 __gnu_cxx::new_allocator::allocate
53       7fc33ef69242 void DispatchToMethod
54       2 0x0000000000000002
55       7fc33ef7bc3e std::map::operator[]
56       7fc34411f9d5 WTF::RefCounted::operator new
57       """)
58
59   _TEST_FUNCTION_ADDRESS_LIST1 = [
60       0x1, 0x7fc33eebcaa4, 0x7fc33ef69242]
61
62   _TEST_FUNCTION_ADDRESS_LIST2 = [
63       0x1, 0x2, 0x7fc33eebcaa4, 0x7fc33ef69242, 0x7fc33ef7bc3e, 0x7fc34411f9d5]
64
65   _TEST_FUNCTION_DICT = {
66       0x1: '0x0000000000000001',
67       0x2: '0x0000000000000002',
68       0x7fc33eebcaa4: '__gnu_cxx::new_allocator::allocate',
69       0x7fc33ef69242: 'void DispatchToMethod',
70       0x7fc33ef7bc3e: 'std::map::operator[]',
71       0x7fc34411f9d5: 'WTF::RefCounted::operator new',
72   }
73
74   def test_update(self):
75     symbol_mapping_cache = SymbolMappingCache()
76     cache_f = cStringIO.StringIO()
77     cache_f.write(self._TEST_FUNCTION_CACHE)
78
79     # No update from self._TEST_FUNCTION_CACHE
80     symbol_mapping_cache.update(
81         FUNCTION_SYMBOLS,
82         self.MockBucketSet(self._TEST_FUNCTION_ADDRESS_LIST1),
83         self.MockSymbolFinder(self._TEST_FUNCTION_DICT), cache_f)
84     for address in self._TEST_FUNCTION_ADDRESS_LIST1:
85       self.assertEqual(self._TEST_FUNCTION_DICT[address],
86                        symbol_mapping_cache.lookup(FUNCTION_SYMBOLS, address))
87     self.assertEqual(self._TEST_FUNCTION_CACHE, cache_f.getvalue())
88
89     # Update to self._TEST_FUNCTION_ADDRESS_LIST2
90     symbol_mapping_cache.update(
91         FUNCTION_SYMBOLS,
92         self.MockBucketSet(self._TEST_FUNCTION_ADDRESS_LIST2),
93         self.MockSymbolFinder(self._TEST_FUNCTION_DICT), cache_f)
94     for address in self._TEST_FUNCTION_ADDRESS_LIST2:
95       self.assertEqual(self._TEST_FUNCTION_DICT[address],
96                        symbol_mapping_cache.lookup(FUNCTION_SYMBOLS, address))
97     self.assertEqual(self._EXPECTED_TEST_FUNCTION_CACHE, cache_f.getvalue())
98
99
100 class PolicyTest(unittest.TestCase):
101   class MockSymbolMappingCache(object):
102     def __init__(self):
103       self._symbol_caches = {
104           FUNCTION_SYMBOLS: {},
105           SOURCEFILE_SYMBOLS: {},
106           TYPEINFO_SYMBOLS: {},
107           }
108
109     def add(self, symbol_type, address, symbol):
110       self._symbol_caches[symbol_type][address] = symbol
111
112     def lookup(self, symbol_type, address):
113       symbol = self._symbol_caches[symbol_type].get(address)
114       return symbol if symbol else '0x%016x' % address
115
116   _TEST_POLICY = textwrap.dedent("""\
117       {
118         "components": [
119           "second",
120           "mmap-v8",
121           "malloc-v8",
122           "malloc-WebKit",
123           "mmap-catch-all",
124           "malloc-catch-all"
125         ],
126         "rules": [
127           {
128             "name": "second",
129             "stacktrace": "optional",
130             "allocator": "optional"
131           },
132           {
133             "name": "mmap-v8",
134             "stacktrace": ".*v8::.*",
135             "allocator": "mmap"
136           },
137           {
138             "name": "malloc-v8",
139             "stacktrace": ".*v8::.*",
140             "allocator": "malloc"
141           },
142           {
143             "name": "malloc-WebKit",
144             "stacktrace": ".*WebKit::.*",
145             "allocator": "malloc"
146           },
147           {
148             "name": "mmap-catch-all",
149             "stacktrace": ".*",
150             "allocator": "mmap"
151           },
152           {
153             "name": "malloc-catch-all",
154             "stacktrace": ".*",
155             "allocator": "malloc"
156           }
157         ],
158         "version": "POLICY_DEEP_3"
159       }
160       """)
161
162   def test_load(self):
163     policy = Policy.parse(cStringIO.StringIO(self._TEST_POLICY), 'json')
164     self.assertTrue(policy)
165     self.assertEqual('POLICY_DEEP_3', policy.version)
166
167   def test_find(self):
168     policy = Policy.parse(cStringIO.StringIO(self._TEST_POLICY), 'json')
169     self.assertTrue(policy)
170
171     symbol_mapping_cache = self.MockSymbolMappingCache()
172     symbol_mapping_cache.add(FUNCTION_SYMBOLS, 0x1212, 'v8::create')
173     symbol_mapping_cache.add(FUNCTION_SYMBOLS, 0x1381, 'WebKit::create')
174
175     bucket1 = Bucket([0x1212, 0x013], 'malloc', 0x29492, '_Z')
176     bucket1.symbolize(symbol_mapping_cache)
177     bucket2 = Bucket([0x18242, 0x1381], 'malloc', 0x9492, '_Z')
178     bucket2.symbolize(symbol_mapping_cache)
179     bucket3 = Bucket([0x18242, 0x181], 'malloc', 0x949, '_Z')
180     bucket3.symbolize(symbol_mapping_cache)
181
182     self.assertEqual('malloc-v8', policy.find_malloc(bucket1))
183     self.assertEqual('malloc-WebKit', policy.find_malloc(bucket2))
184     self.assertEqual('malloc-catch-all', policy.find_malloc(bucket3))
185
186
187 class BucketsCommandTest(unittest.TestCase):
188   def test(self):
189     BUCKETS_PATH = os.path.join(BASE_PATH, 'tests', 'output', 'buckets')
190     with open(BUCKETS_PATH) as output_f:
191       expected = output_f.read()
192
193     out = cStringIO.StringIO()
194
195     HEAP_PATH = os.path.join(BASE_PATH, 'tests', 'data', 'heap.01234.0001.heap')
196     subcommand = subcommands.BucketsCommand()
197     returncode = subcommand.do(['buckets', HEAP_PATH], out)
198     self.assertEqual(0, returncode)
199     self.assertEqual(expected, out.getvalue())
200
201
202 class UploadCommandTest(unittest.TestCase):
203   def test(self):
204     MOCK_GSUTIL_PATH = os.path.join(BASE_PATH, 'tests', 'mock_gsutil.py')
205     HEAP_PATH = os.path.join(BASE_PATH, 'tests', 'data', 'heap.01234.0001.heap')
206     subcommand = subcommands.UploadCommand()
207     returncode = subcommand.do([
208         'upload',
209          '--gsutil',
210         MOCK_GSUTIL_PATH,
211         HEAP_PATH,
212         'gs://test-storage/'])
213     self.assertEqual(0, returncode)
214
215
216 if __name__ == '__main__':
217   logging.basicConfig(
218       level=logging.DEBUG if '-v' in sys.argv else logging.ERROR,
219       format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s')
220   unittest.main()