| 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 |