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

Side by Side Diff: scripts/slave/unittests/expect_tests/pipeline.py

Issue 355143002: Set coverage path globs on a per-Test basis instead of in main(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: fix _covers 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 import Queue 5 import Queue
6 import glob 6 import glob
7 import logging 7 import logging
8 import multiprocessing 8 import multiprocessing
9 import re 9 import re
10 import signal 10 import signal
11 import traceback 11 import traceback
12 12
13 from cStringIO import StringIO 13 from cStringIO import StringIO
14 14
15 from .type_definitions import ( 15 from .type_definitions import (
16 Test, UnknownError, TestError, NoMatchingTestsError, MultiTest, 16 Test, UnknownError, TestError, NoMatchingTestsError, MultiTest,
17 Result, ResultStageAbort) 17 Result, ResultStageAbort)
18 18
19 from . import util
20
19 21
20 class ResetableStringIO(object): 22 class ResetableStringIO(object):
21 def __init__(self): 23 def __init__(self):
22 self._stream = StringIO() 24 self._stream = StringIO()
23 25
24 def reset(self): 26 def reset(self):
25 self._stream = StringIO() 27 self._stream = StringIO()
26 28
27 def __getattr__(self, key): 29 def __getattr__(self, key):
28 return getattr(self._stream, key) 30 return getattr(self._stream, key)
(...skipping 24 matching lines...) Expand all
53 matcher = re.compile('^.*$') 55 matcher = re.compile('^.*$')
54 56
55 neg_matcher = re.compile( 57 neg_matcher = re.compile(
56 '^%s$' % '|'.join('(?:%s)' % glob.fnmatch.translate(g[1:]) 58 '^%s$' % '|'.join('(?:%s)' % glob.fnmatch.translate(g[1:])
57 for g in globs if g[0] == '-')) 59 for g in globs if g[0] == '-'))
58 60
59 def generate_tests(): 61 def generate_tests():
60 paths_seen = set() 62 paths_seen = set()
61 seen_tests = False 63 seen_tests = False
62 try: 64 try:
63 for root_test in gen(): 65 with cover_ctx:
66 gen_inst = gen()
67
68 while not kill_switch.is_set():
69 with cover_ctx:
70 root_test = next(gen_inst)
71
64 if kill_switch.is_set(): 72 if kill_switch.is_set():
65 break 73 break
66 74
67 ok_tests = [] 75 ok_tests = []
68 76
69 if isinstance(root_test, MultiTest): 77 if isinstance(root_test, MultiTest):
70 subtests = root_test.tests 78 subtests = root_test.tests
71 else: 79 else:
72 subtests = [root_test] 80 subtests = [root_test]
73 81
(...skipping 14 matching lines...) Expand all
88 name = subtest.name 96 name = subtest.name
89 if not neg_matcher.match(name) and matcher.match(name): 97 if not neg_matcher.match(name) and matcher.match(name):
90 ok_tests.append(subtest) 98 ok_tests.append(subtest)
91 99
92 if ok_tests: 100 if ok_tests:
93 seen_tests = True 101 seen_tests = True
94 yield root_test.restrict(ok_tests) 102 yield root_test.restrict(ok_tests)
95 103
96 if not seen_tests: 104 if not seen_tests:
97 result_queue.put_nowait(NoMatchingTestsError()) 105 result_queue.put_nowait(NoMatchingTestsError())
106 except StopIteration:
107 pass
98 except KeyboardInterrupt: 108 except KeyboardInterrupt:
99 pass 109 pass
100 finally: 110 finally:
101 for _ in xrange(opts.jobs): 111 for _ in xrange(opts.jobs):
102 test_queue.put_nowait(None) 112 test_queue.put_nowait(None)
103 113
104 114
105 next_stage = (result_queue if opts.handler.SKIP_RUNLOOP else test_queue) 115 next_stage = (result_queue if opts.handler.SKIP_RUNLOOP else test_queue)
106 with cover_ctx: 116 opts.handler.gen_stage_loop(opts, generate_tests(), next_stage.put_nowait,
107 opts.handler.gen_stage_loop(opts, generate_tests(), next_stage.put_nowait, 117 result_queue.put_nowait)
108 result_queue.put_nowait)
109 118
110 119
111 def run_loop_process(test_queue, result_queue, opts, kill_switch, cover_ctx): 120 def run_loop_process(test_queue, result_queue, opts, kill_switch, cover_ctx):
112 """Consume `Test` instances from |test_queue|, run them, and yield the results 121 """Consume `Test` instances from |test_queue|, run them, and yield the results
113 into opts.run_stage_loop(). 122 into opts.run_stage_loop().
114 123
115 Generates coverage data as a side-effect. 124 Generates coverage data as a side-effect.
125
116 @type test_queue: multiprocessing.Queue() 126 @type test_queue: multiprocessing.Queue()
117 @type result_queue: multiprocessing.Queue() 127 @type result_queue: multiprocessing.Queue()
118 @type opts: argparse.Namespace 128 @type opts: argparse.Namespace
119 @type kill_switch: multiprocessing.Event() 129 @type kill_switch: multiprocessing.Event()
120 @type cover_ctx: cover.CoverageContext().create_subprocess_context() 130 @type cover_ctx: cover.CoverageContext().create_subprocess_context()
121 """ 131 """
122 logstream = ResetableStringIO() 132 logstream = ResetableStringIO()
123 logger = logging.getLogger() 133 logger = logging.getLogger()
124 logger.setLevel(logging.DEBUG) 134 logger.setLevel(logging.DEBUG)
125 shandler = logging.StreamHandler(logstream) 135 shandler = logging.StreamHandler(logstream)
126 shandler.setFormatter( 136 shandler.setFormatter(
127 logging.Formatter('%(levelname)s: %(message)s')) 137 logging.Formatter('%(levelname)s: %(message)s'))
128 logger.addHandler(shandler) 138 logger.addHandler(shandler)
129 139
130 SKIP = object() 140 SKIP = object()
131 def process_test(subtest): 141 def process_test(subtest):
132 logstream.reset() 142 logstream.reset()
133 subresult = subtest.run() 143 with cover_ctx(include=subtest.coverage_includes()):
144 subresult = subtest.run()
134 if isinstance(subresult, TestError): 145 if isinstance(subresult, TestError):
135 result_queue.put_nowait(subresult) 146 result_queue.put_nowait(subresult)
136 return SKIP 147 return SKIP
137 elif not isinstance(subresult, Result): 148 elif not isinstance(subresult, Result):
138 result_queue.put_nowait( 149 result_queue.put_nowait(
139 TestError( 150 TestError(
140 subtest, 151 subtest,
141 'Got non-Result instance from test: %r' % subresult)) 152 'Got non-Result instance from test: %r' % subresult))
142 return SKIP 153 return SKIP
143 return subresult 154 return subresult
(...skipping 12 matching lines...) Expand all
156 for subtest, subresult in test.process(process_test): 167 for subtest, subresult in test.process(process_test):
157 if subresult is not SKIP: 168 if subresult is not SKIP:
158 yield subtest, subresult, logstream.getvalue().splitlines() 169 yield subtest, subresult, logstream.getvalue().splitlines()
159 except Exception: 170 except Exception:
160 result_queue.put_nowait( 171 result_queue.put_nowait(
161 TestError(test, traceback.format_exc(), 172 TestError(test, traceback.format_exc(),
162 logstream.getvalue().splitlines())) 173 logstream.getvalue().splitlines()))
163 except KeyboardInterrupt: 174 except KeyboardInterrupt:
164 pass 175 pass
165 176
166 with cover_ctx: 177 opts.handler.run_stage_loop(opts, generate_tests_results(),
167 opts.handler.run_stage_loop(opts, generate_tests_results(), 178 result_queue.put_nowait)
168 result_queue.put_nowait)
169 179
170 180
171 def result_loop(test_gen, cover_ctx, opts): 181 def result_loop(test_gen, cover_ctx, opts):
172 kill_switch = multiprocessing.Event() 182 kill_switch = multiprocessing.Event()
173 def handle_killswitch(*_): 183 def handle_killswitch(*_):
174 kill_switch.set() 184 kill_switch.set()
175 # Reset the signal to DFL so that double ctrl-C kills us for sure. 185 # Reset the signal to DFL so that double ctrl-C kills us for sure.
176 signal.signal(signal.SIGINT, signal.SIG_DFL) 186 signal.signal(signal.SIGINT, signal.SIG_DFL)
177 signal.signal(signal.SIGTERM, signal.SIG_DFL) 187 signal.signal(signal.SIGTERM, signal.SIG_DFL)
178 signal.signal(signal.SIGINT, handle_killswitch) 188 signal.signal(signal.SIGINT, handle_killswitch)
179 signal.signal(signal.SIGTERM, handle_killswitch) 189 signal.signal(signal.SIGTERM, handle_killswitch)
180 190
181 test_queue = multiprocessing.Queue() 191 test_queue = multiprocessing.Queue()
182 result_queue = multiprocessing.Queue() 192 result_queue = multiprocessing.Queue()
183 193
194 gen_cover_ctx = cover_ctx
195 if cover_ctx.enabled:
196 gen_cover_ctx = cover_ctx(include=util.get_cover_list(test_gen))
197
184 test_gen_args = ( 198 test_gen_args = (
185 test_gen, test_queue, result_queue, opts, kill_switch, cover_ctx) 199 test_gen, test_queue, result_queue, opts, kill_switch, gen_cover_ctx)
186 200
187 procs = [] 201 procs = []
188 if opts.handler.SKIP_RUNLOOP: 202 if opts.handler.SKIP_RUNLOOP:
189 gen_loop_process(*test_gen_args) 203 gen_loop_process(*test_gen_args)
190 else: 204 else:
191 procs = [multiprocessing.Process( 205 procs = [multiprocessing.Process(
192 target=gen_loop_process, args=test_gen_args)] 206 target=gen_loop_process, args=test_gen_args)]
193 207
194 procs += [ 208 procs += [
195 multiprocessing.Process( 209 multiprocessing.Process(
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 except ResultStageAbort: 243 except ResultStageAbort:
230 pass 244 pass
231 245
232 for p in procs: 246 for p in procs:
233 p.join() 247 p.join()
234 248
235 if not kill_switch.is_set() and not result_queue.empty(): 249 if not kill_switch.is_set() and not result_queue.empty():
236 error = True 250 error = True
237 251
238 return error, kill_switch.is_set() 252 return error, kill_switch.is_set()
OLDNEW
« no previous file with comments | « scripts/slave/unittests/expect_tests/main.py ('k') | scripts/slave/unittests/expect_tests/type_definitions.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698