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 hashlib | 7 import hashlib |
8 import json | 8 import json |
9 import logging | 9 import logging |
10 import os | 10 import os |
(...skipping 11 matching lines...) Expand all Loading... |
22 | 22 |
23 | 23 |
24 # Keep the list hard coded. | 24 # Keep the list hard coded. |
25 EXPECTED_MODES = ('check', 'hashtable', 'remap', 'run', 'trace') | 25 EXPECTED_MODES = ('check', 'hashtable', 'remap', 'run', 'trace') |
26 # These are per test case, not per mode. | 26 # These are per test case, not per mode. |
27 RELATIVE_CWD = { | 27 RELATIVE_CWD = { |
28 'fail': '.', | 28 'fail': '.', |
29 'missing_trailing_slash': '.', | 29 'missing_trailing_slash': '.', |
30 'no_run': '.', | 30 'no_run': '.', |
31 'non_existent': '.', | 31 'non_existent': '.', |
32 'touch_root': 'data/isolate', | 32 'touch_root': os.path.join('data', 'isolate'), |
33 'with_flag': '.', | 33 'with_flag': '.', |
34 } | 34 } |
35 DEPENDENCIES = { | 35 DEPENDENCIES = { |
36 'fail': ['fail.py'], | 36 'fail': ['fail.py'], |
37 'missing_trailing_slash': [], | 37 'missing_trailing_slash': [], |
38 'no_run': [ | 38 'no_run': [ |
39 'no_run.isolate', 'files1/test_file1.txt', 'files1/test_file2.txt', | 39 'no_run.isolate', |
| 40 os.path.join('files1', 'test_file1.txt'), |
| 41 os.path.join('files1', 'test_file2.txt'), |
40 ], | 42 ], |
41 'non_existent': [], | 43 'non_existent': [], |
42 'touch_root': ['data/isolate/touch_root.py', 'isolate.py'], | 44 'touch_root': [ |
| 45 os.path.join('data', 'isolate', 'touch_root.py'), |
| 46 'isolate.py', |
| 47 ], |
43 'with_flag': [ | 48 'with_flag': [ |
44 'with_flag.py', 'files1/test_file1.txt', 'files1/test_file2.txt', | 49 'with_flag.py', |
| 50 os.path.join('files1', 'test_file1.txt'), |
| 51 os.path.join('files1', 'test_file2.txt'), |
45 ], | 52 ], |
46 } | 53 } |
47 | 54 |
48 class CalledProcessError(subprocess.CalledProcessError): | 55 class CalledProcessError(subprocess.CalledProcessError): |
49 """Makes 2.6 version act like 2.7""" | 56 """Makes 2.6 version act like 2.7""" |
50 def __init__(self, returncode, cmd, output, cwd): | 57 def __init__(self, returncode, cmd, output, cwd): |
51 super(CalledProcessError, self).__init__(returncode, cmd) | 58 super(CalledProcessError, self).__init__(returncode, cmd) |
52 self.output = output | 59 self.output = output |
53 self.cwd = cwd | 60 self.cwd = cwd |
54 | 61 |
55 def __str__(self): | 62 def __str__(self): |
56 return super(CalledProcessError, self).__str__() + ( | 63 return super(CalledProcessError, self).__str__() + ( |
57 '\n' | 64 '\n' |
58 'cwd=%s\n%s') % (self.cwd, self.output) | 65 'cwd=%s\n%s') % (self.cwd, self.output) |
59 | 66 |
60 | 67 |
61 class IsolateBase(unittest.TestCase): | 68 class IsolateBase(unittest.TestCase): |
62 # To be defined by the subclass, it defines the amount of meta data saved by | 69 # 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). | 70 # isolate.py for each file. Should be one of (NO_INFO, STATS_ONLY, WITH_HASH). |
64 LEVEL = None | 71 LEVEL = None |
65 | 72 |
66 def setUp(self): | 73 def setUp(self): |
67 # The tests assume the current directory is the file's directory. | 74 # The tests assume the current directory is the file's directory. |
68 os.chdir(ROOT_DIR) | 75 os.chdir(ROOT_DIR) |
69 self.tempdir = tempfile.mkdtemp() | 76 self.tempdir = tempfile.mkdtemp() |
70 self.result = os.path.join(self.tempdir, 'isolate_smoke_test.result') | 77 self.result = os.path.join(self.tempdir, 'isolate_smoke_test.result') |
71 self.outdir = os.path.join(self.tempdir, 'isolated') | 78 self.outdir = os.path.join(self.tempdir, 'isolated') |
| 79 self.maxDiff = None |
72 | 80 |
73 def tearDown(self): | 81 def tearDown(self): |
74 shutil.rmtree(self.tempdir) | 82 shutil.rmtree(self.tempdir) |
75 | 83 |
76 def _expect_no_tree(self): | 84 def _expect_no_tree(self): |
77 self.assertFalse(os.path.exists(self.outdir)) | 85 self.assertFalse(os.path.exists(self.outdir)) |
78 | 86 |
79 def _result_tree(self): | 87 def _result_tree(self): |
80 actual = [] | 88 actual = [] |
81 for root, _dirs, files in os.walk(self.outdir): | 89 for root, _dirs, files in os.walk(self.outdir): |
82 actual.extend( | 90 actual.extend(os.path.join(root, f)[len(self.outdir)+1:] for f in files) |
83 os.path.join(root, f)[len(self.outdir)+1:].replace(os.path.sep, '/') | |
84 for f in files) | |
85 return sorted(actual) | 91 return sorted(actual) |
86 | 92 |
87 def _expected_tree(self): | 93 def _expected_tree(self): |
88 """Verifies the files written in the temporary directory.""" | 94 """Verifies the files written in the temporary directory.""" |
89 self.assertEquals(sorted(DEPENDENCIES[self.case()]), self._result_tree()) | 95 self.assertEquals(sorted(DEPENDENCIES[self.case()]), self._result_tree()) |
90 | 96 |
91 @staticmethod | 97 @staticmethod |
92 def _fix_file_mode(filename, read_only): | 98 def _fix_file_mode(filename, read_only): |
93 """4 modes are supported, 0755 (rwx), 0644 (rw), 0555 (rx), 0444 (r).""" | 99 """4 modes are supported, 0755 (rwx), 0644 (rw), 0555 (rx), 0444 (r).""" |
94 min_mode = 0444 | 100 min_mode = 0444 |
(...skipping 19 matching lines...) Expand all Loading... |
114 v[u'timestamp'] = int(round(filestats.st_mtime)) | 120 v[u'timestamp'] = int(round(filestats.st_mtime)) |
115 | 121 |
116 if self.LEVEL >= isolate.WITH_HASH: | 122 if self.LEVEL >= isolate.WITH_HASH: |
117 for filename in files: | 123 for filename in files: |
118 # Calculate our hash. | 124 # Calculate our hash. |
119 h = hashlib.sha1() | 125 h = hashlib.sha1() |
120 h.update(open(os.path.join(root_dir, filename), 'rb').read()) | 126 h.update(open(os.path.join(root_dir, filename), 'rb').read()) |
121 files[filename][u'sha-1'] = unicode(h.hexdigest()) | 127 files[filename][u'sha-1'] = unicode(h.hexdigest()) |
122 return files | 128 return files |
123 | 129 |
124 def _expected_result(self, args, read_only, extra_vars=None): | 130 def _expected_result(self, args, read_only): |
125 """Verifies self.result contains the expected data.""" | 131 """Verifies self.result contains the expected data.""" |
126 flavor = isolate.trace_inputs.get_flavor() | |
127 expected = { | 132 expected = { |
128 u'files': self._gen_files(read_only), | 133 u'files': self._gen_files(read_only), |
129 u'read_only': read_only, | 134 u'read_only': read_only, |
130 u'relative_cwd': unicode(RELATIVE_CWD[self.case()]), | 135 u'relative_cwd': unicode(RELATIVE_CWD[self.case()]), |
131 u'resultdir': os.path.dirname(self.result), | 136 } |
132 u'resultfile': self.result, | 137 if args: |
| 138 expected[u'command'] = [u'python'] + [unicode(x) for x in args] |
| 139 else: |
| 140 expected[u'command'] = [] |
| 141 self.assertEquals(expected, json.load(open(self.result, 'r'))) |
| 142 |
| 143 def _expected_saved_state(self, extra_vars): |
| 144 flavor = isolate.trace_inputs.get_flavor() |
| 145 expected = { |
| 146 u'isolate_file': unicode(self.filename()), |
133 u'variables': { | 147 u'variables': { |
134 u'EXECUTABLE_SUFFIX': '.exe' if flavor == 'win' else '', | 148 u'EXECUTABLE_SUFFIX': '.exe' if flavor == 'win' else '', |
135 u'OS': unicode(flavor), | 149 u'OS': unicode(flavor), |
136 }, | 150 }, |
137 } | 151 } |
138 expected['variables'].update(extra_vars or {}) | 152 expected['variables'].update(extra_vars or {}) |
139 if args: | 153 self.assertEquals(expected, json.load(open(self.saved_state(), 'r'))) |
140 expected[u'command'] = [u'python'] + [unicode(x) for x in args] | |
141 else: | |
142 expected[u'command'] = [] | |
143 | 154 |
144 self.assertEquals(expected, json.load(open(self.result, 'rb'))) | 155 def _expect_results(self, args, read_only, extra_vars): |
145 return expected | 156 self._expected_result(args, read_only) |
| 157 self._expected_saved_state(extra_vars) |
146 | 158 |
147 def _expect_no_result(self): | 159 def _expect_no_result(self): |
148 self.assertFalse(os.path.exists(self.result)) | 160 self.assertFalse(os.path.exists(self.result)) |
149 | 161 |
150 def _execute(self, mode, case, args, need_output): | 162 def _execute(self, mode, case, args, need_output): |
151 """Executes isolate.py.""" | 163 """Executes isolate.py.""" |
152 self.assertEquals( | 164 self.assertEquals( |
153 mode, self.mode(), 'Rename the test fixture to Isolate_%s' % mode) | 165 mode, self.mode(), 'Rename the test fixture to Isolate_%s' % mode) |
154 self.assertEquals( | 166 self.assertEquals( |
155 case, | 167 case, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 test_id = self.id().split('.') | 213 test_id = self.id().split('.') |
202 return re.match('^test_([a-z_]+)$', test_id[2]).group(1) | 214 return re.match('^test_([a-z_]+)$', test_id[2]).group(1) |
203 | 215 |
204 def filename(self): | 216 def filename(self): |
205 """Returns the filename corresponding to this test case.""" | 217 """Returns the filename corresponding to this test case.""" |
206 filename = os.path.join( | 218 filename = os.path.join( |
207 ROOT_DIR, 'data', 'isolate', self.case() + '.isolate') | 219 ROOT_DIR, 'data', 'isolate', self.case() + '.isolate') |
208 self.assertTrue(os.path.isfile(filename), filename) | 220 self.assertTrue(os.path.isfile(filename), filename) |
209 return filename | 221 return filename |
210 | 222 |
| 223 def saved_state(self): |
| 224 return isolate.result_to_state(self.result) |
| 225 |
211 | 226 |
212 class Isolate(unittest.TestCase): | 227 class Isolate(unittest.TestCase): |
213 def test_help_modes(self): | 228 def test_help_modes(self): |
214 # Check coherency in the help and implemented modes. | 229 # Check coherency in the help and implemented modes. |
215 p = subprocess.Popen( | 230 p = subprocess.Popen( |
216 [sys.executable, os.path.join(ROOT_DIR, 'isolate.py'), '--help'], | 231 [sys.executable, os.path.join(ROOT_DIR, 'isolate.py'), '--help'], |
217 stdout=subprocess.PIPE, | 232 stdout=subprocess.PIPE, |
218 stderr=subprocess.STDOUT, | 233 stderr=subprocess.STDOUT, |
219 cwd=ROOT_DIR) | 234 cwd=ROOT_DIR) |
220 out = p.communicate()[0].splitlines() | 235 out = p.communicate()[0].splitlines() |
(...skipping 22 matching lines...) Expand all Loading... |
243 missing = expected_cases - actual_cases | 258 missing = expected_cases - actual_cases |
244 self.assertFalse(missing, '%s.%s' % (fixture_name, missing)) | 259 self.assertFalse(missing, '%s.%s' % (fixture_name, missing)) |
245 | 260 |
246 | 261 |
247 class Isolate_check(IsolateBase): | 262 class Isolate_check(IsolateBase): |
248 LEVEL = isolate.NO_INFO | 263 LEVEL = isolate.NO_INFO |
249 | 264 |
250 def test_fail(self): | 265 def test_fail(self): |
251 self._execute('check', 'fail.isolate', [], False) | 266 self._execute('check', 'fail.isolate', [], False) |
252 self._expect_no_tree() | 267 self._expect_no_tree() |
253 self._expected_result(['fail.py'], None) | 268 self._expect_results(['fail.py'], None, None) |
254 | 269 |
255 def test_missing_trailing_slash(self): | 270 def test_missing_trailing_slash(self): |
256 try: | 271 try: |
257 self._execute('check', 'missing_trailing_slash.isolate', [], False) | 272 self._execute('check', 'missing_trailing_slash.isolate', [], False) |
258 self.fail() | 273 self.fail() |
259 except subprocess.CalledProcessError: | 274 except subprocess.CalledProcessError: |
260 pass | 275 pass |
261 self._expect_no_tree() | 276 self._expect_no_tree() |
262 self._expect_no_result() | 277 self._expect_no_result() |
263 | 278 |
264 def test_non_existent(self): | 279 def test_non_existent(self): |
265 try: | 280 try: |
266 self._execute('check', 'non_existent.isolate', [], False) | 281 self._execute('check', 'non_existent.isolate', [], False) |
267 self.fail() | 282 self.fail() |
268 except subprocess.CalledProcessError: | 283 except subprocess.CalledProcessError: |
269 pass | 284 pass |
270 self._expect_no_tree() | 285 self._expect_no_tree() |
271 self._expect_no_result() | 286 self._expect_no_result() |
272 | 287 |
273 def test_no_run(self): | 288 def test_no_run(self): |
274 self._execute('check', 'no_run.isolate', [], False) | 289 self._execute('check', 'no_run.isolate', [], False) |
275 self._expect_no_tree() | 290 self._expect_no_tree() |
276 self._expected_result([], None) | 291 self._expect_results([], None, None) |
277 | 292 |
278 def test_touch_root(self): | 293 def test_touch_root(self): |
279 self._execute('check', 'touch_root.isolate', [], False) | 294 self._execute('check', 'touch_root.isolate', [], False) |
280 self._expect_no_tree() | 295 self._expect_no_tree() |
281 self._expected_result(['touch_root.py'], None) | 296 self._expect_results(['touch_root.py'], None, None) |
282 | 297 |
283 def test_with_flag(self): | 298 def test_with_flag(self): |
284 self._execute('check', 'with_flag.isolate', ['-V', 'FLAG', 'gyp'], False) | 299 self._execute('check', 'with_flag.isolate', ['-V', 'FLAG', 'gyp'], False) |
285 self._expect_no_tree() | 300 self._expect_no_tree() |
286 self._expected_result(['with_flag.py', 'gyp'], None, {u'FLAG': u'gyp'}) | 301 self._expect_results( |
| 302 ['with_flag.py', 'gyp'], None, {u'FLAG': u'gyp'}) |
287 | 303 |
288 | 304 |
289 class Isolate_hashtable(IsolateBase): | 305 class Isolate_hashtable(IsolateBase): |
290 LEVEL = isolate.WITH_HASH | 306 LEVEL = isolate.WITH_HASH |
291 | 307 |
292 def _expected_hash_tree(self): | 308 def _expected_hash_tree(self): |
293 """Verifies the files written in the temporary directory.""" | 309 """Verifies the files written in the temporary directory.""" |
294 expected = [v['sha-1'] for v in self._gen_files(False).itervalues()] | 310 expected = [v['sha-1'] for v in self._gen_files(False).itervalues()] |
295 self.assertEquals(sorted(expected), self._result_tree()) | 311 self.assertEquals(sorted(expected), self._result_tree()) |
296 | 312 |
297 def test_fail(self): | 313 def test_fail(self): |
298 self._execute('hashtable', 'fail.isolate', [], False) | 314 self._execute('hashtable', 'fail.isolate', [], False) |
299 self._expected_hash_tree() | 315 self._expected_hash_tree() |
300 self._expected_result(['fail.py'], None) | 316 self._expect_results(['fail.py'], None, None) |
301 | 317 |
302 def test_missing_trailing_slash(self): | 318 def test_missing_trailing_slash(self): |
303 try: | 319 try: |
304 self._execute('hashtable', 'missing_trailing_slash.isolate', [], False) | 320 self._execute('hashtable', 'missing_trailing_slash.isolate', [], False) |
305 self.fail() | 321 self.fail() |
306 except subprocess.CalledProcessError: | 322 except subprocess.CalledProcessError: |
307 pass | 323 pass |
308 self._expect_no_tree() | 324 self._expect_no_tree() |
309 self._expect_no_result() | 325 self._expect_no_result() |
310 | 326 |
311 def test_non_existent(self): | 327 def test_non_existent(self): |
312 try: | 328 try: |
313 self._execute('hashtable', 'non_existent.isolate', [], False) | 329 self._execute('hashtable', 'non_existent.isolate', [], False) |
314 self.fail() | 330 self.fail() |
315 except subprocess.CalledProcessError: | 331 except subprocess.CalledProcessError: |
316 pass | 332 pass |
317 self._expect_no_tree() | 333 self._expect_no_tree() |
318 self._expect_no_result() | 334 self._expect_no_result() |
319 | 335 |
320 def test_no_run(self): | 336 def test_no_run(self): |
321 self._execute('hashtable', 'no_run.isolate', [], False) | 337 self._execute('hashtable', 'no_run.isolate', [], False) |
322 self._expected_hash_tree() | 338 self._expected_hash_tree() |
323 self._expected_result([], None) | 339 self._expect_results([], None, None) |
324 | 340 |
325 def test_touch_root(self): | 341 def test_touch_root(self): |
326 self._execute('hashtable', 'touch_root.isolate', [], False) | 342 self._execute('hashtable', 'touch_root.isolate', [], False) |
327 self._expected_hash_tree() | 343 self._expected_hash_tree() |
328 self._expected_result(['touch_root.py'], None) | 344 self._expect_results(['touch_root.py'], None, None) |
329 | 345 |
330 def test_with_flag(self): | 346 def test_with_flag(self): |
331 self._execute( | 347 self._execute( |
332 'hashtable', 'with_flag.isolate', ['-V', 'FLAG', 'gyp'], False) | 348 'hashtable', 'with_flag.isolate', ['-V', 'FLAG', 'gyp'], False) |
333 self._expected_hash_tree() | 349 self._expected_hash_tree() |
334 self._expected_result(['with_flag.py', 'gyp'], None, {u'FLAG': u'gyp'}) | 350 self._expect_results( |
| 351 ['with_flag.py', 'gyp'], None, {u'FLAG': u'gyp'}) |
335 | 352 |
336 | 353 |
337 class Isolate_remap(IsolateBase): | 354 class Isolate_remap(IsolateBase): |
338 LEVEL = isolate.STATS_ONLY | 355 LEVEL = isolate.STATS_ONLY |
339 | 356 |
340 def test_fail(self): | 357 def test_fail(self): |
341 self._execute('remap', 'fail.isolate', [], False) | 358 self._execute('remap', 'fail.isolate', [], False) |
342 self._expected_tree() | 359 self._expected_tree() |
343 self._expected_result(['fail.py'], None) | 360 self._expect_results(['fail.py'], None, None) |
344 | 361 |
345 def test_missing_trailing_slash(self): | 362 def test_missing_trailing_slash(self): |
346 try: | 363 try: |
347 self._execute('remap', 'missing_trailing_slash.isolate', [], False) | 364 self._execute('remap', 'missing_trailing_slash.isolate', [], False) |
348 self.fail() | 365 self.fail() |
349 except subprocess.CalledProcessError: | 366 except subprocess.CalledProcessError: |
350 pass | 367 pass |
351 self._expect_no_tree() | 368 self._expect_no_tree() |
352 self._expect_no_result() | 369 self._expect_no_result() |
353 | 370 |
354 def test_non_existent(self): | 371 def test_non_existent(self): |
355 try: | 372 try: |
356 self._execute('remap', 'non_existent.isolate', [], False) | 373 self._execute('remap', 'non_existent.isolate', [], False) |
357 self.fail() | 374 self.fail() |
358 except subprocess.CalledProcessError: | 375 except subprocess.CalledProcessError: |
359 pass | 376 pass |
360 self._expect_no_tree() | 377 self._expect_no_tree() |
361 self._expect_no_result() | 378 self._expect_no_result() |
362 | 379 |
363 def test_no_run(self): | 380 def test_no_run(self): |
364 self._execute('remap', 'no_run.isolate', [], False) | 381 self._execute('remap', 'no_run.isolate', [], False) |
365 self._expected_tree() | 382 self._expected_tree() |
366 self._expected_result([], None) | 383 self._expect_results([], None, None) |
367 | 384 |
368 def test_touch_root(self): | 385 def test_touch_root(self): |
369 self._execute('remap', 'touch_root.isolate', [], False) | 386 self._execute('remap', 'touch_root.isolate', [], False) |
370 self._expected_tree() | 387 self._expected_tree() |
371 self._expected_result(['touch_root.py'], None) | 388 self._expect_results(['touch_root.py'], None, None) |
372 | 389 |
373 def test_with_flag(self): | 390 def test_with_flag(self): |
374 self._execute('remap', 'with_flag.isolate', ['-V', 'FLAG', 'gyp'], False) | 391 self._execute('remap', 'with_flag.isolate', ['-V', 'FLAG', 'gyp'], False) |
375 self._expected_tree() | 392 self._expected_tree() |
376 self._expected_result(['with_flag.py', 'gyp'], None, {u'FLAG': u'gyp'}) | 393 self._expect_results( |
| 394 ['with_flag.py', 'gyp'], None, {u'FLAG': u'gyp'}) |
377 | 395 |
378 | 396 |
379 class Isolate_run(IsolateBase): | 397 class Isolate_run(IsolateBase): |
380 LEVEL = isolate.STATS_ONLY | 398 LEVEL = isolate.STATS_ONLY |
381 | 399 |
382 def _expect_empty_tree(self): | 400 def _expect_empty_tree(self): |
383 self.assertEquals([], self._result_tree()) | 401 self.assertEquals([], self._result_tree()) |
384 | 402 |
385 def test_fail(self): | 403 def test_fail(self): |
386 try: | 404 try: |
387 self._execute('run', 'fail.isolate', [], False) | 405 self._execute('run', 'fail.isolate', [], False) |
388 self.fail() | 406 self.fail() |
389 except subprocess.CalledProcessError: | 407 except subprocess.CalledProcessError: |
390 pass | 408 pass |
391 self._expect_empty_tree() | 409 self._expect_empty_tree() |
392 self._expected_result(['fail.py'], None) | 410 self._expect_results(['fail.py'], None, None) |
393 | 411 |
394 def test_missing_trailing_slash(self): | 412 def test_missing_trailing_slash(self): |
395 try: | 413 try: |
396 self._execute('run', 'missing_trailing_slash.isolate', [], False) | 414 self._execute('run', 'missing_trailing_slash.isolate', [], False) |
397 self.fail() | 415 self.fail() |
398 except subprocess.CalledProcessError: | 416 except subprocess.CalledProcessError: |
399 pass | 417 pass |
400 self._expect_no_tree() | 418 self._expect_no_tree() |
401 self._expect_no_result() | 419 self._expect_no_result() |
402 | 420 |
403 def test_non_existent(self): | 421 def test_non_existent(self): |
404 try: | 422 try: |
405 self._execute('run', 'non_existent.isolate', [], False) | 423 self._execute('run', 'non_existent.isolate', [], False) |
406 self.fail() | 424 self.fail() |
407 except subprocess.CalledProcessError: | 425 except subprocess.CalledProcessError: |
408 pass | 426 pass |
409 self._expect_no_tree() | 427 self._expect_no_tree() |
410 self._expect_no_result() | 428 self._expect_no_result() |
411 | 429 |
412 def test_no_run(self): | 430 def test_no_run(self): |
413 try: | 431 try: |
414 self._execute('run', 'no_run.isolate', [], False) | 432 self._execute('run', 'no_run.isolate', [], False) |
415 self.fail() | 433 self.fail() |
416 except subprocess.CalledProcessError: | 434 except subprocess.CalledProcessError: |
417 pass | 435 pass |
418 self._expect_empty_tree() | 436 self._expect_empty_tree() |
419 self._expected_result([], None) | 437 self._expect_results([], None, None) |
420 | 438 |
421 def test_touch_root(self): | 439 def test_touch_root(self): |
422 self._execute('run', 'touch_root.isolate', [], False) | 440 self._execute('run', 'touch_root.isolate', [], False) |
423 self._expect_empty_tree() | 441 self._expect_empty_tree() |
424 self._expected_result(['touch_root.py'], None) | 442 self._expect_results(['touch_root.py'], None, None) |
425 | 443 |
426 def test_with_flag(self): | 444 def test_with_flag(self): |
427 self._execute('run', 'with_flag.isolate', ['-V', 'FLAG', 'run'], False) | 445 self._execute('run', 'with_flag.isolate', ['-V', 'FLAG', 'run'], False) |
428 # Not sure about the empty tree, should be deleted. | 446 # Not sure about the empty tree, should be deleted. |
429 self._expect_empty_tree() | 447 self._expect_empty_tree() |
430 self._expected_result(['with_flag.py', 'run'], None, {u'FLAG': u'run'}) | 448 self._expect_results( |
| 449 ['with_flag.py', 'run'], None, {u'FLAG': u'run'}) |
431 | 450 |
432 | 451 |
433 class Isolate_trace(IsolateBase): | 452 class Isolate_trace(IsolateBase): |
434 LEVEL = isolate.STATS_ONLY | 453 LEVEL = isolate.STATS_ONLY |
435 | 454 |
436 @staticmethod | 455 @staticmethod |
437 def _to_string(values): | 456 def _to_string(values): |
438 buf = cStringIO.StringIO() | 457 buf = cStringIO.StringIO() |
439 isolate.trace_inputs.pretty_print(values, buf) | 458 isolate.trace_inputs.pretty_print(values, buf) |
440 return buf.getvalue() | 459 return buf.getvalue() |
441 | 460 |
442 def test_fail(self): | 461 def test_fail(self): |
443 try: | 462 try: |
444 self._execute('trace', 'fail.isolate', [], True) | 463 self._execute('trace', 'fail.isolate', [], True) |
445 self.fail() | 464 self.fail() |
446 except subprocess.CalledProcessError, e: | 465 except subprocess.CalledProcessError, e: |
447 out = e.output | 466 out = e.output |
448 self._expect_no_tree() | 467 self._expect_no_tree() |
449 self._expected_result(['fail.py'], None) | 468 self._expect_results(['fail.py'], None, None) |
450 # In theory, there should be 2 \n at the end of expected but for an | 469 # In theory, there should be 2 \n at the end of expected but for an |
451 # unknown reason there's 3 \n on Windows so just rstrip() and compare the | 470 # unknown reason there's 3 \n on Windows so just rstrip() and compare the |
452 # text, that's sufficient for this test. | 471 # text, that's sufficient for this test. |
453 expected = 'Failure: 1\nFailing' | 472 expected = 'Failure: 1\nFailing' |
454 self.assertEquals(expected, out.rstrip()) | 473 self.assertEquals(expected, out.rstrip()) |
455 | 474 |
456 def test_missing_trailing_slash(self): | 475 def test_missing_trailing_slash(self): |
457 try: | 476 try: |
458 self._execute('trace', 'missing_trailing_slash.isolate', [], True) | 477 self._execute('trace', 'missing_trailing_slash.isolate', [], True) |
459 self.fail() | 478 self.fail() |
460 except subprocess.CalledProcessError, e: | 479 except subprocess.CalledProcessError, e: |
461 out = e.output | 480 out = e.output |
462 self._expect_no_tree() | 481 self._expect_no_tree() |
463 self._expect_no_result() | 482 self._expect_no_result() |
464 expected = 'Input directory %s must have a trailing slash\n' % os.path.join( | 483 expected = ( |
465 ROOT_DIR, 'data', 'isolate', 'files1') | 484 'Usage: isolate.py [options] [.isolate file]\n\n' |
| 485 'isolate.py: error: Input directory %s must have a trailing slash\n' % |
| 486 os.path.join(ROOT_DIR, 'data', 'isolate', 'files1') |
| 487 ) |
466 self.assertEquals(expected, out) | 488 self.assertEquals(expected, out) |
467 | 489 |
468 def test_non_existent(self): | 490 def test_non_existent(self): |
469 try: | 491 try: |
470 self._execute('trace', 'non_existent.isolate', [], True) | 492 self._execute('trace', 'non_existent.isolate', [], True) |
471 self.fail() | 493 self.fail() |
472 except subprocess.CalledProcessError, e: | 494 except subprocess.CalledProcessError, e: |
473 out = e.output | 495 out = e.output |
474 self._expect_no_tree() | 496 self._expect_no_tree() |
475 self._expect_no_result() | 497 self._expect_no_result() |
476 expected = 'Input file %s doesn\'t exist\n' % os.path.join( | 498 expected = ( |
477 ROOT_DIR, 'data', 'isolate', 'A_file_that_do_not_exist') | 499 'Usage: isolate.py [options] [.isolate file]\n\n' |
| 500 'isolate.py: error: Input file %s doesn\'t exist\n' % |
| 501 os.path.join(ROOT_DIR, 'data', 'isolate', 'A_file_that_do_not_exist') |
| 502 ) |
478 self.assertEquals(expected, out) | 503 self.assertEquals(expected, out) |
479 | 504 |
480 def test_no_run(self): | 505 def test_no_run(self): |
481 try: | 506 try: |
482 self._execute('trace', 'no_run.isolate', [], True) | 507 self._execute('trace', 'no_run.isolate', [], True) |
483 self.fail() | 508 self.fail() |
484 except subprocess.CalledProcessError, e: | 509 except subprocess.CalledProcessError, e: |
485 out = e.output | 510 out = e.output |
486 self._expect_no_tree() | 511 self._expect_no_tree() |
487 self._expected_result([], None) | 512 self._expect_results([], None, None) |
488 expected = 'No command to run\n' | 513 expected = 'No command to run\n' |
489 self.assertEquals(expected, out) | 514 self.assertEquals(expected, out) |
490 | 515 |
491 def test_touch_root(self): | 516 def test_touch_root(self): |
492 out = self._execute('trace', 'touch_root.isolate', [], True) | 517 out = self._execute('trace', 'touch_root.isolate', [], True) |
493 self._expect_no_tree() | 518 self._expect_no_tree() |
494 self._expected_result(['touch_root.py'], None) | 519 self._expect_results(['touch_root.py'], None, None) |
495 expected = { | 520 expected = { |
496 'conditions': [ | 521 'conditions': [ |
497 ['OS=="%s"' % isolate.trace_inputs.get_flavor(), { | 522 ['OS=="%s"' % isolate.trace_inputs.get_flavor(), { |
498 'variables': { | 523 'variables': { |
499 isolate.trace_inputs.KEY_TRACKED: [ | 524 isolate.trace_inputs.KEY_TRACKED: [ |
500 'touch_root.py', | 525 'touch_root.py', |
501 '../../isolate.py', | 526 '../../isolate.py', |
502 ], | 527 ], |
503 }, | 528 }, |
504 }], | 529 }], |
505 ], | 530 ], |
506 } | 531 } |
507 self.assertEquals(self._to_string(expected), out) | 532 self.assertEquals(self._to_string(expected), out) |
508 | 533 |
509 def test_with_flag(self): | 534 def test_with_flag(self): |
510 out = self._execute( | 535 out = self._execute( |
511 'trace', 'with_flag.isolate', ['-V', 'FLAG', 'trace'], True) | 536 'trace', 'with_flag.isolate', ['-V', 'FLAG', 'trace'], True) |
512 self._expect_no_tree() | 537 self._expect_no_tree() |
513 self._expected_result(['with_flag.py', 'trace'], None, {u'FLAG': u'trace'}) | 538 self._expect_results(['with_flag.py', 'trace'], None, {u'FLAG': u'trace'}) |
514 expected = { | 539 expected = { |
515 'conditions': [ | 540 'conditions': [ |
516 ['OS=="%s"' % isolate.trace_inputs.get_flavor(), { | 541 ['OS=="%s"' % isolate.trace_inputs.get_flavor(), { |
517 'variables': { | 542 'variables': { |
518 isolate.trace_inputs.KEY_TRACKED: [ | 543 isolate.trace_inputs.KEY_TRACKED: [ |
519 'with_flag.py', | 544 'with_flag.py', |
520 ], | 545 ], |
521 isolate.trace_inputs.KEY_UNTRACKED: [ | 546 isolate.trace_inputs.KEY_UNTRACKED: [ |
| 547 # Note that .isolate format mandates / and not os.path.sep. |
522 'files1/', | 548 'files1/', |
523 ], | 549 ], |
524 }, | 550 }, |
525 }], | 551 }], |
526 ], | 552 ], |
527 } | 553 } |
528 self.assertEquals(self._to_string(expected), out) | 554 self.assertEquals(self._to_string(expected), out) |
529 | 555 |
530 | 556 |
531 | 557 |
532 if __name__ == '__main__': | 558 if __name__ == '__main__': |
533 VERBOSE = '-v' in sys.argv | 559 VERBOSE = '-v' in sys.argv |
534 logging.basicConfig(level=logging.DEBUG if VERBOSE else logging.ERROR) | 560 logging.basicConfig(level=logging.DEBUG if VERBOSE else logging.ERROR) |
535 unittest.main() | 561 unittest.main() |
OLD | NEW |