blob: a49c54d784fee204f6f98e0ff33fc76b85b48b90 [file] [log] [blame]
# Copyright 2020 The LUCI Authors. All rights reserved.
# Use of this source code is governed under the Apache License, Version 2.0
# that can be found in the LICENSE file.
"""Simple recipe which runs a bunch of subprocesses which react to early
termination in different ways."""
DEPS = [
'file',
'futures',
'path',
'platform',
'step',
]
from PB.recipes.recipe_engine.engine_tests import early_termination
PROPERTIES = early_termination.InputProperties
def RunSteps(api, props):
work = []
output_touchfile = props.output_touchfile
if not output_touchfile:
output_touchfile = api.path.cleanup_dir.joinpath('output_touchfile')
running_touchfile = props.running_touchfile
if not running_touchfile:
running_touchfile = api.path.cleanup_dir.joinpath('running_touchfile')
# make sure touchfile is there
api.file.write_text("ensure output_touchfile", output_touchfile,
"meep".encode('utf-8'))
# note that our helper script
# * Looks for the output touchfile as the first arg
# * Looks for `--always-ignore` or `--no-handler` somewhere in argv
# * Ignores everything else.
#
# We add the step name at the end of the command so that when debugging this
# locally it's easy to tell which processes are which with e.g. `pstree`.
# This one tries its darndest to stay alive
work.append(
api.futures.spawn_immediate(api.step, 'ignore always', [
'python3',
api.resource('sleepytime.py'), output_touchfile, '--always-ignore',
'ignore always'
]))
# This one nicely quits on TERM
work.append(
api.futures.spawn_immediate(api.step, 'nice shutdown', [
'python3',
api.resource('sleepytime.py'), output_touchfile, 'nice shutdown'
]))
# This one is self-timed-out
work.append(
api.futures.spawn_immediate(
api.step,
'self timeout', [
'python3',
api.resource('sleepytime.py'), output_touchfile,
'--always-ignore', 'self timeout'
],
timeout=5))
def _pure_sleep():
# This one is totally oblivious
try:
api.step('sleep', [
'python3',
api.resource('sleepytime.py'), output_touchfile, '--no-handler',
'sleep'
])
except Exception: # pragma: no cover
# BAD! don't do bare exceptions... however...
api.step('no run', None).presentation.step_text = "I don't run"
work.append(api.futures.spawn_immediate(_pure_sleep))
# all greenlets running, write our running file
api.file.write_text("ensure running_touchfile", running_touchfile,
"meep".encode('utf-8'))
for w in work:
w.exception() # mark exception as handled.
def GenTests(api):
yield api.test('basic')