• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[
2  {
3    "cmd": [
4      "vpython",
5      "-u",
6      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
7      "--json-output",
8      "/path/to/tmp/json",
9      "ensure-directory",
10      "--mode",
11      "0777",
12      "[START_DIR]/tmp"
13    ],
14    "infra_step": true,
15    "name": "makedirs tmp_dir"
16  },
17  {
18    "cmd": [
19      "python",
20      "-u",
21      "import os\nprint(os.environ.get('SWARMING_BOT_ID', ''))\n"
22    ],
23    "name": "get swarming bot id",
24    "~followup_annotations": [
25      "@@@STEP_LOG_LINE@python.inline@import os@@@",
26      "@@@STEP_LOG_LINE@python.inline@print(os.environ.get('SWARMING_BOT_ID', ''))@@@",
27      "@@@STEP_LOG_END@python.inline@@@"
28    ]
29  },
30  {
31    "cmd": [
32      "/usr/bin/adb.1.0.35",
33      "shell",
34      "mkdir",
35      "-p",
36      "/sdcard/revenge_of_the_skiabot/resources"
37    ],
38    "cwd": "[START_DIR]/skia",
39    "env": {
40      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
41      "CHROME_HEADLESS": "1",
42      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
43    },
44    "infra_step": true,
45    "name": "mkdir /sdcard/revenge_of_the_skiabot/resources"
46  },
47  {
48    "cmd": [
49      "python",
50      "-u",
51      "\nimport os\nimport subprocess\nimport sys\nimport time\nADB = sys.argv[1]\ncpu = int(sys.argv[2])\ngov = sys.argv[3]\n\nlog = subprocess.check_output([ADB, 'root'])\n# check for message like 'adbd cannot run as root in production builds'\nprint(log)\nif 'cannot' in log:\n  raise Exception('adb root failed')\n\nsubprocess.check_output([ADB, 'shell', 'echo \"%s\" > '\n    '/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor' % (gov, cpu)])\nactual_gov = subprocess.check_output([ADB, 'shell', 'cat '\n    '/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor' % cpu]).strip()\nif actual_gov != gov:\n  raise Exception('(actual, expected) (%s, %s)'\n                  % (actual_gov, gov))\n",
52      "/usr/bin/adb.1.0.35",
53      "0",
54      "userspace"
55    ],
56    "env": {
57      "CHROME_HEADLESS": "1",
58      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
59    },
60    "infra_step": true,
61    "name": "Set CPU 0's governor to userspace",
62    "timeout": 30,
63    "~followup_annotations": [
64      "@@@STEP_LOG_LINE@python.inline@@@@",
65      "@@@STEP_LOG_LINE@python.inline@import os@@@",
66      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
67      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
68      "@@@STEP_LOG_LINE@python.inline@import time@@@",
69      "@@@STEP_LOG_LINE@python.inline@ADB = sys.argv[1]@@@",
70      "@@@STEP_LOG_LINE@python.inline@cpu = int(sys.argv[2])@@@",
71      "@@@STEP_LOG_LINE@python.inline@gov = sys.argv[3]@@@",
72      "@@@STEP_LOG_LINE@python.inline@@@@",
73      "@@@STEP_LOG_LINE@python.inline@log = subprocess.check_output([ADB, 'root'])@@@",
74      "@@@STEP_LOG_LINE@python.inline@# check for message like 'adbd cannot run as root in production builds'@@@",
75      "@@@STEP_LOG_LINE@python.inline@print(log)@@@",
76      "@@@STEP_LOG_LINE@python.inline@if 'cannot' in log:@@@",
77      "@@@STEP_LOG_LINE@python.inline@  raise Exception('adb root failed')@@@",
78      "@@@STEP_LOG_LINE@python.inline@@@@",
79      "@@@STEP_LOG_LINE@python.inline@subprocess.check_output([ADB, 'shell', 'echo \"%s\" > '@@@",
80      "@@@STEP_LOG_LINE@python.inline@    '/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor' % (gov, cpu)])@@@",
81      "@@@STEP_LOG_LINE@python.inline@actual_gov = subprocess.check_output([ADB, 'shell', 'cat '@@@",
82      "@@@STEP_LOG_LINE@python.inline@    '/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor' % cpu]).strip()@@@",
83      "@@@STEP_LOG_LINE@python.inline@if actual_gov != gov:@@@",
84      "@@@STEP_LOG_LINE@python.inline@  raise Exception('(actual, expected) (%s, %s)'@@@",
85      "@@@STEP_LOG_LINE@python.inline@                  % (actual_gov, gov))@@@",
86      "@@@STEP_LOG_END@python.inline@@@"
87    ]
88  },
89  {
90    "cmd": [
91      "python",
92      "-u",
93      "\nimport os\nimport subprocess\nimport sys\nimport time\nADB = sys.argv[1]\ntarget_percent = float(sys.argv[2])\ncpu = int(sys.argv[3])\nlog = subprocess.check_output([ADB, 'root'])\n# check for message like 'adbd cannot run as root in production builds'\nprint(log)\nif 'cannot' in log:\n  raise Exception('adb root failed')\n\nroot = '/sys/devices/system/cpu/cpu%d/cpufreq' %cpu\n\n# All devices we test on give a list of their available frequencies.\navailable_freqs = subprocess.check_output([ADB, 'shell',\n    'cat %s/scaling_available_frequencies' % root])\n\n# Check for message like '/system/bin/sh: file not found'\nif available_freqs and '/system/bin/sh' not in available_freqs:\n  available_freqs = sorted(\n      int(i) for i in available_freqs.strip().split())\nelse:\n  raise Exception('Could not get list of available frequencies: %s' %\n                  available_freqs)\n\nmaxfreq = available_freqs[-1]\ntarget = int(round(maxfreq * target_percent))\nfreq = maxfreq\nfor f in reversed(available_freqs):\n  if f <= target:\n    freq = f\n    break\n\nprint('Setting frequency to %d' % freq)\n\n# If scaling_max_freq is lower than our attempted setting, it won't take.\n# We must set min first, because if we try to set max to be less than min\n# (which sometimes happens after certain devices reboot) it returns a\n# perplexing permissions error.\nsubprocess.check_output([ADB, 'shell', 'echo 0 > '\n    '%s/scaling_min_freq' % root])\nsubprocess.check_output([ADB, 'shell', 'echo %d > '\n    '%s/scaling_max_freq' % (freq, root)])\nsubprocess.check_output([ADB, 'shell', 'echo %d > '\n    '%s/scaling_setspeed' % (freq, root)])\ntime.sleep(5)\nactual_freq = subprocess.check_output([ADB, 'shell', 'cat '\n    '%s/scaling_cur_freq' % root]).strip()\nif actual_freq != str(freq):\n  raise Exception('(actual, expected) (%s, %d)'\n                  % (actual_freq, freq))\n",
94      "/usr/bin/adb.1.0.35",
95      "0.6",
96      "0"
97    ],
98    "env": {
99      "CHROME_HEADLESS": "1",
100      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
101    },
102    "infra_step": true,
103    "name": "Scale CPU 0 to 0.600000",
104    "timeout": 30,
105    "~followup_annotations": [
106      "@@@STEP_LOG_LINE@python.inline@@@@",
107      "@@@STEP_LOG_LINE@python.inline@import os@@@",
108      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
109      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
110      "@@@STEP_LOG_LINE@python.inline@import time@@@",
111      "@@@STEP_LOG_LINE@python.inline@ADB = sys.argv[1]@@@",
112      "@@@STEP_LOG_LINE@python.inline@target_percent = float(sys.argv[2])@@@",
113      "@@@STEP_LOG_LINE@python.inline@cpu = int(sys.argv[3])@@@",
114      "@@@STEP_LOG_LINE@python.inline@log = subprocess.check_output([ADB, 'root'])@@@",
115      "@@@STEP_LOG_LINE@python.inline@# check for message like 'adbd cannot run as root in production builds'@@@",
116      "@@@STEP_LOG_LINE@python.inline@print(log)@@@",
117      "@@@STEP_LOG_LINE@python.inline@if 'cannot' in log:@@@",
118      "@@@STEP_LOG_LINE@python.inline@  raise Exception('adb root failed')@@@",
119      "@@@STEP_LOG_LINE@python.inline@@@@",
120      "@@@STEP_LOG_LINE@python.inline@root = '/sys/devices/system/cpu/cpu%d/cpufreq' %cpu@@@",
121      "@@@STEP_LOG_LINE@python.inline@@@@",
122      "@@@STEP_LOG_LINE@python.inline@# All devices we test on give a list of their available frequencies.@@@",
123      "@@@STEP_LOG_LINE@python.inline@available_freqs = subprocess.check_output([ADB, 'shell',@@@",
124      "@@@STEP_LOG_LINE@python.inline@    'cat %s/scaling_available_frequencies' % root])@@@",
125      "@@@STEP_LOG_LINE@python.inline@@@@",
126      "@@@STEP_LOG_LINE@python.inline@# Check for message like '/system/bin/sh: file not found'@@@",
127      "@@@STEP_LOG_LINE@python.inline@if available_freqs and '/system/bin/sh' not in available_freqs:@@@",
128      "@@@STEP_LOG_LINE@python.inline@  available_freqs = sorted(@@@",
129      "@@@STEP_LOG_LINE@python.inline@      int(i) for i in available_freqs.strip().split())@@@",
130      "@@@STEP_LOG_LINE@python.inline@else:@@@",
131      "@@@STEP_LOG_LINE@python.inline@  raise Exception('Could not get list of available frequencies: %s' %@@@",
132      "@@@STEP_LOG_LINE@python.inline@                  available_freqs)@@@",
133      "@@@STEP_LOG_LINE@python.inline@@@@",
134      "@@@STEP_LOG_LINE@python.inline@maxfreq = available_freqs[-1]@@@",
135      "@@@STEP_LOG_LINE@python.inline@target = int(round(maxfreq * target_percent))@@@",
136      "@@@STEP_LOG_LINE@python.inline@freq = maxfreq@@@",
137      "@@@STEP_LOG_LINE@python.inline@for f in reversed(available_freqs):@@@",
138      "@@@STEP_LOG_LINE@python.inline@  if f <= target:@@@",
139      "@@@STEP_LOG_LINE@python.inline@    freq = f@@@",
140      "@@@STEP_LOG_LINE@python.inline@    break@@@",
141      "@@@STEP_LOG_LINE@python.inline@@@@",
142      "@@@STEP_LOG_LINE@python.inline@print('Setting frequency to %d' % freq)@@@",
143      "@@@STEP_LOG_LINE@python.inline@@@@",
144      "@@@STEP_LOG_LINE@python.inline@# If scaling_max_freq is lower than our attempted setting, it won't take.@@@",
145      "@@@STEP_LOG_LINE@python.inline@# We must set min first, because if we try to set max to be less than min@@@",
146      "@@@STEP_LOG_LINE@python.inline@# (which sometimes happens after certain devices reboot) it returns a@@@",
147      "@@@STEP_LOG_LINE@python.inline@# perplexing permissions error.@@@",
148      "@@@STEP_LOG_LINE@python.inline@subprocess.check_output([ADB, 'shell', 'echo 0 > '@@@",
149      "@@@STEP_LOG_LINE@python.inline@    '%s/scaling_min_freq' % root])@@@",
150      "@@@STEP_LOG_LINE@python.inline@subprocess.check_output([ADB, 'shell', 'echo %d > '@@@",
151      "@@@STEP_LOG_LINE@python.inline@    '%s/scaling_max_freq' % (freq, root)])@@@",
152      "@@@STEP_LOG_LINE@python.inline@subprocess.check_output([ADB, 'shell', 'echo %d > '@@@",
153      "@@@STEP_LOG_LINE@python.inline@    '%s/scaling_setspeed' % (freq, root)])@@@",
154      "@@@STEP_LOG_LINE@python.inline@time.sleep(5)@@@",
155      "@@@STEP_LOG_LINE@python.inline@actual_freq = subprocess.check_output([ADB, 'shell', 'cat '@@@",
156      "@@@STEP_LOG_LINE@python.inline@    '%s/scaling_cur_freq' % root]).strip()@@@",
157      "@@@STEP_LOG_LINE@python.inline@if actual_freq != str(freq):@@@",
158      "@@@STEP_LOG_LINE@python.inline@  raise Exception('(actual, expected) (%s, %d)'@@@",
159      "@@@STEP_LOG_LINE@python.inline@                  % (actual_freq, freq))@@@",
160      "@@@STEP_LOG_END@python.inline@@@"
161    ]
162  },
163  {
164    "cmd": [
165      "/usr/bin/adb.1.0.35",
166      "push",
167      "[START_DIR]/build/nanobench",
168      "/data/local/tmp/"
169    ],
170    "cwd": "[START_DIR]/skia",
171    "env": {
172      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
173      "CHROME_HEADLESS": "1",
174      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
175    },
176    "infra_step": true,
177    "name": "push nanobench"
178  },
179  {
180    "cmd": [
181      "vpython",
182      "-u",
183      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
184      "--json-output",
185      "/path/to/tmp/json",
186      "copy",
187      "[START_DIR]/skia/infra/bots/assets/text_blob_traces/VERSION",
188      "/path/to/tmp/"
189    ],
190    "infra_step": true,
191    "name": "Get text_blob_traces VERSION",
192    "~followup_annotations": [
193      "@@@STEP_LOG_LINE@VERSION@42@@@",
194      "@@@STEP_LOG_END@VERSION@@@"
195    ]
196  },
197  {
198    "cmd": [
199      "vpython",
200      "-u",
201      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
202      "--json-output",
203      "/path/to/tmp/json",
204      "copy",
205      "42",
206      "[START_DIR]/tmp/TEXTTRACES_VERSION"
207    ],
208    "infra_step": true,
209    "name": "write TEXTTRACES_VERSION",
210    "~followup_annotations": [
211      "@@@STEP_LOG_LINE@TEXTTRACES_VERSION@42@@@",
212      "@@@STEP_LOG_END@TEXTTRACES_VERSION@@@"
213    ]
214  },
215  {
216    "cmd": [
217      "/usr/bin/adb.1.0.35",
218      "shell",
219      "cat",
220      "/sdcard/revenge_of_the_skiabot/TEXTTRACES_VERSION"
221    ],
222    "cwd": "[START_DIR]/skia",
223    "env": {
224      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
225      "CHROME_HEADLESS": "1",
226      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
227    },
228    "infra_step": true,
229    "name": "read /sdcard/revenge_of_the_skiabot/TEXTTRACES_VERSION"
230  },
231  {
232    "cmd": [
233      "python",
234      "-u",
235      "\nimport subprocess\nimport sys\n\n# Remove the path.\nadb = sys.argv[1]\npath = sys.argv[2]\nprint('Removing %s' % path)\ncmd = [adb, 'shell', 'rm', '-rf', path]\nprint(' '.join(cmd))\nsubprocess.check_call(cmd)\n\n# Verify that the path was deleted.\nprint('Checking for existence of %s' % path)\ncmd = [adb, 'shell', 'ls', path]\nprint(' '.join(cmd))\ntry:\n  output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)\nexcept subprocess.CalledProcessError as e:\n  output = e.output\nprint('Output was:')\nprint('======')\nprint(output)\nprint('======')\nif 'No such file or directory' not in output:\n  raise Exception('%s exists despite being deleted' % path)\n",
236      "/usr/bin/adb.1.0.35",
237      "/sdcard/revenge_of_the_skiabot/TEXTTRACES_VERSION"
238    ],
239    "env": {
240      "CHROME_HEADLESS": "1",
241      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
242    },
243    "infra_step": true,
244    "name": "rm /sdcard/revenge_of_the_skiabot/TEXTTRACES_VERSION",
245    "~followup_annotations": [
246      "@@@STEP_LOG_LINE@python.inline@@@@",
247      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
248      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
249      "@@@STEP_LOG_LINE@python.inline@@@@",
250      "@@@STEP_LOG_LINE@python.inline@# Remove the path.@@@",
251      "@@@STEP_LOG_LINE@python.inline@adb = sys.argv[1]@@@",
252      "@@@STEP_LOG_LINE@python.inline@path = sys.argv[2]@@@",
253      "@@@STEP_LOG_LINE@python.inline@print('Removing %s' % path)@@@",
254      "@@@STEP_LOG_LINE@python.inline@cmd = [adb, 'shell', 'rm', '-rf', path]@@@",
255      "@@@STEP_LOG_LINE@python.inline@print(' '.join(cmd))@@@",
256      "@@@STEP_LOG_LINE@python.inline@subprocess.check_call(cmd)@@@",
257      "@@@STEP_LOG_LINE@python.inline@@@@",
258      "@@@STEP_LOG_LINE@python.inline@# Verify that the path was deleted.@@@",
259      "@@@STEP_LOG_LINE@python.inline@print('Checking for existence of %s' % path)@@@",
260      "@@@STEP_LOG_LINE@python.inline@cmd = [adb, 'shell', 'ls', path]@@@",
261      "@@@STEP_LOG_LINE@python.inline@print(' '.join(cmd))@@@",
262      "@@@STEP_LOG_LINE@python.inline@try:@@@",
263      "@@@STEP_LOG_LINE@python.inline@  output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)@@@",
264      "@@@STEP_LOG_LINE@python.inline@except subprocess.CalledProcessError as e:@@@",
265      "@@@STEP_LOG_LINE@python.inline@  output = e.output@@@",
266      "@@@STEP_LOG_LINE@python.inline@print('Output was:')@@@",
267      "@@@STEP_LOG_LINE@python.inline@print('======')@@@",
268      "@@@STEP_LOG_LINE@python.inline@print(output)@@@",
269      "@@@STEP_LOG_LINE@python.inline@print('======')@@@",
270      "@@@STEP_LOG_LINE@python.inline@if 'No such file or directory' not in output:@@@",
271      "@@@STEP_LOG_LINE@python.inline@  raise Exception('%s exists despite being deleted' % path)@@@",
272      "@@@STEP_LOG_END@python.inline@@@"
273    ]
274  },
275  {
276    "cmd": [
277      "python",
278      "-u",
279      "\nimport subprocess\nimport sys\n\n# Remove the path.\nadb = sys.argv[1]\npath = sys.argv[2]\nprint('Removing %s' % path)\ncmd = [adb, 'shell', 'rm', '-rf', path]\nprint(' '.join(cmd))\nsubprocess.check_call(cmd)\n\n# Verify that the path was deleted.\nprint('Checking for existence of %s' % path)\ncmd = [adb, 'shell', 'ls', path]\nprint(' '.join(cmd))\ntry:\n  output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)\nexcept subprocess.CalledProcessError as e:\n  output = e.output\nprint('Output was:')\nprint('======')\nprint(output)\nprint('======')\nif 'No such file or directory' not in output:\n  raise Exception('%s exists despite being deleted' % path)\n",
280      "/usr/bin/adb.1.0.35",
281      "/sdcard/revenge_of_the_skiabot/text_blob_traces"
282    ],
283    "env": {
284      "CHROME_HEADLESS": "1",
285      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
286    },
287    "infra_step": true,
288    "name": "rm /sdcard/revenge_of_the_skiabot/text_blob_traces",
289    "~followup_annotations": [
290      "@@@STEP_LOG_LINE@python.inline@@@@",
291      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
292      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
293      "@@@STEP_LOG_LINE@python.inline@@@@",
294      "@@@STEP_LOG_LINE@python.inline@# Remove the path.@@@",
295      "@@@STEP_LOG_LINE@python.inline@adb = sys.argv[1]@@@",
296      "@@@STEP_LOG_LINE@python.inline@path = sys.argv[2]@@@",
297      "@@@STEP_LOG_LINE@python.inline@print('Removing %s' % path)@@@",
298      "@@@STEP_LOG_LINE@python.inline@cmd = [adb, 'shell', 'rm', '-rf', path]@@@",
299      "@@@STEP_LOG_LINE@python.inline@print(' '.join(cmd))@@@",
300      "@@@STEP_LOG_LINE@python.inline@subprocess.check_call(cmd)@@@",
301      "@@@STEP_LOG_LINE@python.inline@@@@",
302      "@@@STEP_LOG_LINE@python.inline@# Verify that the path was deleted.@@@",
303      "@@@STEP_LOG_LINE@python.inline@print('Checking for existence of %s' % path)@@@",
304      "@@@STEP_LOG_LINE@python.inline@cmd = [adb, 'shell', 'ls', path]@@@",
305      "@@@STEP_LOG_LINE@python.inline@print(' '.join(cmd))@@@",
306      "@@@STEP_LOG_LINE@python.inline@try:@@@",
307      "@@@STEP_LOG_LINE@python.inline@  output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)@@@",
308      "@@@STEP_LOG_LINE@python.inline@except subprocess.CalledProcessError as e:@@@",
309      "@@@STEP_LOG_LINE@python.inline@  output = e.output@@@",
310      "@@@STEP_LOG_LINE@python.inline@print('Output was:')@@@",
311      "@@@STEP_LOG_LINE@python.inline@print('======')@@@",
312      "@@@STEP_LOG_LINE@python.inline@print(output)@@@",
313      "@@@STEP_LOG_LINE@python.inline@print('======')@@@",
314      "@@@STEP_LOG_LINE@python.inline@if 'No such file or directory' not in output:@@@",
315      "@@@STEP_LOG_LINE@python.inline@  raise Exception('%s exists despite being deleted' % path)@@@",
316      "@@@STEP_LOG_END@python.inline@@@"
317    ]
318  },
319  {
320    "cmd": [
321      "/usr/bin/adb.1.0.35",
322      "shell",
323      "mkdir",
324      "-p",
325      "/sdcard/revenge_of_the_skiabot/text_blob_traces"
326    ],
327    "cwd": "[START_DIR]/skia",
328    "env": {
329      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
330      "CHROME_HEADLESS": "1",
331      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
332    },
333    "infra_step": true,
334    "name": "mkdir /sdcard/revenge_of_the_skiabot/text_blob_traces"
335  },
336  {
337    "cmd": [
338      "vpython",
339      "-u",
340      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
341      "--json-output",
342      "/path/to/tmp/json",
343      "glob",
344      "[START_DIR]/text_blob_traces",
345      "*"
346    ],
347    "infra_step": true,
348    "name": "ls [START_DIR]/text_blob_traces/*",
349    "~followup_annotations": [
350      "@@@STEP_LOG_LINE@glob@[START_DIR]/text_blob_traces/bar.jpg@@@",
351      "@@@STEP_LOG_LINE@glob@[START_DIR]/text_blob_traces/foo.png@@@",
352      "@@@STEP_LOG_END@glob@@@"
353    ]
354  },
355  {
356    "cmd": [
357      "/usr/bin/adb.1.0.35",
358      "push",
359      "[START_DIR]/text_blob_traces/bar.jpg",
360      "[START_DIR]/text_blob_traces/foo.png",
361      "/sdcard/revenge_of_the_skiabot/text_blob_traces"
362    ],
363    "cwd": "[START_DIR]/skia",
364    "env": {
365      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
366      "CHROME_HEADLESS": "1",
367      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
368    },
369    "infra_step": true,
370    "name": "push [START_DIR]/text_blob_traces/* /sdcard/revenge_of_the_skiabot/text_blob_traces"
371  },
372  {
373    "cmd": [
374      "/usr/bin/adb.1.0.35",
375      "push",
376      "[START_DIR]/tmp/TEXTTRACES_VERSION",
377      "/sdcard/revenge_of_the_skiabot/TEXTTRACES_VERSION"
378    ],
379    "cwd": "[START_DIR]/skia",
380    "env": {
381      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
382      "CHROME_HEADLESS": "1",
383      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
384    },
385    "infra_step": true,
386    "name": "push [START_DIR]/tmp/TEXTTRACES_VERSION /sdcard/revenge_of_the_skiabot/TEXTTRACES_VERSION"
387  },
388  {
389    "cmd": [
390      "vpython",
391      "-u",
392      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
393      "--json-output",
394      "/path/to/tmp/json",
395      "glob",
396      "[START_DIR]/skia/resources",
397      "*"
398    ],
399    "infra_step": true,
400    "name": "ls [START_DIR]/skia/resources/*",
401    "~followup_annotations": [
402      "@@@STEP_LOG_LINE@glob@[START_DIR]/skia/resources/bar.jpg@@@",
403      "@@@STEP_LOG_LINE@glob@[START_DIR]/skia/resources/foo.png@@@",
404      "@@@STEP_LOG_END@glob@@@"
405    ]
406  },
407  {
408    "cmd": [
409      "/usr/bin/adb.1.0.35",
410      "push",
411      "[START_DIR]/skia/resources/bar.jpg",
412      "[START_DIR]/skia/resources/foo.png",
413      "/sdcard/revenge_of_the_skiabot/resources"
414    ],
415    "cwd": "[START_DIR]/skia",
416    "env": {
417      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
418      "CHROME_HEADLESS": "1",
419      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
420    },
421    "infra_step": true,
422    "name": "push [START_DIR]/skia/resources/* /sdcard/revenge_of_the_skiabot/resources"
423  },
424  {
425    "cmd": [
426      "vpython",
427      "-u",
428      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
429      "--json-output",
430      "/path/to/tmp/json",
431      "copy",
432      "[START_DIR]/skia/infra/bots/assets/skp/VERSION",
433      "/path/to/tmp/"
434    ],
435    "infra_step": true,
436    "name": "Get skp VERSION",
437    "~followup_annotations": [
438      "@@@STEP_LOG_LINE@VERSION@42@@@",
439      "@@@STEP_LOG_END@VERSION@@@"
440    ]
441  },
442  {
443    "cmd": [
444      "vpython",
445      "-u",
446      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
447      "--json-output",
448      "/path/to/tmp/json",
449      "copy",
450      "42",
451      "[START_DIR]/tmp/SKP_VERSION"
452    ],
453    "infra_step": true,
454    "name": "write SKP_VERSION",
455    "~followup_annotations": [
456      "@@@STEP_LOG_LINE@SKP_VERSION@42@@@",
457      "@@@STEP_LOG_END@SKP_VERSION@@@"
458    ]
459  },
460  {
461    "cmd": [
462      "/usr/bin/adb.1.0.35",
463      "shell",
464      "cat",
465      "/sdcard/revenge_of_the_skiabot/SKP_VERSION"
466    ],
467    "cwd": "[START_DIR]/skia",
468    "env": {
469      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
470      "CHROME_HEADLESS": "1",
471      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
472    },
473    "infra_step": true,
474    "name": "read /sdcard/revenge_of_the_skiabot/SKP_VERSION"
475  },
476  {
477    "cmd": [
478      "python",
479      "-u",
480      "\nimport subprocess\nimport sys\n\n# Remove the path.\nadb = sys.argv[1]\npath = sys.argv[2]\nprint('Removing %s' % path)\ncmd = [adb, 'shell', 'rm', '-rf', path]\nprint(' '.join(cmd))\nsubprocess.check_call(cmd)\n\n# Verify that the path was deleted.\nprint('Checking for existence of %s' % path)\ncmd = [adb, 'shell', 'ls', path]\nprint(' '.join(cmd))\ntry:\n  output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)\nexcept subprocess.CalledProcessError as e:\n  output = e.output\nprint('Output was:')\nprint('======')\nprint(output)\nprint('======')\nif 'No such file or directory' not in output:\n  raise Exception('%s exists despite being deleted' % path)\n",
481      "/usr/bin/adb.1.0.35",
482      "/sdcard/revenge_of_the_skiabot/SKP_VERSION"
483    ],
484    "env": {
485      "CHROME_HEADLESS": "1",
486      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
487    },
488    "infra_step": true,
489    "name": "rm /sdcard/revenge_of_the_skiabot/SKP_VERSION",
490    "~followup_annotations": [
491      "@@@STEP_LOG_LINE@python.inline@@@@",
492      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
493      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
494      "@@@STEP_LOG_LINE@python.inline@@@@",
495      "@@@STEP_LOG_LINE@python.inline@# Remove the path.@@@",
496      "@@@STEP_LOG_LINE@python.inline@adb = sys.argv[1]@@@",
497      "@@@STEP_LOG_LINE@python.inline@path = sys.argv[2]@@@",
498      "@@@STEP_LOG_LINE@python.inline@print('Removing %s' % path)@@@",
499      "@@@STEP_LOG_LINE@python.inline@cmd = [adb, 'shell', 'rm', '-rf', path]@@@",
500      "@@@STEP_LOG_LINE@python.inline@print(' '.join(cmd))@@@",
501      "@@@STEP_LOG_LINE@python.inline@subprocess.check_call(cmd)@@@",
502      "@@@STEP_LOG_LINE@python.inline@@@@",
503      "@@@STEP_LOG_LINE@python.inline@# Verify that the path was deleted.@@@",
504      "@@@STEP_LOG_LINE@python.inline@print('Checking for existence of %s' % path)@@@",
505      "@@@STEP_LOG_LINE@python.inline@cmd = [adb, 'shell', 'ls', path]@@@",
506      "@@@STEP_LOG_LINE@python.inline@print(' '.join(cmd))@@@",
507      "@@@STEP_LOG_LINE@python.inline@try:@@@",
508      "@@@STEP_LOG_LINE@python.inline@  output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)@@@",
509      "@@@STEP_LOG_LINE@python.inline@except subprocess.CalledProcessError as e:@@@",
510      "@@@STEP_LOG_LINE@python.inline@  output = e.output@@@",
511      "@@@STEP_LOG_LINE@python.inline@print('Output was:')@@@",
512      "@@@STEP_LOG_LINE@python.inline@print('======')@@@",
513      "@@@STEP_LOG_LINE@python.inline@print(output)@@@",
514      "@@@STEP_LOG_LINE@python.inline@print('======')@@@",
515      "@@@STEP_LOG_LINE@python.inline@if 'No such file or directory' not in output:@@@",
516      "@@@STEP_LOG_LINE@python.inline@  raise Exception('%s exists despite being deleted' % path)@@@",
517      "@@@STEP_LOG_END@python.inline@@@"
518    ]
519  },
520  {
521    "cmd": [
522      "python",
523      "-u",
524      "\nimport subprocess\nimport sys\n\n# Remove the path.\nadb = sys.argv[1]\npath = sys.argv[2]\nprint('Removing %s' % path)\ncmd = [adb, 'shell', 'rm', '-rf', path]\nprint(' '.join(cmd))\nsubprocess.check_call(cmd)\n\n# Verify that the path was deleted.\nprint('Checking for existence of %s' % path)\ncmd = [adb, 'shell', 'ls', path]\nprint(' '.join(cmd))\ntry:\n  output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)\nexcept subprocess.CalledProcessError as e:\n  output = e.output\nprint('Output was:')\nprint('======')\nprint(output)\nprint('======')\nif 'No such file or directory' not in output:\n  raise Exception('%s exists despite being deleted' % path)\n",
525      "/usr/bin/adb.1.0.35",
526      "/sdcard/revenge_of_the_skiabot/skps"
527    ],
528    "env": {
529      "CHROME_HEADLESS": "1",
530      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
531    },
532    "infra_step": true,
533    "name": "rm /sdcard/revenge_of_the_skiabot/skps",
534    "~followup_annotations": [
535      "@@@STEP_LOG_LINE@python.inline@@@@",
536      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
537      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
538      "@@@STEP_LOG_LINE@python.inline@@@@",
539      "@@@STEP_LOG_LINE@python.inline@# Remove the path.@@@",
540      "@@@STEP_LOG_LINE@python.inline@adb = sys.argv[1]@@@",
541      "@@@STEP_LOG_LINE@python.inline@path = sys.argv[2]@@@",
542      "@@@STEP_LOG_LINE@python.inline@print('Removing %s' % path)@@@",
543      "@@@STEP_LOG_LINE@python.inline@cmd = [adb, 'shell', 'rm', '-rf', path]@@@",
544      "@@@STEP_LOG_LINE@python.inline@print(' '.join(cmd))@@@",
545      "@@@STEP_LOG_LINE@python.inline@subprocess.check_call(cmd)@@@",
546      "@@@STEP_LOG_LINE@python.inline@@@@",
547      "@@@STEP_LOG_LINE@python.inline@# Verify that the path was deleted.@@@",
548      "@@@STEP_LOG_LINE@python.inline@print('Checking for existence of %s' % path)@@@",
549      "@@@STEP_LOG_LINE@python.inline@cmd = [adb, 'shell', 'ls', path]@@@",
550      "@@@STEP_LOG_LINE@python.inline@print(' '.join(cmd))@@@",
551      "@@@STEP_LOG_LINE@python.inline@try:@@@",
552      "@@@STEP_LOG_LINE@python.inline@  output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)@@@",
553      "@@@STEP_LOG_LINE@python.inline@except subprocess.CalledProcessError as e:@@@",
554      "@@@STEP_LOG_LINE@python.inline@  output = e.output@@@",
555      "@@@STEP_LOG_LINE@python.inline@print('Output was:')@@@",
556      "@@@STEP_LOG_LINE@python.inline@print('======')@@@",
557      "@@@STEP_LOG_LINE@python.inline@print(output)@@@",
558      "@@@STEP_LOG_LINE@python.inline@print('======')@@@",
559      "@@@STEP_LOG_LINE@python.inline@if 'No such file or directory' not in output:@@@",
560      "@@@STEP_LOG_LINE@python.inline@  raise Exception('%s exists despite being deleted' % path)@@@",
561      "@@@STEP_LOG_END@python.inline@@@"
562    ]
563  },
564  {
565    "cmd": [
566      "/usr/bin/adb.1.0.35",
567      "shell",
568      "mkdir",
569      "-p",
570      "/sdcard/revenge_of_the_skiabot/skps"
571    ],
572    "cwd": "[START_DIR]/skia",
573    "env": {
574      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
575      "CHROME_HEADLESS": "1",
576      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
577    },
578    "infra_step": true,
579    "name": "mkdir /sdcard/revenge_of_the_skiabot/skps"
580  },
581  {
582    "cmd": [
583      "vpython",
584      "-u",
585      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
586      "--json-output",
587      "/path/to/tmp/json",
588      "glob",
589      "[START_DIR]/skp",
590      "*"
591    ],
592    "infra_step": true,
593    "name": "ls [START_DIR]/skp/*",
594    "~followup_annotations": [
595      "@@@STEP_LOG_LINE@glob@[START_DIR]/skp/bar.jpg@@@",
596      "@@@STEP_LOG_LINE@glob@[START_DIR]/skp/foo.png@@@",
597      "@@@STEP_LOG_END@glob@@@"
598    ]
599  },
600  {
601    "cmd": [
602      "/usr/bin/adb.1.0.35",
603      "push",
604      "[START_DIR]/skp/bar.jpg",
605      "[START_DIR]/skp/foo.png",
606      "/sdcard/revenge_of_the_skiabot/skps"
607    ],
608    "cwd": "[START_DIR]/skia",
609    "env": {
610      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
611      "CHROME_HEADLESS": "1",
612      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
613    },
614    "infra_step": true,
615    "name": "push [START_DIR]/skp/* /sdcard/revenge_of_the_skiabot/skps"
616  },
617  {
618    "cmd": [
619      "/usr/bin/adb.1.0.35",
620      "push",
621      "[START_DIR]/tmp/SKP_VERSION",
622      "/sdcard/revenge_of_the_skiabot/SKP_VERSION"
623    ],
624    "cwd": "[START_DIR]/skia",
625    "env": {
626      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
627      "CHROME_HEADLESS": "1",
628      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
629    },
630    "infra_step": true,
631    "name": "push [START_DIR]/tmp/SKP_VERSION /sdcard/revenge_of_the_skiabot/SKP_VERSION"
632  },
633  {
634    "cmd": [
635      "vpython",
636      "-u",
637      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
638      "--json-output",
639      "/path/to/tmp/json",
640      "copy",
641      "[START_DIR]/skia/infra/bots/assets/skimage/VERSION",
642      "/path/to/tmp/"
643    ],
644    "infra_step": true,
645    "name": "Get skimage VERSION",
646    "~followup_annotations": [
647      "@@@STEP_LOG_LINE@VERSION@42@@@",
648      "@@@STEP_LOG_END@VERSION@@@"
649    ]
650  },
651  {
652    "cmd": [
653      "vpython",
654      "-u",
655      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
656      "--json-output",
657      "/path/to/tmp/json",
658      "copy",
659      "42",
660      "[START_DIR]/tmp/SK_IMAGE_VERSION"
661    ],
662    "infra_step": true,
663    "name": "write SK_IMAGE_VERSION",
664    "~followup_annotations": [
665      "@@@STEP_LOG_LINE@SK_IMAGE_VERSION@42@@@",
666      "@@@STEP_LOG_END@SK_IMAGE_VERSION@@@"
667    ]
668  },
669  {
670    "cmd": [
671      "/usr/bin/adb.1.0.35",
672      "shell",
673      "cat",
674      "/sdcard/revenge_of_the_skiabot/SK_IMAGE_VERSION"
675    ],
676    "cwd": "[START_DIR]/skia",
677    "env": {
678      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
679      "CHROME_HEADLESS": "1",
680      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
681    },
682    "infra_step": true,
683    "name": "read /sdcard/revenge_of_the_skiabot/SK_IMAGE_VERSION"
684  },
685  {
686    "cmd": [
687      "python",
688      "-u",
689      "\nimport subprocess\nimport sys\n\n# Remove the path.\nadb = sys.argv[1]\npath = sys.argv[2]\nprint('Removing %s' % path)\ncmd = [adb, 'shell', 'rm', '-rf', path]\nprint(' '.join(cmd))\nsubprocess.check_call(cmd)\n\n# Verify that the path was deleted.\nprint('Checking for existence of %s' % path)\ncmd = [adb, 'shell', 'ls', path]\nprint(' '.join(cmd))\ntry:\n  output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)\nexcept subprocess.CalledProcessError as e:\n  output = e.output\nprint('Output was:')\nprint('======')\nprint(output)\nprint('======')\nif 'No such file or directory' not in output:\n  raise Exception('%s exists despite being deleted' % path)\n",
690      "/usr/bin/adb.1.0.35",
691      "/sdcard/revenge_of_the_skiabot/SK_IMAGE_VERSION"
692    ],
693    "env": {
694      "CHROME_HEADLESS": "1",
695      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
696    },
697    "infra_step": true,
698    "name": "rm /sdcard/revenge_of_the_skiabot/SK_IMAGE_VERSION",
699    "~followup_annotations": [
700      "@@@STEP_LOG_LINE@python.inline@@@@",
701      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
702      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
703      "@@@STEP_LOG_LINE@python.inline@@@@",
704      "@@@STEP_LOG_LINE@python.inline@# Remove the path.@@@",
705      "@@@STEP_LOG_LINE@python.inline@adb = sys.argv[1]@@@",
706      "@@@STEP_LOG_LINE@python.inline@path = sys.argv[2]@@@",
707      "@@@STEP_LOG_LINE@python.inline@print('Removing %s' % path)@@@",
708      "@@@STEP_LOG_LINE@python.inline@cmd = [adb, 'shell', 'rm', '-rf', path]@@@",
709      "@@@STEP_LOG_LINE@python.inline@print(' '.join(cmd))@@@",
710      "@@@STEP_LOG_LINE@python.inline@subprocess.check_call(cmd)@@@",
711      "@@@STEP_LOG_LINE@python.inline@@@@",
712      "@@@STEP_LOG_LINE@python.inline@# Verify that the path was deleted.@@@",
713      "@@@STEP_LOG_LINE@python.inline@print('Checking for existence of %s' % path)@@@",
714      "@@@STEP_LOG_LINE@python.inline@cmd = [adb, 'shell', 'ls', path]@@@",
715      "@@@STEP_LOG_LINE@python.inline@print(' '.join(cmd))@@@",
716      "@@@STEP_LOG_LINE@python.inline@try:@@@",
717      "@@@STEP_LOG_LINE@python.inline@  output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)@@@",
718      "@@@STEP_LOG_LINE@python.inline@except subprocess.CalledProcessError as e:@@@",
719      "@@@STEP_LOG_LINE@python.inline@  output = e.output@@@",
720      "@@@STEP_LOG_LINE@python.inline@print('Output was:')@@@",
721      "@@@STEP_LOG_LINE@python.inline@print('======')@@@",
722      "@@@STEP_LOG_LINE@python.inline@print(output)@@@",
723      "@@@STEP_LOG_LINE@python.inline@print('======')@@@",
724      "@@@STEP_LOG_LINE@python.inline@if 'No such file or directory' not in output:@@@",
725      "@@@STEP_LOG_LINE@python.inline@  raise Exception('%s exists despite being deleted' % path)@@@",
726      "@@@STEP_LOG_END@python.inline@@@"
727    ]
728  },
729  {
730    "cmd": [
731      "python",
732      "-u",
733      "\nimport subprocess\nimport sys\n\n# Remove the path.\nadb = sys.argv[1]\npath = sys.argv[2]\nprint('Removing %s' % path)\ncmd = [adb, 'shell', 'rm', '-rf', path]\nprint(' '.join(cmd))\nsubprocess.check_call(cmd)\n\n# Verify that the path was deleted.\nprint('Checking for existence of %s' % path)\ncmd = [adb, 'shell', 'ls', path]\nprint(' '.join(cmd))\ntry:\n  output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)\nexcept subprocess.CalledProcessError as e:\n  output = e.output\nprint('Output was:')\nprint('======')\nprint(output)\nprint('======')\nif 'No such file or directory' not in output:\n  raise Exception('%s exists despite being deleted' % path)\n",
734      "/usr/bin/adb.1.0.35",
735      "/sdcard/revenge_of_the_skiabot/images"
736    ],
737    "env": {
738      "CHROME_HEADLESS": "1",
739      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
740    },
741    "infra_step": true,
742    "name": "rm /sdcard/revenge_of_the_skiabot/images",
743    "~followup_annotations": [
744      "@@@STEP_LOG_LINE@python.inline@@@@",
745      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
746      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
747      "@@@STEP_LOG_LINE@python.inline@@@@",
748      "@@@STEP_LOG_LINE@python.inline@# Remove the path.@@@",
749      "@@@STEP_LOG_LINE@python.inline@adb = sys.argv[1]@@@",
750      "@@@STEP_LOG_LINE@python.inline@path = sys.argv[2]@@@",
751      "@@@STEP_LOG_LINE@python.inline@print('Removing %s' % path)@@@",
752      "@@@STEP_LOG_LINE@python.inline@cmd = [adb, 'shell', 'rm', '-rf', path]@@@",
753      "@@@STEP_LOG_LINE@python.inline@print(' '.join(cmd))@@@",
754      "@@@STEP_LOG_LINE@python.inline@subprocess.check_call(cmd)@@@",
755      "@@@STEP_LOG_LINE@python.inline@@@@",
756      "@@@STEP_LOG_LINE@python.inline@# Verify that the path was deleted.@@@",
757      "@@@STEP_LOG_LINE@python.inline@print('Checking for existence of %s' % path)@@@",
758      "@@@STEP_LOG_LINE@python.inline@cmd = [adb, 'shell', 'ls', path]@@@",
759      "@@@STEP_LOG_LINE@python.inline@print(' '.join(cmd))@@@",
760      "@@@STEP_LOG_LINE@python.inline@try:@@@",
761      "@@@STEP_LOG_LINE@python.inline@  output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)@@@",
762      "@@@STEP_LOG_LINE@python.inline@except subprocess.CalledProcessError as e:@@@",
763      "@@@STEP_LOG_LINE@python.inline@  output = e.output@@@",
764      "@@@STEP_LOG_LINE@python.inline@print('Output was:')@@@",
765      "@@@STEP_LOG_LINE@python.inline@print('======')@@@",
766      "@@@STEP_LOG_LINE@python.inline@print(output)@@@",
767      "@@@STEP_LOG_LINE@python.inline@print('======')@@@",
768      "@@@STEP_LOG_LINE@python.inline@if 'No such file or directory' not in output:@@@",
769      "@@@STEP_LOG_LINE@python.inline@  raise Exception('%s exists despite being deleted' % path)@@@",
770      "@@@STEP_LOG_END@python.inline@@@"
771    ]
772  },
773  {
774    "cmd": [
775      "/usr/bin/adb.1.0.35",
776      "shell",
777      "mkdir",
778      "-p",
779      "/sdcard/revenge_of_the_skiabot/images"
780    ],
781    "cwd": "[START_DIR]/skia",
782    "env": {
783      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
784      "CHROME_HEADLESS": "1",
785      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
786    },
787    "infra_step": true,
788    "name": "mkdir /sdcard/revenge_of_the_skiabot/images"
789  },
790  {
791    "cmd": [
792      "vpython",
793      "-u",
794      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
795      "--json-output",
796      "/path/to/tmp/json",
797      "glob",
798      "[START_DIR]/skimage",
799      "*"
800    ],
801    "infra_step": true,
802    "name": "ls [START_DIR]/skimage/*",
803    "~followup_annotations": [
804      "@@@STEP_LOG_LINE@glob@[START_DIR]/skimage/bar.jpg@@@",
805      "@@@STEP_LOG_LINE@glob@[START_DIR]/skimage/foo.png@@@",
806      "@@@STEP_LOG_END@glob@@@"
807    ]
808  },
809  {
810    "cmd": [
811      "/usr/bin/adb.1.0.35",
812      "push",
813      "[START_DIR]/skimage/bar.jpg",
814      "[START_DIR]/skimage/foo.png",
815      "/sdcard/revenge_of_the_skiabot/images"
816    ],
817    "cwd": "[START_DIR]/skia",
818    "env": {
819      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
820      "CHROME_HEADLESS": "1",
821      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
822    },
823    "infra_step": true,
824    "name": "push [START_DIR]/skimage/* /sdcard/revenge_of_the_skiabot/images"
825  },
826  {
827    "cmd": [
828      "/usr/bin/adb.1.0.35",
829      "push",
830      "[START_DIR]/tmp/SK_IMAGE_VERSION",
831      "/sdcard/revenge_of_the_skiabot/SK_IMAGE_VERSION"
832    ],
833    "cwd": "[START_DIR]/skia",
834    "env": {
835      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
836      "CHROME_HEADLESS": "1",
837      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
838    },
839    "infra_step": true,
840    "name": "push [START_DIR]/tmp/SK_IMAGE_VERSION /sdcard/revenge_of_the_skiabot/SK_IMAGE_VERSION"
841  },
842  {
843    "cmd": [
844      "vpython",
845      "-u",
846      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
847      "--json-output",
848      "/path/to/tmp/json",
849      "copy",
850      "[START_DIR]/skia/infra/bots/assets/svg/VERSION",
851      "/path/to/tmp/"
852    ],
853    "infra_step": true,
854    "name": "Get svg VERSION",
855    "~followup_annotations": [
856      "@@@STEP_LOG_LINE@VERSION@42@@@",
857      "@@@STEP_LOG_END@VERSION@@@"
858    ]
859  },
860  {
861    "cmd": [
862      "vpython",
863      "-u",
864      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
865      "--json-output",
866      "/path/to/tmp/json",
867      "copy",
868      "42",
869      "[START_DIR]/tmp/SVG_VERSION"
870    ],
871    "infra_step": true,
872    "name": "write SVG_VERSION",
873    "~followup_annotations": [
874      "@@@STEP_LOG_LINE@SVG_VERSION@42@@@",
875      "@@@STEP_LOG_END@SVG_VERSION@@@"
876    ]
877  },
878  {
879    "cmd": [
880      "/usr/bin/adb.1.0.35",
881      "shell",
882      "cat",
883      "/sdcard/revenge_of_the_skiabot/SVG_VERSION"
884    ],
885    "cwd": "[START_DIR]/skia",
886    "env": {
887      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
888      "CHROME_HEADLESS": "1",
889      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
890    },
891    "infra_step": true,
892    "name": "read /sdcard/revenge_of_the_skiabot/SVG_VERSION"
893  },
894  {
895    "cmd": [
896      "python",
897      "-u",
898      "\nimport subprocess\nimport sys\n\n# Remove the path.\nadb = sys.argv[1]\npath = sys.argv[2]\nprint('Removing %s' % path)\ncmd = [adb, 'shell', 'rm', '-rf', path]\nprint(' '.join(cmd))\nsubprocess.check_call(cmd)\n\n# Verify that the path was deleted.\nprint('Checking for existence of %s' % path)\ncmd = [adb, 'shell', 'ls', path]\nprint(' '.join(cmd))\ntry:\n  output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)\nexcept subprocess.CalledProcessError as e:\n  output = e.output\nprint('Output was:')\nprint('======')\nprint(output)\nprint('======')\nif 'No such file or directory' not in output:\n  raise Exception('%s exists despite being deleted' % path)\n",
899      "/usr/bin/adb.1.0.35",
900      "/sdcard/revenge_of_the_skiabot/SVG_VERSION"
901    ],
902    "env": {
903      "CHROME_HEADLESS": "1",
904      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
905    },
906    "infra_step": true,
907    "name": "rm /sdcard/revenge_of_the_skiabot/SVG_VERSION",
908    "~followup_annotations": [
909      "@@@STEP_LOG_LINE@python.inline@@@@",
910      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
911      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
912      "@@@STEP_LOG_LINE@python.inline@@@@",
913      "@@@STEP_LOG_LINE@python.inline@# Remove the path.@@@",
914      "@@@STEP_LOG_LINE@python.inline@adb = sys.argv[1]@@@",
915      "@@@STEP_LOG_LINE@python.inline@path = sys.argv[2]@@@",
916      "@@@STEP_LOG_LINE@python.inline@print('Removing %s' % path)@@@",
917      "@@@STEP_LOG_LINE@python.inline@cmd = [adb, 'shell', 'rm', '-rf', path]@@@",
918      "@@@STEP_LOG_LINE@python.inline@print(' '.join(cmd))@@@",
919      "@@@STEP_LOG_LINE@python.inline@subprocess.check_call(cmd)@@@",
920      "@@@STEP_LOG_LINE@python.inline@@@@",
921      "@@@STEP_LOG_LINE@python.inline@# Verify that the path was deleted.@@@",
922      "@@@STEP_LOG_LINE@python.inline@print('Checking for existence of %s' % path)@@@",
923      "@@@STEP_LOG_LINE@python.inline@cmd = [adb, 'shell', 'ls', path]@@@",
924      "@@@STEP_LOG_LINE@python.inline@print(' '.join(cmd))@@@",
925      "@@@STEP_LOG_LINE@python.inline@try:@@@",
926      "@@@STEP_LOG_LINE@python.inline@  output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)@@@",
927      "@@@STEP_LOG_LINE@python.inline@except subprocess.CalledProcessError as e:@@@",
928      "@@@STEP_LOG_LINE@python.inline@  output = e.output@@@",
929      "@@@STEP_LOG_LINE@python.inline@print('Output was:')@@@",
930      "@@@STEP_LOG_LINE@python.inline@print('======')@@@",
931      "@@@STEP_LOG_LINE@python.inline@print(output)@@@",
932      "@@@STEP_LOG_LINE@python.inline@print('======')@@@",
933      "@@@STEP_LOG_LINE@python.inline@if 'No such file or directory' not in output:@@@",
934      "@@@STEP_LOG_LINE@python.inline@  raise Exception('%s exists despite being deleted' % path)@@@",
935      "@@@STEP_LOG_END@python.inline@@@"
936    ]
937  },
938  {
939    "cmd": [
940      "python",
941      "-u",
942      "\nimport subprocess\nimport sys\n\n# Remove the path.\nadb = sys.argv[1]\npath = sys.argv[2]\nprint('Removing %s' % path)\ncmd = [adb, 'shell', 'rm', '-rf', path]\nprint(' '.join(cmd))\nsubprocess.check_call(cmd)\n\n# Verify that the path was deleted.\nprint('Checking for existence of %s' % path)\ncmd = [adb, 'shell', 'ls', path]\nprint(' '.join(cmd))\ntry:\n  output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)\nexcept subprocess.CalledProcessError as e:\n  output = e.output\nprint('Output was:')\nprint('======')\nprint(output)\nprint('======')\nif 'No such file or directory' not in output:\n  raise Exception('%s exists despite being deleted' % path)\n",
943      "/usr/bin/adb.1.0.35",
944      "/sdcard/revenge_of_the_skiabot/svgs"
945    ],
946    "env": {
947      "CHROME_HEADLESS": "1",
948      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
949    },
950    "infra_step": true,
951    "name": "rm /sdcard/revenge_of_the_skiabot/svgs",
952    "~followup_annotations": [
953      "@@@STEP_LOG_LINE@python.inline@@@@",
954      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
955      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
956      "@@@STEP_LOG_LINE@python.inline@@@@",
957      "@@@STEP_LOG_LINE@python.inline@# Remove the path.@@@",
958      "@@@STEP_LOG_LINE@python.inline@adb = sys.argv[1]@@@",
959      "@@@STEP_LOG_LINE@python.inline@path = sys.argv[2]@@@",
960      "@@@STEP_LOG_LINE@python.inline@print('Removing %s' % path)@@@",
961      "@@@STEP_LOG_LINE@python.inline@cmd = [adb, 'shell', 'rm', '-rf', path]@@@",
962      "@@@STEP_LOG_LINE@python.inline@print(' '.join(cmd))@@@",
963      "@@@STEP_LOG_LINE@python.inline@subprocess.check_call(cmd)@@@",
964      "@@@STEP_LOG_LINE@python.inline@@@@",
965      "@@@STEP_LOG_LINE@python.inline@# Verify that the path was deleted.@@@",
966      "@@@STEP_LOG_LINE@python.inline@print('Checking for existence of %s' % path)@@@",
967      "@@@STEP_LOG_LINE@python.inline@cmd = [adb, 'shell', 'ls', path]@@@",
968      "@@@STEP_LOG_LINE@python.inline@print(' '.join(cmd))@@@",
969      "@@@STEP_LOG_LINE@python.inline@try:@@@",
970      "@@@STEP_LOG_LINE@python.inline@  output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)@@@",
971      "@@@STEP_LOG_LINE@python.inline@except subprocess.CalledProcessError as e:@@@",
972      "@@@STEP_LOG_LINE@python.inline@  output = e.output@@@",
973      "@@@STEP_LOG_LINE@python.inline@print('Output was:')@@@",
974      "@@@STEP_LOG_LINE@python.inline@print('======')@@@",
975      "@@@STEP_LOG_LINE@python.inline@print(output)@@@",
976      "@@@STEP_LOG_LINE@python.inline@print('======')@@@",
977      "@@@STEP_LOG_LINE@python.inline@if 'No such file or directory' not in output:@@@",
978      "@@@STEP_LOG_LINE@python.inline@  raise Exception('%s exists despite being deleted' % path)@@@",
979      "@@@STEP_LOG_END@python.inline@@@"
980    ]
981  },
982  {
983    "cmd": [
984      "/usr/bin/adb.1.0.35",
985      "shell",
986      "mkdir",
987      "-p",
988      "/sdcard/revenge_of_the_skiabot/svgs"
989    ],
990    "cwd": "[START_DIR]/skia",
991    "env": {
992      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
993      "CHROME_HEADLESS": "1",
994      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
995    },
996    "infra_step": true,
997    "name": "mkdir /sdcard/revenge_of_the_skiabot/svgs"
998  },
999  {
1000    "cmd": [
1001      "vpython",
1002      "-u",
1003      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
1004      "--json-output",
1005      "/path/to/tmp/json",
1006      "glob",
1007      "[START_DIR]/svg",
1008      "*"
1009    ],
1010    "infra_step": true,
1011    "name": "ls [START_DIR]/svg/*",
1012    "~followup_annotations": [
1013      "@@@STEP_LOG_LINE@glob@[START_DIR]/svg/bar.jpg@@@",
1014      "@@@STEP_LOG_LINE@glob@[START_DIR]/svg/foo.png@@@",
1015      "@@@STEP_LOG_END@glob@@@"
1016    ]
1017  },
1018  {
1019    "cmd": [
1020      "/usr/bin/adb.1.0.35",
1021      "push",
1022      "[START_DIR]/svg/bar.jpg",
1023      "[START_DIR]/svg/foo.png",
1024      "/sdcard/revenge_of_the_skiabot/svgs"
1025    ],
1026    "cwd": "[START_DIR]/skia",
1027    "env": {
1028      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
1029      "CHROME_HEADLESS": "1",
1030      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
1031    },
1032    "infra_step": true,
1033    "name": "push [START_DIR]/svg/* /sdcard/revenge_of_the_skiabot/svgs"
1034  },
1035  {
1036    "cmd": [
1037      "/usr/bin/adb.1.0.35",
1038      "push",
1039      "[START_DIR]/tmp/SVG_VERSION",
1040      "/sdcard/revenge_of_the_skiabot/SVG_VERSION"
1041    ],
1042    "cwd": "[START_DIR]/skia",
1043    "env": {
1044      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
1045      "CHROME_HEADLESS": "1",
1046      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
1047    },
1048    "infra_step": true,
1049    "name": "push [START_DIR]/tmp/SVG_VERSION /sdcard/revenge_of_the_skiabot/SVG_VERSION"
1050  },
1051  {
1052    "cmd": [
1053      "python",
1054      "-u",
1055      "import os\nprint(os.environ.get('SWARMING_TASK_ID', ''))\n"
1056    ],
1057    "name": "get swarming task id",
1058    "~followup_annotations": [
1059      "@@@STEP_LOG_LINE@python.inline@import os@@@",
1060      "@@@STEP_LOG_LINE@python.inline@print(os.environ.get('SWARMING_TASK_ID', ''))@@@",
1061      "@@@STEP_LOG_END@python.inline@@@"
1062    ]
1063  },
1064  {
1065    "cmd": [
1066      "vpython",
1067      "-u",
1068      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
1069      "--json-output",
1070      "/path/to/tmp/json",
1071      "copy",
1072      "set -x; LD_LIBRARY_PATH=/data/local/tmp/ /data/local/tmp/nanobench --example --flags -i /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/nanobench --texttraces /sdcard/revenge_of_the_skiabot/text_blob_traces --svgs /sdcard/revenge_of_the_skiabot/svgs; echo $? >/data/local/tmp/rc",
1073      "[START_DIR]/tmp/nanobench.sh"
1074    ],
1075    "env": {
1076      "CHROME_HEADLESS": "1",
1077      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
1078    },
1079    "infra_step": true,
1080    "name": "write nanobench.sh",
1081    "~followup_annotations": [
1082      "@@@STEP_LOG_LINE@nanobench.sh@set -x; LD_LIBRARY_PATH=/data/local/tmp/ /data/local/tmp/nanobench --example --flags -i /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/nanobench --texttraces /sdcard/revenge_of_the_skiabot/text_blob_traces --svgs /sdcard/revenge_of_the_skiabot/svgs; echo $? >/data/local/tmp/rc@@@",
1083      "@@@STEP_LOG_END@nanobench.sh@@@"
1084    ]
1085  },
1086  {
1087    "cmd": [
1088      "/usr/bin/adb.1.0.35",
1089      "push",
1090      "[START_DIR]/tmp/nanobench.sh",
1091      "/data/local/tmp/"
1092    ],
1093    "cwd": "[START_DIR]/skia",
1094    "env": {
1095      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
1096      "CHROME_HEADLESS": "1",
1097      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
1098    },
1099    "infra_step": true,
1100    "name": "push nanobench.sh"
1101  },
1102  {
1103    "cmd": [
1104      "/usr/bin/adb.1.0.35",
1105      "logcat",
1106      "-c"
1107    ],
1108    "cwd": "[START_DIR]/skia",
1109    "env": {
1110      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
1111      "CHROME_HEADLESS": "1",
1112      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
1113    },
1114    "infra_step": true,
1115    "name": "clear log"
1116  },
1117  {
1118    "cmd": [
1119      "python",
1120      "-u",
1121      "\nimport subprocess\nimport sys\nbin_dir = sys.argv[1]\nsh      = sys.argv[2]\nsubprocess.check_call(['/usr/bin/adb.1.0.35', 'shell', 'sh', bin_dir + sh])\ntry:\n  sys.exit(int(subprocess.check_output(['/usr/bin/adb.1.0.35', 'shell', 'cat',\n                                        bin_dir + 'rc'])))\nexcept ValueError:\n  print(\"Couldn't read the return code.  Probably killed for OOM.\")\n  sys.exit(1)\n",
1122      "/data/local/tmp/",
1123      "nanobench.sh"
1124    ],
1125    "env": {
1126      "CHROME_HEADLESS": "1",
1127      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
1128    },
1129    "name": "nanobench",
1130    "~followup_annotations": [
1131      "@@@STEP_LOG_LINE@python.inline@@@@",
1132      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
1133      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
1134      "@@@STEP_LOG_LINE@python.inline@bin_dir = sys.argv[1]@@@",
1135      "@@@STEP_LOG_LINE@python.inline@sh      = sys.argv[2]@@@",
1136      "@@@STEP_LOG_LINE@python.inline@subprocess.check_call(['/usr/bin/adb.1.0.35', 'shell', 'sh', bin_dir + sh])@@@",
1137      "@@@STEP_LOG_LINE@python.inline@try:@@@",
1138      "@@@STEP_LOG_LINE@python.inline@  sys.exit(int(subprocess.check_output(['/usr/bin/adb.1.0.35', 'shell', 'cat',@@@",
1139      "@@@STEP_LOG_LINE@python.inline@                                        bin_dir + 'rc'])))@@@",
1140      "@@@STEP_LOG_LINE@python.inline@except ValueError:@@@",
1141      "@@@STEP_LOG_LINE@python.inline@  print(\"Couldn't read the return code.  Probably killed for OOM.\")@@@",
1142      "@@@STEP_LOG_LINE@python.inline@  sys.exit(1)@@@",
1143      "@@@STEP_LOG_END@python.inline@@@"
1144    ]
1145  },
1146  {
1147    "cmd": [
1148      "python",
1149      "-u",
1150      "\nimport os\nimport subprocess\nimport sys\nout = sys.argv[1]\nlog = subprocess.check_output(['/usr/bin/adb.1.0.35', 'logcat', '-d'])\nfor line in log.split('\\n'):\n  tokens = line.split()\n  if len(tokens) == 11 and tokens[-7] == 'F' and tokens[-3] == 'pc':\n    addr, path = tokens[-2:]\n    local = os.path.join(out, os.path.basename(path))\n    if os.path.exists(local):\n      try:\n        sym = subprocess.check_output(['addr2line', '-Cfpe', local, addr])\n        line = line.replace(addr, addr + ' ' + sym.strip())\n      except subprocess.CalledProcessError:\n        pass\n  print(line)\n",
1151      "[START_DIR]/build"
1152    ],
1153    "env": {
1154      "CHROME_HEADLESS": "1",
1155      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
1156    },
1157    "infra_step": true,
1158    "name": "dump log",
1159    "timeout": 300,
1160    "~followup_annotations": [
1161      "@@@STEP_LOG_LINE@python.inline@@@@",
1162      "@@@STEP_LOG_LINE@python.inline@import os@@@",
1163      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
1164      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
1165      "@@@STEP_LOG_LINE@python.inline@out = sys.argv[1]@@@",
1166      "@@@STEP_LOG_LINE@python.inline@log = subprocess.check_output(['/usr/bin/adb.1.0.35', 'logcat', '-d'])@@@",
1167      "@@@STEP_LOG_LINE@python.inline@for line in log.split('\\n'):@@@",
1168      "@@@STEP_LOG_LINE@python.inline@  tokens = line.split()@@@",
1169      "@@@STEP_LOG_LINE@python.inline@  if len(tokens) == 11 and tokens[-7] == 'F' and tokens[-3] == 'pc':@@@",
1170      "@@@STEP_LOG_LINE@python.inline@    addr, path = tokens[-2:]@@@",
1171      "@@@STEP_LOG_LINE@python.inline@    local = os.path.join(out, os.path.basename(path))@@@",
1172      "@@@STEP_LOG_LINE@python.inline@    if os.path.exists(local):@@@",
1173      "@@@STEP_LOG_LINE@python.inline@      try:@@@",
1174      "@@@STEP_LOG_LINE@python.inline@        sym = subprocess.check_output(['addr2line', '-Cfpe', local, addr])@@@",
1175      "@@@STEP_LOG_LINE@python.inline@        line = line.replace(addr, addr + ' ' + sym.strip())@@@",
1176      "@@@STEP_LOG_LINE@python.inline@      except subprocess.CalledProcessError:@@@",
1177      "@@@STEP_LOG_LINE@python.inline@        pass@@@",
1178      "@@@STEP_LOG_LINE@python.inline@  print(line)@@@",
1179      "@@@STEP_LOG_END@python.inline@@@"
1180    ]
1181  },
1182  {
1183    "cmd": [
1184      "/usr/bin/adb.1.0.35",
1185      "kill-server"
1186    ],
1187    "cwd": "[START_DIR]/skia",
1188    "env": {
1189      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
1190      "CHROME_HEADLESS": "1",
1191      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
1192    },
1193    "infra_step": true,
1194    "name": "kill adb server"
1195  },
1196  {
1197    "name": "$result"
1198  }
1199]