• Home
Name Date Size #Lines LOC

..--

analysis/12-May-2024-11442

assets/12-May-2024-2,6191,535

buildstats/12-May-2024-454298

gen_tasks_logic/12-May-2024-4,7723,714

recipe_modules/12-May-2024-41,37639,910

recipes/12-May-2024-25,45624,834

task_drivers/12-May-2024-4,0733,364

tools/luci-go/12-May-2024-1710

MakefileD12-May-202468 64

README.mdD12-May-20243 KiB9764

README.recipes.mdD12-May-202443.9 KiB609372

build_task_drivers.shD12-May-20241.1 KiB3723

bundle_recipes.shD12-May-2024284 146

cfg.jsonD12-May-20241.1 KiB2726

check_deps.pyD12-May-20241.9 KiB7248

gen_tasks.goD12-May-2024359 197

git_utils.pyD12-May-20245.7 KiB161129

infra_tests.pyD12-May-20241.9 KiB9264

jobs.jsonD12-May-202445.9 KiB700699

recipes.pyD12-May-20248.5 KiB267176

run_recipe.pyD12-May-20241.2 KiB4129

tasks.jsonD12-May-20243.8 MiB83,43883,437

test_utils.pyD12-May-20242 KiB7450

utils.pyD12-May-20246.6 KiB204145

zip_utils.pyD12-May-20242.5 KiB7960

zip_utils_test.pyD12-May-20241.9 KiB7545

README.md

