xref: /aosp_15_r20/external/skia/infra/bots/recipes/test.py (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker# Copyright 2016 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
6*c8dee2aaSAndroid Build Coastguard Worker# Recipe module for Skia Swarming test.
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker
9*c8dee2aaSAndroid Build Coastguard Workerimport json
10*c8dee2aaSAndroid Build Coastguard Worker
11*c8dee2aaSAndroid Build Coastguard WorkerPYTHON_VERSION_COMPATIBILITY = "PY3"
12*c8dee2aaSAndroid Build Coastguard Worker
13*c8dee2aaSAndroid Build Coastguard WorkerDEPS = [
14*c8dee2aaSAndroid Build Coastguard Worker  'env',
15*c8dee2aaSAndroid Build Coastguard Worker  'flavor',
16*c8dee2aaSAndroid Build Coastguard Worker  'recipe_engine/context',
17*c8dee2aaSAndroid Build Coastguard Worker  'recipe_engine/file',
18*c8dee2aaSAndroid Build Coastguard Worker  'recipe_engine/path',
19*c8dee2aaSAndroid Build Coastguard Worker  'recipe_engine/platform',
20*c8dee2aaSAndroid Build Coastguard Worker  'recipe_engine/properties',
21*c8dee2aaSAndroid Build Coastguard Worker  'recipe_engine/raw_io',
22*c8dee2aaSAndroid Build Coastguard Worker  'recipe_engine/step',
23*c8dee2aaSAndroid Build Coastguard Worker  'gold_upload',
24*c8dee2aaSAndroid Build Coastguard Worker  'run',
25*c8dee2aaSAndroid Build Coastguard Worker  'vars',
26*c8dee2aaSAndroid Build Coastguard Worker]
27*c8dee2aaSAndroid Build Coastguard Worker
28*c8dee2aaSAndroid Build Coastguard WorkerDM_JSON = 'dm.json'
29*c8dee2aaSAndroid Build Coastguard Worker
30*c8dee2aaSAndroid Build Coastguard Workerdef test_steps(api):
31*c8dee2aaSAndroid Build Coastguard Worker  """Run the DM test."""
32*c8dee2aaSAndroid Build Coastguard Worker  do_upload = api.properties.get('do_upload') == 'true'
33*c8dee2aaSAndroid Build Coastguard Worker  images = api.properties.get('images') == 'true'
34*c8dee2aaSAndroid Build Coastguard Worker  lotties = api.properties.get('lotties') == 'true'
35*c8dee2aaSAndroid Build Coastguard Worker  resources = api.properties.get('resources') == 'true'
36*c8dee2aaSAndroid Build Coastguard Worker  skps = api.properties.get('skps') == 'true'
37*c8dee2aaSAndroid Build Coastguard Worker  svgs = api.properties.get('svgs') == 'true'
38*c8dee2aaSAndroid Build Coastguard Worker
39*c8dee2aaSAndroid Build Coastguard Worker  api.flavor.install(
40*c8dee2aaSAndroid Build Coastguard Worker      images=images,
41*c8dee2aaSAndroid Build Coastguard Worker      lotties=lotties,
42*c8dee2aaSAndroid Build Coastguard Worker      resources=resources,
43*c8dee2aaSAndroid Build Coastguard Worker      skps=skps,
44*c8dee2aaSAndroid Build Coastguard Worker      svgs=svgs,
45*c8dee2aaSAndroid Build Coastguard Worker  )
46*c8dee2aaSAndroid Build Coastguard Worker
47*c8dee2aaSAndroid Build Coastguard Worker  use_hash_file = False
48*c8dee2aaSAndroid Build Coastguard Worker  if do_upload:
49*c8dee2aaSAndroid Build Coastguard Worker    host_dm_dir = str(api.flavor.host_dirs.dm_dir)
50*c8dee2aaSAndroid Build Coastguard Worker    api.flavor.create_clean_host_dir(api.path.start_dir.joinpath('test'))
51*c8dee2aaSAndroid Build Coastguard Worker    device_dm_dir = str(api.flavor.device_dirs.dm_dir)
52*c8dee2aaSAndroid Build Coastguard Worker    if host_dm_dir != device_dm_dir:
53*c8dee2aaSAndroid Build Coastguard Worker      api.flavor.create_clean_device_dir(device_dm_dir)
54*c8dee2aaSAndroid Build Coastguard Worker
55*c8dee2aaSAndroid Build Coastguard Worker    # Obtain the list of already-generated hashes.
56*c8dee2aaSAndroid Build Coastguard Worker    hash_filename = 'uninteresting_hashes.txt'
57*c8dee2aaSAndroid Build Coastguard Worker
58*c8dee2aaSAndroid Build Coastguard Worker    host_hashes_file = api.vars.tmp_dir.joinpath(hash_filename)
59*c8dee2aaSAndroid Build Coastguard Worker    hashes_file = api.flavor.device_path_join(
60*c8dee2aaSAndroid Build Coastguard Worker        api.flavor.device_dirs.tmp_dir, hash_filename)
61*c8dee2aaSAndroid Build Coastguard Worker    script = api.gold_upload.resource('get_uninteresting_hashes.py')
62*c8dee2aaSAndroid Build Coastguard Worker    api.run(
63*c8dee2aaSAndroid Build Coastguard Worker        api.step,
64*c8dee2aaSAndroid Build Coastguard Worker        'get uninteresting hashes',
65*c8dee2aaSAndroid Build Coastguard Worker        cmd=['python3', script, api.properties['gold_hashes_url'],
66*c8dee2aaSAndroid Build Coastguard Worker              host_hashes_file],
67*c8dee2aaSAndroid Build Coastguard Worker        # If this fails, we want to know about it because it means Gold is down
68*c8dee2aaSAndroid Build Coastguard Worker        # and proceeding onwards would take a very long time, but be hard to notice.
69*c8dee2aaSAndroid Build Coastguard Worker        abort_on_failure=True,
70*c8dee2aaSAndroid Build Coastguard Worker        fail_build_on_failure=True,
71*c8dee2aaSAndroid Build Coastguard Worker        infra_step=True)
72*c8dee2aaSAndroid Build Coastguard Worker
73*c8dee2aaSAndroid Build Coastguard Worker    if api.path.exists(host_hashes_file):
74*c8dee2aaSAndroid Build Coastguard Worker      api.flavor.copy_file_to_device(host_hashes_file, hashes_file)
75*c8dee2aaSAndroid Build Coastguard Worker      use_hash_file = True
76*c8dee2aaSAndroid Build Coastguard Worker
77*c8dee2aaSAndroid Build Coastguard Worker  # Find DM flags.
78*c8dee2aaSAndroid Build Coastguard Worker  args = json.loads(api.properties['dm_flags'])
79*c8dee2aaSAndroid Build Coastguard Worker  props = json.loads(api.properties['dm_properties'])
80*c8dee2aaSAndroid Build Coastguard Worker  args.append('--properties')
81*c8dee2aaSAndroid Build Coastguard Worker  # Map iteration order is arbitrary; in order to maintain a consistent step
82*c8dee2aaSAndroid Build Coastguard Worker  # ordering, sort by key.
83*c8dee2aaSAndroid Build Coastguard Worker  for k in sorted(props.keys()):
84*c8dee2aaSAndroid Build Coastguard Worker    v = props[k]
85*c8dee2aaSAndroid Build Coastguard Worker    if v == '${SWARMING_BOT_ID}':
86*c8dee2aaSAndroid Build Coastguard Worker      v = api.vars.swarming_bot_id
87*c8dee2aaSAndroid Build Coastguard Worker    elif v == '${SWARMING_TASK_ID}':
88*c8dee2aaSAndroid Build Coastguard Worker      v = api.vars.swarming_task_id
89*c8dee2aaSAndroid Build Coastguard Worker    if v != '':
90*c8dee2aaSAndroid Build Coastguard Worker      args.extend([k, v])
91*c8dee2aaSAndroid Build Coastguard Worker
92*c8dee2aaSAndroid Build Coastguard Worker  # Paths to required resources.
93*c8dee2aaSAndroid Build Coastguard Worker  if resources:
94*c8dee2aaSAndroid Build Coastguard Worker    args.extend(['--resourcePath', api.flavor.device_dirs.resource_dir])
95*c8dee2aaSAndroid Build Coastguard Worker  if skps:
96*c8dee2aaSAndroid Build Coastguard Worker    args.extend(['--skps', api.flavor.device_dirs.skp_dir])
97*c8dee2aaSAndroid Build Coastguard Worker  if images:
98*c8dee2aaSAndroid Build Coastguard Worker    args.extend([
99*c8dee2aaSAndroid Build Coastguard Worker        '--images', api.flavor.device_path_join(
100*c8dee2aaSAndroid Build Coastguard Worker            api.flavor.device_dirs.images_dir, 'dm'),
101*c8dee2aaSAndroid Build Coastguard Worker        '--colorImages', api.flavor.device_path_join(
102*c8dee2aaSAndroid Build Coastguard Worker            api.flavor.device_dirs.images_dir, 'colorspace'),
103*c8dee2aaSAndroid Build Coastguard Worker    ])
104*c8dee2aaSAndroid Build Coastguard Worker  if svgs:
105*c8dee2aaSAndroid Build Coastguard Worker    # svg_dir is the root of the SVG corpus. Within that directory,
106*c8dee2aaSAndroid Build Coastguard Worker    # the *.svg inputs are in the 'svg' subdirectory. See skbug.com/11229
107*c8dee2aaSAndroid Build Coastguard Worker    args.extend(['--svgs', api.flavor.device_path_join(
108*c8dee2aaSAndroid Build Coastguard Worker      api.flavor.device_dirs.svg_dir, "svg")])
109*c8dee2aaSAndroid Build Coastguard Worker  if lotties:
110*c8dee2aaSAndroid Build Coastguard Worker    args.extend([
111*c8dee2aaSAndroid Build Coastguard Worker      '--lotties',
112*c8dee2aaSAndroid Build Coastguard Worker      api.flavor.device_path_join(
113*c8dee2aaSAndroid Build Coastguard Worker          api.flavor.device_dirs.resource_dir, 'skottie'),
114*c8dee2aaSAndroid Build Coastguard Worker      api.flavor.device_dirs.lotties_dir,
115*c8dee2aaSAndroid Build Coastguard Worker    ])
116*c8dee2aaSAndroid Build Coastguard Worker  if 'Fontations' in api.vars.builder_cfg.get('extra_config', []):
117*c8dee2aaSAndroid Build Coastguard Worker    args.extend(['--fontTestDataPath', api.flavor.device_dirs.fonts_dir])
118*c8dee2aaSAndroid Build Coastguard Worker
119*c8dee2aaSAndroid Build Coastguard Worker  if use_hash_file:
120*c8dee2aaSAndroid Build Coastguard Worker    args.extend(['--uninterestingHashesFile', hashes_file])
121*c8dee2aaSAndroid Build Coastguard Worker  if do_upload:
122*c8dee2aaSAndroid Build Coastguard Worker    args.extend(['--writePath', api.flavor.device_dirs.dm_dir])
123*c8dee2aaSAndroid Build Coastguard Worker
124*c8dee2aaSAndroid Build Coastguard Worker  # Run DM.
125*c8dee2aaSAndroid Build Coastguard Worker  api.run(api.flavor.step, 'dm', cmd=args, abort_on_failure=False)
126*c8dee2aaSAndroid Build Coastguard Worker
127*c8dee2aaSAndroid Build Coastguard Worker  if do_upload:
128*c8dee2aaSAndroid Build Coastguard Worker    # Copy images and JSON to host machine if needed.
129*c8dee2aaSAndroid Build Coastguard Worker    api.flavor.copy_directory_contents_to_host(
130*c8dee2aaSAndroid Build Coastguard Worker        api.flavor.device_dirs.dm_dir, api.flavor.host_dirs.dm_dir)
131*c8dee2aaSAndroid Build Coastguard Worker    # https://bugs.chromium.org/p/chromium/issues/detail?id=1192611
132*c8dee2aaSAndroid Build Coastguard Worker    if 'Win' not in api.vars.builder_cfg.get('os', ''):
133*c8dee2aaSAndroid Build Coastguard Worker      api.gold_upload.upload()
134*c8dee2aaSAndroid Build Coastguard Worker
135*c8dee2aaSAndroid Build Coastguard Worker
136*c8dee2aaSAndroid Build Coastguard Workerdef RunSteps(api):
137*c8dee2aaSAndroid Build Coastguard Worker  api.vars.setup()
138*c8dee2aaSAndroid Build Coastguard Worker  api.file.ensure_directory('makedirs tmp_dir', api.vars.tmp_dir)
139*c8dee2aaSAndroid Build Coastguard Worker  api.flavor.setup('dm')
140*c8dee2aaSAndroid Build Coastguard Worker
141*c8dee2aaSAndroid Build Coastguard Worker  try:
142*c8dee2aaSAndroid Build Coastguard Worker    test_steps(api)
143*c8dee2aaSAndroid Build Coastguard Worker  finally:
144*c8dee2aaSAndroid Build Coastguard Worker    api.flavor.cleanup_steps()
145*c8dee2aaSAndroid Build Coastguard Worker  api.run.check_failure()
146*c8dee2aaSAndroid Build Coastguard Worker
147*c8dee2aaSAndroid Build Coastguard Worker
148*c8dee2aaSAndroid Build Coastguard WorkerTEST_BUILDERS = [
149*c8dee2aaSAndroid Build Coastguard Worker  'Test-Android-Clang-Pixel2XL-GPU-Adreno540-arm-Debug-All-Android_ASAN',
150*c8dee2aaSAndroid Build Coastguard Worker  'Test-Android-Clang-Pixel2XL-GPU-Adreno540-arm64-Debug-All-Android',
151*c8dee2aaSAndroid Build Coastguard Worker  'Test-Debian10-Clang-GCE-CPU-AVX2-x86_64-Release-All-Lottie',
152*c8dee2aaSAndroid Build Coastguard Worker  'Test-Win10-Clang-ShuttleC-GPU-GTX960-x86_64-Debug-All-ANGLE',
153*c8dee2aaSAndroid Build Coastguard Worker  'Test-Debian10-Clang-GCE-CPU-AVX2-x86_64-Debug-All-Fontations',
154*c8dee2aaSAndroid Build Coastguard Worker]
155*c8dee2aaSAndroid Build Coastguard Worker
156*c8dee2aaSAndroid Build Coastguard Worker
157*c8dee2aaSAndroid Build Coastguard Workerdef GenTests(api):
158*c8dee2aaSAndroid Build Coastguard Worker  for builder in TEST_BUILDERS:
159*c8dee2aaSAndroid Build Coastguard Worker    props = dict(
160*c8dee2aaSAndroid Build Coastguard Worker      buildername=builder,
161*c8dee2aaSAndroid Build Coastguard Worker      buildbucket_build_id='123454321',
162*c8dee2aaSAndroid Build Coastguard Worker      dm_flags='["dm","--example","--flags"]',
163*c8dee2aaSAndroid Build Coastguard Worker      dm_properties=('{"key1":"value1","key2":"",'
164*c8dee2aaSAndroid Build Coastguard Worker                     '"bot":"${SWARMING_BOT_ID}",'
165*c8dee2aaSAndroid Build Coastguard Worker                     '"task":"${SWARMING_TASK_ID}"}'),
166*c8dee2aaSAndroid Build Coastguard Worker      revision='abc123',
167*c8dee2aaSAndroid Build Coastguard Worker      gs_bucket='skia-infra-gm',
168*c8dee2aaSAndroid Build Coastguard Worker      patch_ref='89/456789/12',
169*c8dee2aaSAndroid Build Coastguard Worker      patch_set=7,
170*c8dee2aaSAndroid Build Coastguard Worker      patch_issue=1234,
171*c8dee2aaSAndroid Build Coastguard Worker      path_config='kitchen',
172*c8dee2aaSAndroid Build Coastguard Worker      gold_hashes_url='https://example.com/hashes.txt',
173*c8dee2aaSAndroid Build Coastguard Worker      swarm_out_dir='[SWARM_OUT_DIR]',
174*c8dee2aaSAndroid Build Coastguard Worker      task_id='task_12345',
175*c8dee2aaSAndroid Build Coastguard Worker      resources='true',
176*c8dee2aaSAndroid Build Coastguard Worker    )
177*c8dee2aaSAndroid Build Coastguard Worker    if 'ASAN' not in builder:
178*c8dee2aaSAndroid Build Coastguard Worker      props['do_upload'] = 'true'
179*c8dee2aaSAndroid Build Coastguard Worker    if 'Lottie' in builder:
180*c8dee2aaSAndroid Build Coastguard Worker      props['lotties'] = 'true'
181*c8dee2aaSAndroid Build Coastguard Worker    else:
182*c8dee2aaSAndroid Build Coastguard Worker      props['images'] = 'true'
183*c8dee2aaSAndroid Build Coastguard Worker      props['skps'] = 'true'
184*c8dee2aaSAndroid Build Coastguard Worker      props['svgs'] = 'true'
185*c8dee2aaSAndroid Build Coastguard Worker    test = (
186*c8dee2aaSAndroid Build Coastguard Worker      api.test(builder) +
187*c8dee2aaSAndroid Build Coastguard Worker      api.properties(**props) +
188*c8dee2aaSAndroid Build Coastguard Worker      api.path.exists(
189*c8dee2aaSAndroid Build Coastguard Worker          api.path.start_dir.joinpath('skia'),
190*c8dee2aaSAndroid Build Coastguard Worker          api.path.start_dir.joinpath('skia', 'infra', 'bots', 'assets',
191*c8dee2aaSAndroid Build Coastguard Worker                                      'skimage', 'VERSION'),
192*c8dee2aaSAndroid Build Coastguard Worker          api.path.start_dir.joinpath('skia', 'infra', 'bots', 'assets',
193*c8dee2aaSAndroid Build Coastguard Worker                                      'skp', 'VERSION'),
194*c8dee2aaSAndroid Build Coastguard Worker          api.path.start_dir.joinpath('skia', 'infra', 'bots', 'assets',
195*c8dee2aaSAndroid Build Coastguard Worker                                      'svg', 'VERSION'),
196*c8dee2aaSAndroid Build Coastguard Worker          api.path.start_dir.joinpath('tmp', 'uninteresting_hashes.txt')
197*c8dee2aaSAndroid Build Coastguard Worker      ) +
198*c8dee2aaSAndroid Build Coastguard Worker      api.step_data('get swarming bot id',
199*c8dee2aaSAndroid Build Coastguard Worker          stdout=api.raw_io.output('skia-bot-123')) +
200*c8dee2aaSAndroid Build Coastguard Worker      api.step_data('get swarming task id',
201*c8dee2aaSAndroid Build Coastguard Worker          stdout=api.raw_io.output('123456'))
202*c8dee2aaSAndroid Build Coastguard Worker    )
203*c8dee2aaSAndroid Build Coastguard Worker    if 'Win' in builder:
204*c8dee2aaSAndroid Build Coastguard Worker      test += api.platform('win', 64)
205*c8dee2aaSAndroid Build Coastguard Worker
206*c8dee2aaSAndroid Build Coastguard Worker    yield test
207