Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2014 The Chromium Authors. All rights reserved. | 2 # Copyright 2014 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 json | |
| 6 import os | 7 import os |
| 8 import re | |
| 7 import shutil | 9 import shutil |
| 8 import subprocess | 10 import subprocess |
| 9 import tempfile | 11 import tempfile |
| 10 import unittest | 12 import unittest |
| 11 | 13 |
| 12 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | 14 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
| 13 | 15 |
| 14 class RecipeRepo(object): | 16 class RecipeRepo(object): |
| 15 def __init__(self): | 17 def __init__(self): |
| 16 self._root = tempfile.mkdtemp() | 18 self._root = tempfile.mkdtemp() |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 38 fh.write(contents) | 40 fh.write(contents) |
| 39 | 41 |
| 40 def make_module(self, name, init_contents, api_contents): | 42 def make_module(self, name, init_contents, api_contents): |
| 41 module_root = os.path.join(self._modules_dir, name) | 43 module_root = os.path.join(self._modules_dir, name) |
| 42 os.mkdir(module_root) | 44 os.mkdir(module_root) |
| 43 with open(os.path.join(module_root, '__init__.py'), 'w') as fh: | 45 with open(os.path.join(module_root, '__init__.py'), 'w') as fh: |
| 44 fh.write(init_contents) | 46 fh.write(init_contents) |
| 45 with open(os.path.join(module_root, 'api.py'), 'w') as fh: | 47 with open(os.path.join(module_root, 'api.py'), 'w') as fh: |
| 46 fh.write(api_contents) | 48 fh.write(api_contents) |
| 47 | 49 |
| 48 @property | 50 def make_file(self, relpath, contents): |
| 49 def recipes_cmd(self): | 51 dirname = os.path.join(self._root, os.path.dirname(relpath)) |
| 50 return [ | 52 if dirname and not os.path.exists(dirname): |
| 53 os.makedirs(dirname) | |
| 54 with open(os.path.join(self._root, relpath), 'w') as fh: | |
| 55 fh.write(contents) | |
| 56 | |
| 57 def recipes_cmd(self, package_override=True): | |
| 58 cmd = [ | |
| 51 os.path.join(ROOT_DIR, 'recipes.py'), | 59 os.path.join(ROOT_DIR, 'recipes.py'), |
|
M-A Ruel
2016/01/09 00:52:00
sys.executable,
| |
| 52 '--package', self._recipes_cfg, | 60 '--package', self._recipes_cfg, |
| 53 '-O', 'recipe_engine=%s' % ROOT_DIR] | 61 ] |
| 62 if package_override: | |
| 63 cmd += ['-O', 'recipe_engine=%s' % ROOT_DIR] | |
| 64 return cmd | |
| 54 | 65 |
| 55 def __enter__(self): | 66 def __enter__(self): |
| 56 return self | 67 return self |
| 57 | 68 |
| 58 def __exit__(self, *_): | 69 def __exit__(self, *_): |
| 59 shutil.rmtree(self._root) | 70 shutil.rmtree(self._root) |
| 60 | 71 |
| 61 class ErrorsTest(unittest.TestCase): | 72 class PackageSetupTest(unittest.TestCase): |
| 62 def _test_cmd(self, repo, cmd, asserts, retcode=0): | 73 def _test_cmd(self, repo, cmd, asserts, retcode=0, package_override=True): |
| 63 subp = subprocess.Popen( | 74 subp = subprocess.Popen( |
| 64 repo.recipes_cmd + cmd, | 75 repo.recipes_cmd(package_override=package_override) + cmd, |
| 65 stdout=subprocess.PIPE, | 76 stdout=subprocess.PIPE, |
| 66 stderr=subprocess.PIPE) | 77 stderr=subprocess.PIPE) |
| 67 stdout, stderr = subp.communicate() | 78 stdout, stderr = subp.communicate() |
| 68 if asserts: | 79 if asserts: |
| 69 asserts(stdout, stderr) | 80 asserts(stdout, stderr) |
| 70 self.assertEqual(subp.returncode, retcode) | 81 self.assertEqual(subp.returncode, retcode) |
| 71 | 82 |
| 72 def test_missing_dependency(self): | 83 def test_missing_dependency(self): |
| 73 with RecipeRepo() as repo: | 84 with RecipeRepo() as repo: |
| 74 repo.make_recipe('foo', """ | 85 repo.make_recipe('foo', """ |
| 75 DEPS = ['aint_no_thang'] | 86 DEPS = ['aint_no_thang'] |
| 76 """) | 87 """) |
| 77 subp = subprocess.Popen( | 88 subp = subprocess.Popen( |
| 78 repo.recipes_cmd + ['run', 'foo'], | 89 repo.recipes_cmd() + ['run', 'foo'], |
| 79 stdout=subprocess.PIPE) | 90 stdout=subprocess.PIPE) |
| 80 stdout, _ = subp.communicate() | 91 stdout, _ = subp.communicate() |
| 81 self.assertRegexpMatches(stdout, | 92 self.assertRegexpMatches(stdout, |
| 82 r'aint_no_thang does not exist[^\n]*while loading recipe foo') | 93 r'aint_no_thang does not exist[^\n]*while loading recipe foo') |
| 83 self.assertEqual(subp.returncode, 2) | 94 self.assertEqual(subp.returncode, 2) |
| 84 | 95 |
| 85 def test_missing_module_dependency(self): | 96 def test_missing_module_dependency(self): |
| 86 with RecipeRepo() as repo: | 97 with RecipeRepo() as repo: |
| 87 repo.make_recipe('foo', 'DEPS = ["le_module"]') | 98 repo.make_recipe('foo', 'DEPS = ["le_module"]') |
| 88 repo.make_module('le_module', 'DEPS = ["love"]', '') | 99 repo.make_module('le_module', 'DEPS = ["love"]', '') |
| 89 subp = subprocess.Popen( | 100 subp = subprocess.Popen( |
| 90 repo.recipes_cmd + ['run', 'foo'], | 101 repo.recipes_cmd() + ['run', 'foo'], |
| 91 stdout=subprocess.PIPE) | 102 stdout=subprocess.PIPE) |
| 92 stdout, _ = subp.communicate() | 103 stdout, _ = subp.communicate() |
| 93 self.assertRegexpMatches(stdout, | 104 self.assertRegexpMatches(stdout, |
| 94 r'love does not exist[^\n]*' | 105 r'love does not exist[^\n]*' |
| 95 r'while loading recipe module \S*le_module[^\n]*' | 106 r'while loading recipe module \S*le_module[^\n]*' |
| 96 r'while loading recipe foo') | 107 r'while loading recipe foo') |
| 97 self.assertEqual(subp.returncode, 2) | 108 self.assertEqual(subp.returncode, 2) |
| 98 | 109 |
| 99 def test_no_such_recipe(self): | 110 def test_no_such_recipe(self): |
| 100 with RecipeRepo() as repo: | 111 with RecipeRepo() as repo: |
| 101 subp = subprocess.Popen( | 112 subp = subprocess.Popen( |
| 102 repo.recipes_cmd + ['run', 'nooope'], | 113 repo.recipes_cmd() + ['run', 'nooope'], |
| 103 stdout=subprocess.PIPE) | 114 stdout=subprocess.PIPE) |
| 104 stdout, _ = subp.communicate() | 115 stdout, _ = subp.communicate() |
| 105 self.assertRegexpMatches(stdout, r'No such recipe: nooope') | 116 self.assertRegexpMatches(stdout, r'No such recipe: nooope') |
| 106 self.assertEqual(subp.returncode, 2) | 117 self.assertEqual(subp.returncode, 2) |
| 107 | 118 |
| 108 def test_syntax_error(self): | 119 def test_syntax_error(self): |
| 109 with RecipeRepo() as repo: | 120 with RecipeRepo() as repo: |
| 110 repo.make_recipe('foo', """ | 121 repo.make_recipe('foo', """ |
| 111 DEPS = [ (sic) | 122 DEPS = [ (sic) |
| 112 """) | 123 """) |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 178 pass | 189 pass |
| 179 | 190 |
| 180 def GenTests(api): | 191 def GenTests(api): |
| 181 yield api.test('basic') + api.expect_exception('AssertionError') | 192 yield api.test('basic') + api.expect_exception('AssertionError') |
| 182 """) | 193 """) |
| 183 self._test_cmd(repo, ['simulation_test', 'train', 'unconsumed_assertion'], | 194 self._test_cmd(repo, ['simulation_test', 'train', 'unconsumed_assertion'], |
| 184 asserts=lambda stdout, stderr: self.assertRegexpMatches( | 195 asserts=lambda stdout, stderr: self.assertRegexpMatches( |
| 185 stdout + stderr, 'Unconsumed'), | 196 stdout + stderr, 'Unconsumed'), |
| 186 retcode=1) | 197 retcode=1) |
| 187 | 198 |
| 199 def test_isolate(self): | |
| 200 def check_isolate_form(stdout, stderr): | |
| 201 spec = json.loads(stdout) | |
| 202 self.assertEqual(set(spec.keys()), set(['variables'])) | |
| 203 self.assertEqual(set(spec['variables']), | |
| 204 set(['command', 'files'])) | |
| 205 files = list(spec['variables']['files']) | |
| 206 self.assertTrue(not any( i.endswith('.pyc') for i in files )) | |
| 207 | |
| 208 engine_files, nonengine_files = _partition( | |
| 209 files, lambda i: re.match(r'\.recipe_deps/recipe_engine/.*', i)) | |
| 210 self.assertTrue(engine_files) | |
| 211 | |
| 212 self.assertEqual( | |
| 213 set(nonengine_files), | |
| 214 set(['infra/config/recipes.cfg', | |
| 215 'recipes.py', | |
| 216 'recipes.extra', | |
| 217 'recipes/some_recipe.py', | |
| 218 'recipe_modules/some_module/__init__.py', | |
| 219 'recipe_modules/some_module/api.py', | |
| 220 'supporting/file.txt'])) | |
| 221 | |
| 222 self.assertEqual( | |
| 223 spec['variables']['command'], | |
| 224 ['python', '.recipe_deps/recipe_engine/recipes.py', | |
| 225 '--package', 'infra/config/recipes.cfg', | |
| 226 '--no-fetch']) | |
| 227 | |
| 228 with RecipeRepo() as repo: | |
| 229 repo.make_recipe('some_recipe', '') | |
| 230 repo.make_module('some_module', '', '') | |
| 231 repo.make_file(os.path.join('supporting', 'file.txt'), 'yay') | |
| 232 repo.make_file(os.path.join('unsupporting', 'file.txt'), 'nay') | |
| 233 repo.make_file(os.path.join('recipes.extra'), 'supporting') | |
| 234 self._test_cmd(repo, | |
| 235 ['isolate'], asserts=check_isolate_form, package_override=False) | |
| 236 | |
| 237 def _partition(items, pred): | |
| 238 return ([ item for item in items if pred(item) ], | |
| 239 [ item for item in items if not pred(item) ]) | |
| 240 | |
| 241 | |
| 188 if __name__ == '__main__': | 242 if __name__ == '__main__': |
| 189 unittest.main() | 243 unittest.main() |
| OLD | NEW |