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