Chromium Code Reviews| 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 hashlib | 6 import hashlib |
| 7 import json | |
| 8 import logging | |
| 7 import os | 9 import os |
| 8 import re | 10 import re |
| 9 import shutil | 11 import shutil |
| 10 import subprocess | 12 import subprocess |
| 11 import sys | 13 import sys |
| 12 import tempfile | 14 import tempfile |
| 13 import unittest | 15 import unittest |
| 14 | 16 |
| 15 ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) | 17 ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) |
| 18 VERBOSE = False | |
| 16 | 19 |
| 17 | 20 |
| 18 class Isolate(unittest.TestCase): | 21 class Isolate(unittest.TestCase): |
| 19 def setUp(self): | 22 def setUp(self): |
| 20 # The reason is that isolate_test.py --ok is run in a temporary directory | 23 # The reason is that isolate_test.py --ok is run in a temporary directory |
| 21 # without access to isolate.py | 24 # without access to isolate.py |
| 22 import isolate | 25 import isolate |
| 23 self.isolate = isolate | 26 self.isolate = isolate |
| 24 self.tempdir = tempfile.mkdtemp() | 27 self.tempdir = tempfile.mkdtemp() |
| 25 self.result = os.path.join(self.tempdir, 'result') | 28 self.result = os.path.join(self.tempdir, 'result') |
| 29 if VERBOSE: | |
| 30 print | |
|
csharp
2012/03/08 21:53:39
Why print a new line?
M-A Ruel
2012/03/08 21:56:41
Makes reading the output much easier. It's only wh
| |
| 26 | 31 |
| 27 def tearDown(self): | 32 def tearDown(self): |
| 28 shutil.rmtree(self.tempdir) | 33 shutil.rmtree(self.tempdir) |
| 29 | 34 |
| 35 def _expected_tree(self, files): | |
| 36 self.assertEquals(sorted(files), sorted(os.listdir(self.tempdir))) | |
| 37 | |
| 38 def _expected_result(self, with_hash, files, args, read_only): | |
| 39 # 4 modes are supported, 0755 (rwx), 0644 (rw), 0555 (rx), 0444 (r) | |
| 40 min_mode = 0444 | |
| 41 if not read_only: | |
| 42 min_mode |= 0200 | |
| 43 def mode(filename): | |
| 44 return (min_mode | 0111) if filename.endswith('.py') else min_mode | |
| 45 expected = { | |
| 46 u'command': | |
| 47 [unicode(sys.executable), u'isolate_test.py'] + | |
| 48 [unicode(x) for x in args], | |
| 49 u'files': dict((unicode(f), {u'mode': mode(f)}) for f in files), | |
| 50 } | |
| 51 if with_hash: | |
| 52 for filename in expected[u'files']: | |
| 53 # Calculate our hash. | |
| 54 h = hashlib.sha1() | |
| 55 h.update(open(os.path.join(ROOT_DIR, filename), 'rb').read()) | |
| 56 expected[u'files'][filename][u'sha-1'] = h.hexdigest() | |
| 57 | |
| 58 actual = json.load(open(self.result, 'rb')) | |
| 59 self.assertEquals(expected, actual) | |
| 60 return expected | |
| 61 | |
| 30 def _execute(self, args): | 62 def _execute(self, args): |
| 31 cmd = [ | 63 cmd = [ |
| 32 sys.executable, os.path.join(ROOT_DIR, 'isolate.py'), | 64 sys.executable, os.path.join(ROOT_DIR, 'isolate.py'), |
| 33 '--root', ROOT_DIR, | 65 '--root', ROOT_DIR, |
| 34 '--result', self.result, | 66 '--result', self.result, |
| 35 ] | 67 ] |
| 68 if VERBOSE: | |
| 69 cmd.extend(['-v'] * 3) | |
| 70 stdout = None | |
| 71 stderr = None | |
| 72 else: | |
| 73 stdout = subprocess.PIPE | |
| 74 stderr = subprocess.STDOUT | |
| 36 subprocess.check_call( | 75 subprocess.check_call( |
| 37 cmd + args, | 76 cmd + args, stdout=stdout, stderr=stderr, cwd=ROOT_DIR) |
| 38 stdout=subprocess.PIPE, | |
| 39 stderr=subprocess.STDOUT) | |
| 40 | 77 |
| 41 def test_help_modes(self): | 78 def test_help_modes(self): |
| 42 # Check coherency in the help and implemented modes. | 79 # Check coherency in the help and implemented modes. |
| 43 p = subprocess.Popen( | 80 p = subprocess.Popen( |
| 44 [sys.executable, os.path.join(ROOT_DIR, 'isolate.py'), '--help'], | 81 [sys.executable, os.path.join(ROOT_DIR, 'isolate.py'), '--help'], |
| 45 stdout=subprocess.PIPE, | 82 stdout=subprocess.PIPE, |
| 46 stderr=subprocess.STDOUT) | 83 stderr=subprocess.STDOUT, |
| 84 cwd=ROOT_DIR) | |
| 47 out = p.communicate()[0].splitlines() | 85 out = p.communicate()[0].splitlines() |
| 48 self.assertEquals(0, p.returncode) | 86 self.assertEquals(0, p.returncode) |
| 49 out = out[out.index('') + 1:] | 87 out = out[out.index('') + 1:] |
| 50 out = out[:out.index('')] | 88 out = out[:out.index('')] |
| 51 modes = [re.match(r'^ (\w+) .+', l) for l in out] | 89 modes = [re.match(r'^ (\w+) .+', l) for l in out] |
| 52 modes = tuple(m.group(1) for m in modes if m) | 90 modes = tuple(m.group(1) for m in modes if m) |
| 53 self.assertEquals(self.isolate.VALID_MODES, modes) | 91 self.assertEquals(self.isolate.VALID_MODES, modes) |
| 54 for mode in modes: | 92 for mode in modes: |
| 55 self.assertTrue(hasattr(self, 'test_%s' % mode), mode) | 93 self.assertTrue(hasattr(self, 'test_%s' % mode), mode) |
| 94 self._expected_tree([]) | |
| 56 | 95 |
| 57 def test_check(self): | 96 def test_check(self): |
| 58 cmd = [ | 97 cmd = [ |
| 59 '--mode', 'check', | 98 '--mode', 'check', |
| 60 'isolate_test.py', | 99 'isolate_test.py', |
| 61 ] | 100 ] |
| 62 self._execute(cmd) | 101 self._execute(cmd) |
| 63 self.assertTrue(os.path.isfile(self.result)) | 102 self._expected_tree(['result']) |
| 103 self._expected_result(False, ['isolate_test.py'], [], False) | |
| 64 | 104 |
| 65 def test_check_non_existant(self): | 105 def test_check_non_existant(self): |
| 66 cmd = [ | 106 cmd = [ |
| 67 '--mode', 'check', | 107 '--mode', 'check', |
| 68 'NonExistentFile', | 108 'NonExistentFile', |
| 69 ] | 109 ] |
| 70 try: | 110 try: |
| 71 self._execute(cmd) | 111 self._execute(cmd) |
| 72 self.fail() | 112 self.fail() |
| 73 except subprocess.CalledProcessError: | 113 except subprocess.CalledProcessError: |
| 74 pass | 114 pass |
| 75 self.assertFalse(os.path.isfile(self.result)) | 115 self._expected_tree([]) |
| 116 | |
| 117 def test_check_directory_no_slash(self): | |
| 118 cmd = [ | |
| 119 '--mode', 'check', | |
| 120 # Trailing slash missing. | |
| 121 'data', | |
| 122 ] | |
| 123 try: | |
| 124 self._execute(cmd) | |
| 125 self.fail() | |
| 126 except subprocess.CalledProcessError: | |
| 127 pass | |
| 128 self._expected_tree([]) | |
| 76 | 129 |
| 77 def test_hashtable(self): | 130 def test_hashtable(self): |
| 78 cmd = [ | 131 cmd = [ |
| 79 '--mode', 'hashtable', | 132 '--mode', 'hashtable', |
| 80 '--outdir', self.tempdir, | 133 '--outdir', self.tempdir, |
| 81 'isolate_test.py', | 134 'isolate_test.py', |
| 135 'data/', | |
| 82 ] | 136 ] |
| 83 self._execute(cmd) | 137 self._execute(cmd) |
| 84 # Calculate our hash. | 138 files = ['isolate_test.py', 'data/test_file1.txt', 'data/test_file2.txt'] |
| 85 h = hashlib.sha1() | 139 data = self._expected_result(True, files, [], False) |
| 86 h.update(open(__file__, 'rb').read()) | 140 self._expected_tree( |
| 87 digest = h.hexdigest() | 141 [f['sha-1'] for f in data['files'].itervalues()] + ['result']) |
| 88 self.assertEquals( | |
| 89 '{"files": {"isolate_test.py": {"sha1": "%s"}}}' % digest, | |
| 90 open(self.result, 'rb').read()) | |
| 91 self.assertEquals( | |
| 92 sorted([digest, 'result']), sorted(os.listdir(self.tempdir))) | |
| 93 | 142 |
| 94 def test_remap(self): | 143 def test_remap(self): |
| 95 cmd = [ | 144 cmd = [ |
| 96 '--mode', 'remap', | 145 '--mode', 'remap', |
| 97 '--outdir', self.tempdir, | 146 '--outdir', self.tempdir, |
| 98 'isolate_test.py', | 147 'isolate_test.py', |
| 99 ] | 148 ] |
| 100 self._execute(cmd) | 149 self._execute(cmd) |
| 101 self.assertEquals('isolate_test.py\n', open(self.result, 'rb').read()) | 150 self._expected_tree(['isolate_test.py', 'result']) |
| 102 self.assertEquals( | 151 self._expected_result(False, ['isolate_test.py'], [], False) |
| 103 ['isolate_test.py', 'result'], sorted(os.listdir(self.tempdir))) | |
| 104 | 152 |
| 105 def test_run(self): | 153 def test_run(self): |
| 106 cmd = [ | 154 cmd = [ |
| 107 '--mode', 'run', | 155 '--mode', 'run', |
| 108 'isolate_test.py', | 156 'isolate_test.py', |
| 109 '--', | 157 '--', |
| 110 sys.executable, 'isolate_test.py', '--ok', | 158 sys.executable, 'isolate_test.py', '--ok', |
| 111 ] | 159 ] |
| 112 self._execute(cmd) | 160 self._execute(cmd) |
| 113 self.assertTrue(os.path.isfile(self.result)) | 161 self._expected_tree(['result']) |
| 162 self._expected_result(False, ['isolate_test.py'], ['--ok'], False) | |
| 114 | 163 |
| 115 def test_run_fail(self): | 164 def test_run_fail(self): |
| 116 cmd = [ | 165 cmd = [ |
| 117 '--mode', 'run', | 166 '--mode', 'run', |
| 118 'isolate_test.py', | 167 'isolate_test.py', |
| 119 '--', | 168 '--', |
| 120 sys.executable, 'isolate_test.py', '--fail', | 169 sys.executable, 'isolate_test.py', '--fail', |
| 121 ] | 170 ] |
| 122 try: | 171 try: |
| 123 self._execute(cmd) | 172 self._execute(cmd) |
| 124 self.fail() | 173 self.fail() |
| 125 except subprocess.CalledProcessError: | 174 except subprocess.CalledProcessError: |
| 126 pass | 175 pass |
| 127 self.assertFalse(os.path.isfile(self.result)) | 176 self._expected_tree([]) |
| 128 | 177 |
| 129 | 178 |
| 130 def main(): | 179 def main(): |
| 180 global VERBOSE | |
| 181 VERBOSE = '-v' in sys.argv | |
| 182 level = logging.DEBUG if VERBOSE else logging.ERROR | |
| 183 logging.basicConfig(level=level) | |
| 131 if len(sys.argv) == 1: | 184 if len(sys.argv) == 1: |
| 132 unittest.main() | 185 unittest.main() |
| 133 if sys.argv[1] == '--ok': | 186 if sys.argv[1] == '--ok': |
| 134 return 0 | 187 return 0 |
| 135 if sys.argv[1] == '--fail': | 188 if sys.argv[1] == '--fail': |
| 136 return 1 | 189 return 1 |
| 137 | 190 |
| 138 unittest.main() | 191 unittest.main() |
| 139 | 192 |
| 140 | 193 |
| 141 if __name__ == '__main__': | 194 if __name__ == '__main__': |
| 142 sys.exit(main()) | 195 sys.exit(main()) |
| OLD | NEW |