• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[
2  {
3    "cmd": [
4      "python",
5      "-u",
6      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
7      "--json-output",
8      "/path/to/tmp/json",
9      "ensure-directory",
10      "--mode",
11      "0777",
12      "[START_DIR]/tmp"
13    ],
14    "infra_step": true,
15    "name": "makedirs tmp_dir"
16  },
17  {
18    "cmd": [
19      "python",
20      "-u",
21      "import os\nprint os.environ.get('SWARMING_BOT_ID', '')\n"
22    ],
23    "name": "get swarming bot id",
24    "~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      "/opt/infra-android/tools/adb",
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/chrome_infrastructure_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\nhost   = sys.argv[1]\ndevice = sys.argv[2]\nfor d, _, fs in os.walk(host):\n  p = os.path.relpath(d, host)\n  if p != '.' and p.startswith('.'):\n    continue\n  for f in fs:\n    print os.path.join(p,f)\n    subprocess.check_call(['/opt/infra-android/tools/adb', 'push',\n                           os.path.realpath(os.path.join(host, p, f)),\n                           os.path.join(device, p, f)])\n",
52      "[START_DIR]/skia/resources",
53      "/sdcard/revenge_of_the_skiabot/resources"
54    ],
55    "env": {
56      "CHROME_HEADLESS": "1",
57      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
58    },
59    "infra_step": true,
60    "name": "push [START_DIR]/skia/resources/* /sdcard/revenge_of_the_skiabot/resources",
61    "~followup_annotations": [
62      "@@@STEP_LOG_LINE@python.inline@@@@",
63      "@@@STEP_LOG_LINE@python.inline@import os@@@",
64      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
65      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
66      "@@@STEP_LOG_LINE@python.inline@host   = sys.argv[1]@@@",
67      "@@@STEP_LOG_LINE@python.inline@device = sys.argv[2]@@@",
68      "@@@STEP_LOG_LINE@python.inline@for d, _, fs in os.walk(host):@@@",
69      "@@@STEP_LOG_LINE@python.inline@  p = os.path.relpath(d, host)@@@",
70      "@@@STEP_LOG_LINE@python.inline@  if p != '.' and p.startswith('.'):@@@",
71      "@@@STEP_LOG_LINE@python.inline@    continue@@@",
72      "@@@STEP_LOG_LINE@python.inline@  for f in fs:@@@",
73      "@@@STEP_LOG_LINE@python.inline@    print os.path.join(p,f)@@@",
74      "@@@STEP_LOG_LINE@python.inline@    subprocess.check_call(['/opt/infra-android/tools/adb', 'push',@@@",
75      "@@@STEP_LOG_LINE@python.inline@                           os.path.realpath(os.path.join(host, p, f)),@@@",
76      "@@@STEP_LOG_LINE@python.inline@                           os.path.join(device, p, f)])@@@",
77      "@@@STEP_LOG_END@python.inline@@@"
78    ]
79  },
80  {
81    "cmd": [
82      "python",
83      "-u",
84      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
85      "--json-output",
86      "/path/to/tmp/json",
87      "copy",
88      "[START_DIR]/skia/infra/bots/assets/lottie-samples/VERSION",
89      "/path/to/tmp/"
90    ],
91    "infra_step": true,
92    "name": "Get lottie-samples VERSION"
93  },
94  {
95    "cmd": [
96      "python",
97      "-u",
98      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
99      "--json-output",
100      "/path/to/tmp/json",
101      "copy",
102      "42",
103      "[START_DIR]/tmp/LOTTIE_VERSION"
104    ],
105    "infra_step": true,
106    "name": "write LOTTIE_VERSION",
107    "~followup_annotations": [
108      "@@@STEP_LOG_LINE@LOTTIE_VERSION@42@@@",
109      "@@@STEP_LOG_END@LOTTIE_VERSION@@@"
110    ]
111  },
112  {
113    "cmd": [
114      "/opt/infra-android/tools/adb",
115      "shell",
116      "cat",
117      "/sdcard/revenge_of_the_skiabot/LOTTIE_VERSION"
118    ],
119    "cwd": "[START_DIR]/skia",
120    "env": {
121      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
122      "CHROME_HEADLESS": "1",
123      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
124    },
125    "infra_step": true,
126    "name": "read /sdcard/revenge_of_the_skiabot/LOTTIE_VERSION"
127  },
128  {
129    "cmd": [
130      "/opt/infra-android/tools/adb",
131      "shell",
132      "rm",
133      "-f",
134      "/sdcard/revenge_of_the_skiabot/LOTTIE_VERSION"
135    ],
136    "cwd": "[START_DIR]/skia",
137    "env": {
138      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
139      "CHROME_HEADLESS": "1",
140      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
141    },
142    "infra_step": true,
143    "name": "rm /sdcard/revenge_of_the_skiabot/LOTTIE_VERSION"
144  },
145  {
146    "cmd": [
147      "/opt/infra-android/tools/adb",
148      "shell",
149      "rm",
150      "-rf",
151      "/sdcard/revenge_of_the_skiabot/lotties"
152    ],
153    "cwd": "[START_DIR]/skia",
154    "env": {
155      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
156      "CHROME_HEADLESS": "1",
157      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
158    },
159    "infra_step": true,
160    "name": "rm /sdcard/revenge_of_the_skiabot/lotties"
161  },
162  {
163    "cmd": [
164      "/opt/infra-android/tools/adb",
165      "shell",
166      "mkdir",
167      "-p",
168      "/sdcard/revenge_of_the_skiabot/lotties"
169    ],
170    "cwd": "[START_DIR]/skia",
171    "env": {
172      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
173      "CHROME_HEADLESS": "1",
174      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
175    },
176    "infra_step": true,
177    "name": "mkdir /sdcard/revenge_of_the_skiabot/lotties"
178  },
179  {
180    "cmd": [
181      "python",
182      "-u",
183      "\nimport os\nimport subprocess\nimport sys\nhost   = sys.argv[1]\ndevice = sys.argv[2]\nfor d, _, fs in os.walk(host):\n  p = os.path.relpath(d, host)\n  if p != '.' and p.startswith('.'):\n    continue\n  for f in fs:\n    print os.path.join(p,f)\n    subprocess.check_call(['/opt/infra-android/tools/adb', 'push',\n                           os.path.realpath(os.path.join(host, p, f)),\n                           os.path.join(device, p, f)])\n",
184      "[START_DIR]/lottie-samples",
185      "/sdcard/revenge_of_the_skiabot/lotties"
186    ],
187    "env": {
188      "CHROME_HEADLESS": "1",
189      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
190    },
191    "infra_step": true,
192    "name": "push [START_DIR]/lottie-samples/* /sdcard/revenge_of_the_skiabot/lotties",
193    "~followup_annotations": [
194      "@@@STEP_LOG_LINE@python.inline@@@@",
195      "@@@STEP_LOG_LINE@python.inline@import os@@@",
196      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
197      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
198      "@@@STEP_LOG_LINE@python.inline@host   = sys.argv[1]@@@",
199      "@@@STEP_LOG_LINE@python.inline@device = sys.argv[2]@@@",
200      "@@@STEP_LOG_LINE@python.inline@for d, _, fs in os.walk(host):@@@",
201      "@@@STEP_LOG_LINE@python.inline@  p = os.path.relpath(d, host)@@@",
202      "@@@STEP_LOG_LINE@python.inline@  if p != '.' and p.startswith('.'):@@@",
203      "@@@STEP_LOG_LINE@python.inline@    continue@@@",
204      "@@@STEP_LOG_LINE@python.inline@  for f in fs:@@@",
205      "@@@STEP_LOG_LINE@python.inline@    print os.path.join(p,f)@@@",
206      "@@@STEP_LOG_LINE@python.inline@    subprocess.check_call(['/opt/infra-android/tools/adb', 'push',@@@",
207      "@@@STEP_LOG_LINE@python.inline@                           os.path.realpath(os.path.join(host, p, f)),@@@",
208      "@@@STEP_LOG_LINE@python.inline@                           os.path.join(device, p, f)])@@@",
209      "@@@STEP_LOG_END@python.inline@@@"
210    ]
211  },
212  {
213    "cmd": [
214      "/opt/infra-android/tools/adb",
215      "push",
216      "[START_DIR]/tmp/LOTTIE_VERSION",
217      "/sdcard/revenge_of_the_skiabot/LOTTIE_VERSION"
218    ],
219    "cwd": "[START_DIR]/skia",
220    "env": {
221      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
222      "CHROME_HEADLESS": "1",
223      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
224    },
225    "infra_step": true,
226    "name": "push [START_DIR]/tmp/LOTTIE_VERSION /sdcard/revenge_of_the_skiabot/LOTTIE_VERSION"
227  },
228  {
229    "cmd": [
230      "/opt/infra-android/tools/adb",
231      "shell",
232      "rm",
233      "-rf",
234      "/sdcard/revenge_of_the_skiabot/dm_out"
235    ],
236    "cwd": "[START_DIR]/skia",
237    "env": {
238      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
239      "CHROME_HEADLESS": "1",
240      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
241    },
242    "infra_step": true,
243    "name": "rm /sdcard/revenge_of_the_skiabot/dm_out"
244  },
245  {
246    "cmd": [
247      "/opt/infra-android/tools/adb",
248      "shell",
249      "mkdir",
250      "-p",
251      "/sdcard/revenge_of_the_skiabot/dm_out"
252    ],
253    "cwd": "[START_DIR]/skia",
254    "env": {
255      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
256      "CHROME_HEADLESS": "1",
257      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
258    },
259    "infra_step": true,
260    "name": "mkdir /sdcard/revenge_of_the_skiabot/dm_out"
261  },
262  {
263    "cmd": [
264      "python",
265      "-u",
266      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
267      "--json-output",
268      "/path/to/tmp/json",
269      "listdir",
270      "[START_DIR]/lottie-samples"
271    ],
272    "infra_step": true,
273    "name": "list lottie files",
274    "~followup_annotations": [
275      "@@@STEP_LOG_LINE@listdir@[START_DIR]/lottie-samples/LICENSE@@@",
276      "@@@STEP_LOG_LINE@listdir@[START_DIR]/lottie-samples/lottie 3!.json@@@",
277      "@@@STEP_LOG_LINE@listdir@[START_DIR]/lottie-samples/lottie(test)'!2.json@@@",
278      "@@@STEP_LOG_LINE@listdir@[START_DIR]/lottie-samples/lottie1.json@@@",
279      "@@@STEP_LOG_END@listdir@@@"
280    ]
281  },
282  {
283    "cmd": [
284      "python",
285      "-u",
286      "\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",
287      "/opt/infra-android/tools/adb",
288      "0",
289      "hotplug"
290    ],
291    "env": {
292      "CHROME_HEADLESS": "1",
293      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
294    },
295    "infra_step": true,
296    "name": "Set CPU 0's governor to hotplug",
297    "timeout": 30,
298    "~followup_annotations": [
299      "@@@STEP_LOG_LINE@python.inline@@@@",
300      "@@@STEP_LOG_LINE@python.inline@import os@@@",
301      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
302      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
303      "@@@STEP_LOG_LINE@python.inline@import time@@@",
304      "@@@STEP_LOG_LINE@python.inline@ADB = sys.argv[1]@@@",
305      "@@@STEP_LOG_LINE@python.inline@cpu = int(sys.argv[2])@@@",
306      "@@@STEP_LOG_LINE@python.inline@gov = sys.argv[3]@@@",
307      "@@@STEP_LOG_LINE@python.inline@@@@",
308      "@@@STEP_LOG_LINE@python.inline@log = subprocess.check_output([ADB, 'root'])@@@",
309      "@@@STEP_LOG_LINE@python.inline@# check for message like 'adbd cannot run as root in production builds'@@@",
310      "@@@STEP_LOG_LINE@python.inline@print log@@@",
311      "@@@STEP_LOG_LINE@python.inline@if 'cannot' in log:@@@",
312      "@@@STEP_LOG_LINE@python.inline@  raise Exception('adb root failed')@@@",
313      "@@@STEP_LOG_LINE@python.inline@@@@",
314      "@@@STEP_LOG_LINE@python.inline@subprocess.check_output([ADB, 'shell', 'echo \"%s\" > '@@@",
315      "@@@STEP_LOG_LINE@python.inline@    '/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor' % (gov, cpu)])@@@",
316      "@@@STEP_LOG_LINE@python.inline@actual_gov = subprocess.check_output([ADB, 'shell', 'cat '@@@",
317      "@@@STEP_LOG_LINE@python.inline@    '/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor' % cpu]).strip()@@@",
318      "@@@STEP_LOG_LINE@python.inline@if actual_gov != gov:@@@",
319      "@@@STEP_LOG_LINE@python.inline@  raise Exception('(actual, expected) (%s, %s)'@@@",
320      "@@@STEP_LOG_LINE@python.inline@                  % (actual_gov, gov))@@@",
321      "@@@STEP_LOG_END@python.inline@@@"
322    ]
323  },
324  {
325    "cmd": [
326      "/opt/infra-android/tools/adb",
327      "push",
328      "[START_DIR]/build/dm",
329      "/data/local/tmp/"
330    ],
331    "cwd": "[START_DIR]/skia",
332    "env": {
333      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
334      "CHROME_HEADLESS": "1",
335      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
336    },
337    "infra_step": true,
338    "name": "push dm"
339  },
340  {
341    "cmd": [
342      "python",
343      "-u",
344      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
345      "--json-output",
346      "/path/to/tmp/json",
347      "copy",
348      "set -x; /data/local/tmp/dm --resourcePath /sdcard/revenge_of_the_skiabot/resources --lotties /sdcard/revenge_of_the_skiabot/lotties --src lottie --nonativeFonts --verbose --traceMatch skottie --trace /sdcard/revenge_of_the_skiabot/dm_out/2.json --match \"^lottie 3!.json$\" --config gles --nocpu; echo $? >/data/local/tmp/rc",
349      "[START_DIR]/tmp/dm.sh"
350    ],
351    "env": {
352      "CHROME_HEADLESS": "1",
353      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
354    },
355    "infra_step": true,
356    "name": "write dm.sh",
357    "~followup_annotations": [
358      "@@@STEP_LOG_LINE@dm.sh@set -x; /data/local/tmp/dm --resourcePath /sdcard/revenge_of_the_skiabot/resources --lotties /sdcard/revenge_of_the_skiabot/lotties --src lottie --nonativeFonts --verbose --traceMatch skottie --trace /sdcard/revenge_of_the_skiabot/dm_out/2.json --match \"^lottie 3!.json$\" --config gles --nocpu; echo $? >/data/local/tmp/rc@@@",
359      "@@@STEP_LOG_END@dm.sh@@@"
360    ]
361  },
362  {
363    "cmd": [
364      "/opt/infra-android/tools/adb",
365      "push",
366      "[START_DIR]/tmp/dm.sh",
367      "/data/local/tmp/"
368    ],
369    "cwd": "[START_DIR]/skia",
370    "env": {
371      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
372      "CHROME_HEADLESS": "1",
373      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
374    },
375    "infra_step": true,
376    "name": "push dm.sh"
377  },
378  {
379    "cmd": [
380      "/opt/infra-android/tools/adb",
381      "logcat",
382      "-c"
383    ],
384    "cwd": "[START_DIR]/skia",
385    "env": {
386      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
387      "CHROME_HEADLESS": "1",
388      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
389    },
390    "infra_step": true,
391    "name": "clear log"
392  },
393  {
394    "cmd": [
395      "python",
396      "-u",
397      "\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",
398      "/data/local/tmp/",
399      "dm.sh"
400    ],
401    "env": {
402      "CHROME_HEADLESS": "1",
403      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
404    },
405    "name": "dm",
406    "~followup_annotations": [
407      "@@@STEP_LOG_LINE@python.inline@@@@",
408      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
409      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
410      "@@@STEP_LOG_LINE@python.inline@bin_dir = sys.argv[1]@@@",
411      "@@@STEP_LOG_LINE@python.inline@sh      = sys.argv[2]@@@",
412      "@@@STEP_LOG_LINE@python.inline@subprocess.check_call(['/opt/infra-android/tools/adb', 'shell', 'sh', bin_dir + sh])@@@",
413      "@@@STEP_LOG_LINE@python.inline@try:@@@",
414      "@@@STEP_LOG_LINE@python.inline@  sys.exit(int(subprocess.check_output(['/opt/infra-android/tools/adb', 'shell', 'cat',@@@",
415      "@@@STEP_LOG_LINE@python.inline@                                        bin_dir + 'rc'])))@@@",
416      "@@@STEP_LOG_LINE@python.inline@except ValueError:@@@",
417      "@@@STEP_LOG_LINE@python.inline@  print \"Couldn't read the return code.  Probably killed for OOM.\"@@@",
418      "@@@STEP_LOG_LINE@python.inline@  sys.exit(1)@@@",
419      "@@@STEP_LOG_END@python.inline@@@"
420    ]
421  },
422  {
423    "cmd": [
424      "/opt/infra-android/tools/adb",
425      "shell",
426      "cat",
427      "/sdcard/revenge_of_the_skiabot/dm_out/2.json"
428    ],
429    "cwd": "[START_DIR]/skia",
430    "env": {
431      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
432      "CHROME_HEADLESS": "1",
433      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
434    },
435    "infra_step": true,
436    "name": "read /sdcard/revenge_of_the_skiabot/dm_out/2.json"
437  },
438  {
439    "cmd": [
440      "python",
441      "-u",
442      "\nimport json\nimport sys\n\ntrace_output = sys.argv[1]\ntrace_json = json.loads(trace_output)\nlottie_filename = sys.argv[2]\noutput_json_file = sys.argv[3]\n\nperf_results = {}\nframe_max = 0\nframe_min = 0\nframe_cumulative = 0\ncurrent_frame_duration = 0\ntotal_frames = 0\nframe_start = False\nskipped_first_seek = False  # Skip the first seek constructor call.\nfor trace in trace_json:\n  if 'skottie::Animation::seek' in trace['name']:\n    if not skipped_first_seek:\n      skipped_first_seek = True\n      continue\n    if frame_start:\n      raise Exception('We got consecutive Animation::seek without a ' +\n                      'render. Something is wrong.')\n    frame_start = True\n    current_frame_duration = trace['dur']\n  elif 'skottie::Animation::render' in trace['name']:\n    if not frame_start:\n      raise Exception('We got an Animation::render without a seek first. ' +\n                      'Something is wrong.')\n\n    current_frame_duration += trace['dur']\n    frame_start = False\n    total_frames += 1\n    frame_max = max(frame_max, current_frame_duration)\n    frame_min = (min(frame_min, current_frame_duration)\n                 if frame_min else current_frame_duration)\n    frame_cumulative += current_frame_duration\n\nexpected_dm_frames = 25\nif total_frames != expected_dm_frames:\n  raise Exception(\n      'Got ' + str(total_frames) + ' frames instead of ' +\n      str(expected_dm_frames))\nperf_results['frame_max_us'] = frame_max\nperf_results['frame_min_us'] = frame_min\nperf_results['frame_avg_us'] = frame_cumulative/total_frames\n\n# Write perf_results to the output json.\nwith open(output_json_file, 'w') as f:\n  f.write(json.dumps(perf_results))\n",
443      "\n[{\"ph\":\"X\",\"name\":\"void skottie::Animation::seek(SkScalar)\",\"ts\":452,\"dur\":2.57,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void SkCanvas::drawPaint(const SkPaint &)\",\"ts\":473,\"dur\":2.67e+03,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void skottie::Animation::seek(SkScalar)\",\"ts\":3.15e+03,\"dur\":2.25,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void skottie::Animation::render(SkCanvas *, const SkRect *, RenderFlags) const\",\"ts\":3.15e+03,\"dur\":216,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void SkCanvas::drawPath(const SkPath &, const SkPaint &)\",\"ts\":3.35e+03,\"dur\":15.1,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void skottie::Animation::seek(SkScalar)\",\"ts\":3.37e+03,\"dur\":1.17,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void skottie::Animation::render(SkCanvas *, const SkRect *, RenderFlags) const\",\"ts\":3.37e+03,\"dur\":140,\"tid\":1,\"pid\":0}]\n",
444      "lottie 3!.json",
445      "/path/to/tmp/json"
446    ],
447    "env": {
448      "CHROME_HEADLESS": "1",
449      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
450    },
451    "name": "parse lottie 3!.json trace",
452    "~followup_annotations": [
453      "@@@STEP_LOG_LINE@json.output@{@@@",
454      "@@@STEP_LOG_LINE@json.output@  \"frame_avg_us\": 179.71, @@@",
455      "@@@STEP_LOG_LINE@json.output@  \"frame_max_us\": 218.25, @@@",
456      "@@@STEP_LOG_LINE@json.output@  \"frame_min_us\": 141.17@@@",
457      "@@@STEP_LOG_LINE@json.output@}@@@",
458      "@@@STEP_LOG_END@json.output@@@",
459      "@@@STEP_LOG_LINE@python.inline@@@@",
460      "@@@STEP_LOG_LINE@python.inline@import json@@@",
461      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
462      "@@@STEP_LOG_LINE@python.inline@@@@",
463      "@@@STEP_LOG_LINE@python.inline@trace_output = sys.argv[1]@@@",
464      "@@@STEP_LOG_LINE@python.inline@trace_json = json.loads(trace_output)@@@",
465      "@@@STEP_LOG_LINE@python.inline@lottie_filename = sys.argv[2]@@@",
466      "@@@STEP_LOG_LINE@python.inline@output_json_file = sys.argv[3]@@@",
467      "@@@STEP_LOG_LINE@python.inline@@@@",
468      "@@@STEP_LOG_LINE@python.inline@perf_results = {}@@@",
469      "@@@STEP_LOG_LINE@python.inline@frame_max = 0@@@",
470      "@@@STEP_LOG_LINE@python.inline@frame_min = 0@@@",
471      "@@@STEP_LOG_LINE@python.inline@frame_cumulative = 0@@@",
472      "@@@STEP_LOG_LINE@python.inline@current_frame_duration = 0@@@",
473      "@@@STEP_LOG_LINE@python.inline@total_frames = 0@@@",
474      "@@@STEP_LOG_LINE@python.inline@frame_start = False@@@",
475      "@@@STEP_LOG_LINE@python.inline@skipped_first_seek = False  # Skip the first seek constructor call.@@@",
476      "@@@STEP_LOG_LINE@python.inline@for trace in trace_json:@@@",
477      "@@@STEP_LOG_LINE@python.inline@  if 'skottie::Animation::seek' in trace['name']:@@@",
478      "@@@STEP_LOG_LINE@python.inline@    if not skipped_first_seek:@@@",
479      "@@@STEP_LOG_LINE@python.inline@      skipped_first_seek = True@@@",
480      "@@@STEP_LOG_LINE@python.inline@      continue@@@",
481      "@@@STEP_LOG_LINE@python.inline@    if frame_start:@@@",
482      "@@@STEP_LOG_LINE@python.inline@      raise Exception('We got consecutive Animation::seek without a ' +@@@",
483      "@@@STEP_LOG_LINE@python.inline@                      'render. Something is wrong.')@@@",
484      "@@@STEP_LOG_LINE@python.inline@    frame_start = True@@@",
485      "@@@STEP_LOG_LINE@python.inline@    current_frame_duration = trace['dur']@@@",
486      "@@@STEP_LOG_LINE@python.inline@  elif 'skottie::Animation::render' in trace['name']:@@@",
487      "@@@STEP_LOG_LINE@python.inline@    if not frame_start:@@@",
488      "@@@STEP_LOG_LINE@python.inline@      raise Exception('We got an Animation::render without a seek first. ' +@@@",
489      "@@@STEP_LOG_LINE@python.inline@                      'Something is wrong.')@@@",
490      "@@@STEP_LOG_LINE@python.inline@@@@",
491      "@@@STEP_LOG_LINE@python.inline@    current_frame_duration += trace['dur']@@@",
492      "@@@STEP_LOG_LINE@python.inline@    frame_start = False@@@",
493      "@@@STEP_LOG_LINE@python.inline@    total_frames += 1@@@",
494      "@@@STEP_LOG_LINE@python.inline@    frame_max = max(frame_max, current_frame_duration)@@@",
495      "@@@STEP_LOG_LINE@python.inline@    frame_min = (min(frame_min, current_frame_duration)@@@",
496      "@@@STEP_LOG_LINE@python.inline@                 if frame_min else current_frame_duration)@@@",
497      "@@@STEP_LOG_LINE@python.inline@    frame_cumulative += current_frame_duration@@@",
498      "@@@STEP_LOG_LINE@python.inline@@@@",
499      "@@@STEP_LOG_LINE@python.inline@expected_dm_frames = 25@@@",
500      "@@@STEP_LOG_LINE@python.inline@if total_frames != expected_dm_frames:@@@",
501      "@@@STEP_LOG_LINE@python.inline@  raise Exception(@@@",
502      "@@@STEP_LOG_LINE@python.inline@      'Got ' + str(total_frames) + ' frames instead of ' +@@@",
503      "@@@STEP_LOG_LINE@python.inline@      str(expected_dm_frames))@@@",
504      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_max_us'] = frame_max@@@",
505      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_min_us'] = frame_min@@@",
506      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_avg_us'] = frame_cumulative/total_frames@@@",
507      "@@@STEP_LOG_LINE@python.inline@@@@",
508      "@@@STEP_LOG_LINE@python.inline@# Write perf_results to the output json.@@@",
509      "@@@STEP_LOG_LINE@python.inline@with open(output_json_file, 'w') as f:@@@",
510      "@@@STEP_LOG_LINE@python.inline@  f.write(json.dumps(perf_results))@@@",
511      "@@@STEP_LOG_END@python.inline@@@"
512    ]
513  },
514  {
515    "cmd": [
516      "/opt/infra-android/tools/adb",
517      "shell",
518      "rm",
519      "-f",
520      "/sdcard/revenge_of_the_skiabot/dm_out/2.json"
521    ],
522    "cwd": "[START_DIR]/skia",
523    "env": {
524      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
525      "CHROME_HEADLESS": "1",
526      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
527    },
528    "infra_step": true,
529    "name": "rm /sdcard/revenge_of_the_skiabot/dm_out/2.json"
530  },
531  {
532    "cmd": [
533      "python",
534      "-u",
535      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
536      "--json-output",
537      "/path/to/tmp/json",
538      "copy",
539      "set -x; /data/local/tmp/dm --resourcePath /sdcard/revenge_of_the_skiabot/resources --lotties /sdcard/revenge_of_the_skiabot/lotties --src lottie --nonativeFonts --verbose --traceMatch skottie --trace /sdcard/revenge_of_the_skiabot/dm_out/3.json --match \\^lottie\\(test\\)\\'\\!2\\.json\\$ --config gles --nocpu; echo $? >/data/local/tmp/rc",
540      "[START_DIR]/tmp/dm.sh"
541    ],
542    "env": {
543      "CHROME_HEADLESS": "1",
544      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
545    },
546    "infra_step": true,
547    "name": "write dm.sh (2)",
548    "~followup_annotations": [
549      "@@@STEP_LOG_LINE@dm.sh@set -x; /data/local/tmp/dm --resourcePath /sdcard/revenge_of_the_skiabot/resources --lotties /sdcard/revenge_of_the_skiabot/lotties --src lottie --nonativeFonts --verbose --traceMatch skottie --trace /sdcard/revenge_of_the_skiabot/dm_out/3.json --match \\^lottie\\(test\\)\\'\\!2\\.json\\$ --config gles --nocpu; echo $? >/data/local/tmp/rc@@@",
550      "@@@STEP_LOG_END@dm.sh@@@"
551    ]
552  },
553  {
554    "cmd": [
555      "/opt/infra-android/tools/adb",
556      "push",
557      "[START_DIR]/tmp/dm.sh",
558      "/data/local/tmp/"
559    ],
560    "cwd": "[START_DIR]/skia",
561    "env": {
562      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
563      "CHROME_HEADLESS": "1",
564      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
565    },
566    "infra_step": true,
567    "name": "push dm.sh (2)"
568  },
569  {
570    "cmd": [
571      "/opt/infra-android/tools/adb",
572      "logcat",
573      "-c"
574    ],
575    "cwd": "[START_DIR]/skia",
576    "env": {
577      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
578      "CHROME_HEADLESS": "1",
579      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
580    },
581    "infra_step": true,
582    "name": "clear log (2)"
583  },
584  {
585    "cmd": [
586      "python",
587      "-u",
588      "\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",
589      "/data/local/tmp/",
590      "dm.sh"
591    ],
592    "env": {
593      "CHROME_HEADLESS": "1",
594      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
595    },
596    "name": "dm (2)",
597    "~followup_annotations": [
598      "@@@STEP_LOG_LINE@python.inline@@@@",
599      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
600      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
601      "@@@STEP_LOG_LINE@python.inline@bin_dir = sys.argv[1]@@@",
602      "@@@STEP_LOG_LINE@python.inline@sh      = sys.argv[2]@@@",
603      "@@@STEP_LOG_LINE@python.inline@subprocess.check_call(['/opt/infra-android/tools/adb', 'shell', 'sh', bin_dir + sh])@@@",
604      "@@@STEP_LOG_LINE@python.inline@try:@@@",
605      "@@@STEP_LOG_LINE@python.inline@  sys.exit(int(subprocess.check_output(['/opt/infra-android/tools/adb', 'shell', 'cat',@@@",
606      "@@@STEP_LOG_LINE@python.inline@                                        bin_dir + 'rc'])))@@@",
607      "@@@STEP_LOG_LINE@python.inline@except ValueError:@@@",
608      "@@@STEP_LOG_LINE@python.inline@  print \"Couldn't read the return code.  Probably killed for OOM.\"@@@",
609      "@@@STEP_LOG_LINE@python.inline@  sys.exit(1)@@@",
610      "@@@STEP_LOG_END@python.inline@@@"
611    ]
612  },
613  {
614    "cmd": [
615      "/opt/infra-android/tools/adb",
616      "shell",
617      "cat",
618      "/sdcard/revenge_of_the_skiabot/dm_out/3.json"
619    ],
620    "cwd": "[START_DIR]/skia",
621    "env": {
622      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
623      "CHROME_HEADLESS": "1",
624      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
625    },
626    "infra_step": true,
627    "name": "read /sdcard/revenge_of_the_skiabot/dm_out/3.json"
628  },
629  {
630    "cmd": [
631      "python",
632      "-u",
633      "\nimport json\nimport sys\n\ntrace_output = sys.argv[1]\ntrace_json = json.loads(trace_output)\nlottie_filename = sys.argv[2]\noutput_json_file = sys.argv[3]\n\nperf_results = {}\nframe_max = 0\nframe_min = 0\nframe_cumulative = 0\ncurrent_frame_duration = 0\ntotal_frames = 0\nframe_start = False\nskipped_first_seek = False  # Skip the first seek constructor call.\nfor trace in trace_json:\n  if 'skottie::Animation::seek' in trace['name']:\n    if not skipped_first_seek:\n      skipped_first_seek = True\n      continue\n    if frame_start:\n      raise Exception('We got consecutive Animation::seek without a ' +\n                      'render. Something is wrong.')\n    frame_start = True\n    current_frame_duration = trace['dur']\n  elif 'skottie::Animation::render' in trace['name']:\n    if not frame_start:\n      raise Exception('We got an Animation::render without a seek first. ' +\n                      'Something is wrong.')\n\n    current_frame_duration += trace['dur']\n    frame_start = False\n    total_frames += 1\n    frame_max = max(frame_max, current_frame_duration)\n    frame_min = (min(frame_min, current_frame_duration)\n                 if frame_min else current_frame_duration)\n    frame_cumulative += current_frame_duration\n\nexpected_dm_frames = 25\nif total_frames != expected_dm_frames:\n  raise Exception(\n      'Got ' + str(total_frames) + ' frames instead of ' +\n      str(expected_dm_frames))\nperf_results['frame_max_us'] = frame_max\nperf_results['frame_min_us'] = frame_min\nperf_results['frame_avg_us'] = frame_cumulative/total_frames\n\n# Write perf_results to the output json.\nwith open(output_json_file, 'w') as f:\n  f.write(json.dumps(perf_results))\n",
634      "\n[{\"ph\":\"X\",\"name\":\"void skottie::Animation::seek(SkScalar)\",\"ts\":452,\"dur\":2.57,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void SkCanvas::drawPaint(const SkPaint &)\",\"ts\":473,\"dur\":2.67e+03,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void skottie::Animation::seek(SkScalar)\",\"ts\":3.15e+03,\"dur\":2.25,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void skottie::Animation::render(SkCanvas *, const SkRect *, RenderFlags) const\",\"ts\":3.15e+03,\"dur\":216,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void SkCanvas::drawPath(const SkPath &, const SkPaint &)\",\"ts\":3.35e+03,\"dur\":15.1,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void skottie::Animation::seek(SkScalar)\",\"ts\":3.37e+03,\"dur\":1.17,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void skottie::Animation::render(SkCanvas *, const SkRect *, RenderFlags) const\",\"ts\":3.37e+03,\"dur\":140,\"tid\":1,\"pid\":0}]\n",
635      "lottie(test)'!2.json",
636      "/path/to/tmp/json"
637    ],
638    "env": {
639      "CHROME_HEADLESS": "1",
640      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
641    },
642    "name": "parse lottie(test)'!2.json trace",
643    "~followup_annotations": [
644      "@@@STEP_LOG_LINE@json.output@{@@@",
645      "@@@STEP_LOG_LINE@json.output@  \"frame_avg_us\": 179.71, @@@",
646      "@@@STEP_LOG_LINE@json.output@  \"frame_max_us\": 218.25, @@@",
647      "@@@STEP_LOG_LINE@json.output@  \"frame_min_us\": 141.17@@@",
648      "@@@STEP_LOG_LINE@json.output@}@@@",
649      "@@@STEP_LOG_END@json.output@@@",
650      "@@@STEP_LOG_LINE@python.inline@@@@",
651      "@@@STEP_LOG_LINE@python.inline@import json@@@",
652      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
653      "@@@STEP_LOG_LINE@python.inline@@@@",
654      "@@@STEP_LOG_LINE@python.inline@trace_output = sys.argv[1]@@@",
655      "@@@STEP_LOG_LINE@python.inline@trace_json = json.loads(trace_output)@@@",
656      "@@@STEP_LOG_LINE@python.inline@lottie_filename = sys.argv[2]@@@",
657      "@@@STEP_LOG_LINE@python.inline@output_json_file = sys.argv[3]@@@",
658      "@@@STEP_LOG_LINE@python.inline@@@@",
659      "@@@STEP_LOG_LINE@python.inline@perf_results = {}@@@",
660      "@@@STEP_LOG_LINE@python.inline@frame_max = 0@@@",
661      "@@@STEP_LOG_LINE@python.inline@frame_min = 0@@@",
662      "@@@STEP_LOG_LINE@python.inline@frame_cumulative = 0@@@",
663      "@@@STEP_LOG_LINE@python.inline@current_frame_duration = 0@@@",
664      "@@@STEP_LOG_LINE@python.inline@total_frames = 0@@@",
665      "@@@STEP_LOG_LINE@python.inline@frame_start = False@@@",
666      "@@@STEP_LOG_LINE@python.inline@skipped_first_seek = False  # Skip the first seek constructor call.@@@",
667      "@@@STEP_LOG_LINE@python.inline@for trace in trace_json:@@@",
668      "@@@STEP_LOG_LINE@python.inline@  if 'skottie::Animation::seek' in trace['name']:@@@",
669      "@@@STEP_LOG_LINE@python.inline@    if not skipped_first_seek:@@@",
670      "@@@STEP_LOG_LINE@python.inline@      skipped_first_seek = True@@@",
671      "@@@STEP_LOG_LINE@python.inline@      continue@@@",
672      "@@@STEP_LOG_LINE@python.inline@    if frame_start:@@@",
673      "@@@STEP_LOG_LINE@python.inline@      raise Exception('We got consecutive Animation::seek without a ' +@@@",
674      "@@@STEP_LOG_LINE@python.inline@                      'render. Something is wrong.')@@@",
675      "@@@STEP_LOG_LINE@python.inline@    frame_start = True@@@",
676      "@@@STEP_LOG_LINE@python.inline@    current_frame_duration = trace['dur']@@@",
677      "@@@STEP_LOG_LINE@python.inline@  elif 'skottie::Animation::render' in trace['name']:@@@",
678      "@@@STEP_LOG_LINE@python.inline@    if not frame_start:@@@",
679      "@@@STEP_LOG_LINE@python.inline@      raise Exception('We got an Animation::render without a seek first. ' +@@@",
680      "@@@STEP_LOG_LINE@python.inline@                      'Something is wrong.')@@@",
681      "@@@STEP_LOG_LINE@python.inline@@@@",
682      "@@@STEP_LOG_LINE@python.inline@    current_frame_duration += trace['dur']@@@",
683      "@@@STEP_LOG_LINE@python.inline@    frame_start = False@@@",
684      "@@@STEP_LOG_LINE@python.inline@    total_frames += 1@@@",
685      "@@@STEP_LOG_LINE@python.inline@    frame_max = max(frame_max, current_frame_duration)@@@",
686      "@@@STEP_LOG_LINE@python.inline@    frame_min = (min(frame_min, current_frame_duration)@@@",
687      "@@@STEP_LOG_LINE@python.inline@                 if frame_min else current_frame_duration)@@@",
688      "@@@STEP_LOG_LINE@python.inline@    frame_cumulative += current_frame_duration@@@",
689      "@@@STEP_LOG_LINE@python.inline@@@@",
690      "@@@STEP_LOG_LINE@python.inline@expected_dm_frames = 25@@@",
691      "@@@STEP_LOG_LINE@python.inline@if total_frames != expected_dm_frames:@@@",
692      "@@@STEP_LOG_LINE@python.inline@  raise Exception(@@@",
693      "@@@STEP_LOG_LINE@python.inline@      'Got ' + str(total_frames) + ' frames instead of ' +@@@",
694      "@@@STEP_LOG_LINE@python.inline@      str(expected_dm_frames))@@@",
695      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_max_us'] = frame_max@@@",
696      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_min_us'] = frame_min@@@",
697      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_avg_us'] = frame_cumulative/total_frames@@@",
698      "@@@STEP_LOG_LINE@python.inline@@@@",
699      "@@@STEP_LOG_LINE@python.inline@# Write perf_results to the output json.@@@",
700      "@@@STEP_LOG_LINE@python.inline@with open(output_json_file, 'w') as f:@@@",
701      "@@@STEP_LOG_LINE@python.inline@  f.write(json.dumps(perf_results))@@@",
702      "@@@STEP_LOG_END@python.inline@@@"
703    ]
704  },
705  {
706    "cmd": [
707      "/opt/infra-android/tools/adb",
708      "shell",
709      "rm",
710      "-f",
711      "/sdcard/revenge_of_the_skiabot/dm_out/3.json"
712    ],
713    "cwd": "[START_DIR]/skia",
714    "env": {
715      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
716      "CHROME_HEADLESS": "1",
717      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
718    },
719    "infra_step": true,
720    "name": "rm /sdcard/revenge_of_the_skiabot/dm_out/3.json"
721  },
722  {
723    "cmd": [
724      "python",
725      "-u",
726      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
727      "--json-output",
728      "/path/to/tmp/json",
729      "copy",
730      "set -x; /data/local/tmp/dm --resourcePath /sdcard/revenge_of_the_skiabot/resources --lotties /sdcard/revenge_of_the_skiabot/lotties --src lottie --nonativeFonts --verbose --traceMatch skottie --trace /sdcard/revenge_of_the_skiabot/dm_out/4.json --match \\^lottie1\\.json\\$ --config gles --nocpu; echo $? >/data/local/tmp/rc",
731      "[START_DIR]/tmp/dm.sh"
732    ],
733    "env": {
734      "CHROME_HEADLESS": "1",
735      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
736    },
737    "infra_step": true,
738    "name": "write dm.sh (3)",
739    "~followup_annotations": [
740      "@@@STEP_LOG_LINE@dm.sh@set -x; /data/local/tmp/dm --resourcePath /sdcard/revenge_of_the_skiabot/resources --lotties /sdcard/revenge_of_the_skiabot/lotties --src lottie --nonativeFonts --verbose --traceMatch skottie --trace /sdcard/revenge_of_the_skiabot/dm_out/4.json --match \\^lottie1\\.json\\$ --config gles --nocpu; echo $? >/data/local/tmp/rc@@@",
741      "@@@STEP_LOG_END@dm.sh@@@"
742    ]
743  },
744  {
745    "cmd": [
746      "/opt/infra-android/tools/adb",
747      "push",
748      "[START_DIR]/tmp/dm.sh",
749      "/data/local/tmp/"
750    ],
751    "cwd": "[START_DIR]/skia",
752    "env": {
753      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
754      "CHROME_HEADLESS": "1",
755      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
756    },
757    "infra_step": true,
758    "name": "push dm.sh (3)"
759  },
760  {
761    "cmd": [
762      "/opt/infra-android/tools/adb",
763      "logcat",
764      "-c"
765    ],
766    "cwd": "[START_DIR]/skia",
767    "env": {
768      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
769      "CHROME_HEADLESS": "1",
770      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
771    },
772    "infra_step": true,
773    "name": "clear log (3)"
774  },
775  {
776    "cmd": [
777      "python",
778      "-u",
779      "\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",
780      "/data/local/tmp/",
781      "dm.sh"
782    ],
783    "env": {
784      "CHROME_HEADLESS": "1",
785      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
786    },
787    "name": "dm (3)",
788    "~followup_annotations": [
789      "@@@STEP_LOG_LINE@python.inline@@@@",
790      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
791      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
792      "@@@STEP_LOG_LINE@python.inline@bin_dir = sys.argv[1]@@@",
793      "@@@STEP_LOG_LINE@python.inline@sh      = sys.argv[2]@@@",
794      "@@@STEP_LOG_LINE@python.inline@subprocess.check_call(['/opt/infra-android/tools/adb', 'shell', 'sh', bin_dir + sh])@@@",
795      "@@@STEP_LOG_LINE@python.inline@try:@@@",
796      "@@@STEP_LOG_LINE@python.inline@  sys.exit(int(subprocess.check_output(['/opt/infra-android/tools/adb', 'shell', 'cat',@@@",
797      "@@@STEP_LOG_LINE@python.inline@                                        bin_dir + 'rc'])))@@@",
798      "@@@STEP_LOG_LINE@python.inline@except ValueError:@@@",
799      "@@@STEP_LOG_LINE@python.inline@  print \"Couldn't read the return code.  Probably killed for OOM.\"@@@",
800      "@@@STEP_LOG_LINE@python.inline@  sys.exit(1)@@@",
801      "@@@STEP_LOG_END@python.inline@@@"
802    ]
803  },
804  {
805    "cmd": [
806      "/opt/infra-android/tools/adb",
807      "shell",
808      "cat",
809      "/sdcard/revenge_of_the_skiabot/dm_out/4.json"
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": "read /sdcard/revenge_of_the_skiabot/dm_out/4.json"
819  },
820  {
821    "cmd": [
822      "python",
823      "-u",
824      "\nimport json\nimport sys\n\ntrace_output = sys.argv[1]\ntrace_json = json.loads(trace_output)\nlottie_filename = sys.argv[2]\noutput_json_file = sys.argv[3]\n\nperf_results = {}\nframe_max = 0\nframe_min = 0\nframe_cumulative = 0\ncurrent_frame_duration = 0\ntotal_frames = 0\nframe_start = False\nskipped_first_seek = False  # Skip the first seek constructor call.\nfor trace in trace_json:\n  if 'skottie::Animation::seek' in trace['name']:\n    if not skipped_first_seek:\n      skipped_first_seek = True\n      continue\n    if frame_start:\n      raise Exception('We got consecutive Animation::seek without a ' +\n                      'render. Something is wrong.')\n    frame_start = True\n    current_frame_duration = trace['dur']\n  elif 'skottie::Animation::render' in trace['name']:\n    if not frame_start:\n      raise Exception('We got an Animation::render without a seek first. ' +\n                      'Something is wrong.')\n\n    current_frame_duration += trace['dur']\n    frame_start = False\n    total_frames += 1\n    frame_max = max(frame_max, current_frame_duration)\n    frame_min = (min(frame_min, current_frame_duration)\n                 if frame_min else current_frame_duration)\n    frame_cumulative += current_frame_duration\n\nexpected_dm_frames = 25\nif total_frames != expected_dm_frames:\n  raise Exception(\n      'Got ' + str(total_frames) + ' frames instead of ' +\n      str(expected_dm_frames))\nperf_results['frame_max_us'] = frame_max\nperf_results['frame_min_us'] = frame_min\nperf_results['frame_avg_us'] = frame_cumulative/total_frames\n\n# Write perf_results to the output json.\nwith open(output_json_file, 'w') as f:\n  f.write(json.dumps(perf_results))\n",
825      "\n[{\"ph\":\"X\",\"name\":\"void skottie::Animation::seek(SkScalar)\",\"ts\":452,\"dur\":2.57,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void SkCanvas::drawPaint(const SkPaint &)\",\"ts\":473,\"dur\":2.67e+03,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void skottie::Animation::seek(SkScalar)\",\"ts\":3.15e+03,\"dur\":2.25,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void skottie::Animation::render(SkCanvas *, const SkRect *, RenderFlags) const\",\"ts\":3.15e+03,\"dur\":216,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void SkCanvas::drawPath(const SkPath &, const SkPaint &)\",\"ts\":3.35e+03,\"dur\":15.1,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void skottie::Animation::seek(SkScalar)\",\"ts\":3.37e+03,\"dur\":1.17,\"tid\":1,\"pid\":0},{\"ph\":\"X\",\"name\":\"void skottie::Animation::render(SkCanvas *, const SkRect *, RenderFlags) const\",\"ts\":3.37e+03,\"dur\":140,\"tid\":1,\"pid\":0}]\n",
826      "lottie1.json",
827      "/path/to/tmp/json"
828    ],
829    "env": {
830      "CHROME_HEADLESS": "1",
831      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
832    },
833    "name": "parse lottie1.json trace",
834    "~followup_annotations": [
835      "@@@STEP_LOG_LINE@json.output@{@@@",
836      "@@@STEP_LOG_LINE@json.output@  \"frame_avg_us\": 179.71, @@@",
837      "@@@STEP_LOG_LINE@json.output@  \"frame_max_us\": 218.25, @@@",
838      "@@@STEP_LOG_LINE@json.output@  \"frame_min_us\": 141.17@@@",
839      "@@@STEP_LOG_LINE@json.output@}@@@",
840      "@@@STEP_LOG_END@json.output@@@",
841      "@@@STEP_LOG_LINE@python.inline@@@@",
842      "@@@STEP_LOG_LINE@python.inline@import json@@@",
843      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
844      "@@@STEP_LOG_LINE@python.inline@@@@",
845      "@@@STEP_LOG_LINE@python.inline@trace_output = sys.argv[1]@@@",
846      "@@@STEP_LOG_LINE@python.inline@trace_json = json.loads(trace_output)@@@",
847      "@@@STEP_LOG_LINE@python.inline@lottie_filename = sys.argv[2]@@@",
848      "@@@STEP_LOG_LINE@python.inline@output_json_file = sys.argv[3]@@@",
849      "@@@STEP_LOG_LINE@python.inline@@@@",
850      "@@@STEP_LOG_LINE@python.inline@perf_results = {}@@@",
851      "@@@STEP_LOG_LINE@python.inline@frame_max = 0@@@",
852      "@@@STEP_LOG_LINE@python.inline@frame_min = 0@@@",
853      "@@@STEP_LOG_LINE@python.inline@frame_cumulative = 0@@@",
854      "@@@STEP_LOG_LINE@python.inline@current_frame_duration = 0@@@",
855      "@@@STEP_LOG_LINE@python.inline@total_frames = 0@@@",
856      "@@@STEP_LOG_LINE@python.inline@frame_start = False@@@",
857      "@@@STEP_LOG_LINE@python.inline@skipped_first_seek = False  # Skip the first seek constructor call.@@@",
858      "@@@STEP_LOG_LINE@python.inline@for trace in trace_json:@@@",
859      "@@@STEP_LOG_LINE@python.inline@  if 'skottie::Animation::seek' in trace['name']:@@@",
860      "@@@STEP_LOG_LINE@python.inline@    if not skipped_first_seek:@@@",
861      "@@@STEP_LOG_LINE@python.inline@      skipped_first_seek = True@@@",
862      "@@@STEP_LOG_LINE@python.inline@      continue@@@",
863      "@@@STEP_LOG_LINE@python.inline@    if frame_start:@@@",
864      "@@@STEP_LOG_LINE@python.inline@      raise Exception('We got consecutive Animation::seek without a ' +@@@",
865      "@@@STEP_LOG_LINE@python.inline@                      'render. Something is wrong.')@@@",
866      "@@@STEP_LOG_LINE@python.inline@    frame_start = True@@@",
867      "@@@STEP_LOG_LINE@python.inline@    current_frame_duration = trace['dur']@@@",
868      "@@@STEP_LOG_LINE@python.inline@  elif 'skottie::Animation::render' in trace['name']:@@@",
869      "@@@STEP_LOG_LINE@python.inline@    if not frame_start:@@@",
870      "@@@STEP_LOG_LINE@python.inline@      raise Exception('We got an Animation::render without a seek first. ' +@@@",
871      "@@@STEP_LOG_LINE@python.inline@                      'Something is wrong.')@@@",
872      "@@@STEP_LOG_LINE@python.inline@@@@",
873      "@@@STEP_LOG_LINE@python.inline@    current_frame_duration += trace['dur']@@@",
874      "@@@STEP_LOG_LINE@python.inline@    frame_start = False@@@",
875      "@@@STEP_LOG_LINE@python.inline@    total_frames += 1@@@",
876      "@@@STEP_LOG_LINE@python.inline@    frame_max = max(frame_max, current_frame_duration)@@@",
877      "@@@STEP_LOG_LINE@python.inline@    frame_min = (min(frame_min, current_frame_duration)@@@",
878      "@@@STEP_LOG_LINE@python.inline@                 if frame_min else current_frame_duration)@@@",
879      "@@@STEP_LOG_LINE@python.inline@    frame_cumulative += current_frame_duration@@@",
880      "@@@STEP_LOG_LINE@python.inline@@@@",
881      "@@@STEP_LOG_LINE@python.inline@expected_dm_frames = 25@@@",
882      "@@@STEP_LOG_LINE@python.inline@if total_frames != expected_dm_frames:@@@",
883      "@@@STEP_LOG_LINE@python.inline@  raise Exception(@@@",
884      "@@@STEP_LOG_LINE@python.inline@      'Got ' + str(total_frames) + ' frames instead of ' +@@@",
885      "@@@STEP_LOG_LINE@python.inline@      str(expected_dm_frames))@@@",
886      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_max_us'] = frame_max@@@",
887      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_min_us'] = frame_min@@@",
888      "@@@STEP_LOG_LINE@python.inline@perf_results['frame_avg_us'] = frame_cumulative/total_frames@@@",
889      "@@@STEP_LOG_LINE@python.inline@@@@",
890      "@@@STEP_LOG_LINE@python.inline@# Write perf_results to the output json.@@@",
891      "@@@STEP_LOG_LINE@python.inline@with open(output_json_file, 'w') as f:@@@",
892      "@@@STEP_LOG_LINE@python.inline@  f.write(json.dumps(perf_results))@@@",
893      "@@@STEP_LOG_END@python.inline@@@"
894    ]
895  },
896  {
897    "cmd": [
898      "/opt/infra-android/tools/adb",
899      "shell",
900      "rm",
901      "-f",
902      "/sdcard/revenge_of_the_skiabot/dm_out/4.json"
903    ],
904    "cwd": "[START_DIR]/skia",
905    "env": {
906      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
907      "CHROME_HEADLESS": "1",
908      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
909    },
910    "infra_step": true,
911    "name": "rm /sdcard/revenge_of_the_skiabot/dm_out/4.json"
912  },
913  {
914    "cmd": [
915      "python",
916      "-u",
917      "import os\nprint os.environ.get('SWARMING_BOT_ID', '')\n"
918    ],
919    "name": "get swarming bot id (2)",
920    "~followup_annotations": [
921      "@@@STEP_LOG_LINE@python.inline@import os@@@",
922      "@@@STEP_LOG_LINE@python.inline@print os.environ.get('SWARMING_BOT_ID', '')@@@",
923      "@@@STEP_LOG_END@python.inline@@@"
924    ]
925  },
926  {
927    "cmd": [
928      "python",
929      "-u",
930      "import os\nprint os.environ.get('SWARMING_TASK_ID', '')\n"
931    ],
932    "name": "get swarming task id",
933    "~followup_annotations": [
934      "@@@STEP_LOG_LINE@python.inline@import os@@@",
935      "@@@STEP_LOG_LINE@python.inline@print os.environ.get('SWARMING_TASK_ID', '')@@@",
936      "@@@STEP_LOG_END@python.inline@@@"
937    ]
938  },
939  {
940    "cmd": [
941      "python",
942      "-u",
943      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
944      "--json-output",
945      "/path/to/tmp/json",
946      "ensure-directory",
947      "--mode",
948      "0777",
949      "[START_DIR]/[SWARM_OUT_DIR]"
950    ],
951    "infra_step": true,
952    "name": "makedirs perf_dir"
953  },
954  {
955    "cmd": [
956      "python",
957      "-u",
958      "import json\nwith open('[START_DIR]/[SWARM_OUT_DIR]/perf_abc123_1337000001.json', 'w') as outfile:\n  json.dump(obj={'gitHash': 'abc123', 'results': {\"lottie(test)'!2.json\": {'gles': {'frame_avg_us': 179.71, 'frame_max_us': 218.25, 'frame_min_us': 141.17}}, 'lottie1.json': {'gles': {'frame_avg_us': 179.71, 'frame_max_us': 218.25, 'frame_min_us': 141.17}}, 'lottie 3!.json': {'gles': {'frame_avg_us': 179.71, 'frame_max_us': 218.25, 'frame_min_us': 141.17}}}, 'swarming_task_id': '', 'renderer': 'skottie', 'key': {'extra_config': 'Android_SkottieTracing', 'bench_type': 'tracing', 'cpu_or_gpu_value': 'Mali400MP2', 'arch': 'arm', 'source_type': 'skottie', 'cpu_or_gpu': 'GPU', 'model': 'AndroidOne', 'configuration': 'Release', 'os': 'Android', 'compiler': 'Clang'}, 'swarming_bot_id': ''}, fp=outfile, indent=4)\n"
959    ],
960    "env": {
961      "CHROME_HEADLESS": "1",
962      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
963    },
964    "name": "write output JSON",
965    "~followup_annotations": [
966      "@@@STEP_LOG_LINE@python.inline@import json@@@",
967      "@@@STEP_LOG_LINE@python.inline@with open('[START_DIR]/[SWARM_OUT_DIR]/perf_abc123_1337000001.json', 'w') as outfile:@@@",
968      "@@@STEP_LOG_LINE@python.inline@  json.dump(obj={'gitHash': 'abc123', 'results': {\"lottie(test)'!2.json\": {'gles': {'frame_avg_us': 179.71, 'frame_max_us': 218.25, 'frame_min_us': 141.17}}, 'lottie1.json': {'gles': {'frame_avg_us': 179.71, 'frame_max_us': 218.25, 'frame_min_us': 141.17}}, 'lottie 3!.json': {'gles': {'frame_avg_us': 179.71, 'frame_max_us': 218.25, 'frame_min_us': 141.17}}}, 'swarming_task_id': '', 'renderer': 'skottie', 'key': {'extra_config': 'Android_SkottieTracing', 'bench_type': 'tracing', 'cpu_or_gpu_value': 'Mali400MP2', 'arch': 'arm', 'source_type': 'skottie', 'cpu_or_gpu': 'GPU', 'model': 'AndroidOne', 'configuration': 'Release', 'os': 'Android', 'compiler': 'Clang'}, 'swarming_bot_id': ''}, fp=outfile, indent=4)@@@",
969      "@@@STEP_LOG_END@python.inline@@@"
970    ]
971  },
972  {
973    "cmd": [
974      "python",
975      "-u",
976      "\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      sym = subprocess.check_output(['addr2line', '-Cfpe', local, addr])\n      line = line.replace(addr, addr + ' ' + sym.strip())\n  print line\n",
977      "[START_DIR]/build"
978    ],
979    "env": {
980      "CHROME_HEADLESS": "1",
981      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
982    },
983    "infra_step": true,
984    "name": "dump log",
985    "timeout": 300,
986    "~followup_annotations": [
987      "@@@STEP_LOG_LINE@python.inline@@@@",
988      "@@@STEP_LOG_LINE@python.inline@import os@@@",
989      "@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
990      "@@@STEP_LOG_LINE@python.inline@import sys@@@",
991      "@@@STEP_LOG_LINE@python.inline@out = sys.argv[1]@@@",
992      "@@@STEP_LOG_LINE@python.inline@log = subprocess.check_output(['/opt/infra-android/tools/adb', 'logcat', '-d'])@@@",
993      "@@@STEP_LOG_LINE@python.inline@for line in log.split('\\n'):@@@",
994      "@@@STEP_LOG_LINE@python.inline@  tokens = line.split()@@@",
995      "@@@STEP_LOG_LINE@python.inline@  if len(tokens) == 11 and tokens[-7] == 'F' and tokens[-3] == 'pc':@@@",
996      "@@@STEP_LOG_LINE@python.inline@    addr, path = tokens[-2:]@@@",
997      "@@@STEP_LOG_LINE@python.inline@    local = os.path.join(out, os.path.basename(path))@@@",
998      "@@@STEP_LOG_LINE@python.inline@    if os.path.exists(local):@@@",
999      "@@@STEP_LOG_LINE@python.inline@      sym = subprocess.check_output(['addr2line', '-Cfpe', local, addr])@@@",
1000      "@@@STEP_LOG_LINE@python.inline@      line = line.replace(addr, addr + ' ' + sym.strip())@@@",
1001      "@@@STEP_LOG_LINE@python.inline@  print line@@@",
1002      "@@@STEP_LOG_END@python.inline@@@"
1003    ]
1004  },
1005  {
1006    "cmd": [
1007      "/opt/infra-android/tools/adb",
1008      "kill-server"
1009    ],
1010    "cwd": "[START_DIR]/skia",
1011    "env": {
1012      "ADB_VENDOR_KEYS": "/home/chrome-bot/.android/chrome_infrastructure_adbkey",
1013      "CHROME_HEADLESS": "1",
1014      "PATH": "<PATH>:RECIPE_REPO[depot_tools]"
1015    },
1016    "infra_step": true,
1017    "name": "kill adb server"
1018  },
1019  {
1020    "name": "$result"
1021  }
1022]