OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2013 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 """Provides test coverage for individual recipes. | 6 """Provides test coverage for individual recipes. |
7 | 7 |
8 Recipe tests are located in ../recipes_test/*.py. | 8 Recipe tests are located in ../recipes_test/*.py. |
9 | 9 |
10 Each py file's splitext'd name is expected to match a recipe in ../recipes/*.py. | 10 Each py file's splitext'd name is expected to match a recipe in ../recipes/*.py. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 ROOT_PATH = os.path.abspath(os.path.join(SCRIPT_PATH, os.pardir, os.pardir, | 57 ROOT_PATH = os.path.abspath(os.path.join(SCRIPT_PATH, os.pardir, os.pardir, |
58 os.pardir)) | 58 os.pardir)) |
59 SLAVE_DIR = os.path.join(ROOT_PATH, 'slave', 'fake_slave', 'build') | 59 SLAVE_DIR = os.path.join(ROOT_PATH, 'slave', 'fake_slave', 'build') |
60 INTERNAL_DIR = os.path.join(ROOT_PATH, os.pardir, 'build_internal') | 60 INTERNAL_DIR = os.path.join(ROOT_PATH, os.pardir, 'build_internal') |
61 BASE_DIRS = { | 61 BASE_DIRS = { |
62 'Public': os.path.dirname(SCRIPT_PATH), | 62 'Public': os.path.dirname(SCRIPT_PATH), |
63 'Internal': os.path.join(INTERNAL_DIR, 'scripts', 'slave'), | 63 'Internal': os.path.join(INTERNAL_DIR, 'scripts', 'slave'), |
64 } | 64 } |
65 # TODO(iannucci): Check for duplicate recipe names when we have more than one | 65 # TODO(iannucci): Check for duplicate recipe names when we have more than one |
66 # base_dir | 66 # base_dir |
| 67 RECIPE_MODULES = [os.path.join(x, 'recipe_modules') for x in BASE_DIRS.values()] |
67 | 68 |
68 COVERAGE = coverage.coverage( | 69 COVERAGE = coverage.coverage( |
69 include=([os.path.join(x, 'recipes', '*') for x in BASE_DIRS.values()]+ | 70 include=([os.path.join(x, 'recipes', '*') for x in BASE_DIRS.values()]+ |
70 [os.path.join(SCRIPT_PATH, os.pardir, 'recipe_modules', | 71 [os.path.join(SCRIPT_PATH, os.pardir, 'recipe_modules', |
71 '*', 'api.py')]) | 72 '*', 'api.py')]) |
72 ) | 73 ) |
73 | 74 |
74 | 75 |
75 @contextlib.contextmanager | 76 @contextlib.contextmanager |
76 def cover(): | 77 def cover(): |
77 COVERAGE.start() | 78 COVERAGE.start() |
78 try: | 79 try: |
79 yield | 80 yield |
80 finally: | 81 finally: |
81 COVERAGE.stop() | 82 COVERAGE.stop() |
82 | 83 |
83 with cover(): | 84 with cover(): |
84 from slave import annotated_run | 85 from slave import annotated_run |
85 from slave import recipe_api | 86 from slave import recipe_api |
86 | 87 |
87 class TestAPI(object): | |
88 @staticmethod | |
89 def properties_generic(**kwargs): | |
90 """ | |
91 Merge kwargs into a typical buildbot properties blob, and return the blob. | |
92 """ | |
93 ret = { | |
94 'blamelist': 'cool_dev1337@chromium.org,hax@chromium.org', | |
95 'blamelist_real': ['cool_dev1337@chromium.org', 'hax@chromium.org'], | |
96 'buildername': 'TestBuilder', | |
97 'buildnumber': 571, | |
98 'mastername': 'chromium.testing.master', | |
99 'slavename': 'TestSlavename', | |
100 'workdir': '/path/to/workdir/TestSlavename', | |
101 } | |
102 ret.update(kwargs) | |
103 return ret | |
104 | |
105 @staticmethod | |
106 def properties_scheduled(**kwargs): | |
107 """ | |
108 Merge kwargs into a typical buildbot properties blob for a job fired off | |
109 by a chrome/trunk svn scheduler, and return the blob. | |
110 """ | |
111 ret = TestAPI.properties_generic( | |
112 branch='TestBranch', | |
113 project='', | |
114 repository='svn://svn-mirror.golo.chromium.org/chrome/trunk', | |
115 revision='204787', | |
116 ) | |
117 ret.update(kwargs) | |
118 return ret | |
119 | |
120 @staticmethod | |
121 def properties_tryserver(**kwargs): | |
122 """ | |
123 Merge kwargs into a typical buildbot properties blob for a job fired off | |
124 by a rietveld tryjob on the tryserver, and return the blob. | |
125 """ | |
126 ret = TestAPI.properties_generic( | |
127 branch='', | |
128 issue=12853011, | |
129 patchset=1, | |
130 project='chrome', | |
131 repository='', | |
132 requester='commit-bot@chromium.org', | |
133 revision='HEAD', | |
134 rietveld='https://chromiumcodereview.appspot.com', | |
135 root='src', | |
136 ) | |
137 ret.update(kwargs) | |
138 return ret | |
139 | |
140 | |
141 def expected_for(recipe_path, test_name): | 88 def expected_for(recipe_path, test_name): |
142 root, name = os.path.split(recipe_path) | 89 root, name = os.path.split(recipe_path) |
143 name = os.path.splitext(name)[0] | 90 name = os.path.splitext(name)[0] |
144 expect_path = os.path.join(root, '%s.expected' % name) | 91 expect_path = os.path.join(root, '%s.expected' % name) |
145 if not os.path.isdir(expect_path): | 92 if not os.path.isdir(expect_path): |
146 os.makedirs(expect_path) | 93 os.makedirs(expect_path) |
147 return os.path.join(expect_path, test_name+'.json') | 94 return os.path.join(expect_path, test_name+'.json') |
148 | 95 |
149 | 96 |
150 def exec_test_file(recipe_path): | 97 def exec_test_file(recipe_path): |
151 gvars = {} | 98 gvars = {} |
152 with cover(): | 99 with cover(): |
153 execfile(recipe_path, gvars) | 100 execfile(recipe_path, gvars) |
154 try: | 101 try: |
155 gen = gvars['GenTests'](TestAPI()) | 102 test_api = recipe_api.CreateTestApi(RECIPE_MODULES, gvars['DEPS']) |
| 103 gen = gvars['GenTests'](test_api) |
156 except Exception, e: | 104 except Exception, e: |
157 print "Caught exception while processing %s: %s" % (recipe_path, e) | 105 print "Caught exception while processing %s: %s" % (recipe_path, e) |
158 raise | 106 raise |
159 try: | 107 try: |
160 while True: | 108 while True: |
161 with cover(): | 109 with cover(): |
162 name, test_data = next(gen) | 110 name, test_data = next(gen) |
163 yield name, test_data | 111 yield name, test_data |
164 except StopIteration: | 112 except StopIteration: |
165 pass | 113 pass |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 retcode = retcode or 2 | 244 retcode = retcode or 2 |
297 | 245 |
298 if training: | 246 if training: |
299 test_env.print_coverage_warning() | 247 test_env.print_coverage_warning() |
300 | 248 |
301 return retcode | 249 return retcode |
302 | 250 |
303 | 251 |
304 if __name__ == '__main__': | 252 if __name__ == '__main__': |
305 sys.exit(main(sys.argv)) | 253 sys.exit(main(sys.argv)) |
OLD | NEW |