1cb93a386Sopenharmony_ci# Copyright 2018 The Chromium Authors. All rights reserved.
2cb93a386Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be
3cb93a386Sopenharmony_ci# found in the LICENSE file.
4cb93a386Sopenharmony_ci
5cb93a386Sopenharmony_ci# Recipe which analyzes a compiled binary for information (e.g. file size)
6cb93a386Sopenharmony_ci
7cb93a386Sopenharmony_ciimport ast
8cb93a386Sopenharmony_ciimport json
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ciPYTHON_VERSION_COMPATIBILITY = "PY2+3"
11cb93a386Sopenharmony_ci
12cb93a386Sopenharmony_ciDEPS = [
13cb93a386Sopenharmony_ci  'checkout',
14cb93a386Sopenharmony_ci  'env',
15cb93a386Sopenharmony_ci  'recipe_engine/context',
16cb93a386Sopenharmony_ci  'recipe_engine/file',
17cb93a386Sopenharmony_ci  'recipe_engine/path',
18cb93a386Sopenharmony_ci  'recipe_engine/properties',
19cb93a386Sopenharmony_ci  'recipe_engine/python',
20cb93a386Sopenharmony_ci  'recipe_engine/raw_io',
21cb93a386Sopenharmony_ci  'recipe_engine/step',
22cb93a386Sopenharmony_ci  'run',
23cb93a386Sopenharmony_ci  'vars',
24cb93a386Sopenharmony_ci]
25cb93a386Sopenharmony_ci
26cb93a386Sopenharmony_ci
27cb93a386Sopenharmony_ciMAGIC_SEPERATOR = '#$%^&*'
28cb93a386Sopenharmony_ciTOTAL_SIZE_BYTES_KEY = "total_size_bytes"
29cb93a386Sopenharmony_ci
30cb93a386Sopenharmony_ci
31cb93a386Sopenharmony_cidef add_binary_size_output_property(result, source, binary_size):
32cb93a386Sopenharmony_ci  result.presentation.properties['binary_size_%s' % source] = binary_size
33cb93a386Sopenharmony_ci
34cb93a386Sopenharmony_ci
35cb93a386Sopenharmony_cidef RunSteps(api):
36cb93a386Sopenharmony_ci  api.vars.setup()
37cb93a386Sopenharmony_ci
38cb93a386Sopenharmony_ci  checkout_root = api.checkout.default_checkout_root
39cb93a386Sopenharmony_ci  api.checkout.bot_update(checkout_root=checkout_root)
40cb93a386Sopenharmony_ci
41cb93a386Sopenharmony_ci  out_dir = api.vars.swarming_out_dir
42cb93a386Sopenharmony_ci  # Any binaries to scan should be here.
43cb93a386Sopenharmony_ci  bin_dir = api.vars.build_dir
44cb93a386Sopenharmony_ci
45cb93a386Sopenharmony_ci  api.file.ensure_directory('mkdirs out_dir', out_dir, mode=0o777)
46cb93a386Sopenharmony_ci
47cb93a386Sopenharmony_ci  analyzed = 0
48cb93a386Sopenharmony_ci  with api.context(cwd=bin_dir):
49cb93a386Sopenharmony_ci    files = api.file.glob_paths(
50cb93a386Sopenharmony_ci        'find WASM binaries',
51cb93a386Sopenharmony_ci        bin_dir,
52cb93a386Sopenharmony_ci        '*.wasm',
53cb93a386Sopenharmony_ci        test_data=['pathkit.wasm'])
54cb93a386Sopenharmony_ci    analyzed += len(files)
55cb93a386Sopenharmony_ci    if files:
56cb93a386Sopenharmony_ci      analyze_wasm_file(api, checkout_root, out_dir, files)
57cb93a386Sopenharmony_ci
58cb93a386Sopenharmony_ci    files = api.file.glob_paths(
59cb93a386Sopenharmony_ci        'find JS files',
60cb93a386Sopenharmony_ci        bin_dir,
61cb93a386Sopenharmony_ci        '*.js',
62cb93a386Sopenharmony_ci        test_data=['pathkit.js'])
63cb93a386Sopenharmony_ci    analyzed += len(files)
64cb93a386Sopenharmony_ci    if files:
65cb93a386Sopenharmony_ci      analyze_web_file(api, checkout_root, out_dir, files)
66cb93a386Sopenharmony_ci
67cb93a386Sopenharmony_ci    files = api.file.glob_paths(
68cb93a386Sopenharmony_ci        'find JS mem files',
69cb93a386Sopenharmony_ci        bin_dir,
70cb93a386Sopenharmony_ci        '*.js.mem',
71cb93a386Sopenharmony_ci        test_data=['pathkit.js.mem'])
72cb93a386Sopenharmony_ci    analyzed += len(files)
73cb93a386Sopenharmony_ci    if files:
74cb93a386Sopenharmony_ci      analyze_web_file(api, checkout_root, out_dir, files)
75cb93a386Sopenharmony_ci
76cb93a386Sopenharmony_ci    files = api.file.glob_paths(
77cb93a386Sopenharmony_ci        'find flutter library',
78cb93a386Sopenharmony_ci        bin_dir,
79cb93a386Sopenharmony_ci        'libflutter.so',
80cb93a386Sopenharmony_ci        test_data=['libflutter.so'])
81cb93a386Sopenharmony_ci    analyzed += len(files)
82cb93a386Sopenharmony_ci    if files:
83cb93a386Sopenharmony_ci      analyze_flutter_lib(api, checkout_root, out_dir, files)
84cb93a386Sopenharmony_ci
85cb93a386Sopenharmony_ci    files = api.file.glob_paths(
86cb93a386Sopenharmony_ci        'find skia library',
87cb93a386Sopenharmony_ci        bin_dir,
88cb93a386Sopenharmony_ci        'libskia.so',
89cb93a386Sopenharmony_ci        test_data=['libskia.so'])
90cb93a386Sopenharmony_ci    analyzed += len(files)
91cb93a386Sopenharmony_ci    if files:
92cb93a386Sopenharmony_ci      analyze_cpp_lib(api, checkout_root, out_dir, files)
93cb93a386Sopenharmony_ci
94cb93a386Sopenharmony_ci    files = api.file.glob_paths(
95cb93a386Sopenharmony_ci        'find skottie_tool',
96cb93a386Sopenharmony_ci        bin_dir,
97cb93a386Sopenharmony_ci        'skottie_tool',
98cb93a386Sopenharmony_ci        test_data=['skottie_tool'])
99cb93a386Sopenharmony_ci    analyzed += len(files)
100cb93a386Sopenharmony_ci    if files:
101cb93a386Sopenharmony_ci      make_treemap(api, checkout_root, out_dir, files)
102cb93a386Sopenharmony_ci
103cb93a386Sopenharmony_ci    files = api.file.glob_paths(
104cb93a386Sopenharmony_ci        'find dm',
105cb93a386Sopenharmony_ci        bin_dir,
106cb93a386Sopenharmony_ci        'dm',
107cb93a386Sopenharmony_ci        test_data=['dm'])
108cb93a386Sopenharmony_ci    analyzed += len(files)
109cb93a386Sopenharmony_ci    if files:
110cb93a386Sopenharmony_ci      make_treemap(api, checkout_root, out_dir, files)
111cb93a386Sopenharmony_ci
112cb93a386Sopenharmony_ci  if not analyzed: # pragma: nocover
113cb93a386Sopenharmony_ci    raise Exception('No files were analyzed!')
114cb93a386Sopenharmony_ci
115cb93a386Sopenharmony_ci
116cb93a386Sopenharmony_cidef keys_and_props(api):
117cb93a386Sopenharmony_ci  keys = []
118cb93a386Sopenharmony_ci  for k in sorted(api.vars.builder_cfg.keys()):
119cb93a386Sopenharmony_ci      if not k in ['role']:
120cb93a386Sopenharmony_ci        keys.extend([k, api.vars.builder_cfg[k]])
121cb93a386Sopenharmony_ci  keystr = ' '.join(keys)
122cb93a386Sopenharmony_ci
123cb93a386Sopenharmony_ci  props = [
124cb93a386Sopenharmony_ci    'gitHash', api.properties['revision'],
125cb93a386Sopenharmony_ci    'swarming_bot_id', api.vars.swarming_bot_id,
126cb93a386Sopenharmony_ci    'swarming_task_id', api.vars.swarming_task_id,
127cb93a386Sopenharmony_ci  ]
128cb93a386Sopenharmony_ci
129cb93a386Sopenharmony_ci  if api.vars.is_trybot:
130cb93a386Sopenharmony_ci    props.extend([
131cb93a386Sopenharmony_ci      'issue',    api.vars.issue,
132cb93a386Sopenharmony_ci      'patchset', api.vars.patchset,
133cb93a386Sopenharmony_ci      'patch_storage', api.vars.patch_storage,
134cb93a386Sopenharmony_ci    ])
135cb93a386Sopenharmony_ci  propstr = ' '.join(str(prop) for prop in props)
136cb93a386Sopenharmony_ci  return (keystr, propstr)
137cb93a386Sopenharmony_ci
138cb93a386Sopenharmony_ci
139cb93a386Sopenharmony_ci# Get the raw and gzipped size of the given file
140cb93a386Sopenharmony_cidef analyze_web_file(api, checkout_root, out_dir, files):
141cb93a386Sopenharmony_ci  (keystr, propstr) = keys_and_props(api)
142cb93a386Sopenharmony_ci
143cb93a386Sopenharmony_ci  for f in files:
144cb93a386Sopenharmony_ci    skia_dir = checkout_root.join('skia')
145cb93a386Sopenharmony_ci    with api.context(cwd=skia_dir):
146cb93a386Sopenharmony_ci      script = skia_dir.join('infra', 'bots', 'buildstats',
147cb93a386Sopenharmony_ci                             'buildstats_web.py')
148cb93a386Sopenharmony_ci      step_data = api.run(api.python, 'Analyze %s' % f, script=script,
149cb93a386Sopenharmony_ci          args=[f, out_dir, keystr, propstr, TOTAL_SIZE_BYTES_KEY,
150cb93a386Sopenharmony_ci                MAGIC_SEPERATOR],
151cb93a386Sopenharmony_ci          stdout=api.raw_io.output())
152cb93a386Sopenharmony_ci      if step_data and step_data.stdout:
153cb93a386Sopenharmony_ci        sections = step_data.stdout.decode('utf-8').split(MAGIC_SEPERATOR)
154cb93a386Sopenharmony_ci        result = api.step.active_result
155cb93a386Sopenharmony_ci        logs = result.presentation.logs
156cb93a386Sopenharmony_ci        logs['perf_json'] = sections[1].split('\n')
157cb93a386Sopenharmony_ci
158cb93a386Sopenharmony_ci        add_binary_size_output_property(result, api.path.basename(f), (
159cb93a386Sopenharmony_ci            ast.literal_eval(sections[1])
160cb93a386Sopenharmony_ci              .get('results', {})
161cb93a386Sopenharmony_ci              .get(api.path.basename(f), {})
162cb93a386Sopenharmony_ci              .get('default', {})
163cb93a386Sopenharmony_ci              .get(TOTAL_SIZE_BYTES_KEY, {})))
164cb93a386Sopenharmony_ci
165cb93a386Sopenharmony_ci
166cb93a386Sopenharmony_ci# Get the raw size and a few metrics from bloaty
167cb93a386Sopenharmony_cidef analyze_cpp_lib(api, checkout_root, out_dir, files):
168cb93a386Sopenharmony_ci  (keystr, propstr) = keys_and_props(api)
169cb93a386Sopenharmony_ci  bloaty_exe = api.path['start_dir'].join('bloaty', 'bloaty')
170cb93a386Sopenharmony_ci
171cb93a386Sopenharmony_ci  for f in files:
172cb93a386Sopenharmony_ci    skia_dir = checkout_root.join('skia')
173cb93a386Sopenharmony_ci    with api.context(cwd=skia_dir):
174cb93a386Sopenharmony_ci      script = skia_dir.join('infra', 'bots', 'buildstats',
175cb93a386Sopenharmony_ci                             'buildstats_cpp.py')
176cb93a386Sopenharmony_ci      step_data = api.run(api.python, 'Analyze %s' % f, script=script,
177cb93a386Sopenharmony_ci          args=[f, out_dir, keystr, propstr, bloaty_exe, TOTAL_SIZE_BYTES_KEY,
178cb93a386Sopenharmony_ci                MAGIC_SEPERATOR],
179cb93a386Sopenharmony_ci          stdout=api.raw_io.output())
180cb93a386Sopenharmony_ci      if step_data and step_data.stdout:
181cb93a386Sopenharmony_ci        sections = step_data.stdout.decode('utf-8').split(MAGIC_SEPERATOR)
182cb93a386Sopenharmony_ci        result = api.step.active_result
183cb93a386Sopenharmony_ci        logs = result.presentation.logs
184cb93a386Sopenharmony_ci        logs['perf_json'] = sections[2].split('\n')
185cb93a386Sopenharmony_ci
186cb93a386Sopenharmony_ci        add_binary_size_output_property(result, api.path.basename(f), (
187cb93a386Sopenharmony_ci            ast.literal_eval(sections[2])
188cb93a386Sopenharmony_ci              .get('results', {})
189cb93a386Sopenharmony_ci              .get(api.path.basename(f), {})
190cb93a386Sopenharmony_ci              .get('default', {})
191cb93a386Sopenharmony_ci              .get(TOTAL_SIZE_BYTES_KEY, {})))
192cb93a386Sopenharmony_ci
193cb93a386Sopenharmony_ci
194cb93a386Sopenharmony_ci# Get the size of skia in flutter and a few metrics from bloaty
195cb93a386Sopenharmony_cidef analyze_flutter_lib(api, checkout_root, out_dir, files):
196cb93a386Sopenharmony_ci  (keystr, propstr) = keys_and_props(api)
197cb93a386Sopenharmony_ci  bloaty_exe = api.path['start_dir'].join('bloaty', 'bloaty')
198cb93a386Sopenharmony_ci
199cb93a386Sopenharmony_ci  for f in files:
200cb93a386Sopenharmony_ci
201cb93a386Sopenharmony_ci    skia_dir = checkout_root.join('skia')
202cb93a386Sopenharmony_ci    with api.context(cwd=skia_dir):
203cb93a386Sopenharmony_ci      stripped = api.vars.build_dir.join('libflutter_stripped.so')
204cb93a386Sopenharmony_ci      script = skia_dir.join('infra', 'bots', 'buildstats',
205cb93a386Sopenharmony_ci                             'buildstats_flutter.py')
206cb93a386Sopenharmony_ci      config = "skia_in_flutter"
207cb93a386Sopenharmony_ci      lib_name = "libflutter.so"
208cb93a386Sopenharmony_ci      step_data = api.run(api.python, 'Analyze flutter', script=script,
209cb93a386Sopenharmony_ci                         args=[stripped, out_dir, keystr, propstr, bloaty_exe,
210cb93a386Sopenharmony_ci                               f, config, TOTAL_SIZE_BYTES_KEY, lib_name,
211cb93a386Sopenharmony_ci                               MAGIC_SEPERATOR],
212cb93a386Sopenharmony_ci                         stdout=api.raw_io.output())
213cb93a386Sopenharmony_ci      if step_data and step_data.stdout:
214cb93a386Sopenharmony_ci        sections = step_data.stdout.decode('utf-8').split(MAGIC_SEPERATOR)
215cb93a386Sopenharmony_ci        result = api.step.active_result
216cb93a386Sopenharmony_ci        logs = result.presentation.logs
217cb93a386Sopenharmony_ci        # Skip section 0 because it's everything before first print,
218cb93a386Sopenharmony_ci        # which is probably the empty string.
219cb93a386Sopenharmony_ci        logs['bloaty_file_symbol_short'] = sections[1].split('\n')
220cb93a386Sopenharmony_ci        logs['bloaty_file_symbol_full']  = sections[2].split('\n')
221cb93a386Sopenharmony_ci        logs['bloaty_symbol_file_short'] = sections[3].split('\n')
222cb93a386Sopenharmony_ci        logs['bloaty_symbol_file_full']  = sections[4].split('\n')
223cb93a386Sopenharmony_ci        logs['perf_json'] = sections[5].split('\n')
224cb93a386Sopenharmony_ci
225cb93a386Sopenharmony_ci        add_binary_size_output_property(result, lib_name, (
226cb93a386Sopenharmony_ci            ast.literal_eval(sections[5])
227cb93a386Sopenharmony_ci              .get('results', {})
228cb93a386Sopenharmony_ci              .get(lib_name, {})
229cb93a386Sopenharmony_ci              .get(config, {})
230cb93a386Sopenharmony_ci              .get(TOTAL_SIZE_BYTES_KEY, {})))
231cb93a386Sopenharmony_ci
232cb93a386Sopenharmony_ci
233cb93a386Sopenharmony_ci# Get the size of skia in flutter and a few metrics from bloaty
234cb93a386Sopenharmony_cidef analyze_wasm_file(api, checkout_root, out_dir, files):
235cb93a386Sopenharmony_ci  (keystr, propstr) = keys_and_props(api)
236cb93a386Sopenharmony_ci  bloaty_exe = api.path['start_dir'].join('bloaty', 'bloaty')
237cb93a386Sopenharmony_ci
238cb93a386Sopenharmony_ci  for f in files:
239cb93a386Sopenharmony_ci
240cb93a386Sopenharmony_ci    skia_dir = checkout_root.join('skia')
241cb93a386Sopenharmony_ci    with api.context(cwd=skia_dir):
242cb93a386Sopenharmony_ci      script = skia_dir.join('infra', 'bots', 'buildstats',
243cb93a386Sopenharmony_ci                             'buildstats_wasm.py')
244cb93a386Sopenharmony_ci      step_data = api.run(api.python, 'Analyze wasm', script=script,
245cb93a386Sopenharmony_ci                          args=[f, out_dir, keystr, propstr, bloaty_exe,
246cb93a386Sopenharmony_ci                                TOTAL_SIZE_BYTES_KEY, MAGIC_SEPERATOR],
247cb93a386Sopenharmony_ci                          stdout=api.raw_io.output())
248cb93a386Sopenharmony_ci      if step_data and step_data.stdout:
249cb93a386Sopenharmony_ci        sections = step_data.stdout.decode('utf-8').split(MAGIC_SEPERATOR)
250cb93a386Sopenharmony_ci        result = api.step.active_result
251cb93a386Sopenharmony_ci        logs = result.presentation.logs
252cb93a386Sopenharmony_ci        # Skip section 0 because it's everything before first print,
253cb93a386Sopenharmony_ci        # which is probably the empty string.
254cb93a386Sopenharmony_ci        logs['bloaty_symbol_short'] = sections[1].split('\n')
255cb93a386Sopenharmony_ci        logs['bloaty_symbol_full']  = sections[2].split('\n')
256cb93a386Sopenharmony_ci        logs['perf_json']           = sections[3].split('\n')
257cb93a386Sopenharmony_ci        add_binary_size_output_property(result, api.path.basename(f), (
258cb93a386Sopenharmony_ci            ast.literal_eval(str(sections[3]))
259cb93a386Sopenharmony_ci                .get('results', {})
260cb93a386Sopenharmony_ci                .get(api.path.basename(f), {})
261cb93a386Sopenharmony_ci                .get('default', {})
262cb93a386Sopenharmony_ci                .get(TOTAL_SIZE_BYTES_KEY, {})))
263cb93a386Sopenharmony_ci
264cb93a386Sopenharmony_ci
265cb93a386Sopenharmony_ci# make a zip file containing an HTML treemap of the files
266cb93a386Sopenharmony_cidef make_treemap(api, checkout_root, out_dir, files):
267cb93a386Sopenharmony_ci  for f in files:
268cb93a386Sopenharmony_ci    env = {'DOCKER_CONFIG': '/home/chrome-bot/.docker'}
269cb93a386Sopenharmony_ci    with api.env(env):
270cb93a386Sopenharmony_ci      skia_dir = checkout_root.join('skia')
271cb93a386Sopenharmony_ci      with api.context(cwd=skia_dir):
272cb93a386Sopenharmony_ci        script = skia_dir.join('infra', 'bots', 'buildstats',
273cb93a386Sopenharmony_ci                               'make_treemap.py')
274cb93a386Sopenharmony_ci        api.run(api.python, 'Make code size treemap %s' % f,
275cb93a386Sopenharmony_ci                             script=script,
276cb93a386Sopenharmony_ci                             args=[f, out_dir],
277cb93a386Sopenharmony_ci                             stdout=api.raw_io.output())
278cb93a386Sopenharmony_ci
279cb93a386Sopenharmony_ci
280cb93a386Sopenharmony_cidef GenTests(api):
281cb93a386Sopenharmony_ci  builder = 'BuildStats-Debian10-EMCC-wasm-Release-PathKit'
282cb93a386Sopenharmony_ci  yield (
283cb93a386Sopenharmony_ci    api.test('normal_bot') +
284cb93a386Sopenharmony_ci    api.properties(buildername=builder,
285cb93a386Sopenharmony_ci                   repository='https://skia.googlesource.com/skia.git',
286cb93a386Sopenharmony_ci                   revision='abc123',
287cb93a386Sopenharmony_ci                   swarm_out_dir='[SWARM_OUT_DIR]',
288cb93a386Sopenharmony_ci                   path_config='kitchen') +
289cb93a386Sopenharmony_ci    api.step_data('get swarming bot id',
290cb93a386Sopenharmony_ci        stdout=api.raw_io.output('skia-bot-123')) +
291cb93a386Sopenharmony_ci    api.step_data('get swarming task id',
292cb93a386Sopenharmony_ci        stdout=api.raw_io.output('123456abc')) +
293cb93a386Sopenharmony_ci    api.step_data('Analyze [START_DIR]/build/pathkit.js.mem',
294cb93a386Sopenharmony_ci        stdout=api.raw_io.output(sample_web)) +
295cb93a386Sopenharmony_ci    api.step_data('Analyze [START_DIR]/build/libskia.so',
296cb93a386Sopenharmony_ci        stdout=api.raw_io.output(sample_cpp)) +
297cb93a386Sopenharmony_ci    api.step_data('Analyze wasm',
298cb93a386Sopenharmony_ci        stdout=api.raw_io.output(sample_wasm)) +
299cb93a386Sopenharmony_ci    api.step_data('Analyze flutter',
300cb93a386Sopenharmony_ci          stdout=api.raw_io.output(sample_flutter))
301cb93a386Sopenharmony_ci  )
302cb93a386Sopenharmony_ci
303cb93a386Sopenharmony_ci  yield (
304cb93a386Sopenharmony_ci    api.test('trybot') +
305cb93a386Sopenharmony_ci    api.properties(buildername=builder,
306cb93a386Sopenharmony_ci                   repository='https://skia.googlesource.com/skia.git',
307cb93a386Sopenharmony_ci                   revision='abc123',
308cb93a386Sopenharmony_ci                   swarm_out_dir='[SWARM_OUT_DIR]',
309cb93a386Sopenharmony_ci                   patch_repo='https://skia.googlesource.com/skia.git',
310cb93a386Sopenharmony_ci                   path_config='kitchen') +
311cb93a386Sopenharmony_ci    api.step_data('get swarming bot id',
312cb93a386Sopenharmony_ci        stdout=api.raw_io.output('skia-bot-123')) +
313cb93a386Sopenharmony_ci    api.step_data('get swarming task id',
314cb93a386Sopenharmony_ci        stdout=api.raw_io.output('123456abc')) +
315cb93a386Sopenharmony_ci    api.properties(patch_storage='gerrit') +
316cb93a386Sopenharmony_ci    api.properties.tryserver(
317cb93a386Sopenharmony_ci        buildername=builder,
318cb93a386Sopenharmony_ci        gerrit_project='skia',
319cb93a386Sopenharmony_ci        gerrit_url='https://skia-review.googlesource.com/',
320cb93a386Sopenharmony_ci      ) +
321cb93a386Sopenharmony_ci    api.step_data('Analyze [START_DIR]/build/pathkit.js.mem',
322cb93a386Sopenharmony_ci        stdout=api.raw_io.output(sample_web)) +
323cb93a386Sopenharmony_ci    api.step_data('Analyze [START_DIR]/build/libskia.so',
324cb93a386Sopenharmony_ci        stdout=api.raw_io.output(sample_cpp)) +
325cb93a386Sopenharmony_ci    api.step_data('Analyze wasm',
326cb93a386Sopenharmony_ci        stdout=api.raw_io.output(sample_wasm)) +
327cb93a386Sopenharmony_ci    api.step_data('Analyze flutter',
328cb93a386Sopenharmony_ci          stdout=api.raw_io.output(sample_flutter))
329cb93a386Sopenharmony_ci  )
330cb93a386Sopenharmony_ci
331cb93a386Sopenharmony_cisample_web = """
332cb93a386Sopenharmony_ciReport A
333cb93a386Sopenharmony_ci    Total size: 50 bytes
334cb93a386Sopenharmony_ci#$%^&*
335cb93a386Sopenharmony_ci{
336cb93a386Sopenharmony_ci  "some": "json",
337cb93a386Sopenharmony_ci  "results": {
338cb93a386Sopenharmony_ci    "pathkit.js.mem": {
339cb93a386Sopenharmony_ci      "default": {
340cb93a386Sopenharmony_ci        "total_size_bytes": 7391117,
341cb93a386Sopenharmony_ci        "gzip_size_bytes": 2884841
342cb93a386Sopenharmony_ci      }
343cb93a386Sopenharmony_ci    }
344cb93a386Sopenharmony_ci  }
345cb93a386Sopenharmony_ci}
346cb93a386Sopenharmony_ci"""
347cb93a386Sopenharmony_ci
348cb93a386Sopenharmony_cisample_cpp = """
349cb93a386Sopenharmony_ci#$%^&*
350cb93a386Sopenharmony_ciReport A
351cb93a386Sopenharmony_ci    Total size: 50 bytes
352cb93a386Sopenharmony_ci#$%^&*
353cb93a386Sopenharmony_ci{
354cb93a386Sopenharmony_ci  "some": "json",
355cb93a386Sopenharmony_ci  "results": {
356cb93a386Sopenharmony_ci    "libskia.so": {
357cb93a386Sopenharmony_ci      "default": {
358cb93a386Sopenharmony_ci        "total_size_bytes": 7391117,
359cb93a386Sopenharmony_ci        "gzip_size_bytes": 2884841
360cb93a386Sopenharmony_ci      }
361cb93a386Sopenharmony_ci    }
362cb93a386Sopenharmony_ci  }
363cb93a386Sopenharmony_ci}
364cb93a386Sopenharmony_ci"""
365cb93a386Sopenharmony_ci
366cb93a386Sopenharmony_cisample_wasm = """
367cb93a386Sopenharmony_ci#$%^&*
368cb93a386Sopenharmony_ciReport A
369cb93a386Sopenharmony_ci    Total size: 50 bytes
370cb93a386Sopenharmony_ci#$%^&*
371cb93a386Sopenharmony_ciReport B
372cb93a386Sopenharmony_ci    Total size: 60 bytes
373cb93a386Sopenharmony_ci#$%^&*
374cb93a386Sopenharmony_ci{
375cb93a386Sopenharmony_ci  "some": "json",
376cb93a386Sopenharmony_ci  "results": {
377cb93a386Sopenharmony_ci    "pathkit.wasm": {
378cb93a386Sopenharmony_ci      "default": {
379cb93a386Sopenharmony_ci        "total_size_bytes": 7391117,
380cb93a386Sopenharmony_ci        "gzip_size_bytes": 2884841
381cb93a386Sopenharmony_ci      }
382cb93a386Sopenharmony_ci    }
383cb93a386Sopenharmony_ci  }
384cb93a386Sopenharmony_ci}
385cb93a386Sopenharmony_ci"""
386cb93a386Sopenharmony_ci
387cb93a386Sopenharmony_cisample_flutter = """
388cb93a386Sopenharmony_ci#$%^&*
389cb93a386Sopenharmony_ciReport A
390cb93a386Sopenharmony_ci    Total size: 50 bytes
391cb93a386Sopenharmony_ci#$%^&*
392cb93a386Sopenharmony_ciReport B
393cb93a386Sopenharmony_ci    Total size: 60 bytes
394cb93a386Sopenharmony_ci#$%^&*
395cb93a386Sopenharmony_ciReport C
396cb93a386Sopenharmony_ci    Total size: 70 bytes
397cb93a386Sopenharmony_ci#$%^&*
398cb93a386Sopenharmony_ciReport D
399cb93a386Sopenharmony_ci    Total size: 80 bytes
400cb93a386Sopenharmony_ci#$%^&*
401cb93a386Sopenharmony_ci{
402cb93a386Sopenharmony_ci  "some": "json",
403cb93a386Sopenharmony_ci  "results": {
404cb93a386Sopenharmony_ci    "libflutter.so": {
405cb93a386Sopenharmony_ci      "skia_in_flutter": {
406cb93a386Sopenharmony_ci        "total_size_bytes": 1256676
407cb93a386Sopenharmony_ci      }
408cb93a386Sopenharmony_ci    }
409cb93a386Sopenharmony_ci  }
410cb93a386Sopenharmony_ci}
411cb93a386Sopenharmony_ci"""
412