Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(677)

Side by Side Diff: scripts/slave/unittests/recipe_configs_test.py

Issue 23889036: Refactor the way that TestApi works so that it is actually useful. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: rebase Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright 2013 The Chromium Authors. All rights reserved. 2 # Copyright 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 """Provides test coverage for common recipe configurations. 6 """Provides test coverage for common recipe configurations.
7 7
8 recipe config expectations are located in ../recipe_configs_test/*.expected 8 recipe config expectations are located in ../recipe_configs_test/*.expected
9 9
10 In training mode, this will loop over every config item in ../recipe_configs.py 10 In training mode, this will loop over every config item in ../recipe_configs.py
11 crossed with every platform, and spit out the as_json() representation to 11 crossed with every platform, and spit out the as_json() representation to
12 ../recipe_configs_test 12 ../recipe_configs_test
13 13
14 You must have 100% coverage of ../recipe_configs.py for this test to pass. 14 You must have 100% coverage of ../recipe_configs.py for this test to pass.
15 """ 15 """
16 16
17 import json 17 import json
18 import multiprocessing 18 import multiprocessing
19 import os 19 import os
20 import sys 20 import sys
21 import unittest 21 import unittest
22 from itertools import product, imap 22 from itertools import product, imap
23 23
24 import test_env # pylint: disable=W0611,F0401 24 import test_env # pylint: disable=W0611,F0401
25 25
26 from slave import recipe_api 26 from slave import recipe_loader
27 from slave import annotated_run 27 from slave import recipe_util
28 28
29 import coverage 29 import coverage
30 30
31 SCRIPT_PATH = os.path.abspath(os.path.dirname(__file__)) 31 SCRIPT_PATH = os.path.abspath(os.path.dirname(__file__))
32 SLAVE_DIR = os.path.abspath(os.path.join(SCRIPT_PATH, os.pardir)) 32 SLAVE_DIR = os.path.abspath(os.path.join(SCRIPT_PATH, os.pardir))
33 33
34 COVERAGE = (lambda: coverage.coverage( 34 COVERAGE = (lambda: coverage.coverage(
35 include=[os.path.join(x, '*', '*config.py') 35 include=[os.path.join(x, '*', '*config.py')
36 for x in annotated_run.MODULE_DIRS], 36 for x in recipe_util.MODULE_DIRS()],
37 data_suffix=True))() 37 data_suffix=True))()
38 38
39 def covered(fn, *args, **kwargs): 39 def covered(fn, *args, **kwargs):
40 COVERAGE.start() 40 COVERAGE.start()
41 try: 41 try:
42 return fn(*args, **kwargs) 42 return fn(*args, **kwargs)
43 finally: 43 finally:
44 COVERAGE.stop() 44 COVERAGE.stop()
45 45
46 RECIPE_MODULES = None 46 RECIPE_MODULES = None
47 def init_recipe_modules(): 47 def init_recipe_modules():
48 global RECIPE_MODULES 48 global RECIPE_MODULES
49 RECIPE_MODULES = covered(recipe_api.load_recipe_modules, 49 RECIPE_MODULES = covered(recipe_loader.load_recipe_modules,
50 annotated_run.MODULE_DIRS) 50 recipe_util.MODULE_DIRS())
51 51
52 from slave import recipe_configs_util # pylint: disable=F0401 52 from slave import recipe_config # pylint: disable=F0401
53 53
54 def get_expect_dir(mod): 54 def get_expect_dir(mod):
55 return os.path.join(mod.__path__[0], 'config.expected') 55 return os.path.join(mod.__path__[0], 'config.expected')
56 56
57 57
58 def evaluate_configurations(args): 58 def evaluate_configurations(args):
59 mod_id, var_assignments = args 59 mod_id, var_assignments = args
60 mod = getattr(RECIPE_MODULES, mod_id) 60 mod = getattr(RECIPE_MODULES, mod_id)
61 expect_dir = get_expect_dir(mod) 61 expect_dir = get_expect_dir(mod)
62 ctx = mod.CONFIG_CTX 62 ctx = mod.CONFIG_CTX
63 63
64 config_name = None 64 config_name = None
65 try: 65 try:
66 file_name = os.path.join(expect_dir, ctx.TEST_FILE_FORMAT(var_assignments)) 66 file_name = os.path.join(expect_dir, ctx.TEST_FILE_FORMAT(var_assignments))
67 ret = {} 67 ret = {}
68 68
69 make_item = lambda: covered(ctx.CONFIG_SCHEMA, **var_assignments) 69 make_item = lambda: covered(ctx.CONFIG_SCHEMA, **var_assignments)
70 70
71 # Try ROOT_CONFIG_ITEM first. If it raises BadConf, then we can skip 71 # Try ROOT_CONFIG_ITEM first. If it raises BadConf, then we can skip
72 # this config. 72 # this config.
73 root_item = ctx.ROOT_CONFIG_ITEM 73 root_item = ctx.ROOT_CONFIG_ITEM
74 if root_item: 74 if root_item:
75 config_name = root_item.__name__ 75 config_name = root_item.__name__
76 try: 76 try:
77 result = covered(root_item, make_item()) 77 result = covered(root_item, make_item())
78 if result.complete(): 78 if result.complete():
79 ret[config_name] = result.as_jsonish() 79 ret[config_name] = result.as_jsonish()
80 except recipe_configs_util.BadConf, e: 80 except recipe_config.BadConf, e:
81 return file_name, None, None 81 return file_name, None, None
82 82
83 for config_name, fn in ctx.CONFIG_ITEMS.iteritems(): 83 for config_name, fn in ctx.CONFIG_ITEMS.iteritems():
84 if fn.NO_TEST or fn.IS_ROOT: 84 if fn.NO_TEST or fn.IS_ROOT:
85 continue 85 continue
86 try: 86 try:
87 result = covered(fn, make_item()) 87 result = covered(fn, make_item())
88 if result.complete(): 88 if result.complete():
89 ret[config_name] = result.as_jsonish() 89 ret[config_name] = result.as_jsonish()
90 except recipe_configs_util.BadConf, e: 90 except recipe_config.BadConf, e:
91 ret[config_name] = str(e) 91 ret[config_name] = str(e)
92 return file_name, covered(ctx.TEST_NAME_FORMAT, var_assignments), ret 92 return file_name, covered(ctx.TEST_NAME_FORMAT, var_assignments), ret
93 except Exception, e: 93 except Exception, e:
94 print 'Caught exception [%s] with args %s: %s' % (e, args, config_name) 94 print 'Caught exception [%s] with args %s: %s' % (e, args, config_name)
95 95
96 96
97 def train_from_tests(args): 97 def train_from_tests(args):
98 file_name, _, configuration_results = evaluate_configurations(args) 98 file_name, _, configuration_results = evaluate_configurations(args)
99 if configuration_results is not None: 99 if configuration_results is not None:
100 if configuration_results: 100 if configuration_results:
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 retcode = retcode or 2 233 retcode = retcode or 2
234 234
235 if training: 235 if training:
236 test_env.print_coverage_warning() 236 test_env.print_coverage_warning()
237 237
238 return retcode 238 return retcode
239 239
240 240
241 if __name__ == '__main__': 241 if __name__ == '__main__':
242 sys.exit(main(sys.argv)) 242 sys.exit(main(sys.argv))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698