1Skia Infrastructure
2===================
3
4This directory contains infrastructure elements.
5
6
7Tasks and Jobs
8--------------
9
10Files in this directory define a DAG of tasks which run at every Skia commit. A
11task is a small, self-contained unit which runs via Swarming on a machine in the
12pool. Tasks may be chained together, eg. one task to compile test binaries and
13another to actually run them.
14
15Jobs are collections of related tasks which help define sub-sections of the DAG,
16for example, to be used as try jobs. Each job is defined as an entry point into
17the DAG.
18
19The tasks.json file in this directory is the list of tasks and jobs for
20the repo. Note that tasks.json is NEVER edited by hand but generated via
21gen_task.go and the input files enumerated below. The
22[Task Scheduler](https://skia.googlesource.com/buildbot/+/main/task_scheduler/README.md)
23reads the tasks.json file at each commit to determine which jobs to run. For
24convenience, gen_tasks.go is provided to generate tasks.json and also to test it
25for correct syntax and detecting cycles and orphaned tasks. Always edit
26gen_tasks.go or one of the following input JSON files, rather than tasks.json
27itself:
28
29  * cfg.json - Basic configuration information for gen_tasks.go.
30  * jobs.json - The list of all jobs to run. Edit this to add or remove
31      bots.
32
33Whenever gen_tasks.go, any of the above JSON files, or assets are changed, you
34need to run gen_tasks.go to regenerate tasks.json:
35
36	$ go run infra/bots/gen_tasks.go
37
38Or:
39
40	$ cd infra/bots; make train
41
42There is also a test mode which performs consistency checks and verifies that
43tasks.json is unchanged:
44
45	$ go run infra/bots/gen_tasks.go --test
46
47Or:
48
49	$ cd infra/bots; make test
50
51
52Recipes
53-------
54
55Recipes are the framework used by Skia's infrastructure to perform work inside
56of Swarming tasks. The main elements are:
57
58  * recipes.py - Used for running and testing recipes.
59  * recipes - These are the entry points for each type of task, eg. compiling
60      or running tests.
61  * recipe_modules - Shared modules which are used by recipes.
62  * .recipe_deps - Recipes and modules may depend on modules from other repos.
63      The recipes.py script automatically syncs those dependencies in this
64      directory.
65
66
67Isolate Files
68-------------
69
70These files determine which parts of the repository are transferred to the bot
71when a Swarming task is triggered. The
72[Isolate tool](https://github.com/luci/luci-py/tree/main/appengine/isolate/doc)
73hashes each file and will upload any new/changed files. Bots maintain a cache so
74that they can efficiently download only the files they don't have.
75
76
77Assets
78------
79
80Artifacts used by the infrastructure are versioned here, along with scripts for
81recreating/uploading/downloading them. See the README in that directory for more
82information. Any time an asset used by the bots changes, you need to re-run
83gen_tasks.go.
84
85
86Tools
87-----
88
89Assorted other infrastructure-related tools, eg. isolate and CIPD binaries.
90
91
92CT
93--
94
95Helpers for running Skia tasks in Cluster Telemetry.
96
97

README.recipes.md

1<!--- AUTOGENERATED BY `./recipes.py test train` -->
2# Repo documentation for [skia]()
3## Table of Contents
4
5**[Recipe Modules](#Recipe-Modules)**
6  * [build](#recipe_modules-build) (Python3 ✅) &mdash; Build Skia for various platforms.
7  * [builder_name_schema](#recipe_modules-builder_name_schema) (Python3 ✅)
8  * [checkout](#recipe_modules-checkout) (Python3 ✅)
9  * [docker](#recipe_modules-docker) (Python3 ✅)
10  * [doxygen](#recipe_modules-doxygen) (Python3 ✅)
11  * [env](#recipe_modules-env) (Python3 ✅)
12  * [flavor](#recipe_modules-flavor) (Python3 ✅)
13  * [git](#recipe_modules-git) (Python3 ✅)
14  * [gold_upload](#recipe_modules-gold_upload) (Python3 ✅)
15  * [gsutil](#recipe_modules-gsutil) (Python3 ✅)
16  * [infra](#recipe_modules-infra) (Python3 ✅)
17  * [run](#recipe_modules-run) (Python3 ✅)
18  * [vars](#recipe_modules-vars) (Python3 ✅)
19
20**[Recipes](#Recipes)**
21  * [build:examples/full](#recipes-build_examples_full) (Python3 ✅)
22  * [builder_name_schema:examples/full](#recipes-builder_name_schema_examples_full) (Python3 ✅)
23  * [check_generated_files](#recipes-check_generated_files) (Python3 ✅)
24  * [checkout:examples/full](#recipes-checkout_examples_full) (Python3 ✅)
25  * [compile](#recipes-compile) (Python3 ✅)
26  * [compute_buildstats](#recipes-compute_buildstats) (Python3 ✅)
27  * [docker:examples/full](#recipes-docker_examples_full) (Python3 ✅)
28  * [doxygen:examples/full](#recipes-doxygen_examples_full) (Python3 ✅)
29  * [env:examples/full](#recipes-env_examples_full) (Python3 ✅)
30  * [flavor:examples/full](#recipes-flavor_examples_full) (Python3 ✅)
31  * [git:examples/full](#recipes-git_examples_full) (Python3 ✅)
32  * [gold_upload:examples/full](#recipes-gold_upload_examples_full) (Python3 ✅)
33  * [gsutil:examples/full](#recipes-gsutil_examples_full) (Python3 ✅)
34  * [housekeeper](#recipes-housekeeper) (Python3 ✅)
35  * [infra](#recipes-infra) (Python3 ✅)
36  * [infra:examples/full](#recipes-infra_examples_full) (Python3 ✅)
37  * [perf](#recipes-perf) (Python3 ✅)
38  * [perf_pathkit](#recipes-perf_pathkit) (Python3 ✅)
39  * [perf_skottietrace](#recipes-perf_skottietrace) (Python3 ✅)
40  * [perf_skottiewasm_lottieweb](#recipes-perf_skottiewasm_lottieweb) (Python3 ✅)
41  * [run:examples/full](#recipes-run_examples_full) (Python3 ✅)
42  * [skpbench](#recipes-skpbench) (Python3 ✅)
43  * [sync_and_compile](#recipes-sync_and_compile) (Python3 ✅)
44  * [test](#recipes-test) (Python3 ✅)
45  * [test_canvaskit](#recipes-test_canvaskit) (Python3 ✅)
46  * [test_lottie_web](#recipes-test_lottie_web) (Python3 ✅)
47  * [test_pathkit](#recipes-test_pathkit) (Python3 ✅)
48  * [upload_buildstats_results](#recipes-upload_buildstats_results) (Python3 ✅)
49  * [upload_dm_results](#recipes-upload_dm_results) (Python3 ✅)
50  * [upload_nano_results](#recipes-upload_nano_results) (Python3 ✅)
51  * [vars:examples/full](#recipes-vars_examples_full) (Python3 ✅)
52## Recipe Modules
53
54### *recipe_modules* / [build](/infra/bots/recipe_modules/build)
55
56[DEPS](/infra/bots/recipe_modules/build/__init__.py#7): [depot\_tools/gclient][depot_tools/recipe_modules/gclient], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [docker](#recipe_modules-docker), [env](#recipe_modules-env), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
57
58PYTHON_VERSION_COMPATIBILITY: PY2+3
59
60Build Skia for various platforms.
61
62#### **class [BuildApi](/infra/bots/recipe_modules/build/api.py#21)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
63
64&mdash; **def [\_\_call\_\_](/infra/bots/recipe_modules/build/api.py#51)(self, checkout_root, out_dir):**
65
66Compile the code.
67
68&mdash; **def [copy\_build\_products](/infra/bots/recipe_modules/build/api.py#55)(self, out_dir, dst):**
69
70Copy selected build products to dst.
71### *recipe_modules* / [builder\_name\_schema](/infra/bots/recipe_modules/builder_name_schema)
72
73PYTHON_VERSION_COMPATIBILITY: PY2+3
74
75#### **class [BuilderNameSchemaApi](/infra/bots/recipe_modules/builder_name_schema/api.py#14)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
76
77&mdash; **def [DictForBuilderName](/infra/bots/recipe_modules/builder_name_schema/api.py#32)(self, \*args, \*\*kwargs):**
78
79&mdash; **def [MakeBuilderName](/infra/bots/recipe_modules/builder_name_schema/api.py#29)(self, \*\*kwargs):**
80### *recipe_modules* / [checkout](/infra/bots/recipe_modules/checkout)
81
82[DEPS](/infra/bots/recipe_modules/checkout/__init__.py#7): [depot\_tools/bot\_update][depot_tools/recipe_modules/bot_update], [depot\_tools/gclient][depot_tools/recipe_modules/gclient], [depot\_tools/git][depot_tools/recipe_modules/git], [depot\_tools/tryserver][depot_tools/recipe_modules/tryserver], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [run](#recipe_modules-run), [vars](#recipe_modules-vars)
83
84PYTHON_VERSION_COMPATIBILITY: PY2+3
85
86#### **class [CheckoutApi](/infra/bots/recipe_modules/checkout/api.py#13)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
87
88&mdash; **def [assert\_git\_is\_from\_cipd](/infra/bots/recipe_modules/checkout/api.py#20)(self):**
89
90Fail if git is not obtained from CIPD.
91
92&mdash; **def [bot\_update](/infra/bots/recipe_modules/checkout/api.py#48)(self, checkout_root, gclient_cache=None, checkout_chromium=False, checkout_flutter=False, extra_gclient_env=None, flutter_android=False):**
93
94Run the steps to obtain a checkout using bot_update.
95
96Args:
97  checkout_root: Root directory where the code will be synced.
98  gclient_cache: Optional, directory of the gclient cache.
99  checkout_chromium: If True, will check out chromium/src.git in addition
100      to the primary repo.
101  checkout_flutter: If True, will checkout flutter in addition to the
102      primary repo.
103  extra_gclient_env: Map of extra environment variable names to their values
104      to supply while running gclient.
105  flutter_android: Indicates that we're checking out flutter for Android.
106
107&emsp; **@property**<br>&mdash; **def [default\_checkout\_root](/infra/bots/recipe_modules/checkout/api.py#15)(self):**
108
109The default location for cached persistent checkouts.
110
111&mdash; **def [git](/infra/bots/recipe_modules/checkout/api.py#35)(self, checkout_root):**
112
113Run the steps to perform a pure-git checkout without DEPS.
114### *recipe_modules* / [docker](/infra/bots/recipe_modules/docker)
115
116[DEPS](/infra/bots/recipe_modules/docker/__init__.py#8): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [env](#recipe_modules-env), [run](#recipe_modules-run)
117
118PYTHON_VERSION_COMPATIBILITY: PY2+3
119
120#### **class [DockerApi](/infra/bots/recipe_modules/docker/api.py#15)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
121
122&mdash; **def [mount\_out](/infra/bots/recipe_modules/docker/api.py#27)(self):**
123
124&mdash; **def [mount\_src](/infra/bots/recipe_modules/docker/api.py#24)(self):**
125
126&mdash; **def [run](/infra/bots/recipe_modules/docker/api.py#32)(self, name, docker_image, src_dir, out_dir, script, args=None, docker_args=None, copies=None, recursive_read=None, attempts=1, match_directory_structure=False):**
127### *recipe_modules* / [doxygen](/infra/bots/recipe_modules/doxygen)
128
129[DEPS](/infra/bots/recipe_modules/doxygen/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/step][recipe_engine/recipe_modules/step], [run](#recipe_modules-run)
130
131PYTHON_VERSION_COMPATIBILITY: PY2+3
132
133#### **class [DoxygenApi](/infra/bots/recipe_modules/doxygen/api.py#9)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
134
135&mdash; **def [generate\_and\_upload](/infra/bots/recipe_modules/doxygen/api.py#10)(self, skia_dir):**
136### *recipe_modules* / [env](/infra/bots/recipe_modules/env)
137
138[DEPS](/infra/bots/recipe_modules/env/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context]
139
140PYTHON_VERSION_COMPATIBILITY: PY2+3
141
142#### **class [EnvApi](/infra/bots/recipe_modules/env/api.py#9)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
143### *recipe_modules* / [flavor](/infra/bots/recipe_modules/flavor)
144
145[DEPS](/infra/bots/recipe_modules/flavor/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [docker](#recipe_modules-docker), [env](#recipe_modules-env), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
146
147PYTHON_VERSION_COMPATIBILITY: PY2+3
148
149#### **class [SkiaFlavorApi](/infra/bots/recipe_modules/flavor/api.py#59)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
150
151&mdash; **def [cleanup\_steps](/infra/bots/recipe_modules/flavor/api.py#131)(self):**
152
153&mdash; **def [copy\_directory\_contents\_to\_device](/infra/bots/recipe_modules/flavor/api.py#87)(self, host_dir, device_dir):**
154
155&mdash; **def [copy\_directory\_contents\_to\_host](/infra/bots/recipe_modules/flavor/api.py#90)(self, device_dir, host_dir):**
156
157&mdash; **def [copy\_file\_to\_device](/infra/bots/recipe_modules/flavor/api.py#93)(self, host_path, device_path):**
158
159&mdash; **def [create\_clean\_device\_dir](/infra/bots/recipe_modules/flavor/api.py#99)(self, path):**
160
161&mdash; **def [create\_clean\_host\_dir](/infra/bots/recipe_modules/flavor/api.py#96)(self, path):**
162
163&mdash; **def [device\_path\_join](/infra/bots/recipe_modules/flavor/api.py#84)(self, \*args):**
164
165&mdash; **def [get\_flavor](/infra/bots/recipe_modules/flavor/api.py#60)(self, vars_api, app_name):**
166
167Return a flavor utils object specific to the given builder.
168
169&mdash; **def [install](/infra/bots/recipe_modules/flavor/api.py#108)(self, skps=False, images=False, lotties=False, svgs=False, resources=False, mskps=False, texttraces=False):**
170
171&mdash; **def [read\_file\_on\_device](/infra/bots/recipe_modules/flavor/api.py#102)(self, path, \*\*kwargs):**
172
173&mdash; **def [remove\_file\_on\_device](/infra/bots/recipe_modules/flavor/api.py#105)(self, path):**
174
175&mdash; **def [setup](/infra/bots/recipe_modules/flavor/api.py#75)(self, app_name):**
176
177&mdash; **def [step](/infra/bots/recipe_modules/flavor/api.py#81)(self, name, cmd, \*\*kwargs):**
178### *recipe_modules* / [git](/infra/bots/recipe_modules/git)
179
180[DEPS](/infra/bots/recipe_modules/git/__init__.py#7): [recipe\_engine/path][recipe_engine/recipe_modules/path], [env](#recipe_modules-env)
181
182PYTHON_VERSION_COMPATIBILITY: PY2+3
183
184#### **class [GitApi](/infra/bots/recipe_modules/git/api.py#9)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
185
186&mdash; **def [env](/infra/bots/recipe_modules/git/api.py#10)(self):**
187
188Add Git to PATH
189
190Requires the infra/git and infra/tools/git CIPD packages to be installed
191in the 'git' relative path.
192### *recipe_modules* / [gold\_upload](/infra/bots/recipe_modules/gold_upload)
193
194[DEPS](/infra/bots/recipe_modules/gold_upload/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [flavor](#recipe_modules-flavor), [gsutil](#recipe_modules-gsutil), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
195
196PYTHON_VERSION_COMPATIBILITY: PY2+3
197
198#### **class [GoldUploadApi](/infra/bots/recipe_modules/gold_upload/api.py#11)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
199
200&mdash; **def [upload](/infra/bots/recipe_modules/gold_upload/api.py#12)(self):**
201
202Attempt to upload files to Gold.
203This module assumes setup has occurred for the vars and flavor modules.
204### *recipe_modules* / [gsutil](/infra/bots/recipe_modules/gsutil)
205
206[DEPS](/infra/bots/recipe_modules/gsutil/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [run](#recipe_modules-run), [vars](#recipe_modules-vars)
207
208PYTHON_VERSION_COMPATIBILITY: PY2+3
209
210#### **class [GSUtilApi](/infra/bots/recipe_modules/gsutil/api.py#10)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
211
212&mdash; **def [\_\_call\_\_](/infra/bots/recipe_modules/gsutil/api.py#11)(self, step_name, \*args):**
213
214Run gsutil with the given args.
215
216&mdash; **def [cp](/infra/bots/recipe_modules/gsutil/api.py#17)(self, name, src, dst, extra_args=None, multithread=False):**
217
218Attempt to upload or download files to/from Google Cloud Storage (GCS).
219
220Args:
221  name: string. Will be used to fill out the step name.
222  src: string. Absolute path for a local file or gcs file (e.g. gs://...)
223  dst: string. Same as src.
224  extra_args: optional list of args to be passed to gsutil. e.g. [-Z] asks
225    all files be compressed with gzip after upload and before download.
226  multi_thread: if the -m argument should be used to copy multiple items
227    at once (e.g. gsutil -m cp foo* gs://bar/dir)
228
229If the operation fails, it will be retried multiple times.
230### *recipe_modules* / [infra](/infra/bots/recipe_modules/infra)
231
232[DEPS](/infra/bots/recipe_modules/infra/__init__.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/step][recipe_engine/recipe_modules/step], [run](#recipe_modules-run), [vars](#recipe_modules-vars)
233
234PYTHON_VERSION_COMPATIBILITY: PY2+3
235
236#### **class [InfraApi](/infra/bots/recipe_modules/infra/api.py#14)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
237
238&emsp; **@property**<br>&mdash; **def [go\_bin](/infra/bots/recipe_modules/infra/api.py#19)(self):**
239
240&emsp; **@property**<br>&mdash; **def [go\_env](/infra/bots/recipe_modules/infra/api.py#23)(self):**
241
242&emsp; **@property**<br>&mdash; **def [gopath](/infra/bots/recipe_modules/infra/api.py#33)(self):**
243
244&emsp; **@property**<br>&mdash; **def [goroot](/infra/bots/recipe_modules/infra/api.py#15)(self):**
245### *recipe_modules* / [run](/infra/bots/recipe_modules/run)
246
247[DEPS](/infra/bots/recipe_modules/run/__init__.py#7): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [env](#recipe_modules-env), [vars](#recipe_modules-vars)
248
249PYTHON_VERSION_COMPATIBILITY: PY2+3
250
251#### **class [SkiaStepApi](/infra/bots/recipe_modules/run/api.py#14)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
252
253&mdash; **def [\_\_call\_\_](/infra/bots/recipe_modules/run/api.py#69)(self, steptype, name, abort_on_failure=True, fail_build_on_failure=True, \*\*kwargs):**
254
255Run a step. If it fails, keep going but mark the build status failed.
256
257&mdash; **def [\_\_init\_\_](/infra/bots/recipe_modules/run/api.py#16)(self, \*args, \*\*kwargs):**
258
259Initialize the recipe module.
260
261&mdash; **def [asset\_version](/infra/bots/recipe_modules/run/api.py#54)(self, asset_name, skia_dir, test_data=None):**
262
263Return the contents of VERSION for the given asset as a string.
264
265If test_data is not specified, reads the property
266'test_<asset_name>_version' or if not present, uses
267TEST_DEFAULT_ASSET_VERSION.
268
269&mdash; **def [check\_failure](/infra/bots/recipe_modules/run/api.py#25)(self):**
270
271Raise an exception if any step failed.
272
273&emsp; **@property**<br>&mdash; **def [failed\_steps](/infra/bots/recipe_modules/run/api.py#31)(self):**
274
275&mdash; **def [readfile](/infra/bots/recipe_modules/run/api.py#40)(self, filename, \*args, \*\*kwargs):**
276
277Convenience function for reading files.
278
279&mdash; **def [rmtree](/infra/bots/recipe_modules/run/api.py#50)(self, path):**
280
281Wrapper around api.file.rmtree.
282
283&mdash; **def [run\_once](/infra/bots/recipe_modules/run/api.py#35)(self, fn, \*args, \*\*kwargs):**
284
285&mdash; **def [with\_retry](/infra/bots/recipe_modules/run/api.py#81)(self, steptype, name, attempts, between_attempts_fn=None, abort_on_failure=True, fail_build_on_failure=True, \*\*kwargs):**
286
287&mdash; **def [writefile](/infra/bots/recipe_modules/run/api.py#45)(self, filename, contents):**
288
289Convenience function for writing files.
290### *recipe_modules* / [vars](/infra/bots/recipe_modules/vars)
291
292[DEPS](/infra/bots/recipe_modules/vars/__init__.py#7): [depot\_tools/bot\_update][depot_tools/recipe_modules/bot_update], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [builder\_name\_schema](#recipe_modules-builder_name_schema)
293
294PYTHON_VERSION_COMPATIBILITY: PY2+3
295
296#### **class [SkiaVarsApi](/infra/bots/recipe_modules/vars/api.py#16)([RecipeApi][recipe_engine/wkt/RecipeApi]):**
297
298&emsp; **@property**<br>&mdash; **def [is\_linux](/infra/bots/recipe_modules/vars/api.py#88)(self):**
299
300&mdash; **def [setup](/infra/bots/recipe_modules/vars/api.py#18)(self):**
301
302Prepare the variables.
303
304&emsp; **@property**<br>&mdash; **def [swarming\_bot\_id](/infra/bots/recipe_modules/vars/api.py#96)(self):**
305
306&emsp; **@property**<br>&mdash; **def [swarming\_task\_id](/infra/bots/recipe_modules/vars/api.py#108)(self):**
307## Recipes
308
309### *recipes* / [build:examples/full](/infra/bots/recipe_modules/build/examples/full.py)
310
311[DEPS](/infra/bots/recipe_modules/build/examples/full.py#7): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [build](#recipe_modules-build), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
312
313PYTHON_VERSION_COMPATIBILITY: PY2+3
314
315&mdash; **def [RunSteps](/infra/bots/recipe_modules/build/examples/full.py#18)(api):**
316### *recipes* / [builder\_name\_schema:examples/full](/infra/bots/recipe_modules/builder_name_schema/examples/full.py)
317
318[DEPS](/infra/bots/recipe_modules/builder_name_schema/examples/full.py#7): [builder\_name\_schema](#recipe_modules-builder_name_schema)
319
320PYTHON_VERSION_COMPATIBILITY: PY2+3
321
322&mdash; **def [RunSteps](/infra/bots/recipe_modules/builder_name_schema/examples/full.py#12)(api):**
323### *recipes* / [check\_generated\_files](/infra/bots/recipes/check_generated_files.py)
324
325[DEPS](/infra/bots/recipes/check_generated_files.py#10): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [build](#recipe_modules-build), [checkout](#recipe_modules-checkout), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
326
327PYTHON_VERSION_COMPATIBILITY: PY2+3
328
329&mdash; **def [RunSteps](/infra/bots/recipes/check_generated_files.py#26)(api):**
330### *recipes* / [checkout:examples/full](/infra/bots/recipe_modules/checkout/examples/full.py)
331
332[DEPS](/infra/bots/recipe_modules/checkout/examples/full.py#7): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [checkout](#recipe_modules-checkout), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
333
334PYTHON_VERSION_COMPATIBILITY: PY2+3
335
336&mdash; **def [RunSteps](/infra/bots/recipe_modules/checkout/examples/full.py#18)(api):**
337### *recipes* / [compile](/infra/bots/recipes/compile.py)
338
339[DEPS](/infra/bots/recipes/compile.py#10): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [build](#recipe_modules-build), [checkout](#recipe_modules-checkout), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
340
341PYTHON_VERSION_COMPATIBILITY: PY2+3
342
343&mdash; **def [RunSteps](/infra/bots/recipes/compile.py#26)(api):**
344### *recipes* / [compute\_buildstats](/infra/bots/recipes/compute_buildstats.py)
345
346[DEPS](/infra/bots/recipes/compute_buildstats.py#12): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [checkout](#recipe_modules-checkout), [env](#recipe_modules-env), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
347
348PYTHON_VERSION_COMPATIBILITY: PY2+3
349
350&mdash; **def [RunSteps](/infra/bots/recipes/compute_buildstats.py#35)(api):**
351
352&mdash; **def [add\_binary\_size\_output\_property](/infra/bots/recipes/compute_buildstats.py#31)(result, source, binary_size):**
353
354&mdash; **def [analyze\_cpp\_lib](/infra/bots/recipes/compute_buildstats.py#167)(api, checkout_root, out_dir, files):**
355
356&mdash; **def [analyze\_flutter\_lib](/infra/bots/recipes/compute_buildstats.py#195)(api, checkout_root, out_dir, files):**
357
358&mdash; **def [analyze\_wasm\_file](/infra/bots/recipes/compute_buildstats.py#234)(api, checkout_root, out_dir, files):**
359
360&mdash; **def [analyze\_web\_file](/infra/bots/recipes/compute_buildstats.py#140)(api, checkout_root, out_dir, files):**
361
362&mdash; **def [keys\_and\_props](/infra/bots/recipes/compute_buildstats.py#116)(api):**
363
364&mdash; **def [make\_treemap](/infra/bots/recipes/compute_buildstats.py#266)(api, checkout_root, out_dir, files):**
365### *recipes* / [docker:examples/full](/infra/bots/recipe_modules/docker/examples/full.py)
366
367[DEPS](/infra/bots/recipe_modules/docker/examples/full.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [docker](#recipe_modules-docker), [vars](#recipe_modules-vars)
368
369PYTHON_VERSION_COMPATIBILITY: PY2+3
370
371&mdash; **def [RunSteps](/infra/bots/recipe_modules/docker/examples/full.py#16)(api):**
372### *recipes* / [doxygen:examples/full](/infra/bots/recipe_modules/doxygen/examples/full.py)
373
374[DEPS](/infra/bots/recipe_modules/doxygen/examples/full.py#7): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [doxygen](#recipe_modules-doxygen), [vars](#recipe_modules-vars)
375
376PYTHON_VERSION_COMPATIBILITY: PY2+3
377
378&mdash; **def [RunSteps](/infra/bots/recipe_modules/doxygen/examples/full.py#15)(api):**
379### *recipes* / [env:examples/full](/infra/bots/recipe_modules/env/examples/full.py)
380
381[DEPS](/infra/bots/recipe_modules/env/examples/full.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/step][recipe_engine/recipe_modules/step], [env](#recipe_modules-env)
382
383PYTHON_VERSION_COMPATIBILITY: PY2+3
384
385&mdash; **def [RunSteps](/infra/bots/recipe_modules/env/examples/full.py#14)(api):**
386### *recipes* / [flavor:examples/full](/infra/bots/recipe_modules/flavor/examples/full.py)
387
388[DEPS](/infra/bots/recipe_modules/flavor/examples/full.py#7): [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [flavor](#recipe_modules-flavor), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
389
390PYTHON_VERSION_COMPATIBILITY: PY2+3
391
392&mdash; **def [RunSteps](/infra/bots/recipe_modules/flavor/examples/full.py#32)(api):**
393
394&mdash; **def [test\_exceptions](/infra/bots/recipe_modules/flavor/examples/full.py#17)(api):**
395### *recipes* / [git:examples/full](/infra/bots/recipe_modules/git/examples/full.py)
396
397[DEPS](/infra/bots/recipe_modules/git/examples/full.py#7): [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/step][recipe_engine/recipe_modules/step], [git](#recipe_modules-git)
398
399PYTHON_VERSION_COMPATIBILITY: PY2+3
400
401&mdash; **def [RunSteps](/infra/bots/recipe_modules/git/examples/full.py#14)(api):**
402### *recipes* / [gold\_upload:examples/full](/infra/bots/recipe_modules/gold_upload/examples/full.py)
403
404[DEPS](/infra/bots/recipe_modules/gold_upload/examples/full.py#10): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [flavor](#recipe_modules-flavor), [gold\_upload](#recipe_modules-gold_upload), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
405
406PYTHON_VERSION_COMPATIBILITY: PY2+3
407
408&mdash; **def [RunSteps](/infra/bots/recipe_modules/gold_upload/examples/full.py#22)(api):**
409### *recipes* / [gsutil:examples/full](/infra/bots/recipe_modules/gsutil/examples/full.py)
410
411[DEPS](/infra/bots/recipe_modules/gsutil/examples/full.py#10): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [gsutil](#recipe_modules-gsutil), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
412
413PYTHON_VERSION_COMPATIBILITY: PY2+3
414
415&mdash; **def [RunSteps](/infra/bots/recipe_modules/gsutil/examples/full.py#21)(api):**
416### *recipes* / [housekeeper](/infra/bots/recipes/housekeeper.py)
417
418[DEPS](/infra/bots/recipes/housekeeper.py#13): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [checkout](#recipe_modules-checkout), [doxygen](#recipe_modules-doxygen), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
419
420PYTHON_VERSION_COMPATIBILITY: PY2+3
421
422&mdash; **def [RunSteps](/infra/bots/recipes/housekeeper.py#24)(api):**
423### *recipes* / [infra](/infra/bots/recipes/infra.py)
424
425[DEPS](/infra/bots/recipes/infra.py#10): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [infra](#recipe_modules-infra), [vars](#recipe_modules-vars)
426
427PYTHON_VERSION_COMPATIBILITY: PY2+3
428
429&mdash; **def [RunSteps](/infra/bots/recipes/infra.py#28)(api):**
430
431&mdash; **def [git\_init](/infra/bots/recipes/infra.py#20)(api, repo_root, env):**
432### *recipes* / [infra:examples/full](/infra/bots/recipe_modules/infra/examples/full.py)
433
434[DEPS](/infra/bots/recipe_modules/infra/examples/full.py#10): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
435
436PYTHON_VERSION_COMPATIBILITY: PY2+3
437
438&mdash; **def [RunSteps](/infra/bots/recipe_modules/infra/examples/full.py#23)(api):**
439### *recipes* / [perf](/infra/bots/recipes/perf.py)
440
441[DEPS](/infra/bots/recipes/perf.py#15): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
442
443PYTHON_VERSION_COMPATIBILITY: PY2+3
444
445&mdash; **def [RunSteps](/infra/bots/recipes/perf.py#104)(api):**
446
447&mdash; **def [perf\_steps](/infra/bots/recipes/perf.py#31)(api):**
448
449Run Skia benchmarks.
450### *recipes* / [perf\_pathkit](/infra/bots/recipes/perf_pathkit.py)
451
452[DEPS](/infra/bots/recipes/perf_pathkit.py#9): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [checkout](#recipe_modules-checkout), [docker](#recipe_modules-docker), [env](#recipe_modules-env), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
453
454PYTHON_VERSION_COMPATIBILITY: PY2+3
455
456&mdash; **def [RunSteps](/infra/bots/recipes/perf_pathkit.py#28)(api):**
457### *recipes* / [perf\_skottietrace](/infra/bots/recipes/perf_skottietrace.py)
458
459[DEPS](/infra/bots/recipes/perf_skottietrace.py#17): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [flavor](#recipe_modules-flavor), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
460
461PYTHON_VERSION_COMPATIBILITY: PY2+3
462
463&mdash; **def [RunSteps](/infra/bots/recipes/perf_skottietrace.py#219)(api):**
464
465&mdash; **def [get\_trace\_match](/infra/bots/recipes/perf_skottietrace.py#128)(lottie_filename, is_android):**
466
467Returns the DM regex to match the specified lottie file name.
468
469&mdash; **def [parse\_trace](/infra/bots/recipes/perf_skottietrace.py#143)(trace_json, lottie_filename, api):**
470
471parse_trace parses the specified trace JSON.
472
473Parses the trace JSON and calculates the time of a single frame. Frame time is
474considered the same as seek time + render time.
475Note: The first seek is ignored because it is a constructor call.
476
477A dictionary is returned that has the following structure:
478{
479  'frame_max_us': 100,
480  'frame_min_us': 90,
481  'frame_avg_us': 95,
482}
483
484&mdash; **def [perf\_steps](/infra/bots/recipes/perf_skottietrace.py#37)(api):**
485
486Run DM on lottie files with tracing turned on and then parse the output.
487### *recipes* / [perf\_skottiewasm\_lottieweb](/infra/bots/recipes/perf_skottiewasm_lottieweb.py)
488
489[DEPS](/infra/bots/recipes/perf_skottiewasm_lottieweb.py#14): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [checkout](#recipe_modules-checkout), [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
490
491PYTHON_VERSION_COMPATIBILITY: PY2+3
492
493&mdash; **def [RunSteps](/infra/bots/recipes/perf_skottiewasm_lottieweb.py#84)(api):**
494
495&mdash; **def [parse\_trace](/infra/bots/recipes/perf_skottiewasm_lottieweb.py#205)(trace_json, lottie_filename, api, renderer):**
496
497parse_trace parses the specified trace JSON.
498
499Parses the trace JSON and calculates the time of a single frame.
500A dictionary is returned that has the following structure:
501{
502  'frame_max_us': 100,
503  'frame_min_us': 90,
504  'frame_avg_us': 95,
505}
506### *recipes* / [run:examples/full](/infra/bots/recipe_modules/run/examples/full.py)
507
508[DEPS](/infra/bots/recipe_modules/run/examples/full.py#7): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [run](#recipe_modules-run), [vars](#recipe_modules-vars)
509
510PYTHON_VERSION_COMPATIBILITY: PY2+3
511
512&mdash; **def [RunSteps](/infra/bots/recipe_modules/run/examples/full.py#22)(api):**
513
514&mdash; **def [myfunc](/infra/bots/recipe_modules/run/examples/full.py#18)(api, i):**
515### *recipes* / [skpbench](/infra/bots/recipes/skpbench.py)
516
517[DEPS](/infra/bots/recipes/skpbench.py#13): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [flavor](#recipe_modules-flavor), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
518
519PYTHON_VERSION_COMPATIBILITY: PY2+3
520
521&mdash; **def [RunSteps](/infra/bots/recipes/skpbench.py#163)(api):**
522
523&mdash; **def [skpbench\_steps](/infra/bots/recipes/skpbench.py#42)(api):**
524
525benchmark Skia using skpbench.
526### *recipes* / [sync\_and\_compile](/infra/bots/recipes/sync_and_compile.py)
527
528[DEPS](/infra/bots/recipes/sync_and_compile.py#10): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [build](#recipe_modules-build), [checkout](#recipe_modules-checkout), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
529
530PYTHON_VERSION_COMPATIBILITY: PY2+3
531
532&mdash; **def [RunSteps](/infra/bots/recipes/sync_and_compile.py#26)(api):**
533### *recipes* / [test](/infra/bots/recipes/test.py)
534
535[DEPS](/infra/bots/recipes/test.py#13): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step], [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [gold\_upload](#recipe_modules-gold_upload), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
536
537PYTHON_VERSION_COMPATIBILITY: PY2+3
538
539&mdash; **def [RunSteps](/infra/bots/recipes/test.py#162)(api):**
540
541&mdash; **def [test\_steps](/infra/bots/recipes/test.py#31)(api):**
542
543Run the DM test.
544### *recipes* / [test\_canvaskit](/infra/bots/recipes/test_canvaskit.py)
545
546[DEPS](/infra/bots/recipes/test_canvaskit.py#9): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [checkout](#recipe_modules-checkout), [docker](#recipe_modules-docker), [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [gold\_upload](#recipe_modules-gold_upload), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
547
548PYTHON_VERSION_COMPATIBILITY: PY2+3
549
550&mdash; **def [RunSteps](/infra/bots/recipes/test_canvaskit.py#29)(api):**
551### *recipes* / [test\_lottie\_web](/infra/bots/recipes/test_lottie_web.py)
552
553[DEPS](/infra/bots/recipes/test_lottie_web.py#9): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [checkout](#recipe_modules-checkout), [docker](#recipe_modules-docker), [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [gold\_upload](#recipe_modules-gold_upload), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
554
555PYTHON_VERSION_COMPATIBILITY: PY2+3
556
557&mdash; **def [RunSteps](/infra/bots/recipes/test_lottie_web.py#29)(api):**
558### *recipes* / [test\_pathkit](/infra/bots/recipes/test_pathkit.py)
559
560[DEPS](/infra/bots/recipes/test_pathkit.py#9): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/step][recipe_engine/recipe_modules/step], [checkout](#recipe_modules-checkout), [docker](#recipe_modules-docker), [env](#recipe_modules-env), [flavor](#recipe_modules-flavor), [gold\_upload](#recipe_modules-gold_upload), [infra](#recipe_modules-infra), [run](#recipe_modules-run), [vars](#recipe_modules-vars)
561
562PYTHON_VERSION_COMPATIBILITY: PY2+3
563
564&mdash; **def [RunSteps](/infra/bots/recipes/test_pathkit.py#30)(api):**
565### *recipes* / [upload\_buildstats\_results](/infra/bots/recipes/upload_buildstats_results.py)
566
567[DEPS](/infra/bots/recipes/upload_buildstats_results.py#10): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [vars](#recipe_modules-vars)
568
569PYTHON_VERSION_COMPATIBILITY: PY2+3
570
571&mdash; **def [RunSteps](/infra/bots/recipes/upload_buildstats_results.py#21)(api):**
572### *recipes* / [upload\_dm\_results](/infra/bots/recipes/upload_dm_results.py)
573
574[DEPS](/infra/bots/recipes/upload_dm_results.py#13): [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [gsutil](#recipe_modules-gsutil), [vars](#recipe_modules-vars)
575
576PYTHON_VERSION_COMPATIBILITY: PY2+3
577
578&mdash; **def [RunSteps](/infra/bots/recipes/upload_dm_results.py#29)(api):**
579### *recipes* / [upload\_nano\_results](/infra/bots/recipes/upload_nano_results.py)
580
581[DEPS](/infra/bots/recipes/upload_nano_results.py#10): [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/file][recipe_engine/recipe_modules/file], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [recipe\_engine/time][recipe_engine/recipe_modules/time], [vars](#recipe_modules-vars)
582
583PYTHON_VERSION_COMPATIBILITY: PY2+3
584
585&mdash; **def [RunSteps](/infra/bots/recipes/upload_nano_results.py#21)(api):**
586### *recipes* / [vars:examples/full](/infra/bots/recipe_modules/vars/examples/full.py)
587
588[DEPS](/infra/bots/recipe_modules/vars/examples/full.py#7): [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step], [vars](#recipe_modules-vars)
589
590PYTHON_VERSION_COMPATIBILITY: PY2+3
591
592&mdash; **def [RunSteps](/infra/bots/recipe_modules/vars/examples/full.py#16)(api):**
593
594[depot_tools/recipe_modules/bot_update]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/8a0d05dea6b215cdd68fe2fe8093353baf2b4c22/recipes/README.recipes.md#recipe_modules-bot_update
595[depot_tools/recipe_modules/gclient]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/8a0d05dea6b215cdd68fe2fe8093353baf2b4c22/recipes/README.recipes.md#recipe_modules-gclient
596[depot_tools/recipe_modules/git]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/8a0d05dea6b215cdd68fe2fe8093353baf2b4c22/recipes/README.recipes.md#recipe_modules-git
597[depot_tools/recipe_modules/tryserver]: https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/8a0d05dea6b215cdd68fe2fe8093353baf2b4c22/recipes/README.recipes.md#recipe_modules-tryserver
598[recipe_engine/recipe_modules/context]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/8ac9cf1c9ff01f9fe1276c8532577127f068d576/README.recipes.md#recipe_modules-context
599[recipe_engine/recipe_modules/file]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/8ac9cf1c9ff01f9fe1276c8532577127f068d576/README.recipes.md#recipe_modules-file
600[recipe_engine/recipe_modules/json]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/8ac9cf1c9ff01f9fe1276c8532577127f068d576/README.recipes.md#recipe_modules-json
601[recipe_engine/recipe_modules/path]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/8ac9cf1c9ff01f9fe1276c8532577127f068d576/README.recipes.md#recipe_modules-path
602[recipe_engine/recipe_modules/platform]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/8ac9cf1c9ff01f9fe1276c8532577127f068d576/README.recipes.md#recipe_modules-platform
603[recipe_engine/recipe_modules/properties]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/8ac9cf1c9ff01f9fe1276c8532577127f068d576/README.recipes.md#recipe_modules-properties
604[recipe_engine/recipe_modules/python]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/8ac9cf1c9ff01f9fe1276c8532577127f068d576/README.recipes.md#recipe_modules-python
605[recipe_engine/recipe_modules/raw_io]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/8ac9cf1c9ff01f9fe1276c8532577127f068d576/README.recipes.md#recipe_modules-raw_io
606[recipe_engine/recipe_modules/step]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/8ac9cf1c9ff01f9fe1276c8532577127f068d576/README.recipes.md#recipe_modules-step
607[recipe_engine/recipe_modules/time]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/8ac9cf1c9ff01f9fe1276c8532577127f068d576/README.recipes.md#recipe_modules-time
608[recipe_engine/wkt/RecipeApi]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/8ac9cf1c9ff01f9fe1276c8532577127f068d576/recipe_engine/recipe_api.py#881
609