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

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

Issue 10068032: Rewrite isolate_smoke_test.py to increase the coverage. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 8 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
« no previous file with comments | « tools/isolate/isolate.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 hashlib 7 import hashlib
8 import json 8 import json
9 import logging 9 import logging
10 import os 10 import os
11 import re 11 import re
12 import shutil 12 import shutil
13 import subprocess 13 import subprocess
14 import sys 14 import sys
15 import tempfile 15 import tempfile
16 import unittest 16 import unittest
17 17
18 import isolate 18 import isolate
19 19
20 ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) 20 ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
21 VERBOSE = False 21 VERBOSE = False
22 22
23 23
24 # Keep the list hard coded.
25 EXPECTED_MODES = ('check', 'hashtable', 'remap', 'run', 'trace')
26 # These are per test case, not per mode.
27 RELATIVE_CWD = {
28 'fail': '.',
29 'missing_trailing_slash': '.',
30 'no_run': '.',
31 'non_existent': '.',
32 'touch_root': 'data/isolate',
33 'with_flag': '.',
34 }
35 DEPENDENCIES = {
36 'fail': ['fail.py'],
37 'missing_trailing_slash': [],
38 'no_run': [
39 'no_run.isolate', 'files1/test_file1.txt', 'files1/test_file2.txt',
40 ],
41 'non_existent': [],
42 'touch_root': ['data/isolate/touch_root.py', 'isolate.py'],
43 'with_flag': [
44 'with_flag.py', 'files1/test_file1.txt', 'files1/test_file2.txt',
45 ],
46 }
24 47
25 class CalledProcessError(subprocess.CalledProcessError): 48 class CalledProcessError(subprocess.CalledProcessError):
26 """Makes 2.6 version act like 2.7""" 49 """Makes 2.6 version act like 2.7"""
27 def __init__(self, returncode, cmd, output, cwd): 50 def __init__(self, returncode, cmd, output, cwd):
28 super(CalledProcessError, self).__init__(returncode, cmd) 51 super(CalledProcessError, self).__init__(returncode, cmd)
29 self.output = output 52 self.output = output
30 self.cwd = cwd 53 self.cwd = cwd
31 54
32 def __str__(self): 55 def __str__(self):
33 return super(CalledProcessError, self).__str__() + ( 56 return super(CalledProcessError, self).__str__() + (
34 '\n' 57 '\n'
35 'cwd=%s\n%s') % (self.cwd, self.output) 58 'cwd=%s\n%s') % (self.cwd, self.output)
36 59
37 60
38 class Isolate(unittest.TestCase): 61 class IsolateBase(unittest.TestCase):
62 # To be defined by the subclass, it defines the amount of meta data saved by
63 # isolate.py for each file.
64 LEVEL = None
65
39 def setUp(self): 66 def setUp(self):
40 # The tests assume the current directory is the file's directory. 67 # The tests assume the current directory is the file's directory.
41 os.chdir(ROOT_DIR) 68 os.chdir(ROOT_DIR)
42 self.tempdir = tempfile.mkdtemp() 69 self.tempdir = tempfile.mkdtemp()
43 self.result = os.path.join(self.tempdir, 'result') 70 self.result = os.path.join(self.tempdir, 'isolate_smoke_test.result')
44 self.child = os.path.join('data', 'isolate', 'child.py') 71 self.outdir = os.path.join(self.tempdir, 'isolated')
45 if VERBOSE:
46 print
47 self.files = [
48 self.child,
49 os.path.join('data', 'isolate', 'files1', 'test_file1.txt'),
50 os.path.join('data', 'isolate', 'files1', 'test_file2.txt'),
51 ]
52 72
53 def tearDown(self): 73 def tearDown(self):
54 shutil.rmtree(self.tempdir) 74 shutil.rmtree(self.tempdir)
55 75
56 def _expected_tree(self, files): 76 def _expect_no_tree(self):
57 self.assertEquals(sorted(files), sorted(os.listdir(self.tempdir))) 77 self.assertFalse(os.path.exists(self.outdir))
58 78
59 def _expected_result(self, with_hash, files, args, read_only): 79 def _result_tree(self):
80 actual = []
81 for root, _dirs, files in os.walk(self.outdir):
82 actual.extend(os.path.join(root, f)[len(self.outdir)+1:] for f in files)
83 return sorted(actual)
84
85 def _expected_tree(self):
86 """Verifies the files written in the temporary directory."""
87 self.assertEquals(sorted(DEPENDENCIES[self.case()]), self._result_tree())
88
89 @staticmethod
90 def _fix_file_mode(filename, read_only):
60 if sys.platform == 'win32': 91 if sys.platform == 'win32':
61 mode = lambda _: 420 92 # Deterministic file mode for a deterministic OS.
93 return 420
nsylvain 2012/04/13 15:49:58 do we really need to mess with modes on windows? I
M-A Ruel 2012/04/13 15:56:16 In fact, it's not used. Let's look at removing thi
62 else: 94 else:
63 # 4 modes are supported, 0755 (rwx), 0644 (rw), 0555 (rx), 0444 (r) 95 # 4 modes are supported, 0755 (rwx), 0644 (rw), 0555 (rx), 0444 (r)
64 min_mode = 0444 96 min_mode = 0444
65 if not read_only: 97 if not read_only:
66 min_mode |= 0200 98 min_mode |= 0200
67 def mode(filename): 99 return (min_mode | 0111) if filename.endswith('.py') else min_mode
68 return (min_mode | 0111) if filename.endswith('.py') else min_mode
69 100
70 if not isinstance(files, dict): 101 def _gen_files(self, read_only):
71 # Update files to dict. 102 root_dir = ROOT_DIR
72 files = dict((unicode(f), {u'mode': mode(f)}) for f in files) 103 if RELATIVE_CWD[self.case()] == '.':
73 # Add size and timestamp. 104 #root_dir = os.path.join(root_dir, RELATIVE_CWD[self.case()])
nsylvain 2012/04/13 15:49:58 remove?
M-A Ruel 2012/04/13 15:56:16 done
74 files = files.copy() 105 root_dir = os.path.join(root_dir, 'data', 'isolate')
75 for k, v in files.iteritems(): 106
76 if v: 107 files = dict((unicode(f), {}) for f in DEPENDENCIES[self.case()])
77 filestats = os.stat(k) 108
109 if self.LEVEL > 1:
110 for k, v in files.iteritems():
111 v[u'mode'] = self._fix_file_mode(k, read_only)
112 filestats = os.stat(os.path.join(root_dir, k))
78 v[u'size'] = filestats.st_size 113 v[u'size'] = filestats.st_size
79 # Used the skip recalculating the hash. Use the most recent update 114 # Used the skip recalculating the hash. Use the most recent update
80 # time. 115 # time.
81 v[u'timestamp'] = int(round( 116 v[u'timestamp'] = int(round(filestats.st_mtime))
82 max(filestats.st_mtime, filestats.st_ctime)))
83 117
118 if self.LEVEL > 2:
119 for filename in files:
120 # Calculate our hash.
121 h = hashlib.sha1()
122 h.update(open(os.path.join(root_dir, filename), 'rb').read())
123 files[filename][u'sha-1'] = unicode(h.hexdigest())
124 return files
125
126 def _expected_result(self, args, read_only):
127 """Verifies self.result contains the expected data."""
84 expected = { 128 expected = {
85 u'files': files, 129 u'files': self._gen_files(read_only),
86 u'relative_cwd': u'data/isolate', 130 u'relative_cwd': unicode(RELATIVE_CWD[self.case()]),
87 u'read_only': None, 131 u'read_only': read_only,
88 } 132 }
89 if args: 133 if args:
90 expected[u'command'] = [u'python'] + [unicode(x) for x in args] 134 expected[u'command'] = [u'python'] + [unicode(x) for x in args]
91 else: 135 else:
92 expected[u'command'] = [] 136 expected[u'command'] = []
93 if with_hash:
94 for filename in expected[u'files']:
95 # Calculate our hash.
96 h = hashlib.sha1()
97 h.update(open(os.path.join(ROOT_DIR, filename), 'rb').read())
98 expected[u'files'][filename][u'sha-1'] = unicode(h.hexdigest())
99 137
100 actual = json.load(open(self.result, 'rb')) 138 self.assertEquals(expected, json.load(open(self.result, 'rb')))
101 self.assertEquals(expected, actual)
102 return expected 139 return expected
103 140
104 def _execute(self, filename, args, need_output=False): 141 def _expect_no_result(self):
142 self.assertFalse(os.path.exists(self.result))
143
144 def _execute_base(self, args, need_output):
145 """Executes isolate.py."""
146 # TODO(maruel): This is going away, temporary until DEPTH support is
147 # removed.
148 depth = os.path.join('data', 'isolate')
149 if RELATIVE_CWD[self.case()] != '.':
150 depth = '.'
105 cmd = [ 151 cmd = [
106 sys.executable, os.path.join(ROOT_DIR, 'isolate.py'), 152 sys.executable, os.path.join(ROOT_DIR, 'isolate.py'),
107 '--variable', 'DEPTH=%s' % ROOT_DIR,
108 '--result', self.result, 153 '--result', self.result,
109 os.path.join(ROOT_DIR, 'data', 'isolate', filename), 154 '--outdir', self.outdir,
155 '-V', 'DEPTH=%s' % depth,
110 ] + args 156 ] + args
157
111 env = os.environ.copy() 158 env = os.environ.copy()
112 if 'ISOLATE_DEBUG' in env: 159 if 'ISOLATE_DEBUG' in env:
113 del env['ISOLATE_DEBUG'] 160 del env['ISOLATE_DEBUG']
161
114 if need_output or not VERBOSE: 162 if need_output or not VERBOSE:
115 stdout = subprocess.PIPE 163 stdout = subprocess.PIPE
116 stderr = subprocess.STDOUT 164 stderr = subprocess.STDOUT
117 else: 165 else:
118 cmd.extend(['-v'] * 3) 166 cmd.extend(['-v'] * 3)
119 stdout = None 167 stdout = None
120 stderr = None 168 stderr = None
169
121 cwd = ROOT_DIR 170 cwd = ROOT_DIR
122 p = subprocess.Popen( 171 p = subprocess.Popen(
123 cmd + args, 172 cmd,
124 stdout=stdout, 173 stdout=stdout,
125 stderr=stderr, 174 stderr=stderr,
126 cwd=cwd, 175 cwd=cwd,
127 env=env, 176 env=env,
128 universal_newlines=True) 177 universal_newlines=True)
129 out = p.communicate()[0] 178 out = p.communicate()[0]
130 if p.returncode: 179 if p.returncode:
131 raise CalledProcessError(p.returncode, cmd, out, cwd) 180 raise CalledProcessError(p.returncode, cmd, out, cwd)
132 return out 181 return out
133 182
183 def mode(self):
184 """Returns the execution mode corresponding to this test case."""
185 test_id = self.id().split('.')
186 self.assertEquals(3, len(test_id))
187 self.assertEquals('__main__', test_id[0])
188 return re.match('^Isolate_([a-z]+)$', test_id[1]).group(1)
189
190 def case(self):
191 """Returns the filename corresponding to this test case."""
192 test_id = self.id().split('.')
193 return re.match('^test_([a-z_]+)$', test_id[2]).group(1)
194
195 def filename(self):
196 """Returns the filename corresponding to this test case."""
197 filename = os.path.join(
198 ROOT_DIR, 'data', 'isolate', self.case() + '.isolate')
199 self.assertTrue(os.path.isfile(filename), filename)
200 return filename
201
202 def _execute(self, args=None, need_output=False):
203 """Deduces the arguments based on the test case and function names."""
204 return self._execute_base(
205 [self.filename(), '--mode', self.mode()] + (args or []), need_output)
206
207
208 class Isolate(unittest.TestCase):
134 def test_help_modes(self): 209 def test_help_modes(self):
135 # Check coherency in the help and implemented modes. 210 # Check coherency in the help and implemented modes.
136 p = subprocess.Popen( 211 p = subprocess.Popen(
137 [sys.executable, os.path.join(ROOT_DIR, 'isolate.py'), '--help'], 212 [sys.executable, os.path.join(ROOT_DIR, 'isolate.py'), '--help'],
138 stdout=subprocess.PIPE, 213 stdout=subprocess.PIPE,
139 stderr=subprocess.STDOUT, 214 stderr=subprocess.STDOUT,
140 cwd=ROOT_DIR) 215 cwd=ROOT_DIR)
141 out = p.communicate()[0].splitlines() 216 out = p.communicate()[0].splitlines()
142 self.assertEquals(0, p.returncode) 217 self.assertEquals(0, p.returncode)
143 out = out[out.index('') + 1:] 218 out = out[out.index('') + 1:]
144 out = out[:out.index('')] 219 out = out[:out.index('')]
145 modes = [re.match(r'^ (\w+) .+', l) for l in out] 220 modes = [re.match(r'^ (\w+) .+', l) for l in out]
146 modes = tuple(m.group(1) for m in modes if m) 221 modes = tuple(m.group(1) for m in modes if m)
147 # Keep the list hard coded. 222 self.assertEquals(EXPECTED_MODES, modes)
148 expected = ('check', 'hashtable', 'remap', 'run', 'trace') 223
149 self.assertEquals(expected, modes) 224 def test_modes(self):
150 self.assertEquals(expected, modes) 225 # This is a bit redundant but make sure all combinations are tested.
151 for mode in modes: 226 files = sorted(
152 self.assertTrue(hasattr(self, 'test_%s' % mode), mode) 227 i[:-len('.isolate')]
153 self._expected_tree([]) 228 for i in os.listdir(os.path.join(ROOT_DIR, 'data', 'isolate'))
154 229 if i.endswith('.isolate')
155 def test_check(self): 230 )
156 self._execute('fail.isolate', ['--mode', 'check']) 231 self.assertEquals(sorted(RELATIVE_CWD), files)
157 self._expected_tree(['result']) 232 self.assertEquals(sorted(DEPENDENCIES), files)
158 self._expected_result( 233 for mode in EXPECTED_MODES:
159 False, dict((f, {}) for f in self.files), ['child.py', '--fail'], False) 234 expected_cases = set('test_%s' % f for f in files)
160 235 fixture_name = 'Isolate_%s' % mode
161 def test_check_no_run(self): 236 fixture = getattr(sys.modules[__name__], fixture_name)
162 self._execute('no_run.isolate', ['--mode', 'check']) 237 actual_cases = set(i for i in dir(fixture) if i.startswith('test_'))
163 self._expected_tree(['result']) 238 missing = expected_cases - actual_cases
164 self._expected_result( 239 self.assertFalse(missing, '%s.%s' % (fixture_name, missing))
165 False, dict((f, {}) for f in self.files), None, False) 240
166 241
167 def test_check_non_existent(self): 242 class Isolate_check(IsolateBase):
168 try: 243 # No meta-data
169 self._execute('non_existent.isolate', ['--mode', 'check']) 244 LEVEL = 1
nsylvain 2012/04/13 15:49:58 i dont get the LEVEL thing yet.
M-A Ruel 2012/04/13 15:56:16 Used constants instead to relate to process_inputs
170 self.fail() 245
171 except subprocess.CalledProcessError: 246 def test_fail(self):
172 pass 247 self._execute()
173 self._expected_tree([]) 248 self._expect_no_tree()
174 249 self._expected_result(['fail.py'], None)
175 def test_check_directory_no_slash(self): 250
176 try: 251 def test_missing_trailing_slash(self):
177 self._execute('missing_trailing_slash.isolate', ['--mode', 'check']) 252 try:
178 self.fail() 253 self._execute()
179 except subprocess.CalledProcessError: 254 self.fail()
180 pass 255 except subprocess.CalledProcessError:
181 self._expected_tree([]) 256 pass
nsylvain 2012/04/13 15:49:58 you expect it to go there right? Can't you make s
M-A Ruel 2012/04/13 15:56:16 See line 254, self.fail() would mark the test as f
182 257 self._expect_no_tree()
183 def test_hashtable(self): 258 self._expect_no_result()
184 cmd = [ 259
185 '--mode', 'hashtable', 260 def test_non_existent(self):
186 '--outdir', self.tempdir, 261 try:
187 ] 262 self._execute()
188 self._execute('no_run.isolate', cmd) 263 self.fail()
189 data = self._expected_result(True, self.files, None, False) 264 except subprocess.CalledProcessError:
190 self._expected_tree( 265 pass
191 [f['sha-1'] for f in data['files'].itervalues()] + ['result']) 266 self._expect_no_tree()
192 267 self._expect_no_result()
193 def test_remap(self): 268
194 cmd = [ 269 def test_no_run(self):
195 '--mode', 'remap', 270 self._execute()
196 '--outdir', self.tempdir, 271 self._expect_no_tree()
197 ] 272 self._expected_result([], None)
198 self._execute('no_run.isolate', cmd) 273
199 self._expected_tree(['data', 'result']) 274 def test_touch_root(self):
200 self._expected_result( 275 self._execute()
201 False, 276 self._expect_no_tree()
202 self.files, 277 self._expected_result(['touch_root.py'], None)
203 None, 278
204 False) 279 def test_with_flag(self):
205 280 self._execute(['-V', 'FLAG=gyp'])
206 def test_run(self): 281 self._expect_no_tree()
207 self._execute('ok.isolate', ['--mode', 'run']) 282 self._expected_result(['with_flag.py', 'gyp'], None)
208 self._expected_tree(['result']) 283
209 # cmd[0] is not generated from infiles[0] so it's not using a relative path. 284
210 self._expected_result( 285 class Isolate_hashtable(IsolateBase):
211 False, self.files, ['child.py', '--ok'], False) 286 # Full meta-data
212 287 LEVEL = 3
213 def test_run_fail(self): 288
214 try: 289 def _expected_hash_tree(self):
215 self._execute('fail.isolate', ['--mode', 'run']) 290 """Verifies the files written in the temporary directory."""
216 self.fail() 291 expected = [v['sha-1'] for v in self._gen_files(False).itervalues()]
217 except subprocess.CalledProcessError: 292 self.assertEquals(sorted(expected), self._result_tree())
218 pass 293
219 self._expected_tree(['result']) 294 def test_fail(self):
220 295 self._execute()
221 def test_trace(self): 296 self._expected_hash_tree()
222 out = self._execute('ok.isolate', ['--mode', 'trace'], True) 297 self._expected_result(['fail.py'], None)
223 self._expected_tree(['result', 'result.log']) 298
224 # The 'result.log' log is OS-specific so we can't read it but we can read 299 def test_missing_trailing_slash(self):
225 # the gyp result. 300 try:
226 # cmd[0] is not generated from infiles[0] so it's not using a relative path. 301 self._execute()
227 self._expected_result( 302 self.fail()
228 False, self.files, ['child.py', '--ok'], False) 303 except subprocess.CalledProcessError:
229 304 pass
230 expected_value = { 305 self._expect_no_tree()
306 self._expect_no_result()
307
308 def test_non_existent(self):
309 try:
310 self._execute()
311 self.fail()
312 except subprocess.CalledProcessError:
313 pass
314 self._expect_no_tree()
315 self._expect_no_result()
316
317 def test_no_run(self):
318 self._execute()
319 self._expected_hash_tree()
320 self._expected_result([], None)
321
322 def test_touch_root(self):
323 self._execute()
324 self._expected_hash_tree()
325 self._expected_result(['touch_root.py'], None)
326
327 def test_with_flag(self):
328 self._execute(['-V', 'FLAG=gyp'])
329 self._expected_hash_tree()
330 self._expected_result(['with_flag.py', 'gyp'], None)
331
332
333 class Isolate_remap(IsolateBase):
334 # Basic meta-data
335 LEVEL = 2
336
337 def test_fail(self):
338 self._execute()
339 self._expected_tree()
340 self._expected_result(['fail.py'], None)
341
342 def test_missing_trailing_slash(self):
343 try:
344 self._execute()
345 self.fail()
346 except subprocess.CalledProcessError:
347 pass
348 self._expect_no_tree()
349 self._expect_no_result()
350
351 def test_non_existent(self):
352 try:
353 self._execute()
354 self.fail()
355 except subprocess.CalledProcessError:
356 pass
357 self._expect_no_tree()
358 self._expect_no_result()
359
360 def test_no_run(self):
361 self._execute()
362 self._expected_tree()
363 self._expected_result([], None)
364
365 def test_touch_root(self):
366 self._execute()
367 self._expected_tree()
368 self._expected_result(['touch_root.py'], None)
369
370 def test_with_flag(self):
371 self._execute(['-V', 'FLAG=gyp'])
372 self._expected_tree()
373 self._expected_result(['with_flag.py', 'gyp'], None)
374
375
376 class Isolate_run(IsolateBase):
377 # Basic meta-data
378 LEVEL = 2
nsylvain 2012/04/13 15:49:58 i have a hard time understanding the difference be
M-A Ruel 2012/04/13 15:56:16 Cleaned up.
nsylvain 2012/04/14 21:56:07 Still don't get it. class Isolate_remap(IsolateBa
Marc-Antoine Ruel (Google) 2012/04/14 22:33:58 Should be much more explicit now.
379
380 def _expect_empty_tree(self):
381 self.assertEquals([], self._result_tree())
382
383 def test_fail(self):
384 try:
385 self._execute()
386 self.fail()
387 except subprocess.CalledProcessError:
388 pass
389 self._expect_empty_tree()
390 self._expected_result(['fail.py'], None)
391
392 def test_missing_trailing_slash(self):
393 try:
394 self._execute()
395 self.fail()
396 except subprocess.CalledProcessError:
397 pass
398 self._expect_no_tree()
399 self._expect_no_result()
400
401 def test_non_existent(self):
402 try:
403 self._execute()
404 self.fail()
405 except subprocess.CalledProcessError:
406 pass
407 self._expect_no_tree()
408 self._expect_no_result()
409
410 def test_no_run(self):
411 try:
412 self._execute()
413 self.fail()
414 except subprocess.CalledProcessError:
415 pass
416 self._expect_empty_tree()
417 self._expected_result([], None)
418
419 def test_touch_root(self):
420 self._execute()
421 self._expect_empty_tree()
422 self._expected_result(['touch_root.py'], None)
423
424 def test_with_flag(self):
425 self._execute(['-V', 'FLAG=run'])
426 # Not sure about the empty tree, should be deleted.
427 self._expect_empty_tree()
428 self._expected_result(['with_flag.py', 'run'], None)
429
430
431 class Isolate_trace(IsolateBase):
432 # Basic meta-data
433 LEVEL = 2
434
435 @staticmethod
436 def _to_string(values):
437 buf = cStringIO.StringIO()
438 isolate.trace_inputs.pretty_print(values, buf)
439 return buf.getvalue()
440
441 def test_fail(self):
442 try:
443 self._execute([], True)
444 self.fail()
445 except subprocess.CalledProcessError, e:
446 out = e.output
447 self._expect_no_tree()
448 self._expected_result(['fail.py'], None)
449 expected = 'Failure: 1\nFailing\n\n'
450 self.assertEquals(expected, out)
451
452 def test_missing_trailing_slash(self):
453 try:
454 self._execute([], True)
455 self.fail()
456 except subprocess.CalledProcessError, e:
457 out = e.output
458 self._expect_no_tree()
459 self._expect_no_result()
460 expected = 'Input directory %s must have a trailing slash\n' % os.path.join(
461 ROOT_DIR, 'data', 'isolate', 'files1')
462 self.assertEquals(expected, out)
463
464 def test_non_existent(self):
465 try:
466 self._execute([], True)
467 self.fail()
468 except subprocess.CalledProcessError, e:
469 out = e.output
470 self._expect_no_tree()
471 self._expect_no_result()
472 expected = 'Input file %s doesn\'t exist\n' % os.path.join(
473 ROOT_DIR, 'data', 'isolate', 'A_file_that_do_not_exist')
474 self.assertEquals(expected, out)
475
476 def test_no_run(self):
477 try:
478 self._execute([], True)
479 self.fail()
480 except subprocess.CalledProcessError, e:
481 out = e.output
482 self._expect_no_tree()
483 self._expected_result([], None)
484 expected = 'No command to run\n'
485 self.assertEquals(expected, out)
486
487 def test_touch_root(self):
488 out = self._execute([], True)
489 self._expect_no_tree()
490 self._expected_result(['touch_root.py'], None)
491 expected = {
231 'conditions': [ 492 'conditions': [
232 ['OS=="%s"' % isolate.trace_inputs.get_flavor(), { 493 ['OS=="%s"' % isolate.trace_inputs.get_flavor(), {
233 'variables': { 494 'variables': {
234 isolate.trace_inputs.KEY_TRACKED: [ 495 isolate.trace_inputs.KEY_TRACKED: [
235 'child.py', 496 'touch_root.py',
497 '../../isolate.py',
498 ],
499 },
500 }],
501 ],
502 }
503 self.assertEquals(self._to_string(expected), out)
504
505 def test_with_flag(self):
506 out = self._execute(['-V', 'FLAG=trace'], True)
507 self._expect_no_tree()
508 self._expected_result(['with_flag.py', 'trace'], None)
509 expected = {
510 'conditions': [
511 ['OS=="%s"' % isolate.trace_inputs.get_flavor(), {
512 'variables': {
513 isolate.trace_inputs.KEY_TRACKED: [
514 'with_flag.py',
236 ], 515 ],
237 isolate.trace_inputs.KEY_UNTRACKED: [ 516 isolate.trace_inputs.KEY_UNTRACKED: [
238 'files1/', 517 'files1/',
239 ], 518 ],
240 }, 519 },
241 }], 520 }],
242 ], 521 ],
243 } 522 }
244 expected_buffer = cStringIO.StringIO() 523 self.assertEquals(self._to_string(expected), out)
245 isolate.trace_inputs.pretty_print(expected_value, expected_buffer)
246 self.assertEquals(expected_buffer.getvalue(), out)
247 524
248 525
249 526
250 if __name__ == '__main__': 527 if __name__ == '__main__':
251 VERBOSE = '-v' in sys.argv 528 VERBOSE = '-v' in sys.argv
252 logging.basicConfig(level=logging.DEBUG if VERBOSE else logging.ERROR) 529 logging.basicConfig(level=logging.DEBUG if VERBOSE else logging.ERROR)
253 unittest.main() 530 unittest.main()
OLDNEW
« no previous file with comments | « tools/isolate/isolate.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698