xref: /aosp_15_r20/external/skia/infra/bots/recipes/perf_skottietrace.py (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker# Copyright 2019 The Chromium Authors. All rights reserved.
2*c8dee2aaSAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
3*c8dee2aaSAndroid Build Coastguard Worker# found in the LICENSE file.
4*c8dee2aaSAndroid Build Coastguard Worker
5*c8dee2aaSAndroid Build Coastguard Worker# Recipe which runs DM with trace flag on lottie files and then parses the
6*c8dee2aaSAndroid Build Coastguard Worker# trace output into output JSON files to ingest to perf.skia.org.
7*c8dee2aaSAndroid Build Coastguard Worker# Design doc: go/skottie-tracing
8*c8dee2aaSAndroid Build Coastguard Worker
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Workerimport calendar
11*c8dee2aaSAndroid Build Coastguard Workerimport json
12*c8dee2aaSAndroid Build Coastguard Workerimport re
13*c8dee2aaSAndroid Build Coastguard Workerimport string
14*c8dee2aaSAndroid Build Coastguard Worker
15*c8dee2aaSAndroid Build Coastguard WorkerPYTHON_VERSION_COMPATIBILITY = "PY3"
16*c8dee2aaSAndroid Build Coastguard Worker
17*c8dee2aaSAndroid Build Coastguard WorkerDEPS = [
18*c8dee2aaSAndroid Build Coastguard Worker  'flavor',
19*c8dee2aaSAndroid Build Coastguard Worker  'infra',
20*c8dee2aaSAndroid Build Coastguard Worker  'recipe_engine/context',
21*c8dee2aaSAndroid Build Coastguard Worker  'recipe_engine/file',
22*c8dee2aaSAndroid Build Coastguard Worker  'recipe_engine/json',
23*c8dee2aaSAndroid Build Coastguard Worker  'recipe_engine/path',
24*c8dee2aaSAndroid Build Coastguard Worker  'recipe_engine/step',
25*c8dee2aaSAndroid Build Coastguard Worker  'recipe_engine/time',
26*c8dee2aaSAndroid Build Coastguard Worker  'recipe_engine/properties',
27*c8dee2aaSAndroid Build Coastguard Worker  'recipe_engine/raw_io',
28*c8dee2aaSAndroid Build Coastguard Worker  'run',
29*c8dee2aaSAndroid Build Coastguard Worker  'vars',
30*c8dee2aaSAndroid Build Coastguard Worker]
31*c8dee2aaSAndroid Build Coastguard Worker
32*c8dee2aaSAndroid Build Coastguard WorkerSEEK_TRACE_NAME = 'skottie::Animation::seek'
33*c8dee2aaSAndroid Build Coastguard WorkerRENDER_TRACE_NAME = 'skottie::Animation::render'
34*c8dee2aaSAndroid Build Coastguard WorkerEXPECTED_DM_FRAMES = 25
35*c8dee2aaSAndroid Build Coastguard Worker
36*c8dee2aaSAndroid Build Coastguard Worker
37*c8dee2aaSAndroid Build Coastguard Workerdef perf_steps(api):
38*c8dee2aaSAndroid Build Coastguard Worker  """Run DM on lottie files with tracing turned on and then parse the output."""
39*c8dee2aaSAndroid Build Coastguard Worker  api.flavor.create_clean_device_dir(
40*c8dee2aaSAndroid Build Coastguard Worker        api.flavor.device_dirs.dm_dir)
41*c8dee2aaSAndroid Build Coastguard Worker  lotties_host = api.path.start_dir.joinpath('lotties_with_assets')
42*c8dee2aaSAndroid Build Coastguard Worker  lotties_device = api.path.start_dir.joinpath('lotties_with_assets')
43*c8dee2aaSAndroid Build Coastguard Worker  if 'Android' in api.vars.builder_cfg.get('extra_config'):
44*c8dee2aaSAndroid Build Coastguard Worker    # Due to http://b/72366966 and the fact that CIPD symlinks files in by default, we ran into
45*c8dee2aaSAndroid Build Coastguard Worker    # a strange "Function not implemented" error when trying to copy folders that contained
46*c8dee2aaSAndroid Build Coastguard Worker    # symlinked files. It is not easy to change the CIPD "InstallMode" from symlink to copy, so
47*c8dee2aaSAndroid Build Coastguard Worker    # we use shutil (file.copytree) to make a local copy of the files on the host, which removes
48*c8dee2aaSAndroid Build Coastguard Worker    # the symlinks and adb push --sync works as expected.
49*c8dee2aaSAndroid Build Coastguard Worker    lotties_device = api.flavor.device_path_join(api.flavor.device_dirs.tmp_dir, 'lotties_with_assets')
50*c8dee2aaSAndroid Build Coastguard Worker    api.flavor.create_clean_device_dir(lotties_device)
51*c8dee2aaSAndroid Build Coastguard Worker
52*c8dee2aaSAndroid Build Coastguard Worker    # Make a temp directory and then copy to a *non-existing* subfolder (otherwise copytree crashes).
53*c8dee2aaSAndroid Build Coastguard Worker    lotties_no_symlinks = api.path.mkdtemp('lwa').joinpath('nosymlinks')
54*c8dee2aaSAndroid Build Coastguard Worker    api.file.copytree('Copying files on host to remove symlinks', lotties_host, lotties_no_symlinks)
55*c8dee2aaSAndroid Build Coastguard Worker    lotties_host = lotties_no_symlinks
56*c8dee2aaSAndroid Build Coastguard Worker    api.flavor.copy_directory_contents_to_device(lotties_host, lotties_device)
57*c8dee2aaSAndroid Build Coastguard Worker
58*c8dee2aaSAndroid Build Coastguard Worker  # We expect this to be a bunch of folders that contain a data.json and optionally
59*c8dee2aaSAndroid Build Coastguard Worker  # an images/ subfolder with image assets required.
60*c8dee2aaSAndroid Build Coastguard Worker  lottie_files = api.file.listdir(
61*c8dee2aaSAndroid Build Coastguard Worker      'list lottie files', lotties_host,
62*c8dee2aaSAndroid Build Coastguard Worker      test_data=['skottie_asset_000', 'skottie_asset_001', 'skottie_asset_002'])
63*c8dee2aaSAndroid Build Coastguard Worker  perf_results = {}
64*c8dee2aaSAndroid Build Coastguard Worker  # Run DM on each lottie file and parse the trace files.
65*c8dee2aaSAndroid Build Coastguard Worker  for idx, lottie_file in enumerate(lottie_files):
66*c8dee2aaSAndroid Build Coastguard Worker    lottie_name = api.path.basename(lottie_file)
67*c8dee2aaSAndroid Build Coastguard Worker    lottie_folder = api.flavor.device_path_join(lotties_device, lottie_name)
68*c8dee2aaSAndroid Build Coastguard Worker
69*c8dee2aaSAndroid Build Coastguard Worker    trace_output_path = api.flavor.device_path_join(
70*c8dee2aaSAndroid Build Coastguard Worker        api.flavor.device_dirs.dm_dir, '%s.json' % (idx + 1))
71*c8dee2aaSAndroid Build Coastguard Worker    # See go/skottie-tracing for how these flags were selected.
72*c8dee2aaSAndroid Build Coastguard Worker    dm_args = [
73*c8dee2aaSAndroid Build Coastguard Worker      'dm',
74*c8dee2aaSAndroid Build Coastguard Worker      '--resourcePath', api.flavor.device_dirs.resource_dir,
75*c8dee2aaSAndroid Build Coastguard Worker      '--lotties', lottie_folder,
76*c8dee2aaSAndroid Build Coastguard Worker      '--src', 'lottie',
77*c8dee2aaSAndroid Build Coastguard Worker      '--nonativeFonts',
78*c8dee2aaSAndroid Build Coastguard Worker      '--verbose',
79*c8dee2aaSAndroid Build Coastguard Worker      '--traceMatch', 'skottie',  # recipe can OOM without this.
80*c8dee2aaSAndroid Build Coastguard Worker      '--trace', trace_output_path,
81*c8dee2aaSAndroid Build Coastguard Worker      '--match', get_trace_match(
82*c8dee2aaSAndroid Build Coastguard Worker          'data.json', 'Android' in api.properties['buildername']),
83*c8dee2aaSAndroid Build Coastguard Worker    ]
84*c8dee2aaSAndroid Build Coastguard Worker    if api.vars.builder_cfg.get('cpu_or_gpu') == 'GPU':
85*c8dee2aaSAndroid Build Coastguard Worker      dm_args.extend(['--config', 'gles', '--nocpu'])
86*c8dee2aaSAndroid Build Coastguard Worker    elif api.vars.builder_cfg.get('cpu_or_gpu') == 'CPU':
87*c8dee2aaSAndroid Build Coastguard Worker      dm_args.extend(['--config', '8888', '--nogpu'])
88*c8dee2aaSAndroid Build Coastguard Worker    api.run(api.flavor.step, 'dm', cmd=dm_args, abort_on_failure=False)
89*c8dee2aaSAndroid Build Coastguard Worker
90*c8dee2aaSAndroid Build Coastguard Worker    trace_test_data = api.properties.get('trace_test_data', '{}')
91*c8dee2aaSAndroid Build Coastguard Worker    trace_file_content = api.flavor.read_file_on_device(trace_output_path)
92*c8dee2aaSAndroid Build Coastguard Worker    if not trace_file_content and trace_test_data:
93*c8dee2aaSAndroid Build Coastguard Worker      trace_file_content = trace_test_data
94*c8dee2aaSAndroid Build Coastguard Worker
95*c8dee2aaSAndroid Build Coastguard Worker    key = 'gles'
96*c8dee2aaSAndroid Build Coastguard Worker    if api.vars.builder_cfg.get('cpu_or_gpu') == 'CPU':
97*c8dee2aaSAndroid Build Coastguard Worker        key = '8888'
98*c8dee2aaSAndroid Build Coastguard Worker    perf_results[lottie_name] = {
99*c8dee2aaSAndroid Build Coastguard Worker        key: parse_trace(trace_file_content, lottie_name, api),
100*c8dee2aaSAndroid Build Coastguard Worker    }
101*c8dee2aaSAndroid Build Coastguard Worker    api.flavor.remove_file_on_device(trace_output_path)
102*c8dee2aaSAndroid Build Coastguard Worker
103*c8dee2aaSAndroid Build Coastguard Worker  # Construct contents of the output JSON.
104*c8dee2aaSAndroid Build Coastguard Worker  perf_json = {
105*c8dee2aaSAndroid Build Coastguard Worker      'gitHash': api.properties['revision'],
106*c8dee2aaSAndroid Build Coastguard Worker      'swarming_bot_id': api.vars.swarming_bot_id,
107*c8dee2aaSAndroid Build Coastguard Worker      'swarming_task_id': api.vars.swarming_task_id,
108*c8dee2aaSAndroid Build Coastguard Worker      'renderer': 'skottie',
109*c8dee2aaSAndroid Build Coastguard Worker      'key': {
110*c8dee2aaSAndroid Build Coastguard Worker        'bench_type': 'tracing',
111*c8dee2aaSAndroid Build Coastguard Worker        'source_type': 'skottie',
112*c8dee2aaSAndroid Build Coastguard Worker      },
113*c8dee2aaSAndroid Build Coastguard Worker      'results': perf_results,
114*c8dee2aaSAndroid Build Coastguard Worker  }
115*c8dee2aaSAndroid Build Coastguard Worker  if api.vars.is_trybot:
116*c8dee2aaSAndroid Build Coastguard Worker    perf_json['issue'] = api.vars.issue
117*c8dee2aaSAndroid Build Coastguard Worker    perf_json['patchset'] = api.vars.patchset
118*c8dee2aaSAndroid Build Coastguard Worker    perf_json['patch_storage'] = api.vars.patch_storage
119*c8dee2aaSAndroid Build Coastguard Worker  # Add tokens from the builder name to the key.
120*c8dee2aaSAndroid Build Coastguard Worker  reg = re.compile('Perf-(?P<os>[A-Za-z0-9_]+)-'
121*c8dee2aaSAndroid Build Coastguard Worker                   '(?P<compiler>[A-Za-z0-9_]+)-'
122*c8dee2aaSAndroid Build Coastguard Worker                   '(?P<model>[A-Za-z0-9_]+)-'
123*c8dee2aaSAndroid Build Coastguard Worker                   '(?P<cpu_or_gpu>[A-Z]+)-'
124*c8dee2aaSAndroid Build Coastguard Worker                   '(?P<cpu_or_gpu_value>[A-Za-z0-9_]+)-'
125*c8dee2aaSAndroid Build Coastguard Worker                   '(?P<arch>[A-Za-z0-9_]+)-'
126*c8dee2aaSAndroid Build Coastguard Worker                   '(?P<configuration>[A-Za-z0-9_]+)-'
127*c8dee2aaSAndroid Build Coastguard Worker                   'All(-(?P<extra_config>[A-Za-z0-9_]+)|)')
128*c8dee2aaSAndroid Build Coastguard Worker  m = reg.match(api.properties['buildername'])
129*c8dee2aaSAndroid Build Coastguard Worker  keys = ['os', 'compiler', 'model', 'cpu_or_gpu', 'cpu_or_gpu_value', 'arch',
130*c8dee2aaSAndroid Build Coastguard Worker          'configuration', 'extra_config']
131*c8dee2aaSAndroid Build Coastguard Worker  for k in keys:
132*c8dee2aaSAndroid Build Coastguard Worker    perf_json['key'][k] = m.group(k)
133*c8dee2aaSAndroid Build Coastguard Worker
134*c8dee2aaSAndroid Build Coastguard Worker  # Create the output JSON file in perf_data_dir for the Upload task to upload.
135*c8dee2aaSAndroid Build Coastguard Worker  api.file.ensure_directory(
136*c8dee2aaSAndroid Build Coastguard Worker      'makedirs perf_dir',
137*c8dee2aaSAndroid Build Coastguard Worker      api.flavor.host_dirs.perf_data_dir)
138*c8dee2aaSAndroid Build Coastguard Worker  now = api.time.utcnow()
139*c8dee2aaSAndroid Build Coastguard Worker  ts = int(calendar.timegm(now.utctimetuple()))
140*c8dee2aaSAndroid Build Coastguard Worker  json_path = api.flavor.host_dirs.perf_data_dir.joinpath(
141*c8dee2aaSAndroid Build Coastguard Worker      'perf_%s_%d.json' % (api.properties['revision'], ts))
142*c8dee2aaSAndroid Build Coastguard Worker  json_contents = json.dumps(
143*c8dee2aaSAndroid Build Coastguard Worker      perf_json, indent=4, sort_keys=True, separators=(',', ': '))
144*c8dee2aaSAndroid Build Coastguard Worker  api.file.write_text('write output JSON', json_path, json_contents)
145*c8dee2aaSAndroid Build Coastguard Worker
146*c8dee2aaSAndroid Build Coastguard Worker
147*c8dee2aaSAndroid Build Coastguard Workerdef get_trace_match(lottie_filename, is_android):
148*c8dee2aaSAndroid Build Coastguard Worker  """Returns the DM regex to match the specified lottie file name."""
149*c8dee2aaSAndroid Build Coastguard Worker  trace_match = '^%s$' % lottie_filename
150*c8dee2aaSAndroid Build Coastguard Worker  if is_android and ' ' not in trace_match:
151*c8dee2aaSAndroid Build Coastguard Worker    # Punctuation characters confuse DM when shelled out over adb, so escape
152*c8dee2aaSAndroid Build Coastguard Worker    # them. Do not need to do this when there is a space in the match because
153*c8dee2aaSAndroid Build Coastguard Worker    # subprocess.list2cmdline automatically adds quotes in that case.
154*c8dee2aaSAndroid Build Coastguard Worker    for sp_char in string.punctuation:
155*c8dee2aaSAndroid Build Coastguard Worker      if sp_char == '\\':
156*c8dee2aaSAndroid Build Coastguard Worker        # No need to escape the escape char.
157*c8dee2aaSAndroid Build Coastguard Worker        continue
158*c8dee2aaSAndroid Build Coastguard Worker      trace_match = trace_match.replace(sp_char, '\%s' % sp_char)
159*c8dee2aaSAndroid Build Coastguard Worker  return trace_match
160*c8dee2aaSAndroid Build Coastguard Worker
161*c8dee2aaSAndroid Build Coastguard Worker
162*c8dee2aaSAndroid Build Coastguard Workerdef parse_trace(trace_json, lottie_filename, api):
163*c8dee2aaSAndroid Build Coastguard Worker  """parse_trace parses the specified trace JSON.
164*c8dee2aaSAndroid Build Coastguard Worker
165*c8dee2aaSAndroid Build Coastguard Worker  Parses the trace JSON and calculates the time of a single frame. Frame time is
166*c8dee2aaSAndroid Build Coastguard Worker  considered the same as seek time + render time.
167*c8dee2aaSAndroid Build Coastguard Worker  Note: The first seek is ignored because it is a constructor call.
168*c8dee2aaSAndroid Build Coastguard Worker
169*c8dee2aaSAndroid Build Coastguard Worker  A dictionary is returned that has the following structure:
170*c8dee2aaSAndroid Build Coastguard Worker  {
171*c8dee2aaSAndroid Build Coastguard Worker    'frame_max_us': 100,
172*c8dee2aaSAndroid Build Coastguard Worker    'frame_min_us': 90,
173*c8dee2aaSAndroid Build Coastguard Worker    'frame_avg_us': 95,
174*c8dee2aaSAndroid Build Coastguard Worker  }
175*c8dee2aaSAndroid Build Coastguard Worker  """
176*c8dee2aaSAndroid Build Coastguard Worker  script = api.infra.resource('parse_skottie_trace.py')
177*c8dee2aaSAndroid Build Coastguard Worker  step_result = api.run(
178*c8dee2aaSAndroid Build Coastguard Worker      api.step,
179*c8dee2aaSAndroid Build Coastguard Worker      'parse %s trace' % lottie_filename,
180*c8dee2aaSAndroid Build Coastguard Worker      cmd=['python3', script, trace_json, lottie_filename, api.json.output(),
181*c8dee2aaSAndroid Build Coastguard Worker           SEEK_TRACE_NAME, RENDER_TRACE_NAME, EXPECTED_DM_FRAMES])
182*c8dee2aaSAndroid Build Coastguard Worker
183*c8dee2aaSAndroid Build Coastguard Worker  # Sanitize float outputs to 2 precision points.
184*c8dee2aaSAndroid Build Coastguard Worker  output = dict(step_result.json.output)
185*c8dee2aaSAndroid Build Coastguard Worker  output['frame_max_us'] = float("%.2f" % output['frame_max_us'])
186*c8dee2aaSAndroid Build Coastguard Worker  output['frame_min_us'] = float("%.2f" % output['frame_min_us'])
187*c8dee2aaSAndroid Build Coastguard Worker  output['frame_avg_us'] = float("%.2f" % output['frame_avg_us'])
188*c8dee2aaSAndroid Build Coastguard Worker  return output
189*c8dee2aaSAndroid Build Coastguard Worker
190*c8dee2aaSAndroid Build Coastguard Worker
191*c8dee2aaSAndroid Build Coastguard Workerdef RunSteps(api):
192*c8dee2aaSAndroid Build Coastguard Worker  api.vars.setup()
193*c8dee2aaSAndroid Build Coastguard Worker  api.file.ensure_directory('makedirs tmp_dir', api.vars.tmp_dir)
194*c8dee2aaSAndroid Build Coastguard Worker  api.flavor.setup('dm')
195*c8dee2aaSAndroid Build Coastguard Worker
196*c8dee2aaSAndroid Build Coastguard Worker  with api.context():
197*c8dee2aaSAndroid Build Coastguard Worker    try:
198*c8dee2aaSAndroid Build Coastguard Worker      api.flavor.install(resources=True, lotties=True)
199*c8dee2aaSAndroid Build Coastguard Worker      perf_steps(api)
200*c8dee2aaSAndroid Build Coastguard Worker    finally:
201*c8dee2aaSAndroid Build Coastguard Worker      api.flavor.cleanup_steps()
202*c8dee2aaSAndroid Build Coastguard Worker    api.run.check_failure()
203*c8dee2aaSAndroid Build Coastguard Worker
204*c8dee2aaSAndroid Build Coastguard Worker
205*c8dee2aaSAndroid Build Coastguard Workerdef GenTests(api):
206*c8dee2aaSAndroid Build Coastguard Worker  trace_output = """
207*c8dee2aaSAndroid Build Coastguard Worker[{"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}]
208*c8dee2aaSAndroid Build Coastguard Worker"""
209*c8dee2aaSAndroid Build Coastguard Worker  dm_json_test_data = """
210*c8dee2aaSAndroid Build Coastguard Worker{
211*c8dee2aaSAndroid Build Coastguard Worker  "gitHash": "bac53f089dbc473862bc5a2e328ba7600e0ed9c4",
212*c8dee2aaSAndroid Build Coastguard Worker  "swarming_bot_id": "skia-rpi-094",
213*c8dee2aaSAndroid Build Coastguard Worker  "swarming_task_id": "438f11c0e19eab11",
214*c8dee2aaSAndroid Build Coastguard Worker  "key": {
215*c8dee2aaSAndroid Build Coastguard Worker    "arch": "arm",
216*c8dee2aaSAndroid Build Coastguard Worker    "compiler": "Clang",
217*c8dee2aaSAndroid Build Coastguard Worker    "cpu_or_gpu": "GPU",
218*c8dee2aaSAndroid Build Coastguard Worker    "cpu_or_gpu_value": "Mali400MP2",
219*c8dee2aaSAndroid Build Coastguard Worker    "extra_config": "Android",
220*c8dee2aaSAndroid Build Coastguard Worker    "model": "AndroidOne",
221*c8dee2aaSAndroid Build Coastguard Worker    "os": "Android"
222*c8dee2aaSAndroid Build Coastguard Worker   },
223*c8dee2aaSAndroid Build Coastguard Worker   "results": {
224*c8dee2aaSAndroid Build Coastguard Worker   }
225*c8dee2aaSAndroid Build Coastguard Worker}
226*c8dee2aaSAndroid Build Coastguard Worker"""
227*c8dee2aaSAndroid Build Coastguard Worker  parse_trace_json = {
228*c8dee2aaSAndroid Build Coastguard Worker      'frame_avg_us': 179.71,
229*c8dee2aaSAndroid Build Coastguard Worker      'frame_min_us': 141.17,
230*c8dee2aaSAndroid Build Coastguard Worker      'frame_max_us': 218.25
231*c8dee2aaSAndroid Build Coastguard Worker  }
232*c8dee2aaSAndroid Build Coastguard Worker  android_buildername = ('Perf-Android-Clang-AndroidOne-GPU-Mali400MP2-arm-'
233*c8dee2aaSAndroid Build Coastguard Worker                         'Release-All-Android_SkottieTracing')
234*c8dee2aaSAndroid Build Coastguard Worker  gpu_buildername = ('Perf-Debian10-Clang-NUC7i5BNK-GPU-IntelIris640-x86_64-'
235*c8dee2aaSAndroid Build Coastguard Worker                     'Release-All-SkottieTracing')
236*c8dee2aaSAndroid Build Coastguard Worker  cpu_buildername = ('Perf-Debian10-Clang-GCE-CPU-AVX2-x86_64-Release-All-'
237*c8dee2aaSAndroid Build Coastguard Worker                     'SkottieTracing')
238*c8dee2aaSAndroid Build Coastguard Worker  yield (
239*c8dee2aaSAndroid Build Coastguard Worker      api.test(android_buildername) +
240*c8dee2aaSAndroid Build Coastguard Worker      api.properties(buildername=android_buildername,
241*c8dee2aaSAndroid Build Coastguard Worker                     repository='https://skia.googlesource.com/skia.git',
242*c8dee2aaSAndroid Build Coastguard Worker                     revision='abc123',
243*c8dee2aaSAndroid Build Coastguard Worker                     task_id='abc123',
244*c8dee2aaSAndroid Build Coastguard Worker                     trace_test_data=trace_output,
245*c8dee2aaSAndroid Build Coastguard Worker                     dm_json_test_data=dm_json_test_data,
246*c8dee2aaSAndroid Build Coastguard Worker                     path_config='kitchen',
247*c8dee2aaSAndroid Build Coastguard Worker                     swarm_out_dir='[SWARM_OUT_DIR]') +
248*c8dee2aaSAndroid Build Coastguard Worker      api.step_data('parse skottie_asset_000 trace',
249*c8dee2aaSAndroid Build Coastguard Worker                    api.json.output(parse_trace_json)) +
250*c8dee2aaSAndroid Build Coastguard Worker      api.step_data('parse skottie_asset_001 trace',
251*c8dee2aaSAndroid Build Coastguard Worker                    api.json.output(parse_trace_json)) +
252*c8dee2aaSAndroid Build Coastguard Worker      api.step_data('parse skottie_asset_002 trace',
253*c8dee2aaSAndroid Build Coastguard Worker                    api.json.output(parse_trace_json))
254*c8dee2aaSAndroid Build Coastguard Worker  )
255*c8dee2aaSAndroid Build Coastguard Worker  yield (
256*c8dee2aaSAndroid Build Coastguard Worker      api.test(gpu_buildername) +
257*c8dee2aaSAndroid Build Coastguard Worker      api.properties(buildername=gpu_buildername,
258*c8dee2aaSAndroid Build Coastguard Worker                     repository='https://skia.googlesource.com/skia.git',
259*c8dee2aaSAndroid Build Coastguard Worker                     revision='abc123',
260*c8dee2aaSAndroid Build Coastguard Worker                     task_id='abc123',
261*c8dee2aaSAndroid Build Coastguard Worker                     trace_test_data=trace_output,
262*c8dee2aaSAndroid Build Coastguard Worker                     dm_json_test_data=dm_json_test_data,
263*c8dee2aaSAndroid Build Coastguard Worker                     path_config='kitchen',
264*c8dee2aaSAndroid Build Coastguard Worker                     swarm_out_dir='[SWARM_OUT_DIR]') +
265*c8dee2aaSAndroid Build Coastguard Worker      api.step_data('parse skottie_asset_000 trace',
266*c8dee2aaSAndroid Build Coastguard Worker                    api.json.output(parse_trace_json)) +
267*c8dee2aaSAndroid Build Coastguard Worker      api.step_data('parse skottie_asset_001 trace',
268*c8dee2aaSAndroid Build Coastguard Worker                    api.json.output(parse_trace_json)) +
269*c8dee2aaSAndroid Build Coastguard Worker      api.step_data('parse skottie_asset_002 trace',
270*c8dee2aaSAndroid Build Coastguard Worker                    api.json.output(parse_trace_json))
271*c8dee2aaSAndroid Build Coastguard Worker  )
272*c8dee2aaSAndroid Build Coastguard Worker  yield (
273*c8dee2aaSAndroid Build Coastguard Worker      api.test(cpu_buildername) +
274*c8dee2aaSAndroid Build Coastguard Worker      api.properties(buildername=cpu_buildername,
275*c8dee2aaSAndroid Build Coastguard Worker                     repository='https://skia.googlesource.com/skia.git',
276*c8dee2aaSAndroid Build Coastguard Worker                     revision='abc123',
277*c8dee2aaSAndroid Build Coastguard Worker                     task_id='abc123',
278*c8dee2aaSAndroid Build Coastguard Worker                     trace_test_data=trace_output,
279*c8dee2aaSAndroid Build Coastguard Worker                     dm_json_test_data=dm_json_test_data,
280*c8dee2aaSAndroid Build Coastguard Worker                     path_config='kitchen',
281*c8dee2aaSAndroid Build Coastguard Worker                     swarm_out_dir='[SWARM_OUT_DIR]') +
282*c8dee2aaSAndroid Build Coastguard Worker      api.step_data('parse skottie_asset_000 trace',
283*c8dee2aaSAndroid Build Coastguard Worker                    api.json.output(parse_trace_json)) +
284*c8dee2aaSAndroid Build Coastguard Worker      api.step_data('parse skottie_asset_001 trace',
285*c8dee2aaSAndroid Build Coastguard Worker                    api.json.output(parse_trace_json)) +
286*c8dee2aaSAndroid Build Coastguard Worker      api.step_data('parse skottie_asset_002 trace',
287*c8dee2aaSAndroid Build Coastguard Worker                    api.json.output(parse_trace_json))
288*c8dee2aaSAndroid Build Coastguard Worker  )
289*c8dee2aaSAndroid Build Coastguard Worker  yield (
290*c8dee2aaSAndroid Build Coastguard Worker      api.test('skottietracing_parse_trace_error') +
291*c8dee2aaSAndroid Build Coastguard Worker      api.properties(buildername=android_buildername,
292*c8dee2aaSAndroid Build Coastguard Worker                     repository='https://skia.googlesource.com/skia.git',
293*c8dee2aaSAndroid Build Coastguard Worker                     revision='abc123',
294*c8dee2aaSAndroid Build Coastguard Worker                     task_id='abc123',
295*c8dee2aaSAndroid Build Coastguard Worker                     trace_test_data=trace_output,
296*c8dee2aaSAndroid Build Coastguard Worker                     dm_json_test_data=dm_json_test_data,
297*c8dee2aaSAndroid Build Coastguard Worker                     path_config='kitchen',
298*c8dee2aaSAndroid Build Coastguard Worker                     swarm_out_dir='[SWARM_OUT_DIR]') +
299*c8dee2aaSAndroid Build Coastguard Worker      api.step_data('parse skottie_asset_000 trace',
300*c8dee2aaSAndroid Build Coastguard Worker                    api.json.output(parse_trace_json), retcode=1)
301*c8dee2aaSAndroid Build Coastguard Worker  )
302*c8dee2aaSAndroid Build Coastguard Worker  yield (
303*c8dee2aaSAndroid Build Coastguard Worker      api.test('skottietracing_trybot') +
304*c8dee2aaSAndroid Build Coastguard Worker      api.properties(buildername=android_buildername,
305*c8dee2aaSAndroid Build Coastguard Worker                     repository='https://skia.googlesource.com/skia.git',
306*c8dee2aaSAndroid Build Coastguard Worker                     revision='abc123',
307*c8dee2aaSAndroid Build Coastguard Worker                     task_id='abc123',
308*c8dee2aaSAndroid Build Coastguard Worker                     trace_test_data=trace_output,
309*c8dee2aaSAndroid Build Coastguard Worker                     dm_json_test_data=dm_json_test_data,
310*c8dee2aaSAndroid Build Coastguard Worker                     path_config='kitchen',
311*c8dee2aaSAndroid Build Coastguard Worker                     swarm_out_dir='[SWARM_OUT_DIR]',
312*c8dee2aaSAndroid Build Coastguard Worker                     patch_ref='89/456789/12',
313*c8dee2aaSAndroid Build Coastguard Worker                     patch_repo='https://skia.googlesource.com/skia.git',
314*c8dee2aaSAndroid Build Coastguard Worker                     patch_storage='gerrit',
315*c8dee2aaSAndroid Build Coastguard Worker                     patch_set=7,
316*c8dee2aaSAndroid Build Coastguard Worker                     patch_issue=1234,
317*c8dee2aaSAndroid Build Coastguard Worker                     gerrit_project='skia',
318*c8dee2aaSAndroid Build Coastguard Worker                     gerrit_url='https://skia-review.googlesource.com/') +
319*c8dee2aaSAndroid Build Coastguard Worker      api.step_data('parse skottie_asset_000 trace',
320*c8dee2aaSAndroid Build Coastguard Worker                    api.json.output(parse_trace_json)) +
321*c8dee2aaSAndroid Build Coastguard Worker      api.step_data('parse skottie_asset_001 trace',
322*c8dee2aaSAndroid Build Coastguard Worker                    api.json.output(parse_trace_json)) +
323*c8dee2aaSAndroid Build Coastguard Worker      api.step_data('parse skottie_asset_002 trace',
324*c8dee2aaSAndroid Build Coastguard Worker                    api.json.output(parse_trace_json))
325*c8dee2aaSAndroid Build Coastguard Worker  )
326