Merge lp:~ben-hutchings/ensoft-sextant/wierd-names-clean into lp:ensoft-sextant

Proposed by Ben Hutchings
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
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.

To post a comment you must log in.
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

Revision history for this message
Robert (rjwills) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/sextant/db_api.py'
--- src/sextant/db_api.py 2014-11-25 11:40:03 +0000
+++ src/sextant/db_api.py 2014-12-12 11:30:28 +0000
@@ -996,7 +996,7 @@
996996
997 return self._execute_query(program_name, q)997 return self._execute_query(program_name, q)
998998
999 def get_all_functions_calling(self, program_name, function_called, 999 def get_all_functions_calling(self, program_name, function_calling,
1000 limit_internal=False, max_depth=1):1000 limit_internal=False, max_depth=1):
1001 """1001 """
1002 Return functions calling the specified functions.1002 Return functions calling the specified functions.
@@ -1014,12 +1014,16 @@
1014 program_name: 1014 program_name:
1015 The name of the program to query.1015 The name of the program to query.
10161016
1017 function_called: 1017 function_calling:
1018 A string of form <name_match>:<file_match>, where at least1018 A string of form <name_match>:<file_match>, where at least
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
1020 comma separated list of strings containing wildcard '.*' 1020 comma separated list of strings containing wildcard '.*'
1021 sequences. Specifies the list of functions to match. 1021 sequences. Specifies the list of functions to match.
10221022
1023 NOTE: the name is a bit of a hack to work with the javascript.
1024 Should really be function_called but that would require more
1025 js fiddling.
1026
1023 limit_internal:1027 limit_internal:
1024 If true, only explore internal calls.1028 If true, only explore internal calls.
10251029
@@ -1034,7 +1038,7 @@
1034 q = (' MATCH (p:program {{name: "{}"}})-[:subject]->(g:func) {}'1038 q = (' MATCH (p:program {{name: "{}"}})-[:subject]->(g:func) {}'
1035 ' MATCH (f)-[{}*0..{}]->(g)'1039 ' MATCH (f)-[{}*0..{}]->(g)'
1036 ' RETURN distinct f, g')1040 ' RETURN distinct f, g')
1037 q = q.format(program_name, SextantConnection.get_query('g', function_called),1041 q = q.format(program_name, SextantConnection.get_query('g', function_calling),
1038 ':internal' if limit_internal else ':internal|external',1042 ':internal' if limit_internal else ':internal|external',
1039 max_depth or '')1043 max_depth or '')
10401044
10411045
=== modified file 'src/sextant/objdump_parser.py'
--- src/sextant/objdump_parser.py 2014-11-25 11:40:03 +0000
+++ src/sextant/objdump_parser.py 2014-12-12 11:30:28 +0000
@@ -121,7 +121,7 @@
121 print('func {:25} {:15}{}'.format(name, typ, source))121 print('func {:25} {:15}{}'.format(name, typ, source))
122122
123 def print_call(caller, callee, is_internal):123 def print_call(caller, callee, is_internal):
124 print('call {:25} {:25}'.format(caller, callee))124 print('call {} {:25} {:25}'.format('EI'[is_internal], caller, callee))
125125
126 def print_started(parser):126 def print_started(parser):
127 print('parse started: {}[{}]'.format(self.path, ', '.join(self.sections)))127 print('parse started: {}[{}]'.format(self.path, ', '.join(self.sections)))
@@ -199,10 +199,27 @@
199 self.add_call(caller, callee, False)199 self.add_call(caller, callee, False)
200 self._known_calls.add((caller, callee))200 self._known_calls.add((caller, callee))
201 self.call_count += 1201 self.call_count += 1
202 print(caller, callee)
203 else:202 else:
204 self._partial_calls.add((caller, callee))203 self._partial_calls.add((caller, callee))
205204
205 @staticmethod
206 def clean_id(function_identifier):
207 """
208 Clean the funciton identifier string.
209 """
210 # Bi-endian builds add a __be_ prefix to all functions,
211 # get rid of it if it is there,
212 if function_identifier.startswith('__be_'):
213 function_identifier = function_identifier[len('__be_'):]
214
215 # Some functions look like <identifier>. or <identifier>..<digit>
216 # - get rid of the extra bits here:
217 if '.' in function_identifier:
218 function_identifier = function_identifier.split('.')[0]
219
220 return function_identifier
221
222
206 def parse(self):223 def parse(self):
207 """224 """
208 Parse self._file.225 Parse self._file.
@@ -242,10 +259,7 @@
242 # <function_name>[@plt]259 # <function_name>[@plt]
243 function_identifier = line.split('<')[-1].split('>')[0]260 function_identifier = line.split('<')[-1].split('>')[0]
244261
245 # IOS builds add a __be_ (big endian) prefix to all functions,262 function_identifier = self.clean_id(function_identifier)
246 # get rid of it if it is there,
247 if function_identifier.startswith('__be_'):
248 function_identifier = function_identifier[len('__be_'):]
249263
250 if '@' in function_identifier:264 if '@' in function_identifier:
251 # Of form <function name>@<other stuff>.265 # Of form <function name>@<other stuff>.
@@ -277,8 +291,8 @@
277 # from which we extract name291 # from which we extract name
278 callee_is_ptr = False292 callee_is_ptr = False
279 function_identifier = callee_info.lstrip('<').rstrip('>\n')293 function_identifier = callee_info.lstrip('<').rstrip('>\n')
280 if function_identifier.startswith('__be_'):294
281 function_identifier = function_identifier[len('__be_'):]295 function_identifier = self.clean_id(function_identifier)
282296
283 if '@' in function_identifier:297 if '@' in function_identifier:
284 callee = function_identifier.split('@')[0]298 callee = function_identifier.split('@')[0]
285299
=== added file 'src/sextant/test_all.py'
--- src/sextant/test_all.py 1970-01-01 00:00:00 +0000
+++ src/sextant/test_all.py 2014-12-12 11:30:28 +0000
@@ -0,0 +1,39 @@
1#!/usr/bin/python
2
3from __future__ import print_function
4
5import subprocess
6import shlex
7
8tests = (('test_parser.py', 'objdump_parser.py'),
9 ('test_csvwriter.py', 'csvwriter.py'),
10 ('test_sshmanager.py', 'sshmanager.py'),
11 ('test_db.py', 'db_api.py'))
12
13pycmd = 'coverage run {}'
14covcmd = 'coverage report -m {}'
15
16if __name__ == '__main__':
17 Popen = subprocess.Popen
18
19 for test, name in tests:
20 print('Running tests: {}'.format(test))
21 do_print = False
22
23
24 pyproc = Popen(shlex.split(pycmd.format(test)), stdout=subprocess.PIPE)
25 for line in pyproc.stdout:
26 if '----------' in line or '=========' in line:
27 do_print = True
28
29 if do_print:
30 print(line.rstrip())
31
32 covproc = Popen(shlex.split(covcmd.format(name)))
33 covproc.wait()
34
35
36
37
38
39
040
=== removed file 'src/sextant/test_all.sh'
--- src/sextant/test_all.sh 2014-10-13 16:01:59 +0000
+++ src/sextant/test_all.sh 1970-01-01 00:00:00 +0000
@@ -1,4 +0,0 @@
1#!/usr/bin/bash
2
3PYTHONPATH=$PYTHONPATH:~/.
4python -m unittest discover --pattern=test_*.py
50
=== modified file 'src/sextant/test_db.py'
--- src/sextant/test_db.py 2014-11-25 11:40:03 +0000
+++ src/sextant/test_db.py 2014-12-12 11:30:28 +0000
@@ -12,7 +12,7 @@
12import update_db12import update_db
1313
14PNAME = 'tester-parser_test'14PNAME = 'tester-parser_test'
15NORMAL = {'main', 'normal', 'wierd$name', 'duplicates'}15NORMAL = {'main', 'normal', 'wierd$name', 'duplicates', 'name', 'puts'}
1616
1717
18class TestFunctionQueryResults(unittest.TestCase):18class TestFunctionQueryResults(unittest.TestCase):
@@ -37,10 +37,12 @@
37 names = get_names(PNAME)37 names = get_names(PNAME)
38 # Test file wildcard search38 # Test file wildcard search
39 parser_names = get_names(PNAME, search=':.*parser_test.c')39 parser_names = get_names(PNAME, search=':.*parser_test.c')
40 file2_names = get_names(PNAME, search=':.*parser_file2.c')
4041
41 self.assertTrue(names.issuperset(NORMAL))42 self.assertTrue(names.issuperset(NORMAL))
42 self.assertEquals(len(names), 24)43 self.assertEquals(len(names), 27)
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'})
45 self.assertEquals(file2_names, {u'wierd$name', u'name'})
4446
45 # Test the wildcard matching47 # Test the wildcard matching
46 search = self.connection.get_function_names(PNAME, search='.*libc.*')48 search = self.connection.get_function_names(PNAME, search='.*libc.*')
@@ -58,13 +60,12 @@
58 def test_get_all_functions_called(self):60 def test_get_all_functions_called(self):
59 get_fns = self.connection.get_all_functions_called61 get_fns = self.connection.get_all_functions_called
60 62
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]):
62 result = get_fns(PNAME, 'main', False, depth).functions64 result = get_fns(PNAME, 'main', False, depth).functions
63 self.assertEquals(len(result), num, str(result))65 self.assertEquals(len(result), num)
6466
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]):
66 # Limit to internal functions68 # Limit to internal functions
67 # TODO this isn't a great test - need greater call depth
68 result = get_fns(PNAME, 'main', True, depth).functions69 result = get_fns(PNAME, 'main', True, depth).functions
69 self.assertEquals(len(result), num)70 self.assertEquals(len(result), num)
7071
@@ -80,18 +81,43 @@
80 self.assertEquals(len(result), num)81 self.assertEquals(len(result), num)
8182
82 def test_get_all_paths_between(self):83 def test_get_all_paths_between(self):
83 get_paths = self.connection.get_call_paths84 get_paths = self.connection.get_call_paths
8485
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}
86 exp = {'main', 'normal', 'duplicates', 'wierd$name'}87 exp = {'main', 'normal', 'duplicates', 'wierd$name'}
87 self.assertEquals(result, exp)88 self.assertEquals(result, exp)
89
90 self.assertFalse(get_paths(PNAME, 'main', 'wierd$name', True, 0).functions)
8891
89 def test_get_shortest_paths_between(self):92 def test_get_shortest_paths_between(self):
90 get_paths = self.connection.get_shortest_path_between_functions93 get_paths = self.connection.get_shortest_path_between_functions
9194
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}
93 exp = {u'main', u'normal', u'wierd$name'}96 exp = {u'main', u'normal', u'wierd$name'}
94 self.assertEquals(result, exp)97 self.assertEquals(result, exp)
98
99 self.assertFalse(get_paths(PNAME, 'main', 'wierd$name', True, 0).functions)
100
101 def test_programs_with_metadata(self):
102 result = self.connection.programs_with_metadata()
103 found = False
104
105 for program in result:
106 if program.program_name == PNAME:
107 found = True
108
109 self.assertEquals(program.number_of_funcs, 27)
110 self.assertEquals(program.number_of_calls, 26)
111
112 break
113
114 self.assertTrue(found)
115
116 def test_get_whole_program(self):
117 result = self.connection.get_whole_program(PNAME)
118 self.assertEquals(len(result.functions), 27)
119
120 self.assertFalse(self.connection.get_whole_program('no such program'))
95121
96if __name__ == '__main__':122if __name__ == '__main__':
97 unittest.main()123 unittest.main()
98124
=== modified file 'src/sextant/test_parser.py'
--- src/sextant/test_parser.py 2014-11-20 17:25:59 +0000
+++ src/sextant/test_parser.py 2014-12-12 11:30:28 +0000
@@ -5,6 +5,7 @@
55
6import objdump_parser as parser6import objdump_parser as parser
77
8OBJ_FILE = 'test_resources/parser_test'
8DUMP_FILE = 'test_resources/parser_test.dump'9DUMP_FILE = 'test_resources/parser_test.dump'
910
10class TestSequence(unittest.TestCase):11class TestSequence(unittest.TestCase):
@@ -12,7 +13,8 @@
12 pass13 pass
13 14
14 def add_function(self, dct, name, typ, source):15 def add_function(self, dct, name, typ, source):
15 self.assertFalse(name in dct, "duplicate function added: {} into {}".format(name, dct.keys()))16 self.assertFalse(name in dct, ("duplicate function added: {} into {}"
17 .format(name, dct.keys())))
16 dct[name] = (typ, source)18 dct[name] = (typ, source)
1719
18 def add_call(self, dct, caller, callee, is_internal):20 def add_call(self, dct, caller, callee, is_internal):
@@ -26,7 +28,9 @@
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)
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)
2830
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)
32 p = parser.Parser(file_path=None, file_object=file_object,
33 sections=sections, ignore_ptrs=ignore_ptrs,
30 add_function=add_function, add_call=add_call)34 add_function=add_function, add_call=add_call)
31 res = p.parse()35 res = p.parse()
3236
@@ -44,22 +48,26 @@
44 res, funcs, calls = self.do_parse()48 res, funcs, calls = self.do_parse()
4549
46 known = 'parser_test.c'50 known = 'parser_test.c'
51 files = 'parser_file2.c'
47 unknown = 'unknown'52 unknown = 'unknown'
4853
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',
50 ['normal', 'normal', 'normal', 'stub', 'pointer'],55 'name', 'puts', 'inl_func'],
51 [known, known, known, unknown, unknown]):56 ['normal', 'normal', 'normal', 'stub', 'pointer',
57 'normal', 'stub', 'normal'],
58 [known, known, files, unknown, unknown,
59 files, unknown, 'parser_header.h']):
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))
53 self.assertEquals(funcs[name][0], typ)61 self.assertEquals(funcs[name][0], typ)
54 self.assertTrue(funcs[name][1].endswith(fle))62 self.assertTrue(funcs[name][1].endswith(fle), "{}-{}".format(name, fle))
5563
5664
57 def test_no_ptrs(self):65 def test_no_ptrs(self):
58 # ensure that the ignore_ptrs flags is working66 # ensure that the ignore_ptrs flags is working
59 res, funcs, calls = self.do_parse(ignore_ptrs=True)67 res, funcs, calls = self.do_parse(ignore_ptrs=True)
6068
61 self.assertFalse('pointer' in funcs.values())69 self.assertFalse('pointer' in (typ for typ, src in funcs.values()))
62 self.assertEqual(len(calls['normal']), 2)70 self.assertEqual(len(calls['normal']), 3)
6371
6472
65 def test_calls(self):73 def test_calls(self):
@@ -68,7 +76,11 @@
68 self.assertTrue(('normal', True) in calls['main'])76 self.assertTrue(('normal', True) in calls['main'])
69 self.assertTrue(('duplicates', True) in calls['main'])77 self.assertTrue(('duplicates', True) in calls['main'])
7078
71 normal_calls = sorted(['wierd$name', 'printf', 'func_ptr_3'])79 self.assertTrue(('wierd$name', False) in calls['normal'])
80 self.assertTrue(('name', True) in calls['wierd$name'])
81 self.assertTrue(('puts', False) in calls['name'])
82
83 normal_calls = sorted(['wierd$name', 'printf', 'inl_func', 'func_ptr_3'])
72 self.assertEquals(sorted(zip(*calls['normal'])[0]), normal_calls)84 self.assertEquals(sorted(zip(*calls['normal'])[0]), normal_calls)
7385
74 self.assertEquals(calls['duplicates'].count(('normal', True)), 1)86 self.assertEquals(calls['duplicates'].count(('normal', True)), 1)
@@ -77,6 +89,9 @@
77 self.assertTrue(('func_ptr_4', True) in calls['duplicates'])89 self.assertTrue(('func_ptr_4', True) in calls['duplicates'])
78 self.assertTrue(('func_ptr_5', True) in calls['duplicates'])90 self.assertTrue(('func_ptr_5', True) in calls['duplicates'])
7991
92 # A function that should only be visible in the plt section
93 self.assertFalse('__gmon_start__' in funcs)
94
80 def test_sections(self):95 def test_sections(self):
81 res, funcs, calls = self.do_parse(sections=['.plt', '.text'])96 res, funcs, calls = self.do_parse(sections=['.plt', '.text'])
8297
@@ -84,6 +99,17 @@
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")
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")
86101
87 102 def test_clean_names(self):
103 clean_id = parser.Parser.clean_id
104 # Stripping of ios be prefixes
105 self.assertEquals(clean_id('__be_test__be_name'), 'test__be_name')
106 self.assertEquals(clean_id('_be_test_name'), '_be_test_name')
107 self.assertEquals(clean_id('__betest_name'), '__betest_name')
108
109 # Removing of extra bits at end
110 self.assertEquals(clean_id('test_name.'), 'test_name')
111 self.assertEquals(clean_id('test_name..0'), 'test_name')
112
113
88if __name__ == '__main__':114if __name__ == '__main__':
89 unittest.main()115 unittest.main()
90116
=== added file 'src/sextant/test_resources/parser_file2.c'
--- src/sextant/test_resources/parser_file2.c 1970-01-01 00:00:00 +0000
+++ src/sextant/test_resources/parser_file2.c 2014-12-12 11:30:28 +0000
@@ -0,0 +1,24 @@
1#include <stdio.h>
2#include "parser_header.h"
3
4static int
5wierd$name(int a);
6
7static int
8__be_name(int a);
9
10static int
11wierd$name(int a)
12{
13 a = __be_name(inl_func(a));
14 return (a);
15}
16
17static int
18__be_name(int a)
19{
20 printf("In __be_name\n");
21 return (a+1);
22}
23
24
025
=== added file 'src/sextant/test_resources/parser_header.h'
--- src/sextant/test_resources/parser_header.h 1970-01-01 00:00:00 +0000
+++ src/sextant/test_resources/parser_header.h 2014-12-12 11:30:28 +0000
@@ -0,0 +1,10 @@
1#ifndef PARSER_H
2#define PARSER_H
3
4static inline int
5inl_func(int a)
6{
7 return (2*a);
8}
9
10#endif
011
=== modified file 'src/sextant/test_resources/parser_test'
1Binary 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 differ12Binary 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
=== modified file 'src/sextant/test_resources/parser_test.c'
--- src/sextant/test_resources/parser_test.c 2014-10-13 14:10:01 +0000
+++ src/sextant/test_resources/parser_test.c 2014-12-12 11:30:28 +0000
@@ -1,11 +1,11 @@
1// COMMENT1// COMMENT
2#include<stdio.h>2#include<stdio.h>
3#include "parser_header.h"
4#include "parser_file2.c"
35
4static int6static int
5normal(int a);7normal(int a);
68
7static int
8wierd$name(int a);
99
10typedef int (*pointer)(int);10typedef int (*pointer)(int);
1111
@@ -18,19 +18,13 @@
18 pointer ptr = wierd$name;18 pointer ptr = wierd$name;
1919
20 wierd$name(a);20 wierd$name(a);
21 printf("%d\n", a);21 printf("%d\n", inl_func(a));
22 ptr(a);22 ptr(a);
2323
24 return (a);24 return (a);
25}25}
2626
27static int27static int
28wierd$name(int a)
29{
30 return (a);
31}
32
33static int
34duplicates(int a)28duplicates(int a)
35{29{
36 pointer ptr1 = wierd$name;30 pointer ptr1 = wierd$name;
3731
=== modified file 'src/sextant/test_sshmanager.py'
--- src/sextant/test_sshmanager.py 2014-10-17 14:35:01 +0000
+++ src/sextant/test_sshmanager.py 2014-12-12 11:30:28 +0000
@@ -16,7 +16,7 @@
16 self.manager = None16 self.manager = None
1717
18 def get_manager(self, local_port=9643, remote_host='localhost', 18 def get_manager(self, local_port=9643, remote_host='localhost',
19 remote_port=9643, ssh_user=None):19 remote_port=9643, ssh_user=None, is_localhost=False):
20 return sshmanager.SSHManager(local_port, remote_host, remote_port, ssh_user)20 return sshmanager.SSHManager(local_port, remote_host, remote_port, ssh_user)
2121
22 def test_init(self):22 def test_init(self):
@@ -34,6 +34,15 @@
34 # check connecion failure34 # check connecion failure
35 self.assertRaises(sshmanager.SSHConnectionError, self.get_manager, remote_host='invalid host')35 self.assertRaises(sshmanager.SSHConnectionError, self.get_manager, remote_host='invalid host')
3636
37 def test_localhost(self):
38 self.manager = self.get_manager(is_localhost=True)
39 self.assertTrue(os.path.isdir(self.manager._tmp_dir))
40 self.manager.close()
41 self.assertFalse(os.path.isdir(self.manager._tmp_dir))
42 self.manager = None
43
44
45
37 def test_files(self):46 def test_files(self):
38 genuine_file = 'test_resources/parser_test.c'47 genuine_file = 'test_resources/parser_test.c'
39 genuine_file2 = 'test_resources/parser_test'48 genuine_file2 = 'test_resources/parser_test'

Subscribers

People subscribed via source and target branches