Merge lp:~ben-hutchings/ensoft-sextant/wierd-names-clean into lp:ensoft-sextant
- wierd-names-clean
- Merge into whiteline
Status: | Merged |
---|---|
Approved by: | Robert |
Approved revision: | 69 |
Merged at revision: | 36 |
Proposed branch: | lp:~ben-hutchings/ensoft-sextant/wierd-names-clean |
Merge into: | lp:ensoft-sextant |
Prerequisite: | lp:~ben-hutchings/ensoft-sextant/rel-merge |
Diff against target: |
474 lines (+190/-48) 10 files modified
src/sextant/db_api.py (+7/-3) src/sextant/objdump_parser.py (+22/-8) src/sextant/test_all.py (+39/-0) src/sextant/test_all.sh (+0/-4) src/sextant/test_db.py (+39/-13) src/sextant/test_parser.py (+36/-10) src/sextant/test_resources/parser_file2.c (+24/-0) src/sextant/test_resources/parser_header.h (+10/-0) src/sextant/test_resources/parser_test.c (+3/-9) src/sextant/test_sshmanager.py (+10/-1) |
To merge this branch: | bzr merge lp:~ben-hutchings/ensoft-sextant/wierd-names-clean |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Robert | Approve | ||
Review via email: mp+242752@code.launchpad.net |
This proposal supersedes a proposal from 2014-11-25.
Commit message
Function names are now cleaned up by a helper function, which removes __be_ prefixes if they are there (bi-endian builds) and converts names like <name>.<other stuff> to just <name>.
Tests extended to check that this works.
Description of the change
Function names are now cleaned up by a helper function, which removes __be_ prefixes if they are there (bi-endian builds) and converts names like <name>.<other stuff> to just <name>.
Tests extended to check that this works.
- 64. By Ben Hutchings
-
merge from rel-merge markups
- 65. By Ben Hutchings
-
extended tests, replaced test_all.sh with test_all.py which also generates code coverage reports for the tested modeuls
- 66. By Ben Hutchings
-
whitespace fix
- 67. By Ben Hutchings
-
fixed bug with get_all_
functions_ calling - 68. By Ben Hutchings
-
very minor change to the default objdump_parser print output format to include more information added since this was originally written
- 69. By Ben Hutchings
-
doc comment fix
Robert (rjwills) : | # |
Preview Diff
1 | === modified file 'src/sextant/db_api.py' | |||
2 | --- src/sextant/db_api.py 2014-11-25 11:40:03 +0000 | |||
3 | +++ src/sextant/db_api.py 2014-12-12 11:30:28 +0000 | |||
4 | @@ -996,7 +996,7 @@ | |||
5 | 996 | 996 | ||
6 | 997 | return self._execute_query(program_name, q) | 997 | return self._execute_query(program_name, q) |
7 | 998 | 998 | ||
9 | 999 | def get_all_functions_calling(self, program_name, function_called, | 999 | def get_all_functions_calling(self, program_name, function_calling, |
10 | 1000 | limit_internal=False, max_depth=1): | 1000 | limit_internal=False, max_depth=1): |
11 | 1001 | """ | 1001 | """ |
12 | 1002 | Return functions calling the specified functions. | 1002 | Return functions calling the specified functions. |
13 | @@ -1014,12 +1014,16 @@ | |||
14 | 1014 | program_name: | 1014 | program_name: |
15 | 1015 | The name of the program to query. | 1015 | The name of the program to query. |
16 | 1016 | 1016 | ||
18 | 1017 | function_called: | 1017 | function_calling: |
19 | 1018 | A string of form <name_match>:<file_match>, where at least | 1018 | A string of form <name_match>:<file_match>, where at least |
20 | 1019 | one of name_match and file_match is provided, and each may be a | 1019 | one of name_match and file_match is provided, and each may be a |
21 | 1020 | comma separated list of strings containing wildcard '.*' | 1020 | comma separated list of strings containing wildcard '.*' |
22 | 1021 | sequences. Specifies the list of functions to match. | 1021 | sequences. Specifies the list of functions to match. |
23 | 1022 | 1022 | ||
24 | 1023 | NOTE: the name is a bit of a hack to work with the javascript. | ||
25 | 1024 | Should really be function_called but that would require more | ||
26 | 1025 | js fiddling. | ||
27 | 1026 | |||
28 | 1023 | limit_internal: | 1027 | limit_internal: |
29 | 1024 | If true, only explore internal calls. | 1028 | If true, only explore internal calls. |
30 | 1025 | 1029 | ||
31 | @@ -1034,7 +1038,7 @@ | |||
32 | 1034 | q = (' MATCH (p:program {{name: "{}"}})-[:subject]->(g:func) {}' | 1038 | q = (' MATCH (p:program {{name: "{}"}})-[:subject]->(g:func) {}' |
33 | 1035 | ' MATCH (f)-[{}*0..{}]->(g)' | 1039 | ' MATCH (f)-[{}*0..{}]->(g)' |
34 | 1036 | ' RETURN distinct f, g') | 1040 | ' RETURN distinct f, g') |
36 | 1037 | q = q.format(program_name, SextantConnection.get_query('g', function_called), | 1041 | q = q.format(program_name, SextantConnection.get_query('g', function_calling), |
37 | 1038 | ':internal' if limit_internal else ':internal|external', | 1042 | ':internal' if limit_internal else ':internal|external', |
38 | 1039 | max_depth or '') | 1043 | max_depth or '') |
39 | 1040 | 1044 | ||
40 | 1041 | 1045 | ||
41 | === modified file 'src/sextant/objdump_parser.py' | |||
42 | --- src/sextant/objdump_parser.py 2014-11-25 11:40:03 +0000 | |||
43 | +++ src/sextant/objdump_parser.py 2014-12-12 11:30:28 +0000 | |||
44 | @@ -121,7 +121,7 @@ | |||
45 | 121 | print('func {:25} {:15}{}'.format(name, typ, source)) | 121 | print('func {:25} {:15}{}'.format(name, typ, source)) |
46 | 122 | 122 | ||
47 | 123 | def print_call(caller, callee, is_internal): | 123 | def print_call(caller, callee, is_internal): |
49 | 124 | print('call {:25} {:25}'.format(caller, callee)) | 124 | print('call {} {:25} {:25}'.format('EI'[is_internal], caller, callee)) |
50 | 125 | 125 | ||
51 | 126 | def print_started(parser): | 126 | def print_started(parser): |
52 | 127 | print('parse started: {}[{}]'.format(self.path, ', '.join(self.sections))) | 127 | print('parse started: {}[{}]'.format(self.path, ', '.join(self.sections))) |
53 | @@ -199,10 +199,27 @@ | |||
54 | 199 | self.add_call(caller, callee, False) | 199 | self.add_call(caller, callee, False) |
55 | 200 | self._known_calls.add((caller, callee)) | 200 | self._known_calls.add((caller, callee)) |
56 | 201 | self.call_count += 1 | 201 | self.call_count += 1 |
57 | 202 | print(caller, callee) | ||
58 | 203 | else: | 202 | else: |
59 | 204 | self._partial_calls.add((caller, callee)) | 203 | self._partial_calls.add((caller, callee)) |
60 | 205 | 204 | ||
61 | 205 | @staticmethod | ||
62 | 206 | def clean_id(function_identifier): | ||
63 | 207 | """ | ||
64 | 208 | Clean the funciton identifier string. | ||
65 | 209 | """ | ||
66 | 210 | # Bi-endian builds add a __be_ prefix to all functions, | ||
67 | 211 | # get rid of it if it is there, | ||
68 | 212 | if function_identifier.startswith('__be_'): | ||
69 | 213 | function_identifier = function_identifier[len('__be_'):] | ||
70 | 214 | |||
71 | 215 | # Some functions look like <identifier>. or <identifier>..<digit> | ||
72 | 216 | # - get rid of the extra bits here: | ||
73 | 217 | if '.' in function_identifier: | ||
74 | 218 | function_identifier = function_identifier.split('.')[0] | ||
75 | 219 | |||
76 | 220 | return function_identifier | ||
77 | 221 | |||
78 | 222 | |||
79 | 206 | def parse(self): | 223 | def parse(self): |
80 | 207 | """ | 224 | """ |
81 | 208 | Parse self._file. | 225 | Parse self._file. |
82 | @@ -242,10 +259,7 @@ | |||
83 | 242 | # <function_name>[@plt] | 259 | # <function_name>[@plt] |
84 | 243 | function_identifier = line.split('<')[-1].split('>')[0] | 260 | function_identifier = line.split('<')[-1].split('>')[0] |
85 | 244 | 261 | ||
90 | 245 | # IOS builds add a __be_ (big endian) prefix to all functions, | 262 | function_identifier = self.clean_id(function_identifier) |
87 | 246 | # get rid of it if it is there, | ||
88 | 247 | if function_identifier.startswith('__be_'): | ||
89 | 248 | function_identifier = function_identifier[len('__be_'):] | ||
91 | 249 | 263 | ||
92 | 250 | if '@' in function_identifier: | 264 | if '@' in function_identifier: |
93 | 251 | # Of form <function name>@<other stuff>. | 265 | # Of form <function name>@<other stuff>. |
94 | @@ -277,8 +291,8 @@ | |||
95 | 277 | # from which we extract name | 291 | # from which we extract name |
96 | 278 | callee_is_ptr = False | 292 | callee_is_ptr = False |
97 | 279 | function_identifier = callee_info.lstrip('<').rstrip('>\n') | 293 | function_identifier = callee_info.lstrip('<').rstrip('>\n') |
100 | 280 | if function_identifier.startswith('__be_'): | 294 | |
101 | 281 | function_identifier = function_identifier[len('__be_'):] | 295 | function_identifier = self.clean_id(function_identifier) |
102 | 282 | 296 | ||
103 | 283 | if '@' in function_identifier: | 297 | if '@' in function_identifier: |
104 | 284 | callee = function_identifier.split('@')[0] | 298 | callee = function_identifier.split('@')[0] |
105 | 285 | 299 | ||
106 | === added file 'src/sextant/test_all.py' | |||
107 | --- src/sextant/test_all.py 1970-01-01 00:00:00 +0000 | |||
108 | +++ src/sextant/test_all.py 2014-12-12 11:30:28 +0000 | |||
109 | @@ -0,0 +1,39 @@ | |||
110 | 1 | #!/usr/bin/python | ||
111 | 2 | |||
112 | 3 | from __future__ import print_function | ||
113 | 4 | |||
114 | 5 | import subprocess | ||
115 | 6 | import shlex | ||
116 | 7 | |||
117 | 8 | tests = (('test_parser.py', 'objdump_parser.py'), | ||
118 | 9 | ('test_csvwriter.py', 'csvwriter.py'), | ||
119 | 10 | ('test_sshmanager.py', 'sshmanager.py'), | ||
120 | 11 | ('test_db.py', 'db_api.py')) | ||
121 | 12 | |||
122 | 13 | pycmd = 'coverage run {}' | ||
123 | 14 | covcmd = 'coverage report -m {}' | ||
124 | 15 | |||
125 | 16 | if __name__ == '__main__': | ||
126 | 17 | Popen = subprocess.Popen | ||
127 | 18 | |||
128 | 19 | for test, name in tests: | ||
129 | 20 | print('Running tests: {}'.format(test)) | ||
130 | 21 | do_print = False | ||
131 | 22 | |||
132 | 23 | |||
133 | 24 | pyproc = Popen(shlex.split(pycmd.format(test)), stdout=subprocess.PIPE) | ||
134 | 25 | for line in pyproc.stdout: | ||
135 | 26 | if '----------' in line or '=========' in line: | ||
136 | 27 | do_print = True | ||
137 | 28 | |||
138 | 29 | if do_print: | ||
139 | 30 | print(line.rstrip()) | ||
140 | 31 | |||
141 | 32 | covproc = Popen(shlex.split(covcmd.format(name))) | ||
142 | 33 | covproc.wait() | ||
143 | 34 | |||
144 | 35 | |||
145 | 36 | |||
146 | 37 | |||
147 | 38 | |||
148 | 39 | |||
149 | 0 | 40 | ||
150 | === removed file 'src/sextant/test_all.sh' | |||
151 | --- src/sextant/test_all.sh 2014-10-13 16:01:59 +0000 | |||
152 | +++ src/sextant/test_all.sh 1970-01-01 00:00:00 +0000 | |||
153 | @@ -1,4 +0,0 @@ | |||
154 | 1 | #!/usr/bin/bash | ||
155 | 2 | |||
156 | 3 | PYTHONPATH=$PYTHONPATH:~/. | ||
157 | 4 | python -m unittest discover --pattern=test_*.py | ||
158 | 5 | 0 | ||
159 | === modified file 'src/sextant/test_db.py' | |||
160 | --- src/sextant/test_db.py 2014-11-25 11:40:03 +0000 | |||
161 | +++ src/sextant/test_db.py 2014-12-12 11:30:28 +0000 | |||
162 | @@ -12,7 +12,7 @@ | |||
163 | 12 | import update_db | 12 | import update_db |
164 | 13 | 13 | ||
165 | 14 | PNAME = 'tester-parser_test' | 14 | PNAME = 'tester-parser_test' |
167 | 15 | NORMAL = {'main', 'normal', 'wierd$name', 'duplicates'} | 15 | NORMAL = {'main', 'normal', 'wierd$name', 'duplicates', 'name', 'puts'} |
168 | 16 | 16 | ||
169 | 17 | 17 | ||
170 | 18 | class TestFunctionQueryResults(unittest.TestCase): | 18 | class TestFunctionQueryResults(unittest.TestCase): |
171 | @@ -37,10 +37,12 @@ | |||
172 | 37 | names = get_names(PNAME) | 37 | names = get_names(PNAME) |
173 | 38 | # Test file wildcard search | 38 | # Test file wildcard search |
174 | 39 | parser_names = get_names(PNAME, search=':.*parser_test.c') | 39 | parser_names = get_names(PNAME, search=':.*parser_test.c') |
175 | 40 | file2_names = get_names(PNAME, search=':.*parser_file2.c') | ||
176 | 40 | 41 | ||
177 | 41 | self.assertTrue(names.issuperset(NORMAL)) | 42 | self.assertTrue(names.issuperset(NORMAL)) |
180 | 42 | self.assertEquals(len(names), 24) | 43 | self.assertEquals(len(names), 27) |
181 | 43 | self.assertEquals(parser_names, {u'main', u'normal', u'duplicates', u'wierd$name'}) | 44 | self.assertEquals(parser_names, {u'main', u'normal', u'duplicates'}) |
182 | 45 | self.assertEquals(file2_names, {u'wierd$name', u'name'}) | ||
183 | 44 | 46 | ||
184 | 45 | # Test the wildcard matching | 47 | # Test the wildcard matching |
185 | 46 | search = self.connection.get_function_names(PNAME, search='.*libc.*') | 48 | search = self.connection.get_function_names(PNAME, search='.*libc.*') |
186 | @@ -58,13 +60,12 @@ | |||
187 | 58 | def test_get_all_functions_called(self): | 60 | def test_get_all_functions_called(self): |
188 | 59 | get_fns = self.connection.get_all_functions_called | 61 | get_fns = self.connection.get_all_functions_called |
189 | 60 | 62 | ||
191 | 61 | for depth, num in zip([0, 1, 2, 3], [8, 3, 8, 8]): | 63 | for depth, num in zip(range(5), [11, 3, 9, 10, 11]): |
192 | 62 | result = get_fns(PNAME, 'main', False, depth).functions | 64 | result = get_fns(PNAME, 'main', False, depth).functions |
194 | 63 | self.assertEquals(len(result), num, str(result)) | 65 | self.assertEquals(len(result), num) |
195 | 64 | 66 | ||
197 | 65 | for depth, num in zip([0, 1, 2, 3], [8, 4, 8, 8]): | 67 | for depth, num in zip(range(5), [9, 6, 9, 9, 9]): |
198 | 66 | # Limit to internal functions | 68 | # Limit to internal functions |
199 | 67 | # TODO this isn't a great test - need greater call depth | ||
200 | 68 | result = get_fns(PNAME, 'main', True, depth).functions | 69 | result = get_fns(PNAME, 'main', True, depth).functions |
201 | 69 | self.assertEquals(len(result), num) | 70 | self.assertEquals(len(result), num) |
202 | 70 | 71 | ||
203 | @@ -80,18 +81,43 @@ | |||
204 | 80 | self.assertEquals(len(result), num) | 81 | self.assertEquals(len(result), num) |
205 | 81 | 82 | ||
206 | 82 | def test_get_all_paths_between(self): | 83 | def test_get_all_paths_between(self): |
212 | 83 | get_paths = self.connection.get_call_paths | 84 | get_paths = self.connection.get_call_paths |
213 | 84 | 85 | ||
214 | 85 | result = {f.name for f in get_paths(PNAME, 'main', 'wierd$name', True, 0).functions} | 86 | result = {f.name for f in get_paths(PNAME, 'main', 'wierd$name', False, 0).functions} |
215 | 86 | exp = {'main', 'normal', 'duplicates', 'wierd$name'} | 87 | exp = {'main', 'normal', 'duplicates', 'wierd$name'} |
216 | 87 | self.assertEquals(result, exp) | 88 | self.assertEquals(result, exp) |
217 | 89 | |||
218 | 90 | self.assertFalse(get_paths(PNAME, 'main', 'wierd$name', True, 0).functions) | ||
219 | 88 | 91 | ||
220 | 89 | def test_get_shortest_paths_between(self): | 92 | def test_get_shortest_paths_between(self): |
221 | 90 | get_paths = self.connection.get_shortest_path_between_functions | 93 | get_paths = self.connection.get_shortest_path_between_functions |
222 | 91 | 94 | ||
224 | 92 | result = {f.name for f in get_paths(PNAME, 'main', 'wierd$name', True, 0).functions} | 95 | result = {f.name for f in get_paths(PNAME, 'main', 'wierd$name', False, 0).functions} |
225 | 93 | exp = {u'main', u'normal', u'wierd$name'} | 96 | exp = {u'main', u'normal', u'wierd$name'} |
226 | 94 | self.assertEquals(result, exp) | 97 | self.assertEquals(result, exp) |
227 | 98 | |||
228 | 99 | self.assertFalse(get_paths(PNAME, 'main', 'wierd$name', True, 0).functions) | ||
229 | 100 | |||
230 | 101 | def test_programs_with_metadata(self): | ||
231 | 102 | result = self.connection.programs_with_metadata() | ||
232 | 103 | found = False | ||
233 | 104 | |||
234 | 105 | for program in result: | ||
235 | 106 | if program.program_name == PNAME: | ||
236 | 107 | found = True | ||
237 | 108 | |||
238 | 109 | self.assertEquals(program.number_of_funcs, 27) | ||
239 | 110 | self.assertEquals(program.number_of_calls, 26) | ||
240 | 111 | |||
241 | 112 | break | ||
242 | 113 | |||
243 | 114 | self.assertTrue(found) | ||
244 | 115 | |||
245 | 116 | def test_get_whole_program(self): | ||
246 | 117 | result = self.connection.get_whole_program(PNAME) | ||
247 | 118 | self.assertEquals(len(result.functions), 27) | ||
248 | 119 | |||
249 | 120 | self.assertFalse(self.connection.get_whole_program('no such program')) | ||
250 | 95 | 121 | ||
251 | 96 | if __name__ == '__main__': | 122 | if __name__ == '__main__': |
252 | 97 | unittest.main() | 123 | unittest.main() |
253 | 98 | 124 | ||
254 | === modified file 'src/sextant/test_parser.py' | |||
255 | --- src/sextant/test_parser.py 2014-11-20 17:25:59 +0000 | |||
256 | +++ src/sextant/test_parser.py 2014-12-12 11:30:28 +0000 | |||
257 | @@ -5,6 +5,7 @@ | |||
258 | 5 | 5 | ||
259 | 6 | import objdump_parser as parser | 6 | import objdump_parser as parser |
260 | 7 | 7 | ||
261 | 8 | OBJ_FILE = 'test_resources/parser_test' | ||
262 | 8 | DUMP_FILE = 'test_resources/parser_test.dump' | 9 | DUMP_FILE = 'test_resources/parser_test.dump' |
263 | 9 | 10 | ||
264 | 10 | class TestSequence(unittest.TestCase): | 11 | class TestSequence(unittest.TestCase): |
265 | @@ -12,7 +13,8 @@ | |||
266 | 12 | pass | 13 | pass |
267 | 13 | 14 | ||
268 | 14 | def add_function(self, dct, name, typ, source): | 15 | def add_function(self, dct, name, typ, source): |
270 | 15 | self.assertFalse(name in dct, "duplicate function added: {} into {}".format(name, dct.keys())) | 16 | self.assertFalse(name in dct, ("duplicate function added: {} into {}" |
271 | 17 | .format(name, dct.keys()))) | ||
272 | 16 | dct[name] = (typ, source) | 18 | dct[name] = (typ, source) |
273 | 17 | 19 | ||
274 | 18 | def add_call(self, dct, caller, callee, is_internal): | 20 | def add_call(self, dct, caller, callee, is_internal): |
275 | @@ -26,7 +28,9 @@ | |||
276 | 26 | add_function = lambda n, t, s: self.add_function(functions, n, t, s) | 28 | add_function = lambda n, t, s: self.add_function(functions, n, t, s) |
277 | 27 | add_call = lambda a, b, i: self.add_call(calls, a, b, i) | 29 | add_call = lambda a, b, i: self.add_call(calls, a, b, i) |
278 | 28 | 30 | ||
280 | 29 | p = parser.Parser(path, sections=sections, ignore_ptrs=ignore_ptrs, | 31 | file_path, file_object = parser.run_objdump(OBJ_FILE, add_file_paths=True) |
281 | 32 | p = parser.Parser(file_path=None, file_object=file_object, | ||
282 | 33 | sections=sections, ignore_ptrs=ignore_ptrs, | ||
283 | 30 | add_function=add_function, add_call=add_call) | 34 | add_function=add_function, add_call=add_call) |
284 | 31 | res = p.parse() | 35 | res = p.parse() |
285 | 32 | 36 | ||
286 | @@ -44,22 +48,26 @@ | |||
287 | 44 | res, funcs, calls = self.do_parse() | 48 | res, funcs, calls = self.do_parse() |
288 | 45 | 49 | ||
289 | 46 | known = 'parser_test.c' | 50 | known = 'parser_test.c' |
290 | 51 | files = 'parser_file2.c' | ||
291 | 47 | unknown = 'unknown' | 52 | unknown = 'unknown' |
292 | 48 | 53 | ||
296 | 49 | for name, typ, fle in zip(['normal', 'duplicates', 'wierd$name', 'printf', 'func_ptr_3'], | 54 | for name, typ, fle in zip(['normal', 'duplicates', 'wierd$name', 'printf', 'func_ptr_3', |
297 | 50 | ['normal', 'normal', 'normal', 'stub', 'pointer'], | 55 | 'name', 'puts', 'inl_func'], |
298 | 51 | [known, known, known, unknown, unknown]): | 56 | ['normal', 'normal', 'normal', 'stub', 'pointer', |
299 | 57 | 'normal', 'stub', 'normal'], | ||
300 | 58 | [known, known, files, unknown, unknown, | ||
301 | 59 | files, unknown, 'parser_header.h']): | ||
302 | 52 | self.assertTrue(name in funcs, "'{}' not found in function dictionary".format(name)) | 60 | self.assertTrue(name in funcs, "'{}' not found in function dictionary".format(name)) |
303 | 53 | self.assertEquals(funcs[name][0], typ) | 61 | self.assertEquals(funcs[name][0], typ) |
305 | 54 | self.assertTrue(funcs[name][1].endswith(fle)) | 62 | self.assertTrue(funcs[name][1].endswith(fle), "{}-{}".format(name, fle)) |
306 | 55 | 63 | ||
307 | 56 | 64 | ||
308 | 57 | def test_no_ptrs(self): | 65 | def test_no_ptrs(self): |
309 | 58 | # ensure that the ignore_ptrs flags is working | 66 | # ensure that the ignore_ptrs flags is working |
310 | 59 | res, funcs, calls = self.do_parse(ignore_ptrs=True) | 67 | res, funcs, calls = self.do_parse(ignore_ptrs=True) |
311 | 60 | 68 | ||
314 | 61 | self.assertFalse('pointer' in funcs.values()) | 69 | self.assertFalse('pointer' in (typ for typ, src in funcs.values())) |
315 | 62 | self.assertEqual(len(calls['normal']), 2) | 70 | self.assertEqual(len(calls['normal']), 3) |
316 | 63 | 71 | ||
317 | 64 | 72 | ||
318 | 65 | def test_calls(self): | 73 | def test_calls(self): |
319 | @@ -68,7 +76,11 @@ | |||
320 | 68 | self.assertTrue(('normal', True) in calls['main']) | 76 | self.assertTrue(('normal', True) in calls['main']) |
321 | 69 | self.assertTrue(('duplicates', True) in calls['main']) | 77 | self.assertTrue(('duplicates', True) in calls['main']) |
322 | 70 | 78 | ||
324 | 71 | normal_calls = sorted(['wierd$name', 'printf', 'func_ptr_3']) | 79 | self.assertTrue(('wierd$name', False) in calls['normal']) |
325 | 80 | self.assertTrue(('name', True) in calls['wierd$name']) | ||
326 | 81 | self.assertTrue(('puts', False) in calls['name']) | ||
327 | 82 | |||
328 | 83 | normal_calls = sorted(['wierd$name', 'printf', 'inl_func', 'func_ptr_3']) | ||
329 | 72 | self.assertEquals(sorted(zip(*calls['normal'])[0]), normal_calls) | 84 | self.assertEquals(sorted(zip(*calls['normal'])[0]), normal_calls) |
330 | 73 | 85 | ||
331 | 74 | self.assertEquals(calls['duplicates'].count(('normal', True)), 1) | 86 | self.assertEquals(calls['duplicates'].count(('normal', True)), 1) |
332 | @@ -77,6 +89,9 @@ | |||
333 | 77 | self.assertTrue(('func_ptr_4', True) in calls['duplicates']) | 89 | self.assertTrue(('func_ptr_4', True) in calls['duplicates']) |
334 | 78 | self.assertTrue(('func_ptr_5', True) in calls['duplicates']) | 90 | self.assertTrue(('func_ptr_5', True) in calls['duplicates']) |
335 | 79 | 91 | ||
336 | 92 | # A function that should only be visible in the plt section | ||
337 | 93 | self.assertFalse('__gmon_start__' in funcs) | ||
338 | 94 | |||
339 | 80 | def test_sections(self): | 95 | def test_sections(self): |
340 | 81 | res, funcs, calls = self.do_parse(sections=['.plt', '.text']) | 96 | res, funcs, calls = self.do_parse(sections=['.plt', '.text']) |
341 | 82 | 97 | ||
342 | @@ -84,6 +99,17 @@ | |||
343 | 84 | self.assertTrue('@' not in ''.join(funcs.keys()), "check names are extracted correctly") | 99 | self.assertTrue('@' not in ''.join(funcs.keys()), "check names are extracted correctly") |
344 | 85 | self.assertTrue('__gmon_start__' in funcs, "see a function defined only in .plt") | 100 | self.assertTrue('__gmon_start__' in funcs, "see a function defined only in .plt") |
345 | 86 | 101 | ||
347 | 87 | 102 | def test_clean_names(self): | |
348 | 103 | clean_id = parser.Parser.clean_id | ||
349 | 104 | # Stripping of ios be prefixes | ||
350 | 105 | self.assertEquals(clean_id('__be_test__be_name'), 'test__be_name') | ||
351 | 106 | self.assertEquals(clean_id('_be_test_name'), '_be_test_name') | ||
352 | 107 | self.assertEquals(clean_id('__betest_name'), '__betest_name') | ||
353 | 108 | |||
354 | 109 | # Removing of extra bits at end | ||
355 | 110 | self.assertEquals(clean_id('test_name.'), 'test_name') | ||
356 | 111 | self.assertEquals(clean_id('test_name..0'), 'test_name') | ||
357 | 112 | |||
358 | 113 | |||
359 | 88 | if __name__ == '__main__': | 114 | if __name__ == '__main__': |
360 | 89 | unittest.main() | 115 | unittest.main() |
361 | 90 | 116 | ||
362 | === added file 'src/sextant/test_resources/parser_file2.c' | |||
363 | --- src/sextant/test_resources/parser_file2.c 1970-01-01 00:00:00 +0000 | |||
364 | +++ src/sextant/test_resources/parser_file2.c 2014-12-12 11:30:28 +0000 | |||
365 | @@ -0,0 +1,24 @@ | |||
366 | 1 | #include <stdio.h> | ||
367 | 2 | #include "parser_header.h" | ||
368 | 3 | |||
369 | 4 | static int | ||
370 | 5 | wierd$name(int a); | ||
371 | 6 | |||
372 | 7 | static int | ||
373 | 8 | __be_name(int a); | ||
374 | 9 | |||
375 | 10 | static int | ||
376 | 11 | wierd$name(int a) | ||
377 | 12 | { | ||
378 | 13 | a = __be_name(inl_func(a)); | ||
379 | 14 | return (a); | ||
380 | 15 | } | ||
381 | 16 | |||
382 | 17 | static int | ||
383 | 18 | __be_name(int a) | ||
384 | 19 | { | ||
385 | 20 | printf("In __be_name\n"); | ||
386 | 21 | return (a+1); | ||
387 | 22 | } | ||
388 | 23 | |||
389 | 24 | |||
390 | 0 | 25 | ||
391 | === added file 'src/sextant/test_resources/parser_header.h' | |||
392 | --- src/sextant/test_resources/parser_header.h 1970-01-01 00:00:00 +0000 | |||
393 | +++ src/sextant/test_resources/parser_header.h 2014-12-12 11:30:28 +0000 | |||
394 | @@ -0,0 +1,10 @@ | |||
395 | 1 | #ifndef PARSER_H | ||
396 | 2 | #define PARSER_H | ||
397 | 3 | |||
398 | 4 | static inline int | ||
399 | 5 | inl_func(int a) | ||
400 | 6 | { | ||
401 | 7 | return (2*a); | ||
402 | 8 | } | ||
403 | 9 | |||
404 | 10 | #endif | ||
405 | 0 | 11 | ||
406 | === modified file 'src/sextant/test_resources/parser_test' | |||
407 | 1 | Binary files src/sextant/test_resources/parser_test 2014-11-17 13:53:27 +0000 and src/sextant/test_resources/parser_test 2014-12-12 11:30:28 +0000 differ | 12 | Binary files src/sextant/test_resources/parser_test 2014-11-17 13:53:27 +0000 and src/sextant/test_resources/parser_test 2014-12-12 11:30:28 +0000 differ |
408 | === modified file 'src/sextant/test_resources/parser_test.c' | |||
409 | --- src/sextant/test_resources/parser_test.c 2014-10-13 14:10:01 +0000 | |||
410 | +++ src/sextant/test_resources/parser_test.c 2014-12-12 11:30:28 +0000 | |||
411 | @@ -1,11 +1,11 @@ | |||
412 | 1 | // COMMENT | 1 | // COMMENT |
413 | 2 | #include<stdio.h> | 2 | #include<stdio.h> |
414 | 3 | #include "parser_header.h" | ||
415 | 4 | #include "parser_file2.c" | ||
416 | 3 | 5 | ||
417 | 4 | static int | 6 | static int |
418 | 5 | normal(int a); | 7 | normal(int a); |
419 | 6 | 8 | ||
420 | 7 | static int | ||
421 | 8 | wierd$name(int a); | ||
422 | 9 | 9 | ||
423 | 10 | typedef int (*pointer)(int); | 10 | typedef int (*pointer)(int); |
424 | 11 | 11 | ||
425 | @@ -18,19 +18,13 @@ | |||
426 | 18 | pointer ptr = wierd$name; | 18 | pointer ptr = wierd$name; |
427 | 19 | 19 | ||
428 | 20 | wierd$name(a); | 20 | wierd$name(a); |
430 | 21 | printf("%d\n", a); | 21 | printf("%d\n", inl_func(a)); |
431 | 22 | ptr(a); | 22 | ptr(a); |
432 | 23 | 23 | ||
433 | 24 | return (a); | 24 | return (a); |
434 | 25 | } | 25 | } |
435 | 26 | 26 | ||
436 | 27 | static int | 27 | static int |
437 | 28 | wierd$name(int a) | ||
438 | 29 | { | ||
439 | 30 | return (a); | ||
440 | 31 | } | ||
441 | 32 | |||
442 | 33 | static int | ||
443 | 34 | duplicates(int a) | 28 | duplicates(int a) |
444 | 35 | { | 29 | { |
445 | 36 | pointer ptr1 = wierd$name; | 30 | pointer ptr1 = wierd$name; |
446 | 37 | 31 | ||
447 | === modified file 'src/sextant/test_sshmanager.py' | |||
448 | --- src/sextant/test_sshmanager.py 2014-10-17 14:35:01 +0000 | |||
449 | +++ src/sextant/test_sshmanager.py 2014-12-12 11:30:28 +0000 | |||
450 | @@ -16,7 +16,7 @@ | |||
451 | 16 | self.manager = None | 16 | self.manager = None |
452 | 17 | 17 | ||
453 | 18 | def get_manager(self, local_port=9643, remote_host='localhost', | 18 | def get_manager(self, local_port=9643, remote_host='localhost', |
455 | 19 | remote_port=9643, ssh_user=None): | 19 | remote_port=9643, ssh_user=None, is_localhost=False): |
456 | 20 | return sshmanager.SSHManager(local_port, remote_host, remote_port, ssh_user) | 20 | return sshmanager.SSHManager(local_port, remote_host, remote_port, ssh_user) |
457 | 21 | 21 | ||
458 | 22 | def test_init(self): | 22 | def test_init(self): |
459 | @@ -34,6 +34,15 @@ | |||
460 | 34 | # check connecion failure | 34 | # check connecion failure |
461 | 35 | self.assertRaises(sshmanager.SSHConnectionError, self.get_manager, remote_host='invalid host') | 35 | self.assertRaises(sshmanager.SSHConnectionError, self.get_manager, remote_host='invalid host') |
462 | 36 | 36 | ||
463 | 37 | def test_localhost(self): | ||
464 | 38 | self.manager = self.get_manager(is_localhost=True) | ||
465 | 39 | self.assertTrue(os.path.isdir(self.manager._tmp_dir)) | ||
466 | 40 | self.manager.close() | ||
467 | 41 | self.assertFalse(os.path.isdir(self.manager._tmp_dir)) | ||
468 | 42 | self.manager = None | ||
469 | 43 | |||
470 | 44 | |||
471 | 45 | |||
472 | 37 | def test_files(self): | 46 | def test_files(self): |
473 | 38 | genuine_file = 'test_resources/parser_test.c' | 47 | genuine_file = 'test_resources/parser_test.c' |
474 | 39 | genuine_file2 = 'test_resources/parser_test' | 48 | genuine_file2 = 'test_resources/parser_test' |