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

Side by Side Diff: scripts/slave/recipe_modules/chromium/steps.py

Issue 339183013: De-duplicate steps between chromium and chromium_trybot recipes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: fixes Created 6 years, 5 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 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 class ArchiveBuildStep(object): 5
6 class Test(object):
7 """
8 Base class for tests that can be retried after deapplying a previously
9 applied patch.
10 """
11
12 @property
13 def name(self): # pragma: no cover
Sergiy Byelozyorov 2014/06/30 12:46:19 What does pragma mean here and below? I thought th
14 """Name of the test."""
15 raise NotImplementedError()
16
17 def pre_run(self, api, suffix): # pragma: no cover
18 """Steps to execute before running the test."""
19 return []
20
21 def run(self, api, suffix): # pragma: no cover
22 """Run the test. suffix is 'with patch' or 'without patch'."""
23 raise NotImplementedError()
24
25 def post_run(self, api, suffix): # pragma: no cover
26 """Steps to execute after running the test."""
27 return []
28
29 def has_valid_results(self, api, suffix): # pragma: no cover
30 """
31 Returns True if results (failures) are valid.
32
33 This makes it possible to distinguish between the case of no failures
34 and the test failing to even report its results in machine-readable
35 format.
36 """
37 raise NotImplementedError()
38
39 def failures(self, api, suffix): # pragma: no cover
40 """Return list of failures (list of strings)."""
41 raise NotImplementedError()
42
43 def _step_name(self, suffix):
44 """Helper to uniformly combine tests's name with a suffix."""
45 if not suffix:
46 return self.name
47 return '%s (%s)' % (self.name, suffix)
48
49
50 class ArchiveBuildStep(Test):
6 def __init__(self, gs_bucket, gs_acl=None): 51 def __init__(self, gs_bucket, gs_acl=None):
7 self.gs_bucket = gs_bucket 52 self.gs_bucket = gs_bucket
8 self.gs_acl = gs_acl 53 self.gs_acl = gs_acl
9 54
10 def run(self, api): 55 def run(self, api, suffix):
11 return api.chromium.archive_build( 56 return api.chromium.archive_build(
12 'archive build', 57 'archive build',
13 self.gs_bucket, 58 self.gs_bucket,
14 gs_acl=self.gs_acl, 59 gs_acl=self.gs_acl,
15 ) 60 )
16 61
17 @staticmethod 62 @staticmethod
18 def compile_targets(_): 63 def compile_targets(_):
19 return [] 64 return []
20 65
21 66
22 class CheckpermsTest(object): 67 class CheckdepsTest(Test): # pylint: disable=W0232
23 @staticmethod 68 name = 'checkdeps'
24 def run(api):
25 return api.chromium.checkperms()
26 69
27 @staticmethod 70 @staticmethod
28 def compile_targets(_): 71 def compile_targets(_):
29 return [] 72 return []
30 73
74 @staticmethod
75 def run(api, suffix):
76 return api.chromium.checkdeps(
77 suffix, can_fail_build=(not suffix), always_run=True)
31 78
32 class Deps2GitTest(object): 79 def has_valid_results(self, api, suffix):
33 @staticmethod 80 return api.step_history[self._step_name(suffix)].json.output is not None
34 def run(api): 81
35 return api.chromium.deps2git() 82 def failures(self, api, suffix):
83 results = api.step_history[self._step_name(suffix)].json.output
84 result_set = set()
85 for result in results:
86 for violation in result['violations']:
87 result_set.add((result['dependee_path'], violation['include_path']))
88 return ['%s: %s' % (r[0], r[1]) for r in result_set]
89
90
91 class CheckpermsTest(Test): # pylint: disable=W0232
92 name = 'checkperms'
36 93
37 @staticmethod 94 @staticmethod
38 def compile_targets(_): 95 def compile_targets(_):
39 return [] 96 return []
40 97
98 @staticmethod
99 def run(api, suffix):
100 return api.chromium.checkperms(
101 suffix, can_fail_build=(not suffix), always_run=True)
41 102
42 class Deps2SubmodulesTest(object): 103 def has_valid_results(self, api, suffix):
43 @staticmethod 104 return api.step_history[self._step_name(suffix)].json.output is not None
44 def run(api): 105
45 return api.chromium.deps2submodules() 106 def failures(self, api, suffix):
107 results = api.step_history[self._step_name(suffix)].json.output
108 result_set = set()
109 for result in results:
110 result_set.add((result['rel_path'], result['error']))
111 return ['%s: %s' % (r[0], r[1]) for r in result_set]
112
113 class ChecklicensesTest(Test): # pylint: disable=W0232
114 name = 'checklicenses'
46 115
47 @staticmethod 116 @staticmethod
48 def compile_targets(_): 117 def compile_targets(_):
49 return [] 118 return []
50 119
120 @staticmethod
121 def run(api, suffix):
122 return api.chromium.checklicenses(
123 suffix, can_fail_build=(not suffix), always_run=True)
51 124
52 class GTestTest(object): 125 def has_valid_results(self, api, suffix):
53 def __init__(self, name, args=None, flakiness_dash=False): 126 return api.step_history[self._step_name(suffix)].json.output is not None
54 self.name = name 127
55 self.args = args or [] 128 def failures(self, api, suffix):
129 results = api.step_history[self._step_name(suffix)].json.output
130 result_set = set()
131 for result in results:
132 result_set.add((result['filename'], result['license']))
133 return ['%s: %s' % (r[0], r[1]) for r in result_set]
134
135
136 class Deps2GitTest(Test): # pylint: disable=W0232
137 name = 'deps2git'
138
139 @staticmethod
140 def compile_targets(_):
141 return []
142
143 @staticmethod
144 def run(api, suffix):
145 yield (
146 api.chromium.deps2git(suffix, can_fail_build=(not suffix)),
147 api.chromium.deps2submodules()
148 )
149
150 def has_valid_results(self, api, suffix):
151 return api.step_history[self._step_name(suffix)].json.output is not None
152
153 def failures(self, api, suffix):
154 return api.step_history[self._step_name(suffix)].json.output
155
156
157 class GTestTest(Test):
158 def __init__(self, name, args=None, compile_targets=None, flakiness_dash=False ):
159 self._name = name
160 self._args = args or []
56 self.flakiness_dash = flakiness_dash 161 self.flakiness_dash = flakiness_dash
57 162
58 def run(self, api): 163 @property
59 if api.chromium.c.TARGET_PLATFORM == 'android': 164 def name(self):
60 return api.chromium_android.run_test_suite(self.name, self.args) 165 return self._name
61
62 return api.chromium.runtest(self.name,
63 test_type=self.name,
64 args=self.args,
65 annotate='gtest',
66 xvfb=True,
67 flakiness_dash=self.flakiness_dash)
68 166
69 def compile_targets(self, api): 167 def compile_targets(self, api):
70 if api.chromium.c.TARGET_PLATFORM == 'android': 168 if api.chromium.c.TARGET_PLATFORM == 'android':
71 return [self.name + '_apk'] 169 return [self.name + '_apk']
72 170
73 # On iOS we rely on 'All' target being compiled instead of using 171 # On iOS we rely on 'All' target being compiled instead of using
74 # individual targets. 172 # individual targets.
75 if api.chromium.c.TARGET_PLATFORM == 'ios': 173 if api.chromium.c.TARGET_PLATFORM == 'ios':
76 return [] 174 return []
77 175
78 return [self.name] 176 return [self.name]
79 177
178 def run(self, api, suffix):
179 if api.chromium.c.TARGET_PLATFORM == 'android':
180 return api.chromium_android.run_test_suite(self.name, self._args)
80 181
81 class DynamicGTestTests(object): 182 def followup_fn(step_result):
183 r = step_result.json.gtest_results
184 p = step_result.presentation
185
186 if r.valid:
187 p.step_text += api.test_utils.format_step_text([
188 ['failures:', r.failures]
189 ])
190
191 # Copy the list because run can be invoked multiple times and we modify
192 # the local copy.
193 args = self._args[:]
194
195 if suffix == 'without patch':
196 args.append(api.chromium.test_launcher_filter(
197 self.failures(api, 'with patch')))
198
199 kwargs = {}
200 if suffix:
201 # TODO(phajdan.jr): Just remove it, keeping for now to avoid
202 # expectation changes.
203 kwargs['parallel'] = True
204
205 # TODO(phajdan.jr): Always do that, keeping for now to avoid
206 # expectation changes.
207 kwargs['test_launcher_summary_output'] = api.json.gtest_results(
208 add_json_log=False)
209 kwargs['followup_fn'] = followup_fn
210 else:
211 # TODO(phajdan.jr): Always do that, keeping for now to avoid
212 # expectation changes.
213 kwargs['test_type'] = self.name
214
215 return api.chromium.runtest(
216 self.name,
217 args,
218 annotate='gtest',
219 xvfb=True,
220 name=self._step_name(suffix),
221 can_fail_build=False,
222 flakiness_dash=self.flakiness_dash,
223 step_test_data=lambda: api.json.test_api.canned_gtest_output(True),
224 **kwargs)
225
226 def has_valid_results(self, api, suffix):
227 step_name = self._step_name(suffix)
228 gtest_results = api.step_history[step_name].json.gtest_results
229 if not gtest_results.valid: # pragma: no cover
230 return False
231 global_tags = gtest_results.raw.get('global_tags', [])
232 return 'UNRELIABLE_RESULTS' not in global_tags
233
234 def failures(self, api, suffix):
235 step_name = self._step_name(suffix)
236 return api.step_history[step_name].json.gtest_results.failures
237
238
239 class DynamicGTestTests(Test):
82 def __init__(self, buildername, flakiness_dash=True): 240 def __init__(self, buildername, flakiness_dash=True):
83 self.buildername = buildername 241 self.buildername = buildername
84 self.flakiness_dash = flakiness_dash 242 self.flakiness_dash = flakiness_dash
85 243
86 @staticmethod 244 @staticmethod
87 def _canonicalize_test(test): 245 def _canonicalize_test(test):
88 if isinstance(test, basestring): 246 if isinstance(test, basestring):
89 return {'test': test, 'shard_index': 0, 'total_shards': 1} 247 return {'test': test, 'shard_index': 0, 'total_shards': 1}
90 return test 248 return test
91 249
92 def _get_test_spec(self, api): 250 def _get_test_spec(self, api):
93 all_test_specs = api.step_history['read test spec'].json.output 251 all_test_specs = api.step_history['read test spec'].json.output
94 return all_test_specs.get(self.buildername, {}) 252 return all_test_specs.get(self.buildername, {})
95 253
96 def _get_tests(self, api): 254 def _get_tests(self, api):
97 return [self._canonicalize_test(t) for t in 255 return [self._canonicalize_test(t) for t in
98 self._get_test_spec(api).get('gtest_tests', [])] 256 self._get_test_spec(api).get('gtest_tests', [])]
99 257
100 def run(self, api): 258 def run(self, api, suffix):
101 steps = [] 259 steps = []
102 for test in self._get_tests(api): 260 for test in self._get_tests(api):
103 args = [] 261 args = []
104 if test['shard_index'] != 0 or test['total_shards'] != 1: 262 if test['shard_index'] != 0 or test['total_shards'] != 1:
105 args.extend(['--test-launcher-shard-index=%d' % test['shard_index'], 263 args.extend(['--test-launcher-shard-index=%d' % test['shard_index'],
106 '--test-launcher-total-shards=%d' % test['total_shards']]) 264 '--test-launcher-total-shards=%d' % test['total_shards']])
107 steps.append(api.chromium.runtest( 265 steps.append(api.chromium.runtest(
108 test['test'], test_type=test['test'], args=args, annotate='gtest', 266 test['test'], test_type=test['test'], args=args, annotate='gtest',
109 xvfb=True, flakiness_dash=self.flakiness_dash)) 267 xvfb=True, flakiness_dash=self.flakiness_dash))
110 268
111 return steps 269 return steps
112 270
113 def compile_targets(self, api): 271 def compile_targets(self, api):
114 explicit_targets = self._get_test_spec(api).get('compile_targets', []) 272 explicit_targets = self._get_test_spec(api).get('compile_targets', [])
115 test_targets = [t['test'] for t in self._get_tests(api)] 273 test_targets = [t['test'] for t in self._get_tests(api)]
116 # Remove duplicates. 274 # Remove duplicates.
117 return sorted(set(explicit_targets + test_targets)) 275 return sorted(set(explicit_targets + test_targets))
118 276
119 277
120 class TelemetryUnitTests(object): 278 class SwarmingGTestTest(Test):
279 def __init__(self, name, args=None, shards=1):
280 self._name = name
281 self._args = args or []
282 self._shards = shards
283 self._tasks = {}
284 self._results = {}
285
286 @property
287 def name(self):
288 return self._name
289
290 def compile_targets(self, _):
291 # <X>_run target depends on <X>, and then isolates it invoking isolate.py.
292 # It is a convention, not a hard coded rule.
293 return [self._name + '_run']
294
295 def pre_run(self, api, suffix):
296 """Launches the test on Swarming."""
297 assert suffix not in self._tasks, (
298 'Test %s was already triggered' % self._step_name(suffix))
299
300 # *.isolated may be missing if *_run target is misconfigured. It's a error
301 # in gyp, not a recipe failure. So carry on with recipe execution.
302 isolated_hash = api.isolate.isolated_tests.get(self._name)
303 if not isolated_hash:
304 return api.python.inline(
305 '[error] %s' % self._step_name(suffix),
306 r"""
307 import sys
308 print '*.isolated file for target %s is missing' % sys.argv[1]
309 sys.exit(1)
310 """,
311 args=[self._name],
312 always_run=True)
313
314 # If rerunning without a patch, run only tests that failed.
315 args = self._args[:]
316 if suffix == 'without patch':
317 failed_tests = sorted(self.failures(api, 'with patch'))
318 args.append('--gtest_filter=%s' % ':'.join(failed_tests))
319
320 # Trigger the test on swarming.
321 self._tasks[suffix] = api.swarming.gtest_task(
322 title=self._step_name(suffix),
323 isolated_hash=isolated_hash,
324 shards=self._shards,
325 test_launcher_summary_output=api.json.gtest_results(
326 add_json_log=False),
327 extra_args=args)
328 return api.swarming.trigger([self._tasks[suffix]], always_run=True)
329
330 def run(self, api, suffix): # pylint: disable=R0201
331 """Not used. All logic in pre_run, post_run."""
332 return []
333
334 def post_run(self, api, suffix):
335 """Waits for launched test to finish and collect the results."""
336 assert suffix not in self._results, (
337 'Results of %s were already collected' % self._step_name(suffix))
338
339 # Emit error if test wasn't triggered. This happens if *.isolated is not
340 # found. (The build is already red by this moment anyway).
341 if suffix not in self._tasks:
342 return api.python.inline(
343 '[collect error] %s' % self._step_name(suffix),
344 r"""
345 import sys
346 print '%s wasn\'t triggered' % sys.argv[1]
347 sys.exit(1)
348 """,
349 args=[self._name],
350 always_run=True)
351
352 # Update step presentation, store step results in self._results.
353 def followup_fn(step_result):
354 r = step_result.json.gtest_results
355 p = step_result.presentation
356 if r.valid:
357 p.step_text += api.test_utils.format_step_text([
358 ['failures:', r.failures]
359 ])
360 self._results[suffix] = r
361
362 # Wait for test on swarming to finish. If swarming infrastructure is
363 # having issues, this step produces no valid *.json test summary, and
364 # 'has_valid_results' returns False.
365 return api.swarming.collect(
366 [self._tasks[suffix]],
367 always_run=True,
368 can_fail_build=(not suffix),
369 followup_fn=followup_fn)
370
371 def has_valid_results(self, api, suffix):
372 # Test wasn't triggered or wasn't collected.
373 if suffix not in self._tasks or not suffix in self._results:
374 return False
375 # Test ran, but failed to produce valid *.json.
376 gtest_results = self._results[suffix]
377 if not gtest_results.valid: # pragma: no cover
378 return False
379 global_tags = gtest_results.raw.get('global_tags', [])
380 return 'UNRELIABLE_RESULTS' not in global_tags
381
382 def failures(self, api, suffix):
383 assert self.has_valid_results(api, suffix)
384 return self._results[suffix].failures
385
386
387 class TelemetryUnitTests(Test):
121 @staticmethod 388 @staticmethod
122 def run(api): 389 def run(api, suffix):
123 return api.chromium.run_telemetry_unittests() 390 return api.chromium.run_telemetry_unittests()
124 391
125 @staticmethod 392 @staticmethod
126 def compile_targets(_): 393 def compile_targets(_):
127 return ['chrome'] 394 return ['chrome']
128 395
129 class TelemetryPerfUnitTests(object): 396 class TelemetryPerfUnitTests(Test):
130 @staticmethod 397 @staticmethod
131 def run(api): 398 def run(api, suffix):
132 return api.chromium.run_telemetry_perf_unittests() 399 return api.chromium.run_telemetry_perf_unittests()
133 400
134 @staticmethod 401 @staticmethod
135 def compile_targets(_): 402 def compile_targets(_):
136 return ['chrome'] 403 return ['chrome']
137 404
138 405
139 class NaclIntegrationTest(object): 406 class NaclIntegrationTest(Test): # pylint: disable=W0232
140 @staticmethod 407 name = 'nacl_integration'
141 def run(api):
142 args = [
143 '--mode', api.chromium.c.BUILD_CONFIG,
144 ]
145 return api.python(
146 'nacl_integration',
147 api.path['checkout'].join('chrome',
148 'test',
149 'nacl_test_injection',
150 'buildbot_nacl_integration.py'),
151 args)
152 408
153 @staticmethod 409 @staticmethod
154 def compile_targets(_): 410 def compile_targets(_):
155 return ['chrome'] 411 return ['chrome']
156 412
413 def run(self, api, suffix):
414 args = [
415 ]
157 416
158 class AndroidInstrumentationTest(object): 417 if suffix:
418 # TODO(phajdan.jr): Always do that, keeping for now to avoid
419 # expectation changes.
420 args.extend([
421 '--mode', api.chromium.c.build_config_fs,
422 '--json_build_results_output_file', api.json.output(),
423 ])
424 else:
425 # TODO(phajdan.jr): Just remove it, keeping for now to avoid
426 # expectation changes.
427 args.extend([
428 '--mode', api.chromium.c.BUILD_CONFIG,
429 ])
430
431 return api.python(
432 self._step_name(suffix),
433 api.path['checkout'].join('chrome',
434 'test',
435 'nacl_test_injection',
436 'buildbot_nacl_integration.py'),
437 args,
438 can_fail_build=(not suffix),
439 step_test_data=lambda: api.m.json.test_api.output([]))
440
441 def has_valid_results(self, api, suffix):
442 return api.step_history[self._step_name(suffix)].json.output is not None
443
444 def failures(self, api, suffix):
445 failures = api.step_history[self._step_name(suffix)].json.output
446 return [f['raw_name'] for f in failures]
447
448
449 class AndroidInstrumentationTest(Test):
159 def __init__(self, name, compile_target, test_data=None, 450 def __init__(self, name, compile_target, test_data=None,
160 adb_install_apk=None): 451 adb_install_apk=None):
161 self.name = name 452 self._name = name
162 self.compile_target = compile_target 453 self.compile_target = compile_target
163 454
164 self.test_data = test_data 455 self.test_data = test_data
165 self.adb_install_apk = adb_install_apk 456 self.adb_install_apk = adb_install_apk
166 457
167 def run(self, api): 458 @property
459 def name(self):
460 return self._name
461
462 def run(self, api, suffix):
168 assert api.chromium.c.TARGET_PLATFORM == 'android' 463 assert api.chromium.c.TARGET_PLATFORM == 'android'
169 if self.adb_install_apk: 464 if self.adb_install_apk:
170 yield api.chromium_android.adb_install_apk( 465 yield api.chromium_android.adb_install_apk(
171 self.adb_install_apk[0], self.adb_install_apk[1]) 466 self.adb_install_apk[0], self.adb_install_apk[1])
172 yield api.chromium_android.run_instrumentation_suite( 467 yield api.chromium_android.run_instrumentation_suite(
173 self.name, test_data=self.test_data, 468 self.name, test_data=self.test_data,
174 flakiness_dashboard='test-results.appspot.com', 469 flakiness_dashboard='test-results.appspot.com',
175 verbose=True) 470 verbose=True)
176 471
177 def compile_targets(self, _): 472 def compile_targets(self, _):
178 return [self.compile_target] 473 return [self.compile_target]
179 474
180 class MojoPythonTests(object): 475
476 class MojoPythonTests(Test): # pylint: disable=W0232
477 name = 'mojo_python_tests'
478
181 @staticmethod 479 @staticmethod
182 def run(api): 480 def compile_targets(_):
481 return []
482
483 def run(self, api, suffix):
183 args = ['--write-full-results-to', 484 args = ['--write-full-results-to',
184 api.json.test_results(add_json_log=False)] 485 api.json.test_results(add_json_log=False)]
486 if suffix == 'without patch':
487 args.extend(self.failures(api, 'with patch'))
185 488
186 def followup_fn(step_result): 489 def followup_fn(step_result):
187 r = step_result.json.test_results 490 r = step_result.json.test_results
188 p = step_result.presentation 491 p = step_result.presentation
189 492
190 p.step_text += api.test_utils.format_step_text([ 493 p.step_text += api.test_utils.format_step_text([
191 ['unexpected_failures:', r.unexpected_failures.keys()], 494 ['unexpected_failures:', r.unexpected_failures.keys()],
192 ]) 495 ])
193 496
194 return api.python( 497 return api.python(
195 'mojo_python_tests', 498 self._step_name(suffix),
196 api.path['checkout'].join('mojo', 'tools', 'run_mojo_python_tests.py'), 499 api.path['checkout'].join(
197 args, followup_fn=followup_fn, 500 'mojo',
501 'tools',
502 'run_mojo_python_tests.py'),
503 args,
504 can_fail_build=(not suffix),
198 step_test_data=lambda: api.json.test_api.canned_test_output( 505 step_test_data=lambda: api.json.test_api.canned_test_output(
199 "{'tests': {}}")) 506 True), followup_fn=followup_fn)
200 507
201 @staticmethod 508 def has_valid_results(self, api, suffix):
202 def compile_targets(_): 509 # TODO(dpranke): we should just return zero/nonzero for success/fail.
203 return [] 510 # crbug.com/357866
511 step = api.step_history[self._step_name(suffix)]
512 return (step.json.test_results.valid and
513 step.retcode <= step.json.test_results.MAX_FAILURES_EXIT_STATUS)
514
515 def failures(self, api, suffix):
516 sn = self._step_name(suffix)
517 return api.step_history[sn].json.test_results.unexpected_failures
518
519
520 class BlinkTest(Test):
521 name = 'webkit_tests'
522
523 def __init__(self, api):
524 self.results_dir = api.path['slave_build'].join('layout-test-results')
525 self.layout_test_wrapper = api.path['build'].join(
526 'scripts', 'slave', 'chromium', 'layout_test_wrapper.py')
527
528 def run(self, api, suffix):
529 args = ['--target', api.chromium.c.BUILD_CONFIG,
530 '-o', self.results_dir,
531 '--build-dir', api.chromium.c.build_dir,
532 '--json-test-results', api.json.test_results(add_json_log=False)]
533 if suffix == 'without patch':
534 test_list = "\n".join(self.failures(api, 'with patch'))
535 args.extend(['--test-list', api.raw_io.input(test_list),
536 '--skipped', 'always'])
537
538 if 'oilpan' in api.properties['buildername']:
539 args.extend(['--additional-expectations',
540 api.path['checkout'].join('third_party', 'WebKit',
541 'LayoutTests',
542 'OilpanExpectations')])
543
544 def followup_fn(step_result):
545 r = step_result.json.test_results
546 p = step_result.presentation
547
548 p.step_text += api.test_utils.format_step_text([
549 ['unexpected_flakes:', r.unexpected_flakes.keys()],
550 ['unexpected_failures:', r.unexpected_failures.keys()],
551 ['Total executed: %s' % r.num_passes],
552 ])
553
554 if r.unexpected_flakes or r.unexpected_failures:
555 p.status = 'WARNING'
556 else:
557 p.status = 'SUCCESS'
558
559 yield api.chromium.runtest(self.layout_test_wrapper,
560 args,
561 name=self._step_name(suffix),
562 can_fail_build=False,
563 followup_fn=followup_fn)
564
565 if suffix == 'with patch':
566 buildername = api.properties['buildername']
567 buildnumber = api.properties['buildnumber']
568 def archive_webkit_tests_results_followup(step_result):
569 base = (
570 "https://storage.googleapis.com/chromium-layout-test-archives/%s/%s"
571 % (buildername, buildnumber))
572
573 step_result.presentation.links['layout_test_results'] = (
574 base + '/layout-test-results/results.html')
575 step_result.presentation.links['(zip)'] = (
576 base + '/layout-test-results.zip')
577
578 archive_layout_test_results = api.path['build'].join(
579 'scripts', 'slave', 'chromium', 'archive_layout_test_results.py')
580
581 yield api.python(
582 'archive_webkit_tests_results',
583 archive_layout_test_results,
584 [
585 '--results-dir', self.results_dir,
586 '--build-dir', api.chromium.c.build_dir,
587 '--build-number', buildnumber,
588 '--builder-name', buildername,
589 '--gs-bucket', 'gs://chromium-layout-test-archives',
590 ] + api.json.property_args(),
591 followup_fn=archive_webkit_tests_results_followup
592 )
593
594 def has_valid_results(self, api, suffix):
595 step = api.step_history[self._step_name(suffix)]
596 # TODO(dpranke): crbug.com/357866 - note that all comparing against
597 # MAX_FAILURES_EXIT_STATUS tells us is that we did not exit early
598 # or abnormally; it does not tell us how many failures there actually
599 # were, which might be much higher (up to 5000 diffs, where we
600 # would bail out early with --exit-after-n-failures) or lower
601 # if we bailed out after 100 crashes w/ -exit-after-n-crashes, in
602 # which case the retcode is actually 130
603 return (step.json.test_results.valid and
604 step.retcode <= step.json.test_results.MAX_FAILURES_EXIT_STATUS)
605
606 def failures(self, api, suffix):
607 sn = self._step_name(suffix)
608 return api.step_history[sn].json.test_results.unexpected_failures
204 609
205 610
206 IOS_TESTS = [ 611 IOS_TESTS = [
207 GTestTest('base_unittests'), 612 GTestTest('base_unittests'),
208 GTestTest('components_unittests'), 613 GTestTest('components_unittests'),
209 GTestTest('crypto_unittests'), 614 GTestTest('crypto_unittests'),
210 GTestTest('gfx_unittests'), 615 GTestTest('gfx_unittests'),
211 GTestTest('url_unittests'), 616 GTestTest('url_unittests'),
212 GTestTest('content_unittests'), 617 GTestTest('content_unittests'),
213 GTestTest('net_unittests'), 618 GTestTest('net_unittests'),
214 GTestTest('ui_unittests'), 619 GTestTest('ui_unittests'),
215 GTestTest('sync_unit_tests'), 620 GTestTest('sync_unit_tests'),
216 GTestTest('sql_unittests'), 621 GTestTest('sql_unittests'),
217 ] 622 ]
OLDNEW
« no previous file with comments | « scripts/slave/recipe_modules/chromium/chromium_chromiumos.py ('k') | scripts/slave/recipe_modules/test_utils/api.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698