Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: swarm_client/tests/trace_inputs_smoke_test.py

Issue 69143004: Delete swarm_client. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # coding=utf-8
3 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 import json
8 import logging
9 import os
10 import shutil
11 import subprocess
12 import sys
13 import tempfile
14 import unicodedata
15 import unittest
16
17 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
18 sys.path.insert(0, ROOT_DIR)
19
20 import trace_inputs
21 from utils import file_path
22 from utils import threading_utils
23
24 FILENAME = os.path.basename(__file__)
25 REL_DATA = os.path.join(u'tests', 'trace_inputs')
26 VERBOSE = False
27
28 # TODO(maruel): Have the kernel tracer on Windows differentiate between file
29 # read or file write.
30 MODE_R = trace_inputs.Results.File.READ if sys.platform != 'win32' else None
31 MODE_W = trace_inputs.Results.File.WRITE if sys.platform != 'win32' else None
32 MODE_T = trace_inputs.Results.File.TOUCHED
33
34
35 class CalledProcessError(subprocess.CalledProcessError):
36 """Makes 2.6 version act like 2.7"""
37 def __init__(self, returncode, cmd, output, cwd):
38 super(CalledProcessError, self).__init__(returncode, cmd)
39 self.output = output
40 self.cwd = cwd
41
42 def __str__(self):
43 return super(CalledProcessError, self).__str__() + (
44 '\n'
45 'cwd=%s\n%s') % (self.cwd, self.output)
46
47
48 class TraceInputsBase(unittest.TestCase):
49 def setUp(self):
50 self.tempdir = None
51 self.trace_inputs_path = os.path.join(ROOT_DIR, 'trace_inputs.py')
52
53 # Wraps up all the differences between OSes here.
54 # - Windows doesn't track initial_cwd.
55 # - OSX replaces /usr/bin/python with /usr/bin/python2.7.
56 self.cwd = os.path.join(ROOT_DIR, u'tests')
57 self.initial_cwd = unicode(self.cwd)
58 self.expected_cwd = unicode(ROOT_DIR)
59 if sys.platform == 'win32':
60 # Not supported on Windows.
61 self.initial_cwd = None
62 self.expected_cwd = None
63
64 # There's 3 kinds of references to python, self.executable,
65 # self.real_executable and self.naked_executable. It depends how python was
66 # started.
67 self.executable = sys.executable
68 if sys.platform == 'darwin':
69 # /usr/bin/python is a thunk executable that decides which version of
70 # python gets executed.
71 suffix = '.'.join(map(str, sys.version_info[0:2]))
72 if os.access(self.executable + suffix, os.X_OK):
73 # So it'll look like /usr/bin/python2.7
74 self.executable += suffix
75
76 self.real_executable = file_path.get_native_path_case(
77 unicode(self.executable))
78 self.tempdir = file_path.get_native_path_case(
79 unicode(tempfile.mkdtemp(prefix='trace_smoke_test')))
80 self.log = os.path.join(self.tempdir, 'log')
81
82 # self.naked_executable will only be naked on Windows.
83 self.naked_executable = unicode(sys.executable)
84 if sys.platform == 'win32':
85 self.naked_executable = os.path.basename(sys.executable)
86
87 def tearDown(self):
88 if self.tempdir:
89 if VERBOSE:
90 print 'Leaking: %s' % self.tempdir
91 else:
92 shutil.rmtree(self.tempdir)
93
94 @staticmethod
95 def get_child_command(from_data):
96 """Returns command to run the child1.py."""
97 cmd = [sys.executable]
98 if from_data:
99 # When the gyp argument is specified, the command is started from --cwd
100 # directory. In this case, 'tests'.
101 cmd.extend([os.path.join('trace_inputs', 'child1.py'), '--child-gyp'])
102 else:
103 # When the gyp argument is not specified, the command is started from
104 # --root-dir directory.
105 cmd.extend([os.path.join(REL_DATA, 'child1.py'), '--child'])
106 return cmd
107
108 @staticmethod
109 def _size(*args):
110 return os.stat(os.path.join(ROOT_DIR, *args)).st_size
111
112
113 class TraceInputs(TraceInputsBase):
114 def _execute(self, mode, command, cwd):
115 cmd = [
116 sys.executable,
117 self.trace_inputs_path,
118 mode,
119 '--log', self.log,
120 ]
121 if VERBOSE:
122 cmd.extend(['-v'] * 3)
123 cmd.extend(command)
124 logging.info('Command: %s' % ' '.join(cmd))
125 p = subprocess.Popen(
126 cmd,
127 stdout=subprocess.PIPE,
128 stderr=subprocess.PIPE,
129 cwd=cwd,
130 universal_newlines=True)
131 out, err = p.communicate()
132 if VERBOSE:
133 print err
134 if p.returncode:
135 raise CalledProcessError(p.returncode, cmd, out + err, cwd)
136 return out or ''
137
138 def _trace(self, from_data):
139 if from_data:
140 cwd = os.path.join(ROOT_DIR, 'tests')
141 else:
142 cwd = ROOT_DIR
143 return self._execute('trace', self.get_child_command(from_data), cwd=cwd)
144
145 def test_trace(self):
146 expected = '\n'.join((
147 'Total: 7',
148 'Non existent: 0',
149 'Interesting: 7 reduced to 6',
150 ' tests/trace_inputs/child1.py'.replace('/', os.path.sep),
151 ' tests/trace_inputs/child2.py'.replace('/', os.path.sep),
152 ' tests/trace_inputs/files1/'.replace('/', os.path.sep),
153 ' tests/trace_inputs/test_file.txt'.replace('/', os.path.sep),
154 (' tests/%s' % FILENAME).replace('/', os.path.sep),
155 ' trace_inputs.py',
156 )) + '\n'
157 trace_expected = '\n'.join((
158 'child from %s' % ROOT_DIR,
159 'child2',
160 )) + '\n'
161 trace_actual = self._trace(False)
162 actual = self._execute(
163 'read',
164 [
165 '--root-dir', ROOT_DIR,
166 '--trace-blacklist', '.+\\.pyc',
167 '--trace-blacklist', '.*\\.svn',
168 '--trace-blacklist', '.*do_not_care\\.txt',
169 ],
170 cwd=unicode(ROOT_DIR))
171 self.assertEqual(expected, actual)
172 self.assertEqual(trace_expected, trace_actual)
173
174 def test_trace_json(self):
175 expected = {
176 u'root': {
177 u'children': [
178 {
179 u'children': [],
180 u'command': [u'python', u'child2.py'],
181 u'executable': self.naked_executable,
182 u'files': [
183 {
184 'mode': MODE_R,
185 u'path': os.path.join(REL_DATA, 'child2.py'),
186 u'size': self._size(REL_DATA, 'child2.py'),
187 },
188 {
189 'mode': MODE_R,
190 u'path': os.path.join(REL_DATA, 'files1', 'bar'),
191 u'size': self._size(REL_DATA, 'files1', 'bar'),
192 },
193 {
194 'mode': MODE_R,
195 u'path': os.path.join(REL_DATA, 'files1', 'foo'),
196 u'size': self._size(REL_DATA, 'files1', 'foo'),
197 },
198 {
199 'mode': MODE_R,
200 u'path': os.path.join(REL_DATA, 'test_file.txt'),
201 u'size': self._size(REL_DATA, 'test_file.txt'),
202 },
203 ],
204 u'initial_cwd': self.initial_cwd,
205 #u'pid': 123,
206 },
207 ],
208 u'command': [
209 unicode(self.executable),
210 os.path.join(u'trace_inputs', 'child1.py'),
211 u'--child-gyp',
212 ],
213 u'executable': self.real_executable,
214 u'files': [
215 {
216 u'mode': MODE_R,
217 u'path': os.path.join(REL_DATA, 'child1.py'),
218 u'size': self._size(REL_DATA, 'child1.py'),
219 },
220 {
221 u'mode': MODE_R,
222 u'path': os.path.join(u'tests', u'trace_inputs_smoke_test.py'),
223 u'size': self._size('tests', 'trace_inputs_smoke_test.py'),
224 },
225 {
226 u'mode': MODE_R,
227 u'path': u'trace_inputs.py',
228 u'size': self._size('trace_inputs.py'),
229 },
230 ],
231 u'initial_cwd': self.initial_cwd,
232 #u'pid': 123,
233 },
234 }
235 trace_expected = '\n'.join((
236 'child_gyp from %s' % os.path.join(ROOT_DIR, 'tests'),
237 'child2',
238 )) + '\n'
239 trace_actual = self._trace(True)
240 actual_text = self._execute(
241 'read',
242 [
243 '--root-dir', ROOT_DIR,
244 '--trace-blacklist', '.+\\.pyc',
245 '--trace-blacklist', '.*\\.svn',
246 '--trace-blacklist', '.*do_not_care\\.txt',
247 '--json',
248 ],
249 cwd=unicode(ROOT_DIR))
250 actual_json = json.loads(actual_text)
251 self.assertEqual(list, actual_json.__class__)
252 self.assertEqual(1, len(actual_json))
253 actual_json = actual_json[0]
254 # Removes the pids.
255 self.assertTrue(actual_json['root'].pop('pid'))
256 self.assertTrue(actual_json['root']['children'][0].pop('pid'))
257 self.assertEqual(expected, actual_json)
258 self.assertEqual(trace_expected, trace_actual)
259
260
261 class TraceInputsImport(TraceInputsBase):
262
263 # Similar to TraceInputs test fixture except that it calls the function
264 # directly, so the Results instance can be inspected.
265 # Roughly, make sure the API is stable.
266 def _execute_trace(self, command):
267 # Similar to what trace_test_cases.py does.
268 api = trace_inputs.get_api()
269 _, _ = trace_inputs.trace(self.log, command, self.cwd, api, True)
270 # TODO(maruel): Check
271 #self.assertEqual(0, returncode)
272 #self.assertEqual('', output)
273 def blacklist(f):
274 return f.endswith(('.pyc', '.svn', 'do_not_care.txt'))
275 data = api.parse_log(self.log, blacklist, None)
276 self.assertEqual(1, len(data))
277 if 'exception' in data[0]:
278 raise data[0]['exception'][0], \
279 data[0]['exception'][1], \
280 data[0]['exception'][2]
281
282 return data[0]['results'].strip_root(unicode(ROOT_DIR))
283
284 def _gen_dict_wrong_path(self):
285 """Returns the expected flattened Results when child1.py is called with the
286 wrong relative path.
287 """
288 return {
289 'root': {
290 'children': [],
291 'command': [
292 self.executable,
293 os.path.join(REL_DATA, 'child1.py'),
294 '--child',
295 ],
296 'executable': self.real_executable,
297 'files': [],
298 'initial_cwd': self.initial_cwd,
299 },
300 }
301
302 def _gen_dict_full(self):
303 """Returns the expected flattened Results when child1.py is called with
304 --child.
305 """
306 return {
307 'root': {
308 'children': [
309 {
310 'children': [],
311 'command': ['python', 'child2.py'],
312 'executable': self.naked_executable,
313 'files': [
314 {
315 'mode': MODE_R,
316 'path': os.path.join(REL_DATA, 'child2.py'),
317 'size': self._size(REL_DATA, 'child2.py'),
318 },
319 {
320 'mode': MODE_R,
321 'path': os.path.join(REL_DATA, 'files1', 'bar'),
322 'size': self._size(REL_DATA, 'files1', 'bar'),
323 },
324 {
325 'mode': MODE_R,
326 'path': os.path.join(REL_DATA, 'files1', 'foo'),
327 'size': self._size(REL_DATA, 'files1', 'foo'),
328 },
329 {
330 'mode': MODE_R,
331 'path': os.path.join(REL_DATA, 'test_file.txt'),
332 'size': self._size(REL_DATA, 'test_file.txt'),
333 },
334 ],
335 'initial_cwd': self.expected_cwd,
336 },
337 ],
338 'command': [
339 self.executable,
340 os.path.join(REL_DATA, 'child1.py'),
341 '--child',
342 ],
343 'executable': self.real_executable,
344 'files': [
345 {
346 'mode': MODE_R,
347 'path': os.path.join(REL_DATA, 'child1.py'),
348 'size': self._size(REL_DATA, 'child1.py'),
349 },
350 {
351 'mode': MODE_R,
352 'path': os.path.join(u'tests', u'trace_inputs_smoke_test.py'),
353 'size': self._size('tests', 'trace_inputs_smoke_test.py'),
354 },
355 {
356 'mode': MODE_R,
357 'path': u'trace_inputs.py',
358 'size': self._size('trace_inputs.py'),
359 },
360 ],
361 'initial_cwd': self.expected_cwd,
362 },
363 }
364
365 def _gen_dict_full_gyp(self):
366 """Returns the expected flattened results when child1.py is called with
367 --child-gyp.
368 """
369 return {
370 'root': {
371 'children': [
372 {
373 'children': [],
374 'command': [u'python', u'child2.py'],
375 'executable': self.naked_executable,
376 'files': [
377 {
378 'mode': MODE_R,
379 'path': os.path.join(REL_DATA, 'child2.py'),
380 'size': self._size(REL_DATA, 'child2.py'),
381 },
382 {
383 'mode': MODE_R,
384 'path': os.path.join(REL_DATA, 'files1', 'bar'),
385 'size': self._size(REL_DATA, 'files1', 'bar'),
386 },
387 {
388 'mode': MODE_R,
389 'path': os.path.join(REL_DATA, 'files1', 'foo'),
390 'size': self._size(REL_DATA, 'files1', 'foo'),
391 },
392 {
393 'mode': MODE_R,
394 'path': os.path.join(REL_DATA, 'test_file.txt'),
395 'size': self._size(REL_DATA, 'test_file.txt'),
396 },
397 ],
398 'initial_cwd': self.initial_cwd,
399 },
400 ],
401 'command': [
402 self.executable,
403 os.path.join('trace_inputs', 'child1.py'),
404 '--child-gyp',
405 ],
406 'executable': self.real_executable,
407 'files': [
408 {
409 'mode': MODE_R,
410 'path': os.path.join(REL_DATA, 'child1.py'),
411 'size': self._size(REL_DATA, 'child1.py'),
412 },
413 {
414 'mode': MODE_R,
415 'path': os.path.join(u'tests', u'trace_inputs_smoke_test.py'),
416 'size': self._size('tests', 'trace_inputs_smoke_test.py'),
417 },
418 {
419 'mode': MODE_R,
420 'path': u'trace_inputs.py',
421 'size': self._size('trace_inputs.py'),
422 },
423 ],
424 'initial_cwd': self.initial_cwd,
425 },
426 }
427
428 def test_trace_wrong_path(self):
429 # Deliberately start the trace from the wrong path. Starts it from the
430 # directory 'tests' so 'tests/tests/trace_inputs/child1.py' is not
431 # accessible, so child2.py process is not started.
432 results = self._execute_trace(self.get_child_command(False))
433 expected = self._gen_dict_wrong_path()
434 actual = results.flatten()
435 self.assertTrue(actual['root'].pop('pid'))
436 self.assertEqual(expected, actual)
437
438 def test_trace(self):
439 expected = self._gen_dict_full_gyp()
440 results = self._execute_trace(self.get_child_command(True))
441 actual = results.flatten()
442 self.assertTrue(actual['root'].pop('pid'))
443 self.assertTrue(actual['root']['children'][0].pop('pid'))
444 self.assertEqual(expected, actual)
445 files = [
446 u'tests/trace_inputs/child1.py'.replace('/', os.path.sep),
447 u'tests/trace_inputs/child2.py'.replace('/', os.path.sep),
448 u'tests/trace_inputs/files1/'.replace('/', os.path.sep),
449 u'tests/trace_inputs/test_file.txt'.replace('/', os.path.sep),
450 u'tests/trace_inputs_smoke_test.py'.replace('/', os.path.sep),
451 u'trace_inputs.py',
452 ]
453 def blacklist(f):
454 return f.endswith(('.pyc', 'do_not_care.txt', '.git', '.svn'))
455 simplified = trace_inputs.extract_directories(
456 file_path.get_native_path_case(unicode(ROOT_DIR)),
457 results.files,
458 blacklist)
459 self.assertEqual(files, [f.path for f in simplified])
460
461 def test_trace_multiple(self):
462 # Starts parallel threads and trace parallel child processes simultaneously.
463 # Some are started from 'tests' directory, others from this script's
464 # directory. One trace fails. Verify everything still goes one.
465 parallel = 8
466
467 def trace(tracer, cmd, cwd, tracename):
468 resultcode, output = tracer.trace(cmd, cwd, tracename, True)
469 return (tracename, resultcode, output)
470
471 with threading_utils.ThreadPool(parallel, parallel, 0) as pool:
472 api = trace_inputs.get_api()
473 with api.get_tracer(self.log) as tracer:
474 pool.add_task(
475 0, trace, tracer, self.get_child_command(False), ROOT_DIR, 'trace1')
476 pool.add_task(
477 0, trace, tracer, self.get_child_command(True), self.cwd, 'trace2')
478 pool.add_task(
479 0, trace, tracer, self.get_child_command(False), ROOT_DIR, 'trace3')
480 pool.add_task(
481 0, trace, tracer, self.get_child_command(True), self.cwd, 'trace4')
482 # Have this one fail since it's started from the wrong directory.
483 pool.add_task(
484 0, trace, tracer, self.get_child_command(False), self.cwd, 'trace5')
485 pool.add_task(
486 0, trace, tracer, self.get_child_command(True), self.cwd, 'trace6')
487 pool.add_task(
488 0, trace, tracer, self.get_child_command(False), ROOT_DIR, 'trace7')
489 pool.add_task(
490 0, trace, tracer, self.get_child_command(True), self.cwd, 'trace8')
491 trace_results = pool.join()
492 def blacklist(f):
493 return f.endswith(('.pyc', 'do_not_care.txt', '.git', '.svn'))
494 actual_results = api.parse_log(self.log, blacklist, None)
495 self.assertEqual(8, len(trace_results))
496 self.assertEqual(8, len(actual_results))
497
498 # Convert to dict keyed on the trace name, simpler to verify.
499 trace_results = dict((i[0], i[1:]) for i in trace_results)
500 actual_results = dict((x.pop('trace'), x) for x in actual_results)
501 self.assertEqual(sorted(trace_results), sorted(actual_results))
502
503 # It'd be nice to start different kinds of processes.
504 expected_results = [
505 self._gen_dict_full(),
506 self._gen_dict_full_gyp(),
507 self._gen_dict_full(),
508 self._gen_dict_full_gyp(),
509 self._gen_dict_wrong_path(),
510 self._gen_dict_full_gyp(),
511 self._gen_dict_full(),
512 self._gen_dict_full_gyp(),
513 ]
514 self.assertEqual(len(expected_results), len(trace_results))
515
516 # See the comment above about the trace that fails because it's started from
517 # the wrong directory.
518 busted = 4
519 for index, key in enumerate(sorted(actual_results)):
520 self.assertEqual('trace%d' % (index + 1), key)
521 self.assertEqual(2, len(trace_results[key]))
522 # returncode
523 self.assertEqual(0 if index != busted else 2, trace_results[key][0])
524 # output
525 self.assertEqual(actual_results[key]['output'], trace_results[key][1])
526
527 self.assertEqual(['output', 'results'], sorted(actual_results[key]))
528 results = actual_results[key]['results']
529 results = results.strip_root(unicode(ROOT_DIR))
530 actual = results.flatten()
531 self.assertTrue(actual['root'].pop('pid'))
532 if index != busted:
533 self.assertTrue(actual['root']['children'][0].pop('pid'))
534 self.assertEqual(expected_results[index], actual)
535
536 if sys.platform != 'win32':
537 def test_trace_symlink(self):
538 expected = {
539 'root': {
540 'children': [],
541 'command': [
542 self.executable,
543 os.path.join('trace_inputs', 'symlink.py'),
544 ],
545 'executable': self.real_executable,
546 'files': [
547 {
548 'mode': MODE_R,
549 'path': os.path.join(REL_DATA, 'files2', 'bar'),
550 'size': self._size(REL_DATA, 'files2', 'bar'),
551 },
552 {
553 'mode': MODE_R,
554 'path': os.path.join(REL_DATA, 'files2', 'foo'),
555 'size': self._size(REL_DATA, 'files2', 'foo'),
556 },
557 {
558 'mode': MODE_R,
559 'path': os.path.join(REL_DATA, 'symlink.py'),
560 'size': self._size(REL_DATA, 'symlink.py'),
561 },
562 ],
563 'initial_cwd': self.initial_cwd,
564 },
565 }
566 cmd = [sys.executable, os.path.join('trace_inputs', 'symlink.py')]
567 results = self._execute_trace(cmd)
568 actual = results.flatten()
569 self.assertTrue(actual['root'].pop('pid'))
570 self.assertEqual(expected, actual)
571 files = [
572 # In particular, the symlink is *not* resolved.
573 u'tests/trace_inputs/files2/'.replace('/', os.path.sep),
574 u'tests/trace_inputs/symlink.py'.replace('/', os.path.sep),
575 ]
576 def blacklist(f):
577 return f.endswith(('.pyc', '.svn', 'do_not_care.txt'))
578 simplified = trace_inputs.extract_directories(
579 unicode(ROOT_DIR), results.files, blacklist)
580 self.assertEqual(files, [f.path for f in simplified])
581
582 def test_trace_quoted(self):
583 results = self._execute_trace([sys.executable, '-c', 'print("hi")'])
584 expected = {
585 'root': {
586 'children': [],
587 'command': [
588 self.executable,
589 '-c',
590 'print("hi")',
591 ],
592 'executable': self.real_executable,
593 'files': [],
594 'initial_cwd': self.initial_cwd,
595 },
596 }
597 actual = results.flatten()
598 self.assertTrue(actual['root'].pop('pid'))
599 self.assertEqual(expected, actual)
600
601 def _touch_expected(self, command):
602 # Looks for file that were touched but not opened, using different apis.
603 results = self._execute_trace(
604 [sys.executable, os.path.join('trace_inputs', 'touch_only.py'), command])
605 expected = {
606 'root': {
607 'children': [],
608 'command': [
609 self.executable,
610 os.path.join('trace_inputs', 'touch_only.py'),
611 command,
612 ],
613 'executable': self.real_executable,
614 'files': [
615 {
616 'mode': MODE_T,
617 'path': os.path.join(REL_DATA, 'test_file.txt'),
618 'size': self._size(REL_DATA, 'test_file.txt'),
619 },
620 {
621 'mode': MODE_R,
622 'path': os.path.join(REL_DATA, 'touch_only.py'),
623 'size': self._size(REL_DATA, 'touch_only.py'),
624 },
625 ],
626 'initial_cwd': self.initial_cwd,
627 },
628 }
629 if sys.platform != 'linux2':
630 # TODO(maruel): Remove once properly implemented.
631 expected['root']['files'].pop(0)
632
633 actual = results.flatten()
634 self.assertTrue(actual['root'].pop('pid'))
635 self.assertEqual(expected, actual)
636
637 def test_trace_touch_only_access(self):
638 self._touch_expected('access')
639
640 def test_trace_touch_only_isfile(self):
641 self._touch_expected('isfile')
642
643 def test_trace_touch_only_stat(self):
644 self._touch_expected('stat')
645
646 def test_trace_tricky_filename(self):
647 # TODO(maruel): On Windows, it's using the current code page so some
648 # characters can't be represented. As a nice North American, hard code the
649 # string to something representable in code page 1252. The exact code page
650 # depends on the user system.
651 if sys.platform == 'win32':
652 filename = u'foo, bar, ~p#o,,ué^t%t .txt'
653 else:
654 filename = u'foo, bar, ~p#o,,ué^t%t 和平.txt'
655
656 exe = os.path.join(self.tempdir, 'tricky_filename.py')
657 shutil.copyfile(
658 os.path.join(self.cwd, 'trace_inputs', 'tricky_filename.py'), exe)
659 expected = {
660 'root': {
661 'children': [],
662 'command': [
663 self.executable,
664 exe,
665 ],
666 'executable': self.real_executable,
667 'files': [
668 {
669 'mode': MODE_W,
670 'path': filename,
671 'size': long(len('Bingo!')),
672 },
673 {
674 'mode': MODE_R,
675 'path': u'tricky_filename.py',
676 'size': self._size(REL_DATA, 'tricky_filename.py'),
677 },
678 ],
679 'initial_cwd': self.tempdir if sys.platform != 'win32' else None,
680 },
681 }
682
683 api = trace_inputs.get_api()
684 returncode, output = trace_inputs.trace(
685 self.log, [exe], self.tempdir, api, True)
686 self.assertEqual('', output)
687 self.assertEqual(0, returncode)
688 data = api.parse_log(self.log, lambda _: False, None)
689 self.assertEqual(1, len(data))
690 if 'exception' in data[0]:
691 raise data[0]['exception'][0], \
692 data[0]['exception'][1], \
693 data[0]['exception'][2]
694 actual = data[0]['results'].strip_root(self.tempdir).flatten()
695 self.assertTrue(actual['root'].pop('pid'))
696 self.assertEqual(expected, actual)
697 trace_inputs.get_api().clean_trace(self.log)
698 files = sorted(
699 unicodedata.normalize('NFC', i)
700 for i in os.listdir(unicode(self.tempdir)))
701 self.assertEqual([filename, 'tricky_filename.py'], files)
702
703
704 if __name__ == '__main__':
705 VERBOSE = '-v' in sys.argv
706 logging.basicConfig(level=logging.DEBUG if VERBOSE else logging.ERROR)
707 if VERBOSE:
708 unittest.TestCase.maxDiff = None
709 # Necessary for the dtrace logger to work around execve() hook. See
710 # trace_inputs.py for more details.
711 os.environ['TRACE_INPUTS_DTRACE_ENABLE_EXECVE'] = '1'
712 unittest.main()
OLDNEW
« no previous file with comments | « swarm_client/tests/trace_inputs/tricky_filename.py ('k') | swarm_client/tests/trace_inputs_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698