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

Side by Side Diff: recipe_modules/step/example.py

Issue 2909983003: [loader] Make recipe engine support examples/ module subdir (Closed)
Patch Set: Created 3 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
OLDNEW
(Empty)
1 # Copyright 2013 The LUCI Authors. All rights reserved.
2 # Use of this source code is governed under the Apache License, Version 2.0
3 # that can be found in the LICENSE file.
4
5 from recipe_engine import recipe_api, config
6
7 DEPS = [
8 'context',
9 'path',
10 'properties',
11 'step',
12 ]
13
14
15 RETURN_SCHEMA = config.ReturnSchema(
16 test_me=config.Single(int)
17 )
18
19
20 PROPERTIES = {
21 'bad_return': recipe_api.Property(default=False),
22 'access_invalid_data': recipe_api.Property(default=False),
23 'timeout': recipe_api.Property(default=0, kind=int),
24 }
25
26
27 def RunSteps(api, bad_return, access_invalid_data, timeout):
28 if bad_return:
29 return RETURN_SCHEMA.new(test_me='this should fail')
30 elif timeout:
31 # Timeout causes the recipe engine to raise an exception if your step takes
32 # longer to run than you allow. Units are seconds.
33 if timeout == 1:
34 api.step('timeout', ['sleep', '20'], timeout=1)
35 elif timeout == 2:
36 try:
37 api.step('caught timeout', ['sleep', '20'], timeout=1)
38 except api.step.StepTimeout:
39 return RETURN_SCHEMA(test_me=4)
40
41
42 # TODO(martinis) change this
43 # The api.step object is directly callable.
44 api.step('hello', ['echo', 'Hello World'])
45 api.step('hello', ['echo', 'Why hello, there.'])
46
47 # You can change the current working directory as well
48 api.step('mk subdir', ['mkdir', '-p', 'something'])
49 with api.step.context({'cwd': api.path['start_dir'].join('something')}):
50 api.step('something', ['bash', '-c', 'echo Why hello, there, in a subdir.'])
51
52 # By default, all steps run in 'start_dir', or the cwd of the recipe engine
53 # when the recipe begins. Because of this, setting cwd to start_dir doesn't
54 # show anything in particular in the expectations.
55 with api.step.context({'cwd': api.path['start_dir']}):
56 api.step('start_dir ignored', ['bash', '-c', 'echo what happen'])
57
58 # You can also manipulate various aspects of the step, such as env.
59 # These are passed straight through to subprocess.Popen.
60 # Also, abusing bash -c in this way is a TERRIBLE IDEA DON'T DO IT.
61 with api.context(env={'friend': 'Darth Vader'}):
62 api.step('goodbye', ['bash', '-c', 'echo Good bye, $friend.'])
63
64 # You can modify environment in terms of old environment. Environment
65 # variables are substituted in for expressions of the form %(VARNAME)s.
66 with api.context(env={'PATH': api.path.pathsep.join(
67 [str(api.step.package_repo_resource()), '%(PATH)s'])}):
68 api.step('recipes help', ['recipes.py', '--help'])
69
70 # Finally, you can make your step accept any return code
71 api.step('anything is cool', ['bash', '-c', 'exit 3'],
72 ok_ret='any')
73
74 # We can manipulate the step presentation arbitrarily until we run
75 # the next step.
76 step_result = api.step('hello', ['echo', 'hello'])
77 step_result.presentation.status = api.step.EXCEPTION
78 step_result.presentation.logs['the reason'] = ['The reason\nit failed']
79
80 # Without a command, a step can be used to present some data from the recipe.
81 step_result = api.step('Just print stuff', cmd=None)
82 step_result.presentation.logs['more'] = ['More stuff']
83
84 try:
85 api.step('goodbye', ['echo', 'goodbye'])
86 # Modifying step_result now would raise an AssertionError.
87 except api.step.StepFailure:
88 # Raising anything besides StepFailure or StepWarning causes the build to go
89 # purple.
90 raise ValueError('goodbye must exit 0!')
91
92 try:
93 api.step('warning', ['echo', 'warning'])
94 except api.step.StepFailure as e:
95 e.result.presentation.status = api.step.WARNING
96 raise api.step.StepWarning(e.message)
97
98
99 # Aggregate failures from tests!
100 try:
101 with recipe_api.defer_results():
102 api.step('testa', ['echo', 'testa'])
103 api.step('testb', ['echo', 'testb'])
104 except recipe_api.AggregatedStepFailure as f:
105 raise api.step.StepFailure("You can catch step failures.")
106
107 # Some steps are needed from an infrastructure point of view. If these
108 # steps fail, the build stops, but doesn't get turned red because it's
109 # not the developers' fault.
110 try:
111 api.step('cleanup', ['echo', 'cleaning', 'up', 'build'], infra_step=True)
112 except api.step.InfraFailure as f:
113 assert f.result.presentation.status == api.step.EXCEPTION
114
115 # Run a step through a made-up wrapper program.
116 api.step('application', ['echo', 'main', 'application'],
117 wrapper=['python', '-c', 'import sys; print sys.argv'])
118
119 if access_invalid_data:
120 result = api.step('no-op', ['echo', 'I', 'do', 'nothing'])
121 # Trying to access non-existent attributes on the result should raise.
122 _ = result.json.output
123
124 return RETURN_SCHEMA(test_me=3)
125
126
127 def GenTests(api):
128 yield (
129 api.test('basic') +
130 api.step_data('anything is cool', retcode=3)
131 )
132
133 # If you don't have the expect_exception in this test, you will get something
134 # like this output.
135 # ======================================================================
136 # ERROR: step:example.exceptional (..../exceptional.json)
137 # ----------------------------------------------------------------------
138 # Traceback (most recent call last):
139 # <full stack trace ommitted>
140 # File "annotated_run.py", line 537, in run
141 # retcode = steps_function(api)
142 # File "recipe_modules/step/example.py", line 39, in RunSteps
143 # raise ValueError('goodbye must exit 0!')
144 # ValueError: goodbye must exit 0!
145
146 yield (
147 api.test('exceptional') +
148 api.step_data('goodbye (2)', retcode=1) +
149 api.expect_exception('ValueError')
150 )
151
152 yield (
153 api.test('warning') +
154 api.step_data('warning', retcode=1)
155 )
156
157 yield (
158 api.test('defer_results') +
159 api.step_data('testa', retcode=1)
160 )
161
162 yield (
163 api.test('invalid_access') +
164 api.properties(access_invalid_data=True) +
165 api.expect_exception('StepDataAttributeError')
166 )
167
168 yield (
169 api.test('infra_failure') +
170 api.step_data('cleanup', retcode=1)
171 )
172
173 yield (
174 api.test('bad_return') +
175 api.properties(bad_return=True) +
176 api.expect_exception('TypeError')
177 )
178
179 yield (
180 api.test('timeout') +
181 api.properties(timeout=1) +
182 api.step_data('timeout', times_out_after=20)
183 )
184
185 yield (
186 api.test('catch_timeout') +
187 api.properties(timeout=2) +
188 api.step_data('caught timeout', times_out_after=20)
189 )
OLDNEW
« no previous file with comments | « recipe_modules/shutil/examples/full.expected/basic.json ('k') | recipe_modules/step/example.expected/bad_return.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698