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

Side by Side Diff: tools/isolate/trace_inputs_smoke_test.py

Issue 10444052: Add Results class to hold structured data with details about each of the child processes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 6 months 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
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 shutil 9 import shutil
10 import subprocess 10 import subprocess
11 import sys 11 import sys
12 import tempfile 12 import tempfile
13 import unittest 13 import unittest
14 14
15 ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) 15 FULLNAME = os.path.abspath(__file__)
16 ROOT_DIR = os.path.dirname(FULLNAME)
16 FILENAME = os.path.basename(__file__) 17 FILENAME = os.path.basename(__file__)
17 VERBOSE = False 18 VERBOSE = False
18 19
19 20
20 class CalledProcessError(subprocess.CalledProcessError): 21 class CalledProcessError(subprocess.CalledProcessError):
21 """Makes 2.6 version act like 2.7""" 22 """Makes 2.6 version act like 2.7"""
22 def __init__(self, returncode, cmd, output, cwd): 23 def __init__(self, returncode, cmd, output, cwd):
23 super(CalledProcessError, self).__init__(returncode, cmd) 24 super(CalledProcessError, self).__init__(returncode, cmd)
24 self.output = output 25 self.output = output
25 self.cwd = cwd 26 self.cwd = cwd
26 27
27 def __str__(self): 28 def __str__(self):
28 return super(CalledProcessError, self).__str__() + ( 29 return super(CalledProcessError, self).__str__() + (
29 '\n' 30 '\n'
30 'cwd=%s\n%s') % (self.cwd, self.output) 31 'cwd=%s\n%s') % (self.cwd, self.output)
31 32
32 33
33 class TraceInputs(unittest.TestCase): 34 class TraceInputsBase(unittest.TestCase):
34 def setUp(self): 35 def setUp(self):
35 self.tempdir = tempfile.mkdtemp(prefix='trace_smoke_test') 36 self.tempdir = tempfile.mkdtemp(prefix='trace_smoke_test')
36 self.log = os.path.join(self.tempdir, 'log') 37 self.log = os.path.join(self.tempdir, 'log')
37 os.chdir(ROOT_DIR) 38 os.chdir(ROOT_DIR)
38 39
39 def tearDown(self): 40 def tearDown(self):
40 if VERBOSE: 41 if VERBOSE:
41 print 'Leaking: %s' % self.tempdir 42 print 'Leaking: %s' % self.tempdir
42 else: 43 else:
43 shutil.rmtree(self.tempdir) 44 shutil.rmtree(self.tempdir)
44 45
45 def _execute(self, is_gyp): 46 @staticmethod
46 cmd = [ 47 def command(from_data):
47 sys.executable, os.path.join('..', '..', 'trace_inputs.py'), 48 cmd = [sys.executable]
48 '--log', self.log, 49 if from_data:
49 '--root-dir', ROOT_DIR,
50 ]
51 if VERBOSE:
52 cmd.extend(['-v'] * 3)
53 if is_gyp:
54 cmd.extend(
55 [
56 '--cwd', 'data',
57 '--product', '.', # Not tested.
58 ])
59 cmd.append(sys.executable)
60 if is_gyp:
61 # When the gyp argument is specified, the command is started from --cwd 50 # When the gyp argument is specified, the command is started from --cwd
62 # directory. In this case, 'data'. 51 # directory. In this case, 'data'.
63 cmd.extend([os.path.join('trace_inputs', 'child1.py'), '--child-gyp']) 52 cmd.extend([os.path.join('trace_inputs', 'child1.py'), '--child-gyp'])
64 else: 53 else:
65 # When the gyp argument is not specified, the command is started from 54 # When the gyp argument is not specified, the command is started from
66 # --root-dir directory. 55 # --root-dir directory.
67 cmd.extend([os.path.join('data', 'trace_inputs', 'child1.py'), '--child']) 56 cmd.extend([os.path.join('data', 'trace_inputs', 'child1.py'), '--child'])
57 return cmd
68 58
59
60 class TraceInputs(TraceInputsBase):
61 def _execute(self, command):
62 cmd = [
63 sys.executable, os.path.join('..', '..', 'trace_inputs.py'),
64 '--log', self.log,
65 '--root-dir', ROOT_DIR,
66 ]
67 if VERBOSE:
68 cmd.extend(['-v'] * 3)
69 cmd.extend(command)
69 # The current directory doesn't matter, the traced process will be called 70 # The current directory doesn't matter, the traced process will be called
70 # from the correct cwd. 71 # from the correct cwd.
71 cwd = os.path.join('data', 'trace_inputs') 72 cwd = os.path.join('data', 'trace_inputs')
72 # Ignore stderr. 73 # Ignore stderr.
73 logging.info('Command: %s' % ' '.join(cmd)) 74 logging.info('Command: %s' % ' '.join(cmd))
74 p = subprocess.Popen( 75 p = subprocess.Popen(
75 cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd, 76 cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd,
76 universal_newlines=True) 77 universal_newlines=True)
77 out, err = p.communicate() 78 out, err = p.communicate()
78 if VERBOSE: 79 if VERBOSE:
79 print err 80 print err
80 if p.returncode: 81 if p.returncode:
81 raise CalledProcessError(p.returncode, cmd, out + err, cwd) 82 raise CalledProcessError(p.returncode, cmd, out + err, cwd)
82 return out or '' 83 return out or ''
83 84
84 def test_trace(self): 85 def test_trace(self):
85 expected_end = [ 86 expected_end = [
86 'Interesting: 5 reduced to 3', 87 'Interesting: 5 reduced to 3',
87 ' data/trace_inputs/'.replace('/', os.path.sep), 88 ' data/trace_inputs/'.replace('/', os.path.sep),
88 ' trace_inputs.py', 89 ' trace_inputs.py',
89 ' %s' % FILENAME, 90 ' %s' % FILENAME,
90 ] 91 ]
91 actual = self._execute(False).splitlines() 92 actual = self._execute(self.command(False)).splitlines()
92 self.assertTrue(actual[0].startswith('Tracing... ['), actual) 93 self.assertTrue(actual[0].startswith('Tracing... ['), actual)
93 self.assertTrue(actual[1].startswith('Loading traces... '), actual) 94 self.assertTrue(actual[1].startswith('Loading traces... '), actual)
94 self.assertTrue(actual[2].startswith('Total: '), actual) 95 self.assertTrue(actual[2].startswith('Total: '), actual)
95 if sys.platform == 'win32': 96 if sys.platform == 'win32':
96 # On windows, python searches the current path for python stdlib like 97 # On windows, python searches the current path for python stdlib like
97 # subprocess.py and others, I'm not sure why. 98 # subprocess.py and others, I'm not sure why.
98 self.assertTrue(actual[3].startswith('Non existent: '), actual[3]) 99 self.assertTrue(actual[3].startswith('Non existent: '), actual[3])
99 else: 100 else:
100 self.assertEquals('Non existent: 0', actual[3]) 101 self.assertEquals('Non existent: 0', actual[3])
101 # Ignore any Unexpected part. 102 # Ignore any Unexpected part.
(...skipping 15 matching lines...) Expand all
117 'isolate_dependency_untracked': [ 118 'isolate_dependency_untracked': [
118 'trace_inputs/', 119 'trace_inputs/',
119 ], 120 ],
120 }, 121 },
121 }], 122 }],
122 ], 123 ],
123 } 124 }
124 expected_buffer = cStringIO.StringIO() 125 expected_buffer = cStringIO.StringIO()
125 trace_inputs.pretty_print(expected_value, expected_buffer) 126 trace_inputs.pretty_print(expected_value, expected_buffer)
126 127
127 actual = self._execute(True) 128 cmd = [
129 '--cwd', 'data',
130 '--product', '.', # Not tested.
131 ] + self.command(True)
132 actual = self._execute(cmd)
128 self.assertEquals(expected_buffer.getvalue(), actual) 133 self.assertEquals(expected_buffer.getvalue(), actual)
129 134
130 135
136 class TraceInputsImport(TraceInputsBase):
137 def setUp(self):
138 super(TraceInputsImport, self).setUp()
139 self.cwd = os.path.join(ROOT_DIR, u'data')
140 self.initial_cwd = self.cwd
141 if sys.platform == 'win32':
142 # Still not supported on Windows.
143 self.initial_cwd = None
144
145 # Similar to TraceInputs test fixture except that it calls the function
146 # directly, so the Results instance can be inspected.
147 # Roughly, make sure the API is stable.
148 def _execute(self, command):
149 # Similar to what trace_test_cases.py does.
150 import trace_inputs
151 api = trace_inputs.get_api()
152 _, _ = trace_inputs.trace(
153 self.log, command, self.cwd, api, True)
154 # TODO(maruel): Check
155 #self.assertEquals(0, returncode)
156 #self.assertEquals('', output)
157 return trace_inputs.load_trace(self.log, ROOT_DIR, api)
158
159 def test_trace_wrong_path(self):
160 # Deliberately start the trace from the wrong path. Start it from inside
161 # data so data/data/trace_inputs/child1.py is not accessible.
162 # and no child .
MAD 2012/05/30 20:29:36 and no child?
M-A Ruel 2012/05/30 22:34:10 No child is left behind, finished sentence.
MAD 2012/05/31 14:00:57 You end previous line with a "." and start this on
M-A Ruel 2012/05/31 14:56:45 I can't type. Hopefully fixed.
163 results, simplified = self._execute(self.command(False))
164 expected = {
165 'root': {
166 'children': [],
167 'command': None,
168 'executable': None,
169 'files': [],
170 'initial_cwd': self.initial_cwd,
171 },
172 }
173 actual = results.flatten()
174 self.assertTrue(actual['root'].pop('pid'))
175 self.assertEquals(expected, actual)
176 self.assertEquals([], simplified)
177
178 def test_trace(self):
179 size_t_i_s = os.stat(FULLNAME).st_size
180 size_t_i = os.stat(os.path.join(ROOT_DIR, 'trace_inputs.py')).st_size
181 expected = {
182 'root': {
183 'children': [
184 {
185 'children': [],
186 'command': None,
187 'executable': None,
188 'files': [
189 {
190 'path': os.path.join(u'data', 'trace_inputs', 'child2.py'),
191 'size': 776,
192 },
193 {
194 'path': os.path.join(u'data', 'trace_inputs', 'test_file.txt'),
195 'size': 4,
196 },
197 ],
198 'initial_cwd': self.initial_cwd,
199 },
200 ],
201 'command': None,
202 'executable': None,
203 'files': [
204 {
205 'path': os.path.join(u'data', 'trace_inputs', 'child1.py'),
206 'size': 1364,
207 },
208 {
209 'path': u'trace_inputs.py',
210 'size': size_t_i,
211 },
212 {
213 'path': u'trace_inputs_smoke_test.py',
214 'size': size_t_i_s,
215 },
216 ],
217 'initial_cwd': self.initial_cwd,
218 },
219 }
220 results, simplified = self._execute(self.command(True))
221 actual = results.flatten()
222 self.assertTrue(actual['root'].pop('pid'))
223 self.assertTrue(actual['root']['children'][0].pop('pid'))
224 self.assertEquals(expected, actual)
225 files = [
226 os.path.join(u'data', 'trace_inputs') + os.path.sep,
227 u'trace_inputs.py',
228 u'trace_inputs_smoke_test.py',
229 ]
230 self.assertEquals(files, [f.path for f in simplified])
231
232
233
131 if __name__ == '__main__': 234 if __name__ == '__main__':
132 VERBOSE = '-v' in sys.argv 235 VERBOSE = '-v' in sys.argv
133 logging.basicConfig(level=logging.DEBUG if VERBOSE else logging.ERROR) 236 logging.basicConfig(level=logging.DEBUG if VERBOSE else logging.ERROR)
134 unittest.main() 237 unittest.main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698