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

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: _execute() is now less ambiguous, still with test case name verification 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. Should be one of (NO_INFO, STATS_ONLY, WITH_HASH).
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
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, 'data', 'isolate')
74 files = files.copy() 105
75 for k, v in files.iteritems(): 106 files = dict((unicode(f), {}) for f in DEPENDENCIES[self.case()])
76 if v: 107
77 filestats = os.stat(k) 108 if self.LEVEL >= isolate.STATS_ONLY:
109 for k, v in files.iteritems():
110 v[u'mode'] = self._fix_file_mode(k, read_only)
111 filestats = os.stat(os.path.join(root_dir, k))
78 v[u'size'] = filestats.st_size 112 v[u'size'] = filestats.st_size
79 # Used the skip recalculating the hash. Use the most recent update 113 # Used the skip recalculating the hash. Use the most recent update
80 # time. 114 # time.
81 v[u'timestamp'] = int(round( 115 v[u'timestamp'] = int(round(filestats.st_mtime))
82 max(filestats.st_mtime, filestats.st_ctime)))
83 116
117 if self.LEVEL >= isolate.WITH_HASH:
118 for filename in files:
119 # Calculate our hash.
120 h = hashlib.sha1()
121 h.update(open(os.path.join(root_dir, filename), 'rb').read())
122 files[filename][u'sha-1'] = unicode(h.hexdigest())
123 return files
124
125 def _expected_result(self, args, read_only):
126 """Verifies self.result contains the expected data."""
84 expected = { 127 expected = {
85 u'files': files, 128 u'files': self._gen_files(read_only),
86 u'relative_cwd': u'data/isolate', 129 u'relative_cwd': unicode(RELATIVE_CWD[self.case()]),
87 u'read_only': None, 130 u'read_only': read_only,
88 } 131 }
89 if args: 132 if args:
90 expected[u'command'] = [u'python'] + [unicode(x) for x in args] 133 expected[u'command'] = [u'python'] + [unicode(x) for x in args]
91 else: 134 else:
92 expected[u'command'] = [] 135 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 136
100 actual = json.load(open(self.result, 'rb')) 137 self.assertEquals(expected, json.load(open(self.result, 'rb')))
101 self.assertEquals(expected, actual)
102 return expected 138 return expected
103 139
104 def _execute(self, filename, args, need_output=False): 140 def _expect_no_result(self):
141 self.assertFalse(os.path.exists(self.result))
142
143 def _execute(self, mode, case, args, need_output):
144 """Executes isolate.py."""
145 self.assertEquals(
146 mode, self.mode(), 'Rename the test fixture to Isolate_%s' % mode)
147 self.assertEquals(
148 case,
149 self.case() + '.isolate',
150 'Rename the test case to test_%s()' % case)
151 # TODO(maruel): This is going away, temporary until DEPTH support is
152 # removed.
153 depth = os.path.join('data', 'isolate')
154 if RELATIVE_CWD[self.case()] != '.':
155 depth = '.'
105 cmd = [ 156 cmd = [
106 sys.executable, os.path.join(ROOT_DIR, 'isolate.py'), 157 sys.executable, os.path.join(ROOT_DIR, 'isolate.py'),
107 '--variable', 'DEPTH=%s' % ROOT_DIR,
108 '--result', self.result, 158 '--result', self.result,
109 os.path.join(ROOT_DIR, 'data', 'isolate', filename), 159 '--outdir', self.outdir,
110 ] + args 160 '-V', 'DEPTH=%s' % depth,
161 self.filename(),
162 '--mode', self.mode(),
163 ]
164 cmd.extend(args)
165
111 env = os.environ.copy() 166 env = os.environ.copy()
112 if 'ISOLATE_DEBUG' in env: 167 if 'ISOLATE_DEBUG' in env:
113 del env['ISOLATE_DEBUG'] 168 del env['ISOLATE_DEBUG']
169
114 if need_output or not VERBOSE: 170 if need_output or not VERBOSE:
115 stdout = subprocess.PIPE 171 stdout = subprocess.PIPE
116 stderr = subprocess.STDOUT 172 stderr = subprocess.STDOUT
117 else: 173 else:
118 cmd.extend(['-v'] * 3) 174 cmd.extend(['-v'] * 3)
119 stdout = None 175 stdout = None
120 stderr = None 176 stderr = None
177
121 cwd = ROOT_DIR 178 cwd = ROOT_DIR
122 p = subprocess.Popen( 179 p = subprocess.Popen(
123 cmd + args, 180 cmd,
124 stdout=stdout, 181 stdout=stdout,
125 stderr=stderr, 182 stderr=stderr,
126 cwd=cwd, 183 cwd=cwd,
127 env=env, 184 env=env,
128 universal_newlines=True) 185 universal_newlines=True)
129 out = p.communicate()[0] 186 out = p.communicate()[0]
130 if p.returncode: 187 if p.returncode:
131 raise CalledProcessError(p.returncode, cmd, out, cwd) 188 raise CalledProcessError(p.returncode, cmd, out, cwd)
132 return out 189 return out
133 190
191 def mode(self):
192 """Returns the execution mode corresponding to this test case."""
193 test_id = self.id().split('.')
194 self.assertEquals(3, len(test_id))
195 self.assertEquals('__main__', test_id[0])
196 return re.match('^Isolate_([a-z]+)$', test_id[1]).group(1)
197
198 def case(self):
199 """Returns the filename corresponding to this test case."""
200 test_id = self.id().split('.')
201 return re.match('^test_([a-z_]+)$', test_id[2]).group(1)
202
203 def filename(self):
204 """Returns the filename corresponding to this test case."""
205 filename = os.path.join(
206 ROOT_DIR, 'data', 'isolate', self.case() + '.isolate')
207 self.assertTrue(os.path.isfile(filename), filename)
208 return filename
209
210
211 class Isolate(unittest.TestCase):
134 def test_help_modes(self): 212 def test_help_modes(self):
135 # Check coherency in the help and implemented modes. 213 # Check coherency in the help and implemented modes.
136 p = subprocess.Popen( 214 p = subprocess.Popen(
137 [sys.executable, os.path.join(ROOT_DIR, 'isolate.py'), '--help'], 215 [sys.executable, os.path.join(ROOT_DIR, 'isolate.py'), '--help'],
138 stdout=subprocess.PIPE, 216 stdout=subprocess.PIPE,
139 stderr=subprocess.STDOUT, 217 stderr=subprocess.STDOUT,
140 cwd=ROOT_DIR) 218 cwd=ROOT_DIR)
141 out = p.communicate()[0].splitlines() 219 out = p.communicate()[0].splitlines()
142 self.assertEquals(0, p.returncode) 220 self.assertEquals(0, p.returncode)
143 out = out[out.index('') + 1:] 221 out = out[out.index('') + 1:]
144 out = out[:out.index('')] 222 out = out[:out.index('')]
145 modes = [re.match(r'^ (\w+) .+', l) for l in out] 223 modes = [re.match(r'^ (\w+) .+', l) for l in out]
146 modes = tuple(m.group(1) for m in modes if m) 224 modes = tuple(m.group(1) for m in modes if m)
147 # Keep the list hard coded. 225 self.assertEquals(EXPECTED_MODES, modes)
148 expected = ('check', 'hashtable', 'remap', 'run', 'trace') 226
149 self.assertEquals(expected, modes) 227 def test_modes(self):
150 self.assertEquals(expected, modes) 228 # This is a bit redundant but make sure all combinations are tested.
151 for mode in modes: 229 files = sorted(
152 self.assertTrue(hasattr(self, 'test_%s' % mode), mode) 230 i[:-len('.isolate')]
153 self._expected_tree([]) 231 for i in os.listdir(os.path.join(ROOT_DIR, 'data', 'isolate'))
154 232 if i.endswith('.isolate')
155 def test_check(self): 233 )
156 self._execute('fail.isolate', ['--mode', 'check']) 234 self.assertEquals(sorted(RELATIVE_CWD), files)
157 self._expected_tree(['result']) 235 self.assertEquals(sorted(DEPENDENCIES), files)
158 self._expected_result( 236 for mode in EXPECTED_MODES:
159 False, dict((f, {}) for f in self.files), ['child.py', '--fail'], False) 237 expected_cases = set('test_%s' % f for f in files)
160 238 fixture_name = 'Isolate_%s' % mode
161 def test_check_no_run(self): 239 fixture = getattr(sys.modules[__name__], fixture_name)
162 self._execute('no_run.isolate', ['--mode', 'check']) 240 actual_cases = set(i for i in dir(fixture) if i.startswith('test_'))
163 self._expected_tree(['result']) 241 missing = expected_cases - actual_cases
164 self._expected_result( 242 self.assertFalse(missing, '%s.%s' % (fixture_name, missing))
165 False, dict((f, {}) for f in self.files), None, False) 243
166 244
167 def test_check_non_existent(self): 245 class Isolate_check(IsolateBase):
168 try: 246 LEVEL = isolate.NO_INFO
169 self._execute('non_existent.isolate', ['--mode', 'check']) 247
170 self.fail() 248 def test_fail(self):
171 except subprocess.CalledProcessError: 249 self._execute('check', 'fail.isolate', [], False)
172 pass 250 self._expect_no_tree()
173 self._expected_tree([]) 251 self._expected_result(['fail.py'], None)
174 252
175 def test_check_directory_no_slash(self): 253 def test_missing_trailing_slash(self):
176 try: 254 try:
177 self._execute('missing_trailing_slash.isolate', ['--mode', 'check']) 255 self._execute('check', 'missing_trailing_slash.isolate', [], False)
178 self.fail() 256 self.fail()
179 except subprocess.CalledProcessError: 257 except subprocess.CalledProcessError:
180 pass 258 pass
181 self._expected_tree([]) 259 self._expect_no_tree()
182 260 self._expect_no_result()
183 def test_hashtable(self): 261
184 cmd = [ 262 def test_non_existent(self):
185 '--mode', 'hashtable', 263 try:
186 '--outdir', self.tempdir, 264 self._execute('check', 'non_existent.isolate', [], False)
187 ] 265 self.fail()
188 self._execute('no_run.isolate', cmd) 266 except subprocess.CalledProcessError:
189 data = self._expected_result(True, self.files, None, False) 267 pass
190 self._expected_tree( 268 self._expect_no_tree()
191 [f['sha-1'] for f in data['files'].itervalues()] + ['result']) 269 self._expect_no_result()
192 270
193 def test_remap(self): 271 def test_no_run(self):
194 cmd = [ 272 self._execute('check', 'no_run.isolate', [], False)
195 '--mode', 'remap', 273 self._expect_no_tree()
196 '--outdir', self.tempdir, 274 self._expected_result([], None)
197 ] 275
198 self._execute('no_run.isolate', cmd) 276 def test_touch_root(self):
199 self._expected_tree(['data', 'result']) 277 self._execute('check', 'touch_root.isolate', [], False)
200 self._expected_result( 278 self._expect_no_tree()
201 False, 279 self._expected_result(['touch_root.py'], None)
202 self.files, 280
203 None, 281 def test_with_flag(self):
204 False) 282 self._execute('check', 'with_flag.isolate', ['-V', 'FLAG=gyp'], False)
205 283 self._expect_no_tree()
206 def test_run(self): 284 self._expected_result(['with_flag.py', 'gyp'], None)
207 self._execute('ok.isolate', ['--mode', 'run']) 285
208 self._expected_tree(['result']) 286
209 # cmd[0] is not generated from infiles[0] so it's not using a relative path. 287 class Isolate_hashtable(IsolateBase):
210 self._expected_result( 288 LEVEL = isolate.WITH_HASH
211 False, self.files, ['child.py', '--ok'], False) 289
212 290 def _expected_hash_tree(self):
213 def test_run_fail(self): 291 """Verifies the files written in the temporary directory."""
214 try: 292 expected = [v['sha-1'] for v in self._gen_files(False).itervalues()]
215 self._execute('fail.isolate', ['--mode', 'run']) 293 self.assertEquals(sorted(expected), self._result_tree())
216 self.fail() 294
217 except subprocess.CalledProcessError: 295 def test_fail(self):
218 pass 296 self._execute('hashtable', 'fail.isolate', [], False)
219 self._expected_tree(['result']) 297 self._expected_hash_tree()
220 298 self._expected_result(['fail.py'], None)
221 def test_trace(self): 299
222 out = self._execute('ok.isolate', ['--mode', 'trace'], True) 300 def test_missing_trailing_slash(self):
223 self._expected_tree(['result', 'result.log']) 301 try:
224 # The 'result.log' log is OS-specific so we can't read it but we can read 302 self._execute('hashtable', 'missing_trailing_slash.isolate', [], False)
225 # the gyp result. 303 self.fail()
226 # cmd[0] is not generated from infiles[0] so it's not using a relative path. 304 except subprocess.CalledProcessError:
227 self._expected_result( 305 pass
228 False, self.files, ['child.py', '--ok'], False) 306 self._expect_no_tree()
229 307 self._expect_no_result()
230 expected_value = { 308
309 def test_non_existent(self):
310 try:
311 self._execute('hashtable', 'non_existent.isolate', [], False)
312 self.fail()
313 except subprocess.CalledProcessError:
314 pass
315 self._expect_no_tree()
316 self._expect_no_result()
317
318 def test_no_run(self):
319 self._execute('hashtable', 'no_run.isolate', [], False)
320 self._expected_hash_tree()
321 self._expected_result([], None)
322
323 def test_touch_root(self):
324 self._execute('hashtable', 'touch_root.isolate', [], False)
325 self._expected_hash_tree()
326 self._expected_result(['touch_root.py'], None)
327
328 def test_with_flag(self):
329 self._execute('hashtable', 'with_flag.isolate', ['-V', 'FLAG=gyp'], False)
330 self._expected_hash_tree()
331 self._expected_result(['with_flag.py', 'gyp'], None)
332
333
334 class Isolate_remap(IsolateBase):
335 LEVEL = isolate.STATS_ONLY
336
337 def test_fail(self):
338 self._execute('remap', 'fail.isolate', [], False)
339 self._expected_tree()
340 self._expected_result(['fail.py'], None)
341
342 def test_missing_trailing_slash(self):
343 try:
344 self._execute('remap', 'missing_trailing_slash.isolate', [], False)
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('remap', 'non_existent.isolate', [], False)
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('remap', 'no_run.isolate', [], False)
362 self._expected_tree()
363 self._expected_result([], None)
364
365 def test_touch_root(self):
366 self._execute('remap', 'touch_root.isolate', [], False)
367 self._expected_tree()
368 self._expected_result(['touch_root.py'], None)
369
370 def test_with_flag(self):
371 self._execute('remap', 'with_flag.isolate', ['-V', 'FLAG=gyp'], False)
372 self._expected_tree()
373 self._expected_result(['with_flag.py', 'gyp'], None)
374
375
376 class Isolate_run(IsolateBase):
377 LEVEL = isolate.STATS_ONLY
378
379 def _expect_empty_tree(self):
380 self.assertEquals([], self._result_tree())
381
382 def test_fail(self):
383 try:
384 self._execute('run', 'fail.isolate', [], False)
385 self.fail()
386 except subprocess.CalledProcessError:
387 pass
388 self._expect_empty_tree()
389 self._expected_result(['fail.py'], None)
390
391 def test_missing_trailing_slash(self):
392 try:
393 self._execute('run', 'missing_trailing_slash.isolate', [], False)
394 self.fail()
395 except subprocess.CalledProcessError:
396 pass
397 self._expect_no_tree()
398 self._expect_no_result()
399
400 def test_non_existent(self):
401 try:
402 self._execute('run', 'non_existent.isolate', [], False)
403 self.fail()
404 except subprocess.CalledProcessError:
405 pass
406 self._expect_no_tree()
407 self._expect_no_result()
408
409 def test_no_run(self):
410 try:
411 self._execute('run', 'no_run.isolate', [], False)
412 self.fail()
413 except subprocess.CalledProcessError:
414 pass
415 self._expect_empty_tree()
416 self._expected_result([], None)
417
418 def test_touch_root(self):
419 self._execute('run', 'touch_root.isolate', [], False)
420 self._expect_empty_tree()
421 self._expected_result(['touch_root.py'], None)
422
423 def test_with_flag(self):
424 self._execute('run', 'with_flag.isolate', ['-V', 'FLAG=run'], False)
425 # Not sure about the empty tree, should be deleted.
426 self._expect_empty_tree()
427 self._expected_result(['with_flag.py', 'run'], None)
428
429
430 class Isolate_trace(IsolateBase):
431 LEVEL = isolate.STATS_ONLY
432
433 @staticmethod
434 def _to_string(values):
435 buf = cStringIO.StringIO()
436 isolate.trace_inputs.pretty_print(values, buf)
437 return buf.getvalue()
438
439 def test_fail(self):
440 try:
441 self._execute('trace', 'fail.isolate', [], True)
442 self.fail()
443 except subprocess.CalledProcessError, e:
444 out = e.output
445 self._expect_no_tree()
446 self._expected_result(['fail.py'], None)
447 expected = 'Failure: 1\nFailing\n\n'
448 self.assertEquals(expected, out)
449
450 def test_missing_trailing_slash(self):
451 try:
452 self._execute('trace', 'missing_trailing_slash.isolate', [], True)
453 self.fail()
454 except subprocess.CalledProcessError, e:
455 out = e.output
456 self._expect_no_tree()
457 self._expect_no_result()
458 expected = 'Input directory %s must have a trailing slash\n' % os.path.join(
459 ROOT_DIR, 'data', 'isolate', 'files1')
460 self.assertEquals(expected, out)
461
462 def test_non_existent(self):
463 try:
464 self._execute('trace', 'non_existent.isolate', [], True)
465 self.fail()
466 except subprocess.CalledProcessError, e:
467 out = e.output
468 self._expect_no_tree()
469 self._expect_no_result()
470 expected = 'Input file %s doesn\'t exist\n' % os.path.join(
471 ROOT_DIR, 'data', 'isolate', 'A_file_that_do_not_exist')
472 self.assertEquals(expected, out)
473
474 def test_no_run(self):
475 try:
476 self._execute('trace', 'no_run.isolate', [], True)
477 self.fail()
478 except subprocess.CalledProcessError, e:
479 out = e.output
480 self._expect_no_tree()
481 self._expected_result([], None)
482 expected = 'No command to run\n'
483 self.assertEquals(expected, out)
484
485 def test_touch_root(self):
486 out = self._execute('trace', 'touch_root.isolate', [], True)
487 self._expect_no_tree()
488 self._expected_result(['touch_root.py'], None)
489 expected = {
231 'conditions': [ 490 'conditions': [
232 ['OS=="%s"' % isolate.trace_inputs.get_flavor(), { 491 ['OS=="%s"' % isolate.trace_inputs.get_flavor(), {
233 'variables': { 492 'variables': {
234 isolate.trace_inputs.KEY_TRACKED: [ 493 isolate.trace_inputs.KEY_TRACKED: [
235 'child.py', 494 'touch_root.py',
495 '../../isolate.py',
496 ],
497 },
498 }],
499 ],
500 }
501 self.assertEquals(self._to_string(expected), out)
502
503 def test_with_flag(self):
504 out = self._execute(
505 'trace', 'with_flag.isolate', ['-V', 'FLAG=trace'], True)
506 self._expect_no_tree()
507 self._expected_result(['with_flag.py', 'trace'], None)
508 expected = {
509 'conditions': [
510 ['OS=="%s"' % isolate.trace_inputs.get_flavor(), {
511 'variables': {
512 isolate.trace_inputs.KEY_TRACKED: [
513 'with_flag.py',
236 ], 514 ],
237 isolate.trace_inputs.KEY_UNTRACKED: [ 515 isolate.trace_inputs.KEY_UNTRACKED: [
238 'files1/', 516 'files1/',
239 ], 517 ],
240 }, 518 },
241 }], 519 }],
242 ], 520 ],
243 } 521 }
244 expected_buffer = cStringIO.StringIO() 522 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 523
248 524
249 525
250 if __name__ == '__main__': 526 if __name__ == '__main__':
251 VERBOSE = '-v' in sys.argv 527 VERBOSE = '-v' in sys.argv
252 logging.basicConfig(level=logging.DEBUG if VERBOSE else logging.ERROR) 528 logging.basicConfig(level=logging.DEBUG if VERBOSE else logging.ERROR)
253 unittest.main() 529 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