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

Side by Side Diff: scripts/slave/recipe_modules/test_utils/api.py

Issue 313693003: Swarming: conditionally run tests on swarming in chromium_trybot recipe. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: rebase Created 6 years, 6 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
« no previous file with comments | « scripts/slave/recipe_modules/swarming/api.py ('k') | scripts/slave/recipes/chromium_trybot.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2013 The Chromium Authors. All rights reserved. 1 # Copyright 2013 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 from slave import recipe_api 5 from slave import recipe_api
6 6
7 class TestUtilsApi(recipe_api.RecipeApi): 7 class TestUtilsApi(recipe_api.RecipeApi):
8 @staticmethod 8 @staticmethod
9 def format_step_text(data): 9 def format_step_text(data):
10 """ 10 """
(...skipping 28 matching lines...) Expand all
39 """ 39 """
40 Base class for tests that can be retried after deapplying a previously 40 Base class for tests that can be retried after deapplying a previously
41 applied patch. 41 applied patch.
42 """ 42 """
43 43
44 @property 44 @property
45 def name(self): # pragma: no cover 45 def name(self): # pragma: no cover
46 """Name of the test.""" 46 """Name of the test."""
47 raise NotImplementedError() 47 raise NotImplementedError()
48 48
49 def pre_run(self, suffix): # pragma: no cover
50 """Steps to execute before running the test."""
51 return []
52
49 def run(self, suffix): # pragma: no cover 53 def run(self, suffix): # pragma: no cover
50 """Run the test. suffix is 'with patch' or 'without patch'.""" 54 """Run the test. suffix is 'with patch' or 'without patch'."""
51 raise NotImplementedError() 55 raise NotImplementedError()
52 56
57 def post_run(self, suffix): # pragma: no cover
58 """Steps to execute after running the test."""
59 return []
60
53 def has_valid_results(self, suffix): # pragma: no cover 61 def has_valid_results(self, suffix): # pragma: no cover
54 """ 62 """
55 Returns True if results (failures) are valid. 63 Returns True if results (failures) are valid.
56 64
57 This makes it possible to distinguish between the case of no failures 65 This makes it possible to distinguish between the case of no failures
58 and the test failing to even report its results in machine-readable 66 and the test failing to even report its results in machine-readable
59 format. 67 format.
60 """ 68 """
61 raise NotImplementedError() 69 raise NotImplementedError()
62 70
63 def failures(self, suffix): # pragma: no cover 71 def failures(self, suffix): # pragma: no cover
64 """Return list of failures (list of strings).""" 72 """Return list of failures (list of strings)."""
65 raise NotImplementedError() 73 raise NotImplementedError()
66 74
67 def _step_name(self, suffix): 75 def _step_name(self, suffix):
68 """Helper to uniformly combine tests's name with a suffix.""" 76 """Helper to uniformly combine tests's name with a suffix."""
69 return '%s (%s)' % (self.name, suffix) 77 return '%s (%s)' % (self.name, suffix)
70 78
71 def determine_new_failures(self, tests, deapply_patch_fn): 79 def determine_new_failures(self, tests, deapply_patch_fn):
72 """ 80 """
73 Utility function for running steps with a patch applied, and retrying 81 Utility function for running steps with a patch applied, and retrying
74 failing steps without the patch. Failures from the run without the patch are 82 failing steps without the patch. Failures from the run without the patch are
75 ignored. 83 ignored.
76 84
77 Args: 85 Args:
78 tests - iterable of objects implementing the Test interface above 86 tests - iterable of objects implementing the Test interface above
79 deapply_patch_fn - function that takes a list of failing tests 87 deapply_patch_fn - function that takes a list of failing tests
80 and undoes any effect of the previously applied patch 88 and undoes any effect of the previously applied patch
81 """ 89 """
90 # Convert iterable to list, since it is enumerated multiple times.
91 tests = list(tests)
92
82 if self.m.step_history.failed: 93 if self.m.step_history.failed:
83 yield self.m.python.inline( 94 yield self.m.python.inline(
84 'Aborting due to failed build state.', 95 'Aborting due to failed build state.',
85 "import sys; sys.exit(1)", 96 "import sys; sys.exit(1)",
86 always_run=True, abort_on_failure=True) 97 always_run=True, abort_on_failure=True)
87 return # won't actually hit this, but be explicit 98 return # won't actually hit this, but be explicit
88 99
89 yield (t.run('with patch') for t in tests) 100 def run(prefix, tests):
101 yield (t.pre_run(prefix) for t in tests)
102 yield (t.run(prefix) for t in tests)
103 yield (t.post_run(prefix) for t in tests)
104
105 yield run('with patch', tests)
90 106
91 failing_tests = [] 107 failing_tests = []
92 for t in tests: 108 for t in tests:
93 if not t.has_valid_results('with patch'): 109 if not t.has_valid_results('with patch'):
94 yield self.m.python.inline( 110 yield self.m.python.inline(
95 t.name, 111 t.name,
96 r""" 112 r"""
97 import sys 113 import sys
98 print 'TEST RESULTS WERE INVALID' 114 print 'TEST RESULTS WERE INVALID'
99 sys.exit(1) 115 sys.exit(1)
100 """, 116 """,
101 always_run=True) 117 always_run=True)
102 elif t.failures('with patch'): 118 elif t.failures('with patch'):
103 failing_tests.append(t) 119 failing_tests.append(t)
104 if not failing_tests: 120 if not failing_tests:
105 return 121 return
106 122
107 yield deapply_patch_fn(failing_tests) 123 yield deapply_patch_fn(failing_tests)
108 124
109 yield (t.run('without patch') for t in failing_tests) 125 yield run('without patch', failing_tests)
110 yield (self._summarize_retried_test(t) for t in failing_tests) 126 yield (self._summarize_retried_test(t) for t in failing_tests)
111 127
112 def _summarize_retried_test(self, test): 128 def _summarize_retried_test(self, test):
113 if not test.has_valid_results('without patch'): 129 if not test.has_valid_results('without patch'):
114 return self.m.python.inline( 130 return self.m.python.inline(
115 test.name, 131 test.name,
116 r""" 132 r"""
117 import sys 133 import sys
118 print 'TEST RESULTS WERE INVALID' 134 print 'TEST RESULTS WERE INVALID'
119 sys.exit(1) 135 sys.exit(1)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 """, 175 """,
160 args=[ 176 args=[
161 self.m.json.input({ 177 self.m.json.input({
162 'new': list(new_failures), 178 'new': list(new_failures),
163 'ignored': list(ignored_failures), 179 'ignored': list(ignored_failures),
164 }) 180 })
165 ], 181 ],
166 followup_fn=followup_fn, 182 followup_fn=followup_fn,
167 always_run=True, 183 always_run=True,
168 ) 184 )
OLDNEW
« no previous file with comments | « scripts/slave/recipe_modules/swarming/api.py ('k') | scripts/slave/recipes/chromium_trybot.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698