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

Side by Side Diff: recipe_engine/run.py

Issue 2245113002: Track step nesting in StreamEngine. (Closed) Base URL: https://github.com/luci/recipes-py@emit-initial-properties
Patch Set: Iterate Created 4 years, 4 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
« no previous file with comments | « no previous file | recipe_engine/simulation_test.py » ('j') | recipe_engine/stream.py » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2016 The LUCI Authors. All rights reserved. 1 # Copyright 2016 The LUCI Authors. All rights reserved.
2 # Use of this source code is governed under the Apache License, Version 2.0 2 # Use of this source code is governed under the Apache License, Version 2.0
3 # that can be found in the LICENSE file. 3 # that can be found in the LICENSE file.
4 4
5 """Entry point for fully-annotated builds. 5 """Entry point for fully-annotated builds.
6 6
7 This script is part of the effort to move all builds to annotator-based 7 This script is part of the effort to move all builds to annotator-based
8 systems. Any builder configured to use the AnnotatorFactory.BaseFactory() 8 systems. Any builder configured to use the AnnotatorFactory.BaseFactory()
9 found in scripts/master/factory/annotator_factory.py executes a single 9 found in scripts/master/factory/annotator_factory.py executes a single
10 AddAnnotatedScript step. That step (found in annotator_commands.py) calls 10 AddAnnotatedScript step. That step (found in annotator_commands.py) calls
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 """ 289 """
290 Knows how to execute steps emitted by a recipe, holds global state such as 290 Knows how to execute steps emitted by a recipe, holds global state such as
291 step history and build properties. Each recipe module API has a reference to 291 step history and build properties. Each recipe module API has a reference to
292 this object. 292 this object.
293 293
294 Recipe modules that are aware of the engine: 294 Recipe modules that are aware of the engine:
295 * properties - uses engine.properties. 295 * properties - uses engine.properties.
296 * step - uses engine.create_step(...), and previous_step_result. 296 * step - uses engine.create_step(...), and previous_step_result.
297 """ 297 """
298 298
299 ActiveStep = collections.namedtuple('ActiveStep', 299 ActiveStep = collections.namedtuple('ActiveStep', (
300 'step step_result open_step nest_level') 300 'step', 'step_result', 'open_step', 'nest_level'))
301 301
302 def __init__(self, step_runner, properties, universe_view): 302 def __init__(self, step_runner, properties, universe_view):
303 """See run_steps() for parameter meanings.""" 303 """See run_steps() for parameter meanings."""
304 self._step_runner = step_runner 304 self._step_runner = step_runner
305 self._properties = properties 305 self._properties = properties
306 self._universe_view = universe_view 306 self._universe_view = universe_view
307 307
308 # A stack of ActiveStep objects, holding the most recently executed step at 308 # A stack of ActiveStep objects, holding the most recently executed step at
309 # each nest level (objects deeper in the stack have lower nest levels). 309 # each nest level (objects deeper in the stack have lower nest levels).
310 # When we pop from this stack, we close the corresponding step stream. 310 # When we pop from this stack, we close the corresponding step stream.
(...skipping 25 matching lines...) Expand all
336 336
337 This always returns the innermost nested step that is still open -- 337 This always returns the innermost nested step that is still open --
338 presumably the one that just failed if we are in an exception handler.""" 338 presumably the one that just failed if we are in an exception handler."""
339 if not self._step_stack: 339 if not self._step_stack:
340 raise ValueError( 340 raise ValueError(
341 "No steps have been run yet, and you are asking for a previous step" 341 "No steps have been run yet, and you are asking for a previous step"
342 " result. Check to make sure your code isn't doing incorrect logic" 342 " result. Check to make sure your code isn't doing incorrect logic"
343 " with try-finally blocks.") 343 " with try-finally blocks.")
344 return self._step_stack[-1].step_result 344 return self._step_stack[-1].step_result
345 345
346 def _close_to_level(self, level): 346 def _close_through_level(self, level):
347 """Close all open steps that are at least as deep as level.""" 347 """Close all open steps whose nest level is >= the supplied level.
348 while self._step_stack and level <= self._step_stack[-1].nest_level: 348
349 Args:
350 level (int): the nest level to close through.
351 """
352 while self._step_stack and self._step_stack[-1].nest_level >= level:
349 cur = self._step_stack.pop() 353 cur = self._step_stack.pop()
350 if cur.step_result: 354 if cur.step_result:
351 cur.step_result.presentation.finalize(cur.open_step.stream) 355 cur.step_result.presentation.finalize(cur.open_step.stream)
352 cur.open_step.finalize() 356 cur.open_step.finalize()
353 357
354 def run_step(self, step): 358 def run_step(self, step):
355 """ 359 """
356 Runs a step. 360 Runs a step.
357 361
358 Args: 362 Args:
359 step: The step to run. 363 step: The step to run.
360 364
361 Returns: 365 Returns:
362 A StepData object containing the result of running the step. 366 A StepData object containing the result of running the step.
363 """ 367 """
364 with util.raises((recipe_api.StepFailure, OSError), 368 with util.raises((recipe_api.StepFailure, OSError),
365 self._step_runner.stream_engine): 369 self._step_runner.stream_engine):
366 ok_ret = step.pop('ok_ret') 370 ok_ret = step.pop('ok_ret')
367 infra_step = step.pop('infra_step') 371 infra_step = step.pop('infra_step')
368 372
369 step_result = None 373 step_result = None
370 374
371 nest_level = step.pop('step_nest_level', 0) 375 nest_level = step.get('nest_level', 0)
372 self._close_to_level(nest_level) 376 self._close_through_level(nest_level)
373 377
374 open_step = self._step_runner.open_step(step) 378 open_step = self._step_runner.open_step(step)
375 self._step_stack.append(self.ActiveStep( 379 self._step_stack.append(self.ActiveStep(
376 step=step, 380 step=step,
377 step_result=None, 381 step_result=None,
378 open_step=open_step, 382 open_step=open_step,
379 nest_level=nest_level)) 383 nest_level=nest_level))
380 if nest_level:
381 open_step.stream.set_nest_level(nest_level)
382 384
383 step_result = open_step.run() 385 step_result = open_step.run()
384 self._step_stack[-1] = ( 386 self._step_stack[-1] = (
385 self._step_stack[-1]._replace(step_result=step_result)) 387 self._step_stack[-1]._replace(step_result=step_result))
386 388
387 if step_result.retcode in ok_ret: 389 if step_result.retcode in ok_ret:
388 step_result.presentation.status = 'SUCCESS' 390 step_result.presentation.status = 'SUCCESS'
389 return step_result 391 return step_result
390 else: 392 else:
391 if not infra_step: 393 if not infra_step:
(...skipping 29 matching lines...) Expand all
421 423
422 with self._step_runner.run_context(): 424 with self._step_runner.run_context():
423 try: 425 try:
424 try: 426 try:
425 recipe_result = recipe_script.run(api, api._engine.properties) 427 recipe_result = recipe_script.run(api, api._engine.properties)
426 result = { 428 result = {
427 "recipe_result": recipe_result, 429 "recipe_result": recipe_result,
428 "status_code": 0 430 "status_code": 0
429 } 431 }
430 finally: 432 finally:
431 self._close_to_level(0) 433 self._close_through_level(0)
432 except recipe_api.StepFailure as f: 434 except recipe_api.StepFailure as f:
433 result = { 435 result = {
434 # Include "recipe_result" so it doesn't get marked as infra failure. 436 # Include "recipe_result" so it doesn't get marked as infra failure.
435 "recipe_result": None, 437 "recipe_result": None,
436 "reason": f.reason, 438 "reason": f.reason,
437 "status_code": f.retcode or 1 439 "status_code": f.retcode or 1
438 } 440 }
439 except types.StepDataAttributeError as ex: 441 except types.StepDataAttributeError as ex:
440 result = { 442 result = {
441 "reason": "Invalid Step Data Access: %r" % ex, 443 "reason": "Invalid Step Data Access: %r" % ex,
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 results.append( 503 results.append(
502 loader._invoke_with_properties( 504 loader._invoke_with_properties(
503 run_recipe, properties, recipe_script.PROPERTIES, 505 run_recipe, properties, recipe_script.PROPERTIES,
504 properties.keys())) 506 properties.keys()))
505 except TypeError as e: 507 except TypeError as e:
506 raise TypeError( 508 raise TypeError(
507 "Got %r while trying to call recipe %s with properties %r" % ( 509 "Got %r while trying to call recipe %s with properties %r" % (
508 e, recipe, properties)) 510 e, recipe, properties))
509 511
510 return results 512 return results
OLDNEW
« no previous file with comments | « no previous file | recipe_engine/simulation_test.py » ('j') | recipe_engine/stream.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698