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