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 unittest | 9 import unittest |
10 import sys | 10 import sys |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
88 " },\n" | 88 " },\n" |
89 " }, {\n" | 89 " }, {\n" |
90 " 'variables': {\n" | 90 " 'variables': {\n" |
91 " },\n" | 91 " },\n" |
92 " }],\n" | 92 " }],\n" |
93 " ],\n" | 93 " ],\n" |
94 "}\n") | 94 "}\n") |
95 self._test(value, expected) | 95 self._test(value, expected) |
96 | 96 |
97 | 97 |
98 def join_norm(*args): | |
99 """Joins and normalizes path in a single step.""" | |
100 return unicode(os.path.normpath(os.path.join(*args))) | |
101 | |
102 | |
98 if trace_inputs.get_flavor() == 'linux': | 103 if trace_inputs.get_flavor() == 'linux': |
99 class StraceInputs(unittest.TestCase): | 104 class StraceInputs(unittest.TestCase): |
100 def _test_lines( | 105 # Represents the root process pid (an arbitrary number). |
101 self, lines, initial_cwd, expected_files, expected_non_existent): | 106 _ROOT_PID = 27 |
107 | |
108 @staticmethod | |
109 def _load_context(lines, initial_cwd): | |
102 context = trace_inputs.Strace.Context(lambda _: False, initial_cwd) | 110 context = trace_inputs.Strace.Context(lambda _: False, initial_cwd) |
103 for line in lines: | 111 for line in lines: |
104 context.on_line(*line) | 112 context.on_line(*line) |
105 actual_files, actual_non_existent = context.resolve() | 113 return context.to_results().flatten() |
106 self.assertEquals(sorted(expected_files), sorted(actual_files)) | 114 |
107 self.assertEquals( | 115 def _test_lines(self, lines, initial_cwd, files, command=None): |
108 sorted(expected_non_existent), sorted(actual_non_existent)) | 116 command = command or ['../out/unittests'] |
117 expected = { | |
118 'root': { | |
119 'children': [], | |
120 'command': None, | |
121 'executable': None, | |
122 'files': files, | |
123 'initial_cwd': initial_cwd, | |
124 'pid': self._ROOT_PID, | |
125 } | |
126 } | |
127 if not files: | |
128 expected['root']['command'] = None | |
129 expected['root']['executable'] = None | |
130 self.assertEquals(expected, self._load_context(lines, initial_cwd)) | |
131 | |
132 def test_execve(self): | |
133 lines = [ | |
134 (self._ROOT_PID, | |
135 'execve("/home/foo_bar_user/out/unittests", ' | |
136 '["/home/foo_bar_user/out/unittests", ' | |
137 '"--gtest_filter=AtExitTest.Basic"], [/* 44 vars */]) = 0'), | |
138 (self._ROOT_PID, | |
139 'open("out/unittests.log", O_WRONLY|O_CREAT|O_APPEND, 0666) = 8'), | |
140 ] | |
141 files = [ | |
142 { | |
143 'path': u'/home/foo_bar_user/out/unittests', | |
144 'size': -1, | |
145 }, | |
146 { | |
147 'path': u'/home/foo_bar_user/src/out/unittests.log', | |
148 'size': -1, | |
149 }, | |
150 ] | |
151 command = [ | |
152 '/home/foo_bar_user/out/unittests', '--gtest_filter=AtExitTest.Basic', | |
153 ] | |
154 self._test_lines(lines, '/home/foo_bar_user/src', files, command) | |
109 | 155 |
110 def test_empty(self): | 156 def test_empty(self): |
111 self._test_lines([], None, [], []) | 157 try: |
158 self._load_context([], None) | |
159 self.fail() | |
160 except AssertionError: | |
161 pass | |
112 | 162 |
113 def test_close(self): | 163 def test_close(self): |
114 lines = [ | 164 lines = [ |
115 (90, 'close(7) = 0'), | 165 (self._ROOT_PID, 'close(7) = 0'), |
116 ] | 166 ] |
117 self._test_lines(lines, None, [], []) | 167 self._test_lines(lines, '/home/foo_bar_user/src', []) |
118 | 168 |
119 def test_clone(self): | 169 def test_clone(self): |
120 # Grand-child with relative directory. | 170 # Grand-child with relative directory. |
121 lines = [ | 171 lines = [ |
122 (86, 'clone(child_stack=0, flags=CLONE_CHILD_CLEARTID' | 172 (self._ROOT_PID, |
173 'clone(child_stack=0, flags=CLONE_CHILD_CLEARTID' | |
123 '|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f5350f829d0) = 14'), | 174 '|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f5350f829d0) = 14'), |
124 (86, ') = ? <unavailable>'), | |
125 (14, 'clone(child_stack=0, flags=CLONE_CHILD_CLEARTID' | 175 (14, 'clone(child_stack=0, flags=CLONE_CHILD_CLEARTID' |
MAD
2012/05/31 14:00:57
Why not do it for _CHILD_PID and _GRAND_CHILD_PID
M-A Ruel
2012/05/31 14:56:46
done.
| |
126 '|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f5350f829d0) = 70'), | 176 '|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f5350f829d0) = 70'), |
127 (14, 'close(75) = 0'), | |
128 (70, 'open("%s", O_RDONLY) = 76' % os.path.basename(FILE_NAME)), | 177 (70, 'open("%s", O_RDONLY) = 76' % os.path.basename(FILE_NAME)), |
129 ] | 178 ] |
130 files = [ | 179 size = os.stat(FILE_NAME).st_size |
131 FILE_NAME, | 180 expected = { |
132 ] | 181 'root': { |
133 self._test_lines(lines, ROOT_DIR, files, []) | 182 'children': [ |
183 { | |
184 'children': [ | |
185 { | |
186 'children': [], | |
187 'command': None, | |
188 'executable': None, | |
189 'files': [ | |
190 { | |
191 'path': unicode(FILE_NAME), | |
192 'size': size, | |
193 }, | |
194 ], | |
195 'initial_cwd': ROOT_DIR, | |
196 'pid': 70, | |
197 }, | |
198 ], | |
199 'command': None, | |
200 'executable': None, | |
201 'files': [], | |
202 'initial_cwd': ROOT_DIR, | |
203 'pid': 14, | |
204 }, | |
205 ], | |
206 'command': None, | |
207 'executable': None, | |
208 'files': [], | |
209 'initial_cwd': ROOT_DIR, | |
210 'pid': self._ROOT_PID, | |
211 }, | |
212 } | |
213 self.assertEquals(expected, self._load_context(lines, ROOT_DIR)) | |
214 | |
215 def test_clone_chdir(self): | |
216 # Grand-child with relative directory. | |
217 lines = [ | |
218 (self._ROOT_PID, | |
219 'execve("../out/unittests", ' | |
220 '["../out/unittests"...], [/* 44 vars */]) = 0'), | |
221 (self._ROOT_PID, | |
222 'clone(child_stack=0, flags=CLONE_CHILD_CLEARTID' | |
223 '|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f5350f829d0) = 14'), | |
224 (14, 'chdir("/home_foo_bar_user/path1") = 0'), | |
225 (14, 'clone(child_stack=0, flags=CLONE_CHILD_CLEARTID' | |
226 '|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f5350f829d0) = 70'), | |
227 (self._ROOT_PID, 'chdir("/home_foo_bar_user/path2") = 0'), | |
228 (70, 'open("random.txt", O_RDONLY) = 76'), | |
229 ] | |
230 expected = { | |
231 'root': { | |
232 'children': [ | |
233 { | |
234 'children': [ | |
235 { | |
236 'children': [], | |
237 'command': None, | |
238 'executable': None, | |
239 'files': [ | |
240 { | |
241 'path': u'/home_foo_bar_user/path1/random.txt', | |
242 'size': -1, | |
243 }, | |
244 ], | |
245 'initial_cwd': '/home_foo_bar_user/path1', | |
246 'pid': 70, | |
247 }, | |
248 ], | |
249 'command': None, | |
250 'executable': None, | |
251 # This is important, since no execve call was done, it didn't | |
252 # touch the executable file. | |
253 'files': [], | |
254 'initial_cwd': ROOT_DIR, | |
255 'pid': 14, | |
256 }, | |
257 ], | |
258 'command': None, | |
259 'executable': None, | |
260 'files': [ | |
261 { | |
262 'path': join_norm(ROOT_DIR, '../out/unittests'), | |
263 'size': -1, | |
264 }, | |
265 ], | |
266 'initial_cwd': ROOT_DIR, | |
267 'pid': self._ROOT_PID, | |
268 }, | |
269 } | |
270 self.assertEquals(expected, self._load_context(lines, ROOT_DIR)) | |
134 | 271 |
135 def test_open(self): | 272 def test_open(self): |
136 lines = [ | 273 lines = [ |
137 (42, 'execve("../out/unittests", ' | 274 (self._ROOT_PID, |
138 '["../out/unittests"...], [/* 44 vars */]) = 0'), | 275 'execve("../out/unittests", ' |
139 (42, 'open("out/unittests.log", O_WRONLY|O_CREAT|O_APPEND, 0666) = 8'), | 276 '["../out/unittests"...], [/* 44 vars */]) = 0'), |
140 ] | 277 (self._ROOT_PID, |
141 files = [ | 278 'open("out/unittests.log", O_WRONLY|O_CREAT|O_APPEND, 0666) = 8'), |
142 u'/home/foo_bar_user/out/unittests', | 279 ] |
143 u'/home/foo_bar_user/src/out/unittests.log', | 280 files = [ |
144 ] | 281 { |
145 self._test_lines(lines, '/home/foo_bar_user/src', [], files) | 282 'path': u'/home/foo_bar_user/out/unittests', |
283 'size': -1, | |
284 }, | |
285 { | |
286 'path': u'/home/foo_bar_user/src/out/unittests.log', | |
287 'size': -1, | |
288 }, | |
289 ] | |
290 self._test_lines(lines, '/home/foo_bar_user/src', files) | |
146 | 291 |
147 def test_open_resumed(self): | 292 def test_open_resumed(self): |
148 lines = [ | 293 lines = [ |
149 (42, 'execve("../out/unittests", ' | 294 (self._ROOT_PID, |
150 '["../out/unittests"...], [/* 44 vars */]) = 0'), | 295 'execve("../out/unittests", ' |
151 (42, 'open("out/unittests.log", O_WRONLY|O_CREAT|O_APPEND ' | 296 '["../out/unittests"...], [/* 44 vars */]) = 0'), |
152 '<unfinished ...>'), | 297 (self._ROOT_PID, |
153 (42, '<... open resumed> ) = 3'), | 298 'open("out/unittests.log", O_WRONLY|O_CREAT|O_APPEND ' |
154 ] | 299 '<unfinished ...>'), |
155 files = [ | 300 (self._ROOT_PID, '<... open resumed> ) = 3'), |
156 u'/home/foo_bar_user/out/unittests', | 301 ] |
157 u'/home/foo_bar_user/src/out/unittests.log', | 302 files = [ |
158 ] | 303 { |
159 self._test_lines(lines, '/home/foo_bar_user/src', [], files) | 304 'path': u'/home/foo_bar_user/out/unittests', |
305 'size': -1, | |
306 }, | |
307 { | |
308 'path': u'/home/foo_bar_user/src/out/unittests.log', | |
309 'size': -1, | |
310 }, | |
311 ] | |
312 self._test_lines(lines, '/home/foo_bar_user/src', files) | |
160 | 313 |
161 def test_sig_unexpected(self): | 314 def test_sig_unexpected(self): |
162 lines = [ | 315 lines = [ |
163 (27, 'exit_group(0) = ?'), | 316 (self._ROOT_PID, 'exit_group(0) = ?'), |
164 ] | 317 ] |
165 self._test_lines(lines, ROOT_DIR, [], []) | 318 self._test_lines(lines, '/home/foo_bar_user/src', []) |
319 | |
320 def test_stray(self): | |
321 lines = [ | |
322 (self._ROOT_PID, | |
323 'execve("../out/unittests", ' | |
324 '["../out/unittests"...], [/* 44 vars */]) = 0'), | |
325 (self._ROOT_PID, | |
326 ') = ? <unavailable>'), | |
327 ] | |
328 files = [ | |
329 { | |
330 'path': u'/home/foo_bar_user/out/unittests', | |
331 'size': -1, | |
332 }, | |
333 ] | |
334 self._test_lines(lines, '/home/foo_bar_user/src', files) | |
166 | 335 |
167 | 336 |
168 if __name__ == '__main__': | 337 if __name__ == '__main__': |
169 VERBOSE = '-v' in sys.argv | 338 VERBOSE = '-v' in sys.argv |
170 logging.basicConfig(level=logging.DEBUG if VERBOSE else logging.ERROR) | 339 logging.basicConfig(level=logging.DEBUG if VERBOSE else logging.ERROR) |
171 unittest.main() | 340 unittest.main() |
OLD | NEW |