Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2015 The Chromium Authors. All rights reserved. | 2 # Copyright 2015 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 """Tests that recipes are on their best behavior. | 6 """Tests that recipes are on their best behavior. |
| 7 | 7 |
| 8 Checks that recipes only import modules from a whitelist. Imports are | 8 Checks that recipes only import modules from a whitelist. Imports are |
| 9 generally not safe in recipes if they depend on the platform, since | 9 generally not safe in recipes if they depend on the platform, since |
| 10 e.g. you can run a recipe simulation for a Windows recipe on Linux. | 10 e.g. you can run a recipe simulation for a Windows recipe on Linux. |
| 11 """ | 11 """ |
| 12 | 12 |
| 13 import re | 13 import re |
| 14 import os | |
| 15 import sys | |
| 14 import types | 16 import types |
| 15 | 17 |
| 16 import test_env # pylint: disable=W0611,W0403 | 18 from . import recipe_loader |
| 17 | |
| 18 from slave import recipe_loader | |
| 19 | 19 |
| 20 | 20 |
| 21 MODULES_WHITELIST = map(re.compile, [ | 21 MODULES_WHITELIST = [ |
| 22 r'base64', | 22 r'base64', |
| 23 r'collections', | 23 r'collections', |
| 24 r'datetime', | 24 r'datetime', |
| 25 r'json', | 25 r'json', |
| 26 r'math', | 26 r'math', |
| 27 r're', | 27 r're', |
| 28 r'urlparse', | 28 r'urlparse', |
| 29 | 29 |
| 30 r'slave\.recipe_api', | 30 r'slave\.recipe_api', |
| 31 | 31 |
| 32 # TODO(luqui): Move skia modules into recipe resources | 32 # TODO(luqui): Move skia modules into recipe resources |
| 33 r'common\.skia\..*', | 33 r'common\.skia\..*', |
| 34 r'slave\.skia\..*', | 34 r'slave\.skia\..*', |
| 35 | 35 |
| 36 # TODO(luqui): Move cros modules into recipe resources | 36 # TODO(luqui): Move cros modules into recipe resources |
| 37 r'common\.cros_chromite', | 37 r'common\.cros_chromite', |
|
iannucci
2015/05/27 02:03:27
added more modules and they got rebased away or so
luqui
2015/05/28 21:47:38
Done.
| |
| 38 ]) | 38 ] |
| 39 | 39 |
| 40 | 40 |
| 41 class ImportViolationError(Exception): | 41 class ImportViolationError(Exception): |
| 42 pass | 42 pass |
| 43 | 43 |
| 44 | 44 |
| 45 class TestFailure(Exception): | 45 class TestFailure(Exception): |
| 46 pass | 46 pass |
| 47 | 47 |
| 48 | 48 |
| 49 def ImportsTest(recipe_path, recipe_name, universe): | 49 def ImportsTest(recipe_path, recipe_name, whitelist, universe): |
| 50 """Tests that recipe_name only uses allowed imports. | 50 """Tests that recipe_name only uses allowed imports. |
| 51 | 51 |
| 52 Returns a list of errors, or an empty list if there are no errors (duh). | 52 Returns a list of errors, or an empty list if there are no errors (duh). |
| 53 """ | 53 """ |
| 54 | 54 |
| 55 recipe = universe.load_recipe(recipe_name) | 55 recipe = universe.load_recipe(recipe_name) |
| 56 for attr in dir(recipe): | 56 for attr in dir(recipe): |
| 57 val = getattr(recipe, attr) | 57 val = getattr(recipe, attr) |
| 58 if isinstance(val, types.ModuleType): | 58 if isinstance(val, types.ModuleType): |
| 59 module_name = val.__name__ | 59 module_name = val.__name__ |
| 60 for pattern in MODULES_WHITELIST: | 60 for pattern in whitelist: |
| 61 if pattern.match(val.__name__): | 61 if pattern.match(val.__name__): |
| 62 break | 62 break |
| 63 else: | 63 else: |
| 64 yield ('In %s:\n' | 64 yield ('In %s:\n' |
| 65 ' Non-whitelisted import of %s' % | 65 ' Non-whitelisted import of %s' % |
| 66 (recipe_path, module_name)) | 66 (recipe_path, module_name)) |
| 67 | 67 |
| 68 | 68 |
| 69 def MainTest(): | 69 def main(universe, whitelist=MODULES_WHITELIST): |
|
iannucci
2015/05/27 02:03:27
y u do whitelist?
luqui
2015/05/28 21:47:38
It was because e.g. common.skia didn't belong in h
| |
| 70 universe = recipe_loader.RecipeUniverse() | 70 whitelist = map(re.compile, whitelist) |
| 71 | 71 |
| 72 errors = [] | 72 errors = [] |
| 73 for recipe_path, recipe_name in recipe_loader.loop_over_recipes(): | 73 for recipe_path, recipe_name in universe.loop_over_recipes(): |
| 74 errors.extend(ImportsTest(recipe_path, recipe_name, universe)) | 74 errors.extend(ImportsTest(recipe_path, recipe_name, whitelist, universe)) |
| 75 | 75 |
| 76 if errors: | 76 if errors: |
| 77 raise TestFailure('\n'.join(map(str, errors))) | 77 raise TestFailure('\n'.join(map(str, errors))) |
| 78 | 78 |
| 79 | |
| 80 if __name__ == '__main__': | |
| 81 MainTest() | |
| OLD | NEW |