1[
2  {
3    "cmd": [
4      "python",
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    "stdout": "/path/to/tmp/",
25    "~followup_annotations": [
26      "@@@STEP_LOG_LINE@python.inline@import os@@@",
27      "@@@STEP_LOG_LINE@python.inline@print os.environ.get('SWARMING_BOT_ID', '')@@@",
28      "@@@STEP_LOG_END@python.inline@@@"
29    ]
30  },
31  {
32    "cmd": [
33      "/usr/bin/adb.1.0.35",
34      "shell",
35      "mkdir",
36      "-p",
37      "/sdcard/revenge_of_the_skiabot/resources"
38    ],
39    "cwd": "[START_DIR]/skia",
40    "env": {
41      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
42      "CHROME_HEADLESS": "1",
43      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
44    },
45    "infra_step": true,
46    "name": "mkdir /sdcard/revenge_of_the_skiabot/resources"
47  },
48  {
49    "cmd": [
50      "python",
51      "-u",
52      "\nimport os\nimport subprocess\nimport sys\nimport time\nADB = sys.argv[1]\nASAN_SETUP = sys.argv[2]\n\ndef wait_for_device():\n  while True:\n    time.sleep(5)\n    print 'Waiting for device'\n    subprocess.check_output([ADB, 'wait-for-device'])\n    bit1 = subprocess.check_output([ADB, 'shell', 'getprop',\n                                   'dev.bootcomplete'])\n    bit2 = subprocess.check_output([ADB, 'shell', 'getprop',\n                                   'sys.boot_completed'])\n    if '1' in bit1 and '1' in bit2:\n      print 'Device detected'\n      break\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\noutput = subprocess.check_output([ADB, 'disable-verity'])\nprint output\n\nif 'already disabled' not in output:\n  print 'Rebooting device'\n  subprocess.check_output([ADB, 'reboot'])\n  wait_for_device()\n\ndef installASAN(revert=False):\n  # ASAN setup script is idempotent, either it installs it or\n  # says it's installed.  Returns True on success, false otherwise.\n  out = subprocess.check_output([ADB, 'wait-for-device'])\n  print out\n  cmd = [ASAN_SETUP]\n  if revert:\n    cmd = [ASAN_SETUP, '--revert']\n  process = subprocess.Popen(cmd, env={'ADB': ADB},\n                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n\n  # this also blocks until command finishes\n  (stdout, stderr) = process.communicate()\n  print stdout\n  print 'Stderr: %s' % stderr\n  return process.returncode == 0\n\nif not installASAN():\n  print 'Trying to revert the ASAN install and then re-install'\n  # ASAN script sometimes has issues if it was interrupted or partially applied\n  # Try reverting it, then re-enabling it\n  if not installASAN(revert=True):\n    raise Exception('reverting ASAN install failed')\n\n  # Sleep because device does not reboot instantly\n  time.sleep(10)\n\n  if not installASAN():\n    raise Exception('Tried twice to setup ASAN and failed.')\n\n# Sleep because device does not reboot instantly\ntime.sleep(10)\nwait_for_device()\n# Sleep again to hopefully avoid error \"secure_mkdirs failed: No such file or\n# directory\" when pushing resources to the device.\ntime.sleep(60)\n",
53      "/usr/bin/adb.1.0.35",
54      "[START_DIR]/android_ndk_linux/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/8.0.2/bin/asan_device_setup"
55    ],
56    "env": {
57      "CHROME_HEADLESS": "1",
58      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
59    },
60    "infra_step": true,
61    "name": "Setting up device to run ASAN",
62    "timeout": 300,
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@ASAN_SETUP = sys.argv[2]@@@",
71      "@@@STEP_LOG_LINE@python.inline@@@@",
72      "@@@STEP_LOG_LINE@python.inline@def wait_for_device():@@@",
73      "@@@STEP_LOG_LINE@python.inline@  while True:@@@",
74      "@@@STEP_LOG_LINE@python.inline@    time.sleep(5)@@@",
75      "@@@STEP_LOG_LINE@python.inline@    print 'Waiting for device'@@@",
76      "@@@STEP_LOG_LINE@python.inline@    subprocess.check_output([ADB, 'wait-for-device'])@@@",
77      "@@@STEP_LOG_LINE@python.inline@    bit1 = subprocess.check_output([ADB, 'shell', 'getprop',@@@",
78      "@@@STEP_LOG_LINE@python.inline@                                   'dev.bootcomplete'])@@@",
79      "@@@STEP_LOG_LINE@python.inline@    bit2 = subprocess.check_output([ADB, 'shell', 'getprop',@@@",
80      "@@@STEP_LOG_LINE@python.inline@                                   'sys.boot_completed'])@@@",
81      "@@@STEP_LOG_LINE@python.inline@    if '1' in bit1 and '1' in bit2:@@@",
82      "@@@STEP_LOG_LINE@python.inline@      print 'Device detected'@@@",
83      "@@@STEP_LOG_LINE@python.inline@      break@@@",
84      "@@@STEP_LOG_LINE@python.inline@@@@",
85      "@@@STEP_LOG_LINE@python.inline@log = subprocess.check_output([ADB, 'root'])@@@",
86      "@@@STEP_LOG_LINE@python.inline@# check for message like 'adbd cannot run as root in production builds'@@@",
87      "@@@STEP_LOG_LINE@python.inline@print log@@@",
88      "@@@STEP_LOG_LINE@python.inline@if 'cannot' in log:@@@",
89      "@@@STEP_LOG_LINE@python.inline@  raise Exception('adb root failed')@@@",
90      "@@@STEP_LOG_LINE@python.inline@@@@",
91      "@@@STEP_LOG_LINE@python.inline@output = subprocess.check_output([ADB, 'disable-verity'])@@@",
92      "@@@STEP_LOG_LINE@python.inline@print output@@@",
93      "@@@STEP_LOG_LINE@python.inline@@@@",
94      "@@@STEP_LOG_LINE@python.inline@if 'already disabled' not in output:@@@",
95      "@@@STEP_LOG_LINE@python.inline@  print 'Rebooting device'@@@",
96      "@@@STEP_LOG_LINE@python.inline@  subprocess.check_output([ADB, 'reboot'])@@@",
97      "@@@STEP_LOG_LINE@python.inline@  wait_for_device()@@@",
98      "@@@STEP_LOG_LINE@python.inline@@@@",
99      "@@@STEP_LOG_LINE@python.inline@def installASAN(revert=False):@@@",
100      "@@@STEP_LOG_LINE@python.inline@  # ASAN setup script is idempotent, either it installs it or@@@",
101      "@@@STEP_LOG_LINE@python.inline@  # says it's installed.  Returns True on success, false otherwise.@@@",
102      "@@@STEP_LOG_LINE@python.inline@  out = subprocess.check_output([ADB, 'wait-for-device'])@@@",
103      "@@@STEP_LOG_LINE@python.inline@  print out@@@",
104      "@@@STEP_LOG_LINE@python.inline@  cmd = [ASAN_SETUP]@@@",
105      "@@@STEP_LOG_LINE@python.inline@  if revert:@@@",
106      "@@@STEP_LOG_LINE@python.inline@    cmd = [ASAN_SETUP, '--revert']@@@",
107      "@@@STEP_LOG_LINE@python.inline@  process = subprocess.Popen(cmd, env={'ADB': ADB},@@@",
108      "@@@STEP_LOG_LINE@python.inline@                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)@@@",
109      "@@@STEP_LOG_LINE@python.inline@@@@",
110      "@@@STEP_LOG_LINE@python.inline@  # this also blocks until command finishes@@@",
111      "@@@STEP_LOG_LINE@python.inline@  (stdout, stderr) = process.communicate()@@@",
112      "@@@STEP_LOG_LINE@python.inline@  print stdout@@@",
113      "@@@STEP_LOG_LINE@python.inline@  print 'Stderr: %s' % stderr@@@",
114      "@@@STEP_LOG_LINE@python.inline@  return process.returncode == 0@@@",
115      "@@@STEP_LOG_LINE@python.inline@@@@",
116      "@@@STEP_LOG_LINE@python.inline@if not installASAN():@@@",
117      "@@@STEP_LOG_LINE@python.inline@  print 'Trying to revert the ASAN install and then re-install'@@@",
118      "@@@STEP_LOG_LINE@python.inline@  # ASAN script sometimes has issues if it was interrupted or partially applied@@@",
119      "@@@STEP_LOG_LINE@python.inline@  # Try reverting it, then re-enabling it@@@",
120      "@@@STEP_LOG_LINE@python.inline@  if not installASAN(revert=True):@@@",
121      "@@@STEP_LOG_LINE@python.inline@    raise Exception('reverting ASAN install failed')@@@",
122      "@@@STEP_LOG_LINE@python.inline@@@@",
123      "@@@STEP_LOG_LINE@python.inline@  # Sleep because device does not reboot instantly@@@",
124      "@@@STEP_LOG_LINE@python.inline@  time.sleep(10)@@@",
125      "@@@STEP_LOG_LINE@python.inline@@@@",
126      "@@@STEP_LOG_LINE@python.inline@  if not installASAN():@@@",
127      "@@@STEP_LOG_LINE@python.inline@    raise Exception('Tried twice to setup ASAN and failed.')@@@",
128      "@@@STEP_LOG_LINE@python.inline@@@@",
129      "@@@STEP_LOG_LINE@python.inline@# Sleep because device does not reboot instantly@@@",
130      "@@@STEP_LOG_LINE@python.inline@time.sleep(10)@@@",
131      "@@@STEP_LOG_LINE@python.inline@wait_for_device()@@@",
132      "@@@STEP_LOG_LINE@python.inline@# Sleep again to hopefully avoid error \"secure_mkdirs failed: No such file or@@@",
133      "@@@STEP_LOG_LINE@python.inline@# directory\" when pushing resources to the device.@@@",
134      "@@@STEP_LOG_LINE@python.inline@time.sleep(60)@@@",
135      "@@@STEP_LOG_END@python.inline@@@"
136    ]
137  },
138  {
139    "cmd": [
140      "python",
141      "-u",
142      "\nimport os\nimport subprocess\nimport sys\nhost   = sys.argv[1]\ndevice = sys.argv[2]\nfor d, _, fs in os.walk(host):\n  p = os.path.relpath(d, host)\n  if p != '.' and p.startswith('.'):\n    continue\n  for f in fs:\n    print os.path.join(p,f)\n    subprocess.check_call(['/usr/bin/adb.1.0.35', 'push',\n                           os.path.realpath(os.path.join(host, p, f)),\n                           os.path.join(device, p, f)])\n",
143      "[START_DIR]/skia/resources",
144      "/sdcard/revenge_of_the_skiabot/resources"
145    ],
146    "env": {
147      "CHROME_HEADLESS": "1",
148      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
149    },
150    "infra_step": true,
151    "name": "push [START_DIR]/skia/resources/* /sdcard/revenge_of_the_skiabot/resources",
152    "~followup_annotations": [
153      "@@@STEP_LOG_LINE@python.inline@@@@",
154      "@@@STEP_LOG_LINE@python.inline@import os@@@",
155      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
156      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
157      "@@@STEP_LOG_LINE@python.inline@host   = sys.argv[1]@@@",
158      "@@@STEP_LOG_LINE@python.inline@device = sys.argv[2]@@@",
159      "@@@STEP_LOG_LINE@python.inline@for d, _, fs in os.walk(host):@@@",
160      "@@@STEP_LOG_LINE@python.inline@  p = os.path.relpath(d, host)@@@",
161      "@@@STEP_LOG_LINE@python.inline@  if p != '.' and p.startswith('.'):@@@",
162      "@@@STEP_LOG_LINE@python.inline@    continue@@@",
163      "@@@STEP_LOG_LINE@python.inline@  for f in fs:@@@",
164      "@@@STEP_LOG_LINE@python.inline@    print os.path.join(p,f)@@@",
165      "@@@STEP_LOG_LINE@python.inline@    subprocess.check_call(['/usr/bin/adb.1.0.35', 'push',@@@",
166      "@@@STEP_LOG_LINE@python.inline@                           os.path.realpath(os.path.join(host, p, f)),@@@",
167      "@@@STEP_LOG_LINE@python.inline@                           os.path.join(device, p, f)])@@@",
168      "@@@STEP_LOG_END@python.inline@@@"
169    ]
170  },
171  {
172    "cmd": [
173      "python",
174      "-u",
175      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
176      "--json-output",
177      "/path/to/tmp/json",
178      "copy",
179      "[START_DIR]/skia/infra/bots/assets/skp/VERSION",
180      "/path/to/tmp/"
181    ],
182    "infra_step": true,
183    "name": "Get skp VERSION"
184  },
185  {
186    "cmd": [
187      "python",
188      "-u",
189      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
190      "--json-output",
191      "/path/to/tmp/json",
192      "copy",
193      "42",
194      "[START_DIR]/tmp/SKP_VERSION"
195    ],
196    "infra_step": true,
197    "name": "write SKP_VERSION"
198  },
199  {
200    "cmd": [
201      "/usr/bin/adb.1.0.35",
202      "shell",
203      "cat",
204      "/sdcard/revenge_of_the_skiabot/SKP_VERSION"
205    ],
206    "cwd": "[START_DIR]/skia",
207    "env": {
208      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
209      "CHROME_HEADLESS": "1",
210      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
211    },
212    "infra_step": true,
213    "name": "read /sdcard/revenge_of_the_skiabot/SKP_VERSION",
214    "stdout": "/path/to/tmp/"
215  },
216  {
217    "cmd": [
218      "/usr/bin/adb.1.0.35",
219      "shell",
220      "rm",
221      "-f",
222      "/sdcard/revenge_of_the_skiabot/SKP_VERSION"
223    ],
224    "cwd": "[START_DIR]/skia",
225    "env": {
226      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
227      "CHROME_HEADLESS": "1",
228      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
229    },
230    "infra_step": true,
231    "name": "rm /sdcard/revenge_of_the_skiabot/SKP_VERSION"
232  },
233  {
234    "cmd": [
235      "/usr/bin/adb.1.0.35",
236      "shell",
237      "rm",
238      "-rf",
239      "/sdcard/revenge_of_the_skiabot/skps"
240    ],
241    "cwd": "[START_DIR]/skia",
242    "env": {
243      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
244      "CHROME_HEADLESS": "1",
245      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
246    },
247    "infra_step": true,
248    "name": "rm /sdcard/revenge_of_the_skiabot/skps"
249  },
250  {
251    "cmd": [
252      "/usr/bin/adb.1.0.35",
253      "shell",
254      "mkdir",
255      "-p",
256      "/sdcard/revenge_of_the_skiabot/skps"
257    ],
258    "cwd": "[START_DIR]/skia",
259    "env": {
260      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
261      "CHROME_HEADLESS": "1",
262      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
263    },
264    "infra_step": true,
265    "name": "mkdir /sdcard/revenge_of_the_skiabot/skps"
266  },
267  {
268    "cmd": [
269      "python",
270      "-u",
271      "\nimport os\nimport subprocess\nimport sys\nhost   = sys.argv[1]\ndevice = sys.argv[2]\nfor d, _, fs in os.walk(host):\n  p = os.path.relpath(d, host)\n  if p != '.' and p.startswith('.'):\n    continue\n  for f in fs:\n    print os.path.join(p,f)\n    subprocess.check_call(['/usr/bin/adb.1.0.35', 'push',\n                           os.path.realpath(os.path.join(host, p, f)),\n                           os.path.join(device, p, f)])\n",
272      "[START_DIR]/skp",
273      "/sdcard/revenge_of_the_skiabot/skps"
274    ],
275    "env": {
276      "CHROME_HEADLESS": "1",
277      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
278    },
279    "infra_step": true,
280    "name": "push [START_DIR]/skp/* /sdcard/revenge_of_the_skiabot/skps",
281    "~followup_annotations": [
282      "@@@STEP_LOG_LINE@python.inline@@@@",
283      "@@@STEP_LOG_LINE@python.inline@import os@@@",
284      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
285      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
286      "@@@STEP_LOG_LINE@python.inline@host   = sys.argv[1]@@@",
287      "@@@STEP_LOG_LINE@python.inline@device = sys.argv[2]@@@",
288      "@@@STEP_LOG_LINE@python.inline@for d, _, fs in os.walk(host):@@@",
289      "@@@STEP_LOG_LINE@python.inline@  p = os.path.relpath(d, host)@@@",
290      "@@@STEP_LOG_LINE@python.inline@  if p != '.' and p.startswith('.'):@@@",
291      "@@@STEP_LOG_LINE@python.inline@    continue@@@",
292      "@@@STEP_LOG_LINE@python.inline@  for f in fs:@@@",
293      "@@@STEP_LOG_LINE@python.inline@    print os.path.join(p,f)@@@",
294      "@@@STEP_LOG_LINE@python.inline@    subprocess.check_call(['/usr/bin/adb.1.0.35', 'push',@@@",
295      "@@@STEP_LOG_LINE@python.inline@                           os.path.realpath(os.path.join(host, p, f)),@@@",
296      "@@@STEP_LOG_LINE@python.inline@                           os.path.join(device, p, f)])@@@",
297      "@@@STEP_LOG_END@python.inline@@@"
298    ]
299  },
300  {
301    "cmd": [
302      "/usr/bin/adb.1.0.35",
303      "push",
304      "[START_DIR]/tmp/SKP_VERSION",
305      "/sdcard/revenge_of_the_skiabot/SKP_VERSION"
306    ],
307    "cwd": "[START_DIR]/skia",
308    "env": {
309      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
310      "CHROME_HEADLESS": "1",
311      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
312    },
313    "infra_step": true,
314    "name": "push [START_DIR]/tmp/SKP_VERSION /sdcard/revenge_of_the_skiabot/SKP_VERSION"
315  },
316  {
317    "cmd": [
318      "python",
319      "-u",
320      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
321      "--json-output",
322      "/path/to/tmp/json",
323      "copy",
324      "[START_DIR]/skia/infra/bots/assets/skimage/VERSION",
325      "/path/to/tmp/"
326    ],
327    "infra_step": true,
328    "name": "Get skimage VERSION"
329  },
330  {
331    "cmd": [
332      "python",
333      "-u",
334      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
335      "--json-output",
336      "/path/to/tmp/json",
337      "copy",
338      "42",
339      "[START_DIR]/tmp/SK_IMAGE_VERSION"
340    ],
341    "infra_step": true,
342    "name": "write SK_IMAGE_VERSION"
343  },
344  {
345    "cmd": [
346      "/usr/bin/adb.1.0.35",
347      "shell",
348      "cat",
349      "/sdcard/revenge_of_the_skiabot/SK_IMAGE_VERSION"
350    ],
351    "cwd": "[START_DIR]/skia",
352    "env": {
353      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
354      "CHROME_HEADLESS": "1",
355      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
356    },
357    "infra_step": true,
358    "name": "read /sdcard/revenge_of_the_skiabot/SK_IMAGE_VERSION",
359    "stdout": "/path/to/tmp/"
360  },
361  {
362    "cmd": [
363      "/usr/bin/adb.1.0.35",
364      "shell",
365      "rm",
366      "-f",
367      "/sdcard/revenge_of_the_skiabot/SK_IMAGE_VERSION"
368    ],
369    "cwd": "[START_DIR]/skia",
370    "env": {
371      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
372      "CHROME_HEADLESS": "1",
373      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
374    },
375    "infra_step": true,
376    "name": "rm /sdcard/revenge_of_the_skiabot/SK_IMAGE_VERSION"
377  },
378  {
379    "cmd": [
380      "/usr/bin/adb.1.0.35",
381      "shell",
382      "rm",
383      "-rf",
384      "/sdcard/revenge_of_the_skiabot/images"
385    ],
386    "cwd": "[START_DIR]/skia",
387    "env": {
388      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
389      "CHROME_HEADLESS": "1",
390      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
391    },
392    "infra_step": true,
393    "name": "rm /sdcard/revenge_of_the_skiabot/images"
394  },
395  {
396    "cmd": [
397      "/usr/bin/adb.1.0.35",
398      "shell",
399      "mkdir",
400      "-p",
401      "/sdcard/revenge_of_the_skiabot/images"
402    ],
403    "cwd": "[START_DIR]/skia",
404    "env": {
405      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
406      "CHROME_HEADLESS": "1",
407      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
408    },
409    "infra_step": true,
410    "name": "mkdir /sdcard/revenge_of_the_skiabot/images"
411  },
412  {
413    "cmd": [
414      "python",
415      "-u",
416      "\nimport os\nimport subprocess\nimport sys\nhost   = sys.argv[1]\ndevice = sys.argv[2]\nfor d, _, fs in os.walk(host):\n  p = os.path.relpath(d, host)\n  if p != '.' and p.startswith('.'):\n    continue\n  for f in fs:\n    print os.path.join(p,f)\n    subprocess.check_call(['/usr/bin/adb.1.0.35', 'push',\n                           os.path.realpath(os.path.join(host, p, f)),\n                           os.path.join(device, p, f)])\n",
417      "[START_DIR]/skimage",
418      "/sdcard/revenge_of_the_skiabot/images"
419    ],
420    "env": {
421      "CHROME_HEADLESS": "1",
422      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
423    },
424    "infra_step": true,
425    "name": "push [START_DIR]/skimage/* /sdcard/revenge_of_the_skiabot/images",
426    "~followup_annotations": [
427      "@@@STEP_LOG_LINE@python.inline@@@@",
428      "@@@STEP_LOG_LINE@python.inline@import os@@@",
429      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
430      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
431      "@@@STEP_LOG_LINE@python.inline@host   = sys.argv[1]@@@",
432      "@@@STEP_LOG_LINE@python.inline@device = sys.argv[2]@@@",
433      "@@@STEP_LOG_LINE@python.inline@for d, _, fs in os.walk(host):@@@",
434      "@@@STEP_LOG_LINE@python.inline@  p = os.path.relpath(d, host)@@@",
435      "@@@STEP_LOG_LINE@python.inline@  if p != '.' and p.startswith('.'):@@@",
436      "@@@STEP_LOG_LINE@python.inline@    continue@@@",
437      "@@@STEP_LOG_LINE@python.inline@  for f in fs:@@@",
438      "@@@STEP_LOG_LINE@python.inline@    print os.path.join(p,f)@@@",
439      "@@@STEP_LOG_LINE@python.inline@    subprocess.check_call(['/usr/bin/adb.1.0.35', 'push',@@@",
440      "@@@STEP_LOG_LINE@python.inline@                           os.path.realpath(os.path.join(host, p, f)),@@@",
441      "@@@STEP_LOG_LINE@python.inline@                           os.path.join(device, p, f)])@@@",
442      "@@@STEP_LOG_END@python.inline@@@"
443    ]
444  },
445  {
446    "cmd": [
447      "/usr/bin/adb.1.0.35",
448      "push",
449      "[START_DIR]/tmp/SK_IMAGE_VERSION",
450      "/sdcard/revenge_of_the_skiabot/SK_IMAGE_VERSION"
451    ],
452    "cwd": "[START_DIR]/skia",
453    "env": {
454      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
455      "CHROME_HEADLESS": "1",
456      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
457    },
458    "infra_step": true,
459    "name": "push [START_DIR]/tmp/SK_IMAGE_VERSION /sdcard/revenge_of_the_skiabot/SK_IMAGE_VERSION"
460  },
461  {
462    "cmd": [
463      "python",
464      "-u",
465      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
466      "--json-output",
467      "/path/to/tmp/json",
468      "copy",
469      "[START_DIR]/skia/infra/bots/assets/svg/VERSION",
470      "/path/to/tmp/"
471    ],
472    "infra_step": true,
473    "name": "Get svg VERSION"
474  },
475  {
476    "cmd": [
477      "python",
478      "-u",
479      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
480      "--json-output",
481      "/path/to/tmp/json",
482      "copy",
483      "42",
484      "[START_DIR]/tmp/SVG_VERSION"
485    ],
486    "infra_step": true,
487    "name": "write SVG_VERSION"
488  },
489  {
490    "cmd": [
491      "/usr/bin/adb.1.0.35",
492      "shell",
493      "cat",
494      "/sdcard/revenge_of_the_skiabot/SVG_VERSION"
495    ],
496    "cwd": "[START_DIR]/skia",
497    "env": {
498      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
499      "CHROME_HEADLESS": "1",
500      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
501    },
502    "infra_step": true,
503    "name": "read /sdcard/revenge_of_the_skiabot/SVG_VERSION",
504    "stdout": "/path/to/tmp/"
505  },
506  {
507    "cmd": [
508      "/usr/bin/adb.1.0.35",
509      "shell",
510      "rm",
511      "-f",
512      "/sdcard/revenge_of_the_skiabot/SVG_VERSION"
513    ],
514    "cwd": "[START_DIR]/skia",
515    "env": {
516      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
517      "CHROME_HEADLESS": "1",
518      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
519    },
520    "infra_step": true,
521    "name": "rm /sdcard/revenge_of_the_skiabot/SVG_VERSION"
522  },
523  {
524    "cmd": [
525      "/usr/bin/adb.1.0.35",
526      "shell",
527      "rm",
528      "-rf",
529      "/sdcard/revenge_of_the_skiabot/svgs"
530    ],
531    "cwd": "[START_DIR]/skia",
532    "env": {
533      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
534      "CHROME_HEADLESS": "1",
535      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
536    },
537    "infra_step": true,
538    "name": "rm /sdcard/revenge_of_the_skiabot/svgs"
539  },
540  {
541    "cmd": [
542      "/usr/bin/adb.1.0.35",
543      "shell",
544      "mkdir",
545      "-p",
546      "/sdcard/revenge_of_the_skiabot/svgs"
547    ],
548    "cwd": "[START_DIR]/skia",
549    "env": {
550      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
551      "CHROME_HEADLESS": "1",
552      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
553    },
554    "infra_step": true,
555    "name": "mkdir /sdcard/revenge_of_the_skiabot/svgs"
556  },
557  {
558    "cmd": [
559      "python",
560      "-u",
561      "\nimport os\nimport subprocess\nimport sys\nhost   = sys.argv[1]\ndevice = sys.argv[2]\nfor d, _, fs in os.walk(host):\n  p = os.path.relpath(d, host)\n  if p != '.' and p.startswith('.'):\n    continue\n  for f in fs:\n    print os.path.join(p,f)\n    subprocess.check_call(['/usr/bin/adb.1.0.35', 'push',\n                           os.path.realpath(os.path.join(host, p, f)),\n                           os.path.join(device, p, f)])\n",
562      "[START_DIR]/svg",
563      "/sdcard/revenge_of_the_skiabot/svgs"
564    ],
565    "env": {
566      "CHROME_HEADLESS": "1",
567      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
568    },
569    "infra_step": true,
570    "name": "push [START_DIR]/svg/* /sdcard/revenge_of_the_skiabot/svgs",
571    "~followup_annotations": [
572      "@@@STEP_LOG_LINE@python.inline@@@@",
573      "@@@STEP_LOG_LINE@python.inline@import os@@@",
574      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
575      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
576      "@@@STEP_LOG_LINE@python.inline@host   = sys.argv[1]@@@",
577      "@@@STEP_LOG_LINE@python.inline@device = sys.argv[2]@@@",
578      "@@@STEP_LOG_LINE@python.inline@for d, _, fs in os.walk(host):@@@",
579      "@@@STEP_LOG_LINE@python.inline@  p = os.path.relpath(d, host)@@@",
580      "@@@STEP_LOG_LINE@python.inline@  if p != '.' and p.startswith('.'):@@@",
581      "@@@STEP_LOG_LINE@python.inline@    continue@@@",
582      "@@@STEP_LOG_LINE@python.inline@  for f in fs:@@@",
583      "@@@STEP_LOG_LINE@python.inline@    print os.path.join(p,f)@@@",
584      "@@@STEP_LOG_LINE@python.inline@    subprocess.check_call(['/usr/bin/adb.1.0.35', 'push',@@@",
585      "@@@STEP_LOG_LINE@python.inline@                           os.path.realpath(os.path.join(host, p, f)),@@@",
586      "@@@STEP_LOG_LINE@python.inline@                           os.path.join(device, p, f)])@@@",
587      "@@@STEP_LOG_END@python.inline@@@"
588    ]
589  },
590  {
591    "cmd": [
592      "/usr/bin/adb.1.0.35",
593      "push",
594      "[START_DIR]/tmp/SVG_VERSION",
595      "/sdcard/revenge_of_the_skiabot/SVG_VERSION"
596    ],
597    "cwd": "[START_DIR]/skia",
598    "env": {
599      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
600      "CHROME_HEADLESS": "1",
601      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
602    },
603    "infra_step": true,
604    "name": "push [START_DIR]/tmp/SVG_VERSION /sdcard/revenge_of_the_skiabot/SVG_VERSION"
605  },
606  {
607    "cmd": [
608      "python",
609      "-u",
610      "import os\nprint os.environ.get('SWARMING_TASK_ID', '')\n"
611    ],
612    "name": "get swarming task id",
613    "stdout": "/path/to/tmp/",
614    "~followup_annotations": [
615      "@@@STEP_LOG_LINE@python.inline@import os@@@",
616      "@@@STEP_LOG_LINE@python.inline@print os.environ.get('SWARMING_TASK_ID', '')@@@",
617      "@@@STEP_LOG_END@python.inline@@@"
618    ]
619  },
620  {
621    "cmd": [
622      "python",
623      "-u",
624      "\nimport os\nimport subprocess\nimport sys\nimport time\nADB = sys.argv[1]\ncpu = int(sys.argv[2])\nvalue = int(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\n# If we try to echo 1 to an already online cpu, adb returns exit code 1.\n# So, check the value before trying to write it.\nprior_status = subprocess.check_output([ADB, 'shell', 'cat '\n    '/sys/devices/system/cpu/cpu%d/online' % cpu]).strip()\nif prior_status == str(value):\n  print 'CPU %d online already %d' % (cpu, value)\n  sys.exit()\n\nsubprocess.check_output([ADB, 'shell', 'echo %s > '\n    '/sys/devices/system/cpu/cpu%d/online' % (value, cpu)])\nactual_status = subprocess.check_output([ADB, 'shell', 'cat '\n    '/sys/devices/system/cpu/cpu%d/online' % cpu]).strip()\nif actual_status != str(value):\n  raise Exception('(actual, expected) (%s, %d)'\n                  % (actual_status, value))\n",
625      "/usr/bin/adb.1.0.35",
626      "0",
627      "1"
628    ],
629    "env": {
630      "CHROME_HEADLESS": "1",
631      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
632    },
633    "infra_step": true,
634    "name": "Enabling CPU 0",
635    "timeout": 30,
636    "~followup_annotations": [
637      "@@@STEP_LOG_LINE@python.inline@@@@",
638      "@@@STEP_LOG_LINE@python.inline@import os@@@",
639      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
640      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
641      "@@@STEP_LOG_LINE@python.inline@import time@@@",
642      "@@@STEP_LOG_LINE@python.inline@ADB = sys.argv[1]@@@",
643      "@@@STEP_LOG_LINE@python.inline@cpu = int(sys.argv[2])@@@",
644      "@@@STEP_LOG_LINE@python.inline@value = int(sys.argv[3])@@@",
645      "@@@STEP_LOG_LINE@python.inline@@@@",
646      "@@@STEP_LOG_LINE@python.inline@log = subprocess.check_output([ADB, 'root'])@@@",
647      "@@@STEP_LOG_LINE@python.inline@# check for message like 'adbd cannot run as root in production builds'@@@",
648      "@@@STEP_LOG_LINE@python.inline@print log@@@",
649      "@@@STEP_LOG_LINE@python.inline@if 'cannot' in log:@@@",
650      "@@@STEP_LOG_LINE@python.inline@  raise Exception('adb root failed')@@@",
651      "@@@STEP_LOG_LINE@python.inline@@@@",
652      "@@@STEP_LOG_LINE@python.inline@# If we try to echo 1 to an already online cpu, adb returns exit code 1.@@@",
653      "@@@STEP_LOG_LINE@python.inline@# So, check the value before trying to write it.@@@",
654      "@@@STEP_LOG_LINE@python.inline@prior_status = subprocess.check_output([ADB, 'shell', 'cat '@@@",
655      "@@@STEP_LOG_LINE@python.inline@    '/sys/devices/system/cpu/cpu%d/online' % cpu]).strip()@@@",
656      "@@@STEP_LOG_LINE@python.inline@if prior_status == str(value):@@@",
657      "@@@STEP_LOG_LINE@python.inline@  print 'CPU %d online already %d' % (cpu, value)@@@",
658      "@@@STEP_LOG_LINE@python.inline@  sys.exit()@@@",
659      "@@@STEP_LOG_LINE@python.inline@@@@",
660      "@@@STEP_LOG_LINE@python.inline@subprocess.check_output([ADB, 'shell', 'echo %s > '@@@",
661      "@@@STEP_LOG_LINE@python.inline@    '/sys/devices/system/cpu/cpu%d/online' % (value, cpu)])@@@",
662      "@@@STEP_LOG_LINE@python.inline@actual_status = subprocess.check_output([ADB, 'shell', 'cat '@@@",
663      "@@@STEP_LOG_LINE@python.inline@    '/sys/devices/system/cpu/cpu%d/online' % cpu]).strip()@@@",
664      "@@@STEP_LOG_LINE@python.inline@if actual_status != str(value):@@@",
665      "@@@STEP_LOG_LINE@python.inline@  raise Exception('(actual, expected) (%s, %d)'@@@",
666      "@@@STEP_LOG_LINE@python.inline@                  % (actual_status, value))@@@",
667      "@@@STEP_LOG_END@python.inline@@@"
668    ]
669  },
670  {
671    "cmd": [
672      "python",
673      "-u",
674      "\nimport os\nimport subprocess\nimport sys\nimport time\nADB = sys.argv[1]\ncpu = int(sys.argv[2])\nvalue = int(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\n# If we try to echo 1 to an already online cpu, adb returns exit code 1.\n# So, check the value before trying to write it.\nprior_status = subprocess.check_output([ADB, 'shell', 'cat '\n    '/sys/devices/system/cpu/cpu%d/online' % cpu]).strip()\nif prior_status == str(value):\n  print 'CPU %d online already %d' % (cpu, value)\n  sys.exit()\n\nsubprocess.check_output([ADB, 'shell', 'echo %s > '\n    '/sys/devices/system/cpu/cpu%d/online' % (value, cpu)])\nactual_status = subprocess.check_output([ADB, 'shell', 'cat '\n    '/sys/devices/system/cpu/cpu%d/online' % cpu]).strip()\nif actual_status != str(value):\n  raise Exception('(actual, expected) (%s, %d)'\n                  % (actual_status, value))\n",
675      "/usr/bin/adb.1.0.35",
676      "1",
677      "1"
678    ],
679    "env": {
680      "CHROME_HEADLESS": "1",
681      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
682    },
683    "infra_step": true,
684    "name": "Enabling CPU 1",
685    "timeout": 30,
686    "~followup_annotations": [
687      "@@@STEP_LOG_LINE@python.inline@@@@",
688      "@@@STEP_LOG_LINE@python.inline@import os@@@",
689      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
690      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
691      "@@@STEP_LOG_LINE@python.inline@import time@@@",
692      "@@@STEP_LOG_LINE@python.inline@ADB = sys.argv[1]@@@",
693      "@@@STEP_LOG_LINE@python.inline@cpu = int(sys.argv[2])@@@",
694      "@@@STEP_LOG_LINE@python.inline@value = int(sys.argv[3])@@@",
695      "@@@STEP_LOG_LINE@python.inline@@@@",
696      "@@@STEP_LOG_LINE@python.inline@log = subprocess.check_output([ADB, 'root'])@@@",
697      "@@@STEP_LOG_LINE@python.inline@# check for message like 'adbd cannot run as root in production builds'@@@",
698      "@@@STEP_LOG_LINE@python.inline@print log@@@",
699      "@@@STEP_LOG_LINE@python.inline@if 'cannot' in log:@@@",
700      "@@@STEP_LOG_LINE@python.inline@  raise Exception('adb root failed')@@@",
701      "@@@STEP_LOG_LINE@python.inline@@@@",
702      "@@@STEP_LOG_LINE@python.inline@# If we try to echo 1 to an already online cpu, adb returns exit code 1.@@@",
703      "@@@STEP_LOG_LINE@python.inline@# So, check the value before trying to write it.@@@",
704      "@@@STEP_LOG_LINE@python.inline@prior_status = subprocess.check_output([ADB, 'shell', 'cat '@@@",
705      "@@@STEP_LOG_LINE@python.inline@    '/sys/devices/system/cpu/cpu%d/online' % cpu]).strip()@@@",
706      "@@@STEP_LOG_LINE@python.inline@if prior_status == str(value):@@@",
707      "@@@STEP_LOG_LINE@python.inline@  print 'CPU %d online already %d' % (cpu, value)@@@",
708      "@@@STEP_LOG_LINE@python.inline@  sys.exit()@@@",
709      "@@@STEP_LOG_LINE@python.inline@@@@",
710      "@@@STEP_LOG_LINE@python.inline@subprocess.check_output([ADB, 'shell', 'echo %s > '@@@",
711      "@@@STEP_LOG_LINE@python.inline@    '/sys/devices/system/cpu/cpu%d/online' % (value, cpu)])@@@",
712      "@@@STEP_LOG_LINE@python.inline@actual_status = subprocess.check_output([ADB, 'shell', 'cat '@@@",
713      "@@@STEP_LOG_LINE@python.inline@    '/sys/devices/system/cpu/cpu%d/online' % cpu]).strip()@@@",
714      "@@@STEP_LOG_LINE@python.inline@if actual_status != str(value):@@@",
715      "@@@STEP_LOG_LINE@python.inline@  raise Exception('(actual, expected) (%s, %d)'@@@",
716      "@@@STEP_LOG_LINE@python.inline@                  % (actual_status, value))@@@",
717      "@@@STEP_LOG_END@python.inline@@@"
718    ]
719  },
720  {
721    "cmd": [
722      "python",
723      "-u",
724      "\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",
725      "/usr/bin/adb.1.0.35",
726      "2",
727      "ondemand"
728    ],
729    "env": {
730      "CHROME_HEADLESS": "1",
731      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
732    },
733    "infra_step": true,
734    "name": "Set CPU 2's governor to ondemand",
735    "timeout": 30,
736    "~followup_annotations": [
737      "@@@STEP_LOG_LINE@python.inline@@@@",
738      "@@@STEP_LOG_LINE@python.inline@import os@@@",
739      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
740      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
741      "@@@STEP_LOG_LINE@python.inline@import time@@@",
742      "@@@STEP_LOG_LINE@python.inline@ADB = sys.argv[1]@@@",
743      "@@@STEP_LOG_LINE@python.inline@cpu = int(sys.argv[2])@@@",
744      "@@@STEP_LOG_LINE@python.inline@gov = sys.argv[3]@@@",
745      "@@@STEP_LOG_LINE@python.inline@@@@",
746      "@@@STEP_LOG_LINE@python.inline@log = subprocess.check_output([ADB, 'root'])@@@",
747      "@@@STEP_LOG_LINE@python.inline@# check for message like 'adbd cannot run as root in production builds'@@@",
748      "@@@STEP_LOG_LINE@python.inline@print log@@@",
749      "@@@STEP_LOG_LINE@python.inline@if 'cannot' in log:@@@",
750      "@@@STEP_LOG_LINE@python.inline@  raise Exception('adb root failed')@@@",
751      "@@@STEP_LOG_LINE@python.inline@@@@",
752      "@@@STEP_LOG_LINE@python.inline@subprocess.check_output([ADB, 'shell', 'echo \"%s\" > '@@@",
753      "@@@STEP_LOG_LINE@python.inline@    '/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor' % (gov, cpu)])@@@",
754      "@@@STEP_LOG_LINE@python.inline@actual_gov = subprocess.check_output([ADB, 'shell', 'cat '@@@",
755      "@@@STEP_LOG_LINE@python.inline@    '/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor' % cpu]).strip()@@@",
756      "@@@STEP_LOG_LINE@python.inline@if actual_gov != gov:@@@",
757      "@@@STEP_LOG_LINE@python.inline@  raise Exception('(actual, expected) (%s, %s)'@@@",
758      "@@@STEP_LOG_LINE@python.inline@                  % (actual_gov, gov))@@@",
759      "@@@STEP_LOG_END@python.inline@@@"
760    ]
761  },
762  {
763    "cmd": [
764      "python",
765      "-u",
766      "\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",
767      "/usr/bin/adb.1.0.35",
768      "0",
769      "ondemand"
770    ],
771    "env": {
772      "CHROME_HEADLESS": "1",
773      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
774    },
775    "infra_step": true,
776    "name": "Set CPU 0's governor to ondemand",
777    "timeout": 30,
778    "~followup_annotations": [
779      "@@@STEP_LOG_LINE@python.inline@@@@",
780      "@@@STEP_LOG_LINE@python.inline@import os@@@",
781      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
782      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
783      "@@@STEP_LOG_LINE@python.inline@import time@@@",
784      "@@@STEP_LOG_LINE@python.inline@ADB = sys.argv[1]@@@",
785      "@@@STEP_LOG_LINE@python.inline@cpu = int(sys.argv[2])@@@",
786      "@@@STEP_LOG_LINE@python.inline@gov = sys.argv[3]@@@",
787      "@@@STEP_LOG_LINE@python.inline@@@@",
788      "@@@STEP_LOG_LINE@python.inline@log = subprocess.check_output([ADB, 'root'])@@@",
789      "@@@STEP_LOG_LINE@python.inline@# check for message like 'adbd cannot run as root in production builds'@@@",
790      "@@@STEP_LOG_LINE@python.inline@print log@@@",
791      "@@@STEP_LOG_LINE@python.inline@if 'cannot' in log:@@@",
792      "@@@STEP_LOG_LINE@python.inline@  raise Exception('adb root failed')@@@",
793      "@@@STEP_LOG_LINE@python.inline@@@@",
794      "@@@STEP_LOG_LINE@python.inline@subprocess.check_output([ADB, 'shell', 'echo \"%s\" > '@@@",
795      "@@@STEP_LOG_LINE@python.inline@    '/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor' % (gov, cpu)])@@@",
796      "@@@STEP_LOG_LINE@python.inline@actual_gov = subprocess.check_output([ADB, 'shell', 'cat '@@@",
797      "@@@STEP_LOG_LINE@python.inline@    '/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor' % cpu]).strip()@@@",
798      "@@@STEP_LOG_LINE@python.inline@if actual_gov != gov:@@@",
799      "@@@STEP_LOG_LINE@python.inline@  raise Exception('(actual, expected) (%s, %s)'@@@",
800      "@@@STEP_LOG_LINE@python.inline@                  % (actual_gov, gov))@@@",
801      "@@@STEP_LOG_END@python.inline@@@"
802    ]
803  },
804  {
805    "cmd": [
806      "/usr/bin/adb.1.0.35",
807      "push",
808      "[START_DIR]/build/dm",
809      "/data/local/tmp/"
810    ],
811    "cwd": "[START_DIR]/skia",
812    "env": {
813      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
814      "CHROME_HEADLESS": "1",
815      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
816    },
817    "infra_step": true,
818    "name": "push dm"
819  },
820  {
821    "cmd": [
822      "python",
823      "-u",
824      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
825      "--json-output",
826      "/path/to/tmp/json",
827      "copy",
828      "set -x; /data/local/tmp/dm --resourcePath /sdcard/revenge_of_the_skiabot/resources --skps /sdcard/revenge_of_the_skiabot/skps --images /sdcard/revenge_of_the_skiabot/images/dm --colorImages /sdcard/revenge_of_the_skiabot/images/colorspace --nameByHash --properties gitHash abc123 builder Test-Android-Clang-Pixel-GPU-Adreno530-arm-Debug-All-Android_ASAN buildbucket_build_id 123454321 task_id task_12345 swarming_bot_id skia-bot-123 swarming_task_id 123456 --svgs /sdcard/revenge_of_the_skiabot/svgs --key arch arm compiler Clang configuration Debug cpu_or_gpu GPU cpu_or_gpu_value Adreno530 extra_config Android_ASAN model Pixel os Android style default --dont_write pdf --nocpu --config gles glesdft glessrgb glesmsaa4 --src tests gm image colorImage svg --blacklist _ svg _ svgparse_ glessrgb image _ _ _ image gen_platf error _ test _ GrShape _ image _ interlaced1.png _ image _ interlaced2.png _ image _ interlaced3.png _ image _ .arw _ image _ .cr2 _ image _ .dng _ image _ .nef _ image _ .nrw _ image _ .orf _ image _ .raf _ image _ .rw2 _ image _ .pef _ image _ .srw _ image _ .ARW _ image _ .CR2 _ image _ .DNG _ image _ .NEF _ image _ .NRW _ image _ .ORF _ image _ .RAF _ image _ .RW2 _ image _ .PEF _ image _ .SRW --match ~BadImage --nonativeFonts --verbose; echo $? >/data/local/tmp/rc",
829      "[START_DIR]/tmp/dm.sh"
830    ],
831    "env": {
832      "CHROME_HEADLESS": "1",
833      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
834    },
835    "infra_step": true,
836    "name": "write dm.sh"
837  },
838  {
839    "cmd": [
840      "/usr/bin/adb.1.0.35",
841      "push",
842      "[START_DIR]/tmp/dm.sh",
843      "/data/local/tmp/"
844    ],
845    "cwd": "[START_DIR]/skia",
846    "env": {
847      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
848      "CHROME_HEADLESS": "1",
849      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
850    },
851    "infra_step": true,
852    "name": "push dm.sh"
853  },
854  {
855    "cmd": [
856      "/usr/bin/adb.1.0.35",
857      "logcat",
858      "-c"
859    ],
860    "cwd": "[START_DIR]/skia",
861    "env": {
862      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
863      "CHROME_HEADLESS": "1",
864      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
865    },
866    "infra_step": true,
867    "name": "clear log"
868  },
869  {
870    "cmd": [
871      "python",
872      "-u",
873      "\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",
874      "/data/local/tmp/",
875      "dm.sh"
876    ],
877    "env": {
878      "CHROME_HEADLESS": "1",
879      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
880    },
881    "name": "dm",
882    "~followup_annotations": [
883      "@@@STEP_LOG_LINE@python.inline@@@@",
884      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
885      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
886      "@@@STEP_LOG_LINE@python.inline@bin_dir = sys.argv[1]@@@",
887      "@@@STEP_LOG_LINE@python.inline@sh      = sys.argv[2]@@@",
888      "@@@STEP_LOG_LINE@python.inline@subprocess.check_call(['/usr/bin/adb.1.0.35', 'shell', 'sh', bin_dir + sh])@@@",
889      "@@@STEP_LOG_LINE@python.inline@try:@@@",
890      "@@@STEP_LOG_LINE@python.inline@  sys.exit(int(subprocess.check_output(['/usr/bin/adb.1.0.35', 'shell', 'cat',@@@",
891      "@@@STEP_LOG_LINE@python.inline@                                        bin_dir + 'rc'])))@@@",
892      "@@@STEP_LOG_LINE@python.inline@except ValueError:@@@",
893      "@@@STEP_LOG_LINE@python.inline@  print \"Couldn't read the return code.  Probably killed for OOM.\"@@@",
894      "@@@STEP_LOG_LINE@python.inline@  sys.exit(1)@@@",
895      "@@@STEP_LOG_END@python.inline@@@"
896    ]
897  },
898  {
899    "cmd": [
900      "/usr/bin/adb.1.0.35",
901      "wait-for-device"
902    ],
903    "env": {
904      "CHROME_HEADLESS": "1",
905      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
906    },
907    "infra_step": true,
908    "name": "wait for device before uninstalling ASAN",
909    "timeout": 180
910  },
911  {
912    "cmd": [
913      "[START_DIR]/android_ndk_linux/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/8.0.2/bin/asan_device_setup",
914      "--revert"
915    ],
916    "env": {
917      "CHROME_HEADLESS": "1",
918      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
919    },
920    "infra_step": true,
921    "name": "uninstall ASAN",
922    "timeout": 300
923  },
924  {
925    "cmd": [
926      "python",
927      "-u",
928      "\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      sym = subprocess.check_output(['addr2line', '-Cfpe', local, addr])\n      line = line.replace(addr, addr + ' ' + sym.strip())\n  print line\n",
929      "[START_DIR]/build"
930    ],
931    "env": {
932      "CHROME_HEADLESS": "1",
933      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
934    },
935    "infra_step": true,
936    "name": "dump log",
937    "timeout": 300,
938    "~followup_annotations": [
939      "@@@STEP_LOG_LINE@python.inline@@@@",
940      "@@@STEP_LOG_LINE@python.inline@import os@@@",
941      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
942      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
943      "@@@STEP_LOG_LINE@python.inline@out = sys.argv[1]@@@",
944      "@@@STEP_LOG_LINE@python.inline@log = subprocess.check_output(['/usr/bin/adb.1.0.35', 'logcat', '-d'])@@@",
945      "@@@STEP_LOG_LINE@python.inline@for line in log.split('\\n'):@@@",
946      "@@@STEP_LOG_LINE@python.inline@  tokens = line.split()@@@",
947      "@@@STEP_LOG_LINE@python.inline@  if len(tokens) == 11 and tokens[-7] == 'F' and tokens[-3] == 'pc':@@@",
948      "@@@STEP_LOG_LINE@python.inline@    addr, path = tokens[-2:]@@@",
949      "@@@STEP_LOG_LINE@python.inline@    local = os.path.join(out, os.path.basename(path))@@@",
950      "@@@STEP_LOG_LINE@python.inline@    if os.path.exists(local):@@@",
951      "@@@STEP_LOG_LINE@python.inline@      sym = subprocess.check_output(['addr2line', '-Cfpe', local, addr])@@@",
952      "@@@STEP_LOG_LINE@python.inline@      line = line.replace(addr, addr + ' ' + sym.strip())@@@",
953      "@@@STEP_LOG_LINE@python.inline@  print line@@@",
954      "@@@STEP_LOG_END@python.inline@@@"
955    ]
956  },
957  {
958    "cmd": [
959      "/usr/bin/adb.1.0.35",
960      "kill-server"
961    ],
962    "cwd": "[START_DIR]/skia",
963    "env": {
964      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/adbkey",
965      "CHROME_HEADLESS": "1",
966      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
967    },
968    "infra_step": true,
969    "name": "kill adb server"
970  },
971  {
972    "jsonResult": null,
973    "name": "$result"
974  }
975]