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