blob: 6e58cf634e251f5a2ef9ed8fdb0934f60d18540e [file] [log] [blame]
Vladimir Markoc716cb82021-04-23 10:11:44 +00001#!/usr/bin/env python3
Roland Levillain29e740f2019-08-20 15:31:37 +01002# -*- coding: utf-8 -*-
Andreas Gampe2c846cd2019-01-29 22:06:46 +00003
4# Copyright (C) 2019 The Android Open Source Project
5#
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17#
18
19import argparse
Martin Stjernholm84a32cd2019-03-29 16:39:46 +000020import fnmatch
Andreas Gampe2c846cd2019-01-29 22:06:46 +000021import logging
22import os
Martin Stjernholm84a32cd2019-03-29 16:39:46 +000023import os.path
Martin Stjernholm571a6be2021-05-25 01:16:53 +010024import shutil
Andreas Gampe2c846cd2019-01-29 22:06:46 +000025import subprocess
26import sys
27import zipfile
28
29logging.basicConfig(format='%(message)s')
30
Orion Hodsonaf3ed622019-10-03 16:30:54 +010031# Flavors of ART APEX package.
32FLAVOR_RELEASE = 'release'
33FLAVOR_DEBUG = 'debug'
34FLAVOR_TESTING = 'testing'
35FLAVOR_AUTO = 'auto'
36FLAVORS_ALL = [FLAVOR_RELEASE, FLAVOR_DEBUG, FLAVOR_TESTING, FLAVOR_AUTO]
37
38# Bitness options for APEX package
39BITNESS_32 = '32'
40BITNESS_64 = '64'
41BITNESS_MULTILIB = 'multilib'
42BITNESS_AUTO = 'auto'
43BITNESS_ALL = [BITNESS_32, BITNESS_64, BITNESS_MULTILIB, BITNESS_AUTO]
44
Roland Levillain61f07162019-06-26 12:44:04 +010045# Architectures supported by APEX packages.
Victor Hsieh52f7f632021-09-24 11:50:55 -070046ARCHS_32 = ["arm", "x86"]
47ARCHS_64 = ["arm64", "x86_64"]
48
49# Multilib options
50MULTILIB_32 = '32'
51MULTILIB_64 = '64'
52MULTILIB_BOTH = 'both'
53MULTILIB_FIRST = 'first'
Orion Hodsonaf3ed622019-10-03 16:30:54 +010054
Martin Stjernholme58624f2019-09-20 15:53:40 +010055# Directory containing ART tests within an ART APEX (if the package includes
Roland Levillain61f07162019-06-26 12:44:04 +010056# any). ART test executables are installed in `bin/art/<arch>`. Segregating
57# tests by architecture is useful on devices supporting more than one
Martin Stjernholme58624f2019-09-20 15:53:40 +010058# architecture, as it permits testing all of them using a single ART APEX
Roland Levillain61f07162019-06-26 12:44:04 +010059# package.
Orion Hodsonaf3ed622019-10-03 16:30:54 +010060ART_TEST_DIR = 'bin/art'
Luca Stefani4e91ee92019-03-06 15:08:16 +010061
Ulya Trafimovich7b0df592020-01-03 13:29:00 +000062
63# Test if a given variable is set to a string "true".
64def isEnvTrue(var):
65 return var in os.environ and os.environ[var] == 'true'
66
67
Dennis Shenc2320492022-11-02 16:03:42 +000068def extract_apex(apex_path, deapexer_path, debugfs_path, fsckerofs_path,
69 blkid_path, tmpdir):
Martin Stjernholm571a6be2021-05-25 01:16:53 +010070 _, apex_name = os.path.split(apex_path)
71 extract_path = os.path.join(tmpdir, apex_name)
72 if os.path.exists(extract_path):
73 shutil.rmtree(extract_path)
74 subprocess.check_call([deapexer_path, '--debugfs', debugfs_path,
Dennis Shenc2320492022-11-02 16:03:42 +000075 '--fsckerofs', fsckerofs_path, '--blkid', blkid_path,
Martin Stjernholm571a6be2021-05-25 01:16:53 +010076 'extract', apex_path, extract_path],
77 stdout=subprocess.DEVNULL)
78 return extract_path
79
80
Andreas Gampe2c846cd2019-01-29 22:06:46 +000081class FSObject:
Roland Levillain88e55692019-07-25 15:57:06 +010082 def __init__(self, name, is_dir, is_exec, is_symlink, size):
Andreas Gampe2c846cd2019-01-29 22:06:46 +000083 self.name = name
84 self.is_dir = is_dir
85 self.is_exec = is_exec
86 self.is_symlink = is_symlink
Roland Levillain88e55692019-07-25 15:57:06 +010087 self.size = size
Luca Stefani4e91ee92019-03-06 15:08:16 +010088
Andreas Gampe2c846cd2019-01-29 22:06:46 +000089 def __str__(self):
Roland Levillain88e55692019-07-25 15:57:06 +010090 return '%s(dir=%r,exec=%r,symlink=%r,size=%d)' \
91 % (self.name, self.is_dir, self.is_exec, self.is_symlink, self.size)
Andreas Gampe2c846cd2019-01-29 22:06:46 +000092
Luca Stefani4e91ee92019-03-06 15:08:16 +010093
Andreas Gampe2c846cd2019-01-29 22:06:46 +000094class TargetApexProvider:
Roland Levillaindd20d002019-07-19 16:09:47 +010095 def __init__(self, apex):
96 self._folder_cache = {}
97 self._apex = apex
98
99 def get(self, path):
100 apex_dir, name = os.path.split(path)
101 if not apex_dir:
102 apex_dir = '.'
103 apex_map = self.read_dir(apex_dir)
104 return apex_map[name] if name in apex_map else None
105
106 def read_dir(self, apex_dir):
107 if apex_dir in self._folder_cache:
108 return self._folder_cache[apex_dir]
109 apex_map = {}
110 dirname = os.path.join(self._apex, apex_dir)
111 if os.path.exists(dirname):
112 for basename in os.listdir(dirname):
113 filepath = os.path.join(dirname, basename)
114 is_dir = os.path.isdir(filepath)
115 is_exec = os.access(filepath, os.X_OK)
116 is_symlink = os.path.islink(filepath)
Roland Levillain3cd802e2020-02-20 15:31:20 +0000117 if is_symlink:
118 # Report the length of the symlink's target's path as file size, like `ls`.
119 size = len(os.readlink(filepath))
120 else:
121 size = os.path.getsize(filepath)
Roland Levillain88e55692019-07-25 15:57:06 +0100122 apex_map[basename] = FSObject(basename, is_dir, is_exec, is_symlink, size)
Roland Levillaindd20d002019-07-19 16:09:47 +0100123 self._folder_cache[apex_dir] = apex_map
124 return apex_map
125
126
Andreas Gampe09123952019-01-30 13:17:02 -0800127class HostApexProvider:
128 def __init__(self, apex, tmpdir):
129 self._tmpdir = tmpdir
Roland Levillain77251f92019-08-09 15:00:04 +0100130 self._folder_cache = {}
Andreas Gampe09123952019-01-30 13:17:02 -0800131 self._payload = os.path.join(self._tmpdir, 'apex_payload.zip')
132 # Extract payload to tmpdir.
Luca Stefani4e91ee92019-03-06 15:08:16 +0100133 apex_zip = zipfile.ZipFile(apex)
134 apex_zip.extract('apex_payload.zip', tmpdir)
Andreas Gampe09123952019-01-30 13:17:02 -0800135
136 def __del__(self):
137 # Delete temps.
138 if os.path.exists(self._payload):
139 os.remove(self._payload)
140
141 def get(self, path):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100142 apex_dir, name = os.path.split(path)
143 if not apex_dir:
144 apex_dir = ''
145 apex_map = self.read_dir(apex_dir)
146 return apex_map[name] if name in apex_map else None
Andreas Gampe09123952019-01-30 13:17:02 -0800147
Luca Stefani4e91ee92019-03-06 15:08:16 +0100148 def read_dir(self, apex_dir):
Roland Levillain77251f92019-08-09 15:00:04 +0100149 if apex_dir in self._folder_cache:
150 return self._folder_cache[apex_dir]
151 if not self._folder_cache:
Andreas Gampe09123952019-01-30 13:17:02 -0800152 self.parse_zip()
Roland Levillain77251f92019-08-09 15:00:04 +0100153 if apex_dir in self._folder_cache:
154 return self._folder_cache[apex_dir]
Andreas Gampe09123952019-01-30 13:17:02 -0800155 return {}
156
157 def parse_zip(self):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100158 apex_zip = zipfile.ZipFile(self._payload)
159 infos = apex_zip.infolist()
Andreas Gampe09123952019-01-30 13:17:02 -0800160 for zipinfo in infos:
161 path = zipinfo.filename
162
163 # Assume no empty file is stored.
164 assert path
165
166 def get_octal(val, index):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100167 return (val >> (index * 3)) & 0x7
168
Andreas Gampe09123952019-01-30 13:17:02 -0800169 def bits_is_exec(val):
170 # TODO: Enforce group/other, too?
171 return get_octal(val, 2) & 1 == 1
172
173 is_zipinfo = True
174 while path:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100175 apex_dir, base = os.path.split(path)
Andreas Gampe09123952019-01-30 13:17:02 -0800176 # TODO: If directories are stored, base will be empty.
177
Roland Levillain77251f92019-08-09 15:00:04 +0100178 if apex_dir not in self._folder_cache:
179 self._folder_cache[apex_dir] = {}
180 dir_map = self._folder_cache[apex_dir]
Luca Stefani4e91ee92019-03-06 15:08:16 +0100181 if base not in dir_map:
Andreas Gampe09123952019-01-30 13:17:02 -0800182 if is_zipinfo:
183 bits = (zipinfo.external_attr >> 16) & 0xFFFF
184 is_dir = get_octal(bits, 4) == 4
185 is_symlink = get_octal(bits, 4) == 2
186 is_exec = bits_is_exec(bits)
Roland Levillain88e55692019-07-25 15:57:06 +0100187 size = zipinfo.file_size
Andreas Gampe09123952019-01-30 13:17:02 -0800188 else:
189 is_exec = False # Seems we can't get this easily?
190 is_symlink = False
191 is_dir = True
Roland Levillain88e55692019-07-25 15:57:06 +0100192 # Use a negative value as an indicator of undefined/unknown size.
193 size = -1
194 dir_map[base] = FSObject(base, is_dir, is_exec, is_symlink, size)
Andreas Gampe09123952019-01-30 13:17:02 -0800195 is_zipinfo = False
Luca Stefani4e91ee92019-03-06 15:08:16 +0100196 path = apex_dir
197
Andreas Gampe09123952019-01-30 13:17:02 -0800198
Andreas Gampeeb555b82019-01-30 14:47:49 -0800199# DO NOT USE DIRECTLY! This is an "abstract" base class.
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000200class Checker:
201 def __init__(self, provider):
202 self._provider = provider
203 self._errors = 0
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000204 self._expected_file_globs = set()
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000205
Luca Stefani4e91ee92019-03-06 15:08:16 +0100206 def fail(self, msg, *fail_args):
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000207 self._errors += 1
Martin Stjernholm2babede2019-03-18 21:04:49 +0000208 logging.error(msg, *fail_args)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000209
210 def error_count(self):
211 return self._errors
Luca Stefani4e91ee92019-03-06 15:08:16 +0100212
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800213 def reset_errors(self):
214 self._errors = 0
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000215
Martin Stjernholm2babede2019-03-18 21:04:49 +0000216 def is_file(self, path):
217 fs_object = self._provider.get(path)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000218 if fs_object is None:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100219 return False, 'Could not find %s'
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000220 if fs_object.is_dir:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100221 return False, '%s is a directory'
Roland Levillaina79a6eb2022-05-20 00:05:07 +0100222 if fs_object.is_symlink:
223 return False, '%s is a symlink'
Luca Stefani4e91ee92019-03-06 15:08:16 +0100224 return True, ''
Andreas Gampea0242cf2019-01-29 13:01:23 -0800225
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000226 def is_dir(self, path):
227 fs_object = self._provider.get(path)
228 if fs_object is None:
229 return False, 'Could not find %s'
230 if not fs_object.is_dir:
231 return False, '%s is not a directory'
232 return True, ''
233
Martin Stjernholm2babede2019-03-18 21:04:49 +0000234 def check_file(self, path):
235 ok, msg = self.is_file(path)
236 if not ok:
237 self.fail(msg, path)
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000238 self._expected_file_globs.add(path)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000239 return ok
Luca Stefani4e91ee92019-03-06 15:08:16 +0100240
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000241 def check_executable(self, filename):
Martin Stjernholm2babede2019-03-18 21:04:49 +0000242 path = 'bin/%s' % filename
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000243 if not self.check_file(path):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100244 return
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000245 if not self._provider.get(path).is_exec:
246 self.fail('%s is not executable', path)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000247
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000248 def check_executable_symlink(self, filename):
Martin Stjernholm2babede2019-03-18 21:04:49 +0000249 path = 'bin/%s' % filename
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000250 fs_object = self._provider.get(path)
251 if fs_object is None:
252 self.fail('Could not find %s', path)
Luca Stefani4e91ee92019-03-06 15:08:16 +0100253 return
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000254 if fs_object.is_dir:
255 self.fail('%s is a directory', path)
Luca Stefani4e91ee92019-03-06 15:08:16 +0100256 return
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000257 if not fs_object.is_symlink:
258 self.fail('%s is not a symlink', path)
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000259 self._expected_file_globs.add(path)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000260
Victor Hsieh52f7f632021-09-24 11:50:55 -0700261 def arch_dirs_for_path(self, path, multilib=None):
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000262 # Look for target-specific subdirectories for the given directory path.
263 # This is needed because the list of build targets is not propagated
264 # to this script.
Ulyana Trafimovich0f7c7922019-11-07 16:12:09 +0000265 #
Roland Levillain48136182019-11-15 13:39:03 +0000266 # TODO(b/123602136): Pass build target information to this script and fix
267 # all places where this function in used (or similar workarounds).
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000268 dirs = []
Victor Hsieh52f7f632021-09-24 11:50:55 -0700269 for arch in self.possible_archs(multilib):
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000270 dir = '%s/%s' % (path, arch)
271 found, _ = self.is_dir(dir)
272 if found:
273 dirs.append(dir)
274 return dirs
275
Victor Hsieh52f7f632021-09-24 11:50:55 -0700276 def check_art_test_executable(self, filename, multilib=None):
277 dirs = self.arch_dirs_for_path(ART_TEST_DIR, multilib)
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000278 if not dirs:
Martin Stjernholmafb029f2022-06-10 20:42:47 +0100279 self.fail('Directories for ART test binary missing: %s', filename)
280 return
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000281 for dir in dirs:
282 test_path = '%s/%s' % (dir, filename)
283 self._expected_file_globs.add(test_path)
Martin Stjernholmafb029f2022-06-10 20:42:47 +0100284 file_obj = self._provider.get(test_path)
285 if not file_obj:
286 self.fail('ART test binary missing: %s', test_path)
287 elif not file_obj.is_exec:
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000288 self.fail('%s is not executable', test_path)
Roland Levillain61f07162019-06-26 12:44:04 +0100289
David Srbecky4a88a5a2020-05-05 16:21:57 +0100290 def check_art_test_data(self, filename):
291 dirs = self.arch_dirs_for_path(ART_TEST_DIR)
292 if not dirs:
Martin Stjernholmafb029f2022-06-10 20:42:47 +0100293 self.fail('Directories for ART test data missing: %s', filename)
294 return
David Srbecky4a88a5a2020-05-05 16:21:57 +0100295 for dir in dirs:
296 if not self.check_file('%s/%s' % (dir, filename)):
297 return
298
Martin Stjernholm2babede2019-03-18 21:04:49 +0000299 def check_single_library(self, filename):
300 lib_path = 'lib/%s' % filename
301 lib64_path = 'lib64/%s' % filename
302 lib_is_file, _ = self.is_file(lib_path)
303 if lib_is_file:
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000304 self._expected_file_globs.add(lib_path)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000305 lib64_is_file, _ = self.is_file(lib64_path)
306 if lib64_is_file:
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000307 self._expected_file_globs.add(lib64_path)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000308 if not lib_is_file and not lib64_is_file:
309 self.fail('Library missing: %s', filename)
Andreas Gampea0242cf2019-01-29 13:01:23 -0800310
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000311 def check_dexpreopt(self, basename):
312 dirs = self.arch_dirs_for_path('javalib')
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000313 for dir in dirs:
Tim Joinesbe50bc32020-03-18 18:00:41 +0000314 for ext in ['art', 'oat', 'vdex']:
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000315 self.check_file('%s/%s.%s' % (dir, basename, ext))
316
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000317 def check_java_library(self, basename):
318 return self.check_file('javalib/%s.jar' % basename)
Andreas Gampe09123952019-01-30 13:17:02 -0800319
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000320 def ignore_path(self, path_glob):
321 self._expected_file_globs.add(path_glob)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000322
Roland Levillain61f07162019-06-26 12:44:04 +0100323 def check_optional_art_test_executable(self, filename):
Victor Hsieh52f7f632021-09-24 11:50:55 -0700324 for arch in self.possible_archs():
Orion Hodsonaf3ed622019-10-03 16:30:54 +0100325 self.ignore_path('%s/%s/%s' % (ART_TEST_DIR, arch, filename))
Roland Levillain61f07162019-06-26 12:44:04 +0100326
Martin Stjernholm2babede2019-03-18 21:04:49 +0000327 def check_no_superfluous_files(self, dir_path):
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000328 paths = []
Martin Stjernholm2babede2019-03-18 21:04:49 +0000329 for name in sorted(self._provider.read_dir(dir_path).keys()):
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000330 if name not in ('.', '..'):
331 paths.append(os.path.join(dir_path, name))
332 expected_paths = set()
333 dir_prefix = dir_path + '/'
334 for path_glob in self._expected_file_globs:
335 expected_paths |= set(fnmatch.filter(paths, path_glob))
336 # If there are globs in subdirectories of dir_path we want to match their
337 # path segments at this directory level.
338 if path_glob.startswith(dir_prefix):
339 subpath = path_glob[len(dir_prefix):]
340 subpath_first_segment, _, _ = subpath.partition('/')
341 expected_paths |= set(fnmatch.filter(paths, dir_prefix + subpath_first_segment))
342 for unexpected_path in set(paths) - expected_paths:
343 self.fail('Unexpected file \'%s\'', unexpected_path)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000344
Andreas Gampeeb555b82019-01-30 14:47:49 -0800345 # Just here for docs purposes, even if it isn't good Python style.
346
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000347 def check_symlinked_multilib_executable(self, filename):
348 """Check bin/filename32, and/or bin/filename64, with symlink bin/filename."""
Andreas Gampeeb555b82019-01-30 14:47:49 -0800349 raise NotImplementedError
350
Nicolas Geoffrayd68580e2020-04-15 16:52:32 +0100351 def check_symlinked_first_executable(self, filename):
352 """Check bin/filename32, and/or bin/filename64, with symlink bin/filename."""
353 raise NotImplementedError
354
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000355 def check_native_library(self, basename):
356 """Check lib/basename.so, and/or lib64/basename.so."""
Martin Stjernholm2babede2019-03-18 21:04:49 +0000357 raise NotImplementedError
358
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000359 def check_optional_native_library(self, basename_glob):
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000360 """Allow lib/basename.so and/or lib64/basename.so to exist."""
Martin Stjernholmb81fe232019-03-25 17:38:04 +0000361 raise NotImplementedError
362
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000363 def check_prefer64_library(self, basename):
364 """Check lib64/basename.so, or lib/basename.so on 32 bit only."""
Andreas Gampeeb555b82019-01-30 14:47:49 -0800365 raise NotImplementedError
366
Victor Hsieh52f7f632021-09-24 11:50:55 -0700367 def possible_archs(self, multilib=None):
368 """Returns names of possible archs."""
369 raise NotImplementedError
Andreas Gampeeb555b82019-01-30 14:47:49 -0800370
371class Arch32Checker(Checker):
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000372 def check_symlinked_multilib_executable(self, filename):
373 self.check_executable('%s32' % filename)
374 self.check_executable_symlink(filename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800375
Nicolas Geoffrayd68580e2020-04-15 16:52:32 +0100376 def check_symlinked_first_executable(self, filename):
377 self.check_executable('%s32' % filename)
378 self.check_executable_symlink(filename)
379
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000380 def check_native_library(self, basename):
Andreas Gampeeb555b82019-01-30 14:47:49 -0800381 # TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve
382 # the precision of this test?
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000383 self.check_file('lib/%s.so' % basename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800384
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000385 def check_optional_native_library(self, basename_glob):
386 self.ignore_path('lib/%s.so' % basename_glob)
Martin Stjernholmb81fe232019-03-25 17:38:04 +0000387
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000388 def check_prefer64_library(self, basename):
389 self.check_native_library(basename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800390
Victor Hsieh52f7f632021-09-24 11:50:55 -0700391 def possible_archs(self, multilib=None):
392 return ARCHS_32
Andreas Gampeeb555b82019-01-30 14:47:49 -0800393
394class Arch64Checker(Checker):
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000395 def check_symlinked_multilib_executable(self, filename):
396 self.check_executable('%s64' % filename)
397 self.check_executable_symlink(filename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800398
Nicolas Geoffrayd68580e2020-04-15 16:52:32 +0100399 def check_symlinked_first_executable(self, filename):
400 self.check_executable('%s64' % filename)
401 self.check_executable_symlink(filename)
402
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000403 def check_native_library(self, basename):
Andreas Gampeeb555b82019-01-30 14:47:49 -0800404 # TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve
405 # the precision of this test?
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000406 self.check_file('lib64/%s.so' % basename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800407
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000408 def check_optional_native_library(self, basename_glob):
409 self.ignore_path('lib64/%s.so' % basename_glob)
Martin Stjernholmb81fe232019-03-25 17:38:04 +0000410
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000411 def check_prefer64_library(self, basename):
412 self.check_native_library(basename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800413
Victor Hsieh52f7f632021-09-24 11:50:55 -0700414 def possible_archs(self, multilib=None):
415 return ARCHS_64
416
Andreas Gampeeb555b82019-01-30 14:47:49 -0800417
418class MultilibChecker(Checker):
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000419 def check_symlinked_multilib_executable(self, filename):
420 self.check_executable('%s32' % filename)
421 self.check_executable('%s64' % filename)
422 self.check_executable_symlink(filename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800423
Nicolas Geoffrayd68580e2020-04-15 16:52:32 +0100424 def check_symlinked_first_executable(self, filename):
425 self.check_executable('%s64' % filename)
426 self.check_executable_symlink(filename)
427
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000428 def check_native_library(self, basename):
Andreas Gampeeb555b82019-01-30 14:47:49 -0800429 # TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve
430 # the precision of this test?
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000431 self.check_file('lib/%s.so' % basename)
432 self.check_file('lib64/%s.so' % basename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800433
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000434 def check_optional_native_library(self, basename_glob):
435 self.ignore_path('lib/%s.so' % basename_glob)
436 self.ignore_path('lib64/%s.so' % basename_glob)
Martin Stjernholmb81fe232019-03-25 17:38:04 +0000437
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000438 def check_prefer64_library(self, basename):
439 self.check_file('lib64/%s.so' % basename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800440
Victor Hsieh52f7f632021-09-24 11:50:55 -0700441 def possible_archs(self, multilib=None):
442 if multilib is None or multilib == MULTILIB_BOTH:
443 return ARCHS_32 + ARCHS_64
444 if multilib == MULTILIB_FIRST or multilib == MULTILIB_64:
445 return ARCHS_64
446 elif multilib == MULTILIB_32:
447 return ARCHS_32
448 self.fail('Unrecognized multilib option "%s"', multilib)
449
Andreas Gampeeb555b82019-01-30 14:47:49 -0800450
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800451class ReleaseChecker:
452 def __init__(self, checker):
453 self._checker = checker
Luca Stefani4e91ee92019-03-06 15:08:16 +0100454
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000455 def __str__(self):
456 return 'Release Checker'
457
458 def run(self):
Roland Levillaindf66de02019-11-11 23:22:15 +0000459 # Check the Protocol Buffers APEX manifest.
460 self._checker.check_file('apex_manifest.pb')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000461
Martin Stjernholm77f17662019-04-03 17:08:21 +0100462 # Check binaries for ART.
Martin Stjernholm77f17662019-04-03 17:08:21 +0100463 self._checker.check_executable('dexdump')
464 self._checker.check_executable('dexlist')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000465 self._checker.check_executable('dexoptanalyzer')
466 self._checker.check_executable('profman')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000467 self._checker.check_symlinked_multilib_executable('dalvikvm')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000468
Martin Stjernholm023c2182019-03-28 15:52:32 +0000469 # Check exported libraries for ART.
Martin Stjernholmd3e9ff32021-03-16 00:44:25 +0000470 self._checker.check_native_library('libdexfile')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000471 self._checker.check_native_library('libnativebridge')
472 self._checker.check_native_library('libnativehelper')
473 self._checker.check_native_library('libnativeloader')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000474
475 # Check internal libraries for ART.
476 self._checker.check_native_library('libadbconnection')
477 self._checker.check_native_library('libart')
Dmitrii Ishcheikin00ca1b52022-11-07 19:09:11 +0000478 self._checker.check_native_library('libart-compiler')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000479 self._checker.check_native_library('libart-dexlayout')
Roland Levillain5b768892020-02-19 15:49:02 +0000480 self._checker.check_native_library('libart-disassembler')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000481 self._checker.check_native_library('libartbase')
482 self._checker.check_native_library('libartpalette')
Chris Wailesbefdad42021-01-12 16:37:57 -0800483 self._checker.check_native_library('libarttools')
Roland Levillain3934fe82020-08-20 20:16:42 +0100484 self._checker.check_native_library('libdt_fd_forward')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000485 self._checker.check_native_library('libopenjdkjvm')
486 self._checker.check_native_library('libopenjdkjvmti')
487 self._checker.check_native_library('libprofile')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000488 self._checker.check_native_library('libsigchain')
489
Roland Levillain2af026d2021-06-14 12:25:04 +0100490 # Check Java libraries for Managed Core Library.
Martin Stjernholm023c2182019-03-28 15:52:32 +0000491 self._checker.check_java_library('apache-xml')
492 self._checker.check_java_library('bouncycastle')
493 self._checker.check_java_library('core-libart')
494 self._checker.check_java_library('core-oj')
495 self._checker.check_java_library('okhttp')
Ulya Trafimovich7b0df592020-01-03 13:29:00 +0000496 if isEnvTrue('EMMA_INSTRUMENT_FRAMEWORK'):
497 # In coverage builds jacoco is added to the list of ART apex jars.
498 self._checker.check_java_library('jacocoagent')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000499
500 # Check internal native libraries for Managed Core Library.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000501 self._checker.check_native_library('libjavacore')
502 self._checker.check_native_library('libopenjdk')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000503
Martin Stjernholm2babede2019-03-18 21:04:49 +0000504 # Check internal native library dependencies.
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000505 #
Martin Stjernholm2babede2019-03-18 21:04:49 +0000506 # Any internal dependency not listed here will cause a failure in
507 # NoSuperfluousLibrariesChecker. Internal dependencies are generally just
508 # implementation details, but in the release package we want to track them
509 # because a) they add to the package size and the RAM usage (in particular
510 # if the library is also present in /system or another APEX and hence might
511 # get loaded twice through linker namespace separation), and b) we need to
512 # catch invalid dependencies on /system or other APEXes that should go
513 # through an exported library with stubs (b/128708192 tracks implementing a
514 # better approach for that).
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000515 self._checker.check_native_library('libbase')
516 self._checker.check_native_library('libc++')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000517 self._checker.check_native_library('libdt_socket')
518 self._checker.check_native_library('libjdwp')
Martin Stjernholm2eb1f832020-09-17 00:25:52 +0100519 self._checker.check_native_library('liblz4')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000520 self._checker.check_native_library('liblzma')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000521 self._checker.check_native_library('libnpt')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000522 self._checker.check_native_library('libunwindstack')
Martin Stjernholm2babede2019-03-18 21:04:49 +0000523
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000524 # Allow extra dependencies that appear in ASAN builds.
525 self._checker.check_optional_native_library('libclang_rt.asan*')
526 self._checker.check_optional_native_library('libclang_rt.hwasan*')
527 self._checker.check_optional_native_library('libclang_rt.ubsan*')
528
Ulya Trafimovich7b0df592020-01-03 13:29:00 +0000529 # Check dexpreopt files for libcore bootclasspath jars.
530 self._checker.check_dexpreopt('boot')
531 self._checker.check_dexpreopt('boot-apache-xml')
532 self._checker.check_dexpreopt('boot-bouncycastle')
Ulya Trafimovich7b0df592020-01-03 13:29:00 +0000533 self._checker.check_dexpreopt('boot-core-libart')
534 self._checker.check_dexpreopt('boot-okhttp')
535 if isEnvTrue('EMMA_INSTRUMENT_FRAMEWORK'):
536 # In coverage builds the ART boot image includes jacoco.
537 self._checker.check_dexpreopt('boot-jacocoagent')
Luca Stefani4e91ee92019-03-06 15:08:16 +0100538
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800539class ReleaseTargetChecker:
540 def __init__(self, checker):
541 self._checker = checker
Luca Stefani4e91ee92019-03-06 15:08:16 +0100542
Andreas Gampe09123952019-01-30 13:17:02 -0800543 def __str__(self):
544 return 'Release (Target) Checker'
545
546 def run(self):
Roland Levillaindf66de02019-11-11 23:22:15 +0000547 # We don't check for the presence of the JSON APEX manifest (file
548 # `apex_manifest.json`, only present in target APEXes), as it is only
549 # included for compatibility reasons with Android Q and will likely be
550 # removed in Android R.
551
Martin Stjernholm023c2182019-03-28 15:52:32 +0000552 # Check binaries for ART.
Roland Levillain2af026d2021-06-14 12:25:04 +0100553 self._checker.check_executable('artd')
Orion Hodson4c3ade62021-02-10 14:07:10 +0000554 self._checker.check_executable('oatdump')
555 self._checker.check_executable("odrefresh")
Martin Stjernholm6c61af82021-12-14 01:10:06 +0000556 self._checker.check_symlinked_multilib_executable('dex2oat')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000557
558 # Check internal libraries for ART.
Martin Stjernholm7a476262022-06-06 23:23:51 +0100559 self._checker.check_native_library('libartservice')
Florian Mayer07710c52019-09-16 15:53:38 +0000560 self._checker.check_native_library('libperfetto_hprof')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000561
Roland Levillain2af026d2021-06-14 12:25:04 +0100562 # Check internal Java libraries
563 self._checker.check_java_library("service-art")
564
Martin Stjernholm023c2182019-03-28 15:52:32 +0000565 # Check exported native libraries for Managed Core Library.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000566 self._checker.check_native_library('libandroidio')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000567
568 # Check internal native library dependencies.
569 self._checker.check_native_library('libcrypto')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000570 self._checker.check_native_library('libexpat')
Martin Stjernholm2babede2019-03-18 21:04:49 +0000571
Luca Stefani4e91ee92019-03-06 15:08:16 +0100572
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800573class ReleaseHostChecker:
574 def __init__(self, checker):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100575 self._checker = checker
576
Andreas Gampe09123952019-01-30 13:17:02 -0800577 def __str__(self):
578 return 'Release (Host) Checker'
579
580 def run(self):
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000581 # Check binaries for ART.
582 self._checker.check_executable('hprof-conv')
Nicolas Geoffrayd68580e2020-04-15 16:52:32 +0100583 self._checker.check_symlinked_first_executable('dex2oatd')
584 self._checker.check_symlinked_first_executable('dex2oat')
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000585
Martin Stjernholm023c2182019-03-28 15:52:32 +0000586 # Check exported native libraries for Managed Core Library.
Victor Chang8b247622020-09-22 21:48:15 +0100587 self._checker.check_native_library('libicu')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000588 self._checker.check_native_library('libandroidio')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000589
590 # Check internal libraries for Managed Core Library.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000591 self._checker.check_native_library('libexpat-host')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000592 self._checker.check_native_library('libz-host')
Andreas Gampe09123952019-01-30 13:17:02 -0800593
Luca Stefani4e91ee92019-03-06 15:08:16 +0100594
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800595class DebugChecker:
596 def __init__(self, checker):
597 self._checker = checker
Luca Stefani4e91ee92019-03-06 15:08:16 +0100598
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000599 def __str__(self):
600 return 'Debug Checker'
601
602 def run(self):
Martin Stjernholm023c2182019-03-28 15:52:32 +0000603 # Check binaries for ART.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000604 self._checker.check_executable('dexdiag')
Roland Levillain6dd62122019-06-18 19:10:21 +0100605 self._checker.check_executable('dexanalyze')
606 self._checker.check_executable('dexlayout')
607 self._checker.check_symlinked_multilib_executable('imgdiag')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000608
Martin Stjernholm023c2182019-03-28 15:52:32 +0000609 # Check debug binaries for ART.
Roland Levillain6dd62122019-06-18 19:10:21 +0100610 self._checker.check_executable('dexlayoutd')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000611 self._checker.check_executable('dexoptanalyzerd')
Roland Levillain6dd62122019-06-18 19:10:21 +0100612 self._checker.check_symlinked_multilib_executable('imgdiagd')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000613 self._checker.check_executable('profmand')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000614
Martin Stjernholmd3e9ff32021-03-16 00:44:25 +0000615 # Check exported libraries for ART.
616 self._checker.check_native_library('libdexfiled')
617
Martin Stjernholm023c2182019-03-28 15:52:32 +0000618 # Check internal libraries for ART.
619 self._checker.check_native_library('libadbconnectiond')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000620 self._checker.check_native_library('libartbased')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000621 self._checker.check_native_library('libartd')
Dmitrii Ishcheikin00ca1b52022-11-07 19:09:11 +0000622 self._checker.check_native_library('libartd-compiler')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000623 self._checker.check_native_library('libartd-dexlayout')
Roland Levillain4d6f24d2019-10-02 16:47:36 +0100624 self._checker.check_native_library('libartd-disassembler')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000625 self._checker.check_native_library('libopenjdkjvmd')
626 self._checker.check_native_library('libopenjdkjvmtid')
627 self._checker.check_native_library('libprofiled')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000628
629 # Check internal libraries for Managed Core Library.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000630 self._checker.check_native_library('libopenjdkd')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000631
Luca Stefani4e91ee92019-03-06 15:08:16 +0100632
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800633class DebugTargetChecker:
634 def __init__(self, checker):
635 self._checker = checker
Luca Stefani4e91ee92019-03-06 15:08:16 +0100636
Andreas Gampea0242cf2019-01-29 13:01:23 -0800637 def __str__(self):
638 return 'Debug (Target) Checker'
639
640 def run(self):
Martin Stjernholm023c2182019-03-28 15:52:32 +0000641 # Check ART debug binaries.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000642 self._checker.check_executable('oatdumpd')
Martin Stjernholm6c61af82021-12-14 01:10:06 +0000643 self._checker.check_symlinked_multilib_executable('dex2oatd')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000644
645 # Check ART internal libraries.
Martin Stjernholm7a476262022-06-06 23:23:51 +0100646 self._checker.check_native_library('libartserviced')
Florian Mayer07710c52019-09-16 15:53:38 +0000647 self._checker.check_native_library('libperfetto_hprofd')
Andreas Gampea0242cf2019-01-29 13:01:23 -0800648
Martin Stjernholm2babede2019-03-18 21:04:49 +0000649 # Check internal native library dependencies.
650 #
651 # Like in the release package, we check that we don't get other dependencies
652 # besides those listed here. In this case the concern is not bloat, but
653 # rather that we don't get behavioural differences between user (release)
654 # and userdebug/eng builds, which could happen if the debug package has
655 # duplicate library instances where releases don't. In other words, it's
656 # uncontroversial to add debug-only dependencies, as long as they don't make
657 # assumptions on having a single global state (ideally they should have
658 # double_loadable:true, cf. go/double_loadable). Also, like in the release
659 # package we need to look out for dependencies that should go through
660 # exported library stubs (until b/128708192 is fixed).
Martin Stjernholm77f17662019-04-03 17:08:21 +0100661 self._checker.check_prefer64_library('libmeminfo')
662 self._checker.check_prefer64_library('libprocinfo')
Martin Stjernholm2babede2019-03-18 21:04:49 +0000663
664
Roland Levillain61f07162019-06-26 12:44:04 +0100665class TestingTargetChecker:
666 def __init__(self, checker):
667 self._checker = checker
668
669 def __str__(self):
670 return 'Testing (Target) Checker'
671
672 def run(self):
David Srbecky883c1342020-05-11 23:30:29 +0000673 # Check ART test binaries.
Martin Stjernholm69a57a72022-06-17 22:20:43 +0100674 self._checker.check_art_test_executable('art_artd_tests')
David Srbecky883c1342020-05-11 23:30:29 +0000675 self._checker.check_art_test_executable('art_cmdline_tests')
676 self._checker.check_art_test_executable('art_compiler_tests')
677 self._checker.check_art_test_executable('art_dex2oat_tests')
678 self._checker.check_art_test_executable('art_dexanalyze_tests')
679 self._checker.check_art_test_executable('art_dexdiag_tests')
680 self._checker.check_art_test_executable('art_dexdump_tests')
681 self._checker.check_art_test_executable('art_dexlayout_tests')
682 self._checker.check_art_test_executable('art_dexlist_tests')
683 self._checker.check_art_test_executable('art_dexoptanalyzer_tests')
Greg Cawthornebb3ef5a2021-12-21 22:01:14 +0000684 self._checker.check_art_test_executable('art_disassembler_tests')
David Srbecky883c1342020-05-11 23:30:29 +0000685 self._checker.check_art_test_executable('art_imgdiag_tests')
686 self._checker.check_art_test_executable('art_libartbase_tests')
687 self._checker.check_art_test_executable('art_libartpalette_tests')
Chris Wailesbfd622a2021-01-13 16:13:41 -0800688 self._checker.check_art_test_executable('art_libartservice_tests')
689 self._checker.check_art_test_executable('art_libarttools_tests')
Roland Levillain61f07162019-06-26 12:44:04 +0100690 self._checker.check_art_test_executable('art_libdexfile_support_tests')
David Srbecky883c1342020-05-11 23:30:29 +0000691 self._checker.check_art_test_executable('art_libdexfile_tests')
692 self._checker.check_art_test_executable('art_libprofile_tests')
693 self._checker.check_art_test_executable('art_oatdump_tests')
Victor Hsieh7b798142022-01-18 15:13:14 -0800694 self._checker.check_art_test_executable('art_odrefresh_tests')
David Srbecky883c1342020-05-11 23:30:29 +0000695 self._checker.check_art_test_executable('art_profman_tests')
David Srbecky883c1342020-05-11 23:30:29 +0000696 self._checker.check_art_test_executable('art_runtime_tests')
697 self._checker.check_art_test_executable('art_sigchain_tests')
Roland Levillain61f07162019-06-26 12:44:04 +0100698
699 # Check ART test (internal) libraries.
Roland Levillain55ffe7f2021-06-14 15:18:54 +0100700 self._checker.check_native_library('libartd-gtest')
Ulya Trafimovich5439f052020-07-29 10:03:46 +0100701 self._checker.check_native_library('libartd-simulator-container')
Jiakai Zhangd539f862022-02-08 14:56:05 +0000702 self._checker.check_native_library('libartbased-testing')
Roland Levillain61f07162019-06-26 12:44:04 +0100703
Andreas Gampe816a5522019-09-11 11:29:49 -0700704 # Check ART test tools.
705 self._checker.check_executable('signal_dumper')
706
David Srbecky4a88a5a2020-05-05 16:21:57 +0100707 # Check ART jar files which are needed for gtests.
708 self._checker.check_art_test_data('art-gtest-jars-AbstractMethod.jar')
Nicolas Geoffray74b230a2022-08-01 16:20:06 +0100709 self._checker.check_art_test_data('art-gtest-jars-ArrayClassWithUnresolvedComponent.dex')
David Srbecky4a88a5a2020-05-05 16:21:57 +0100710 self._checker.check_art_test_data('art-gtest-jars-MyClassNatives.jar')
711 self._checker.check_art_test_data('art-gtest-jars-Main.jar')
712 self._checker.check_art_test_data('art-gtest-jars-ProtoCompare.jar')
713 self._checker.check_art_test_data('art-gtest-jars-Transaction.jar')
David Srbeckyedda3ca2020-07-08 00:41:08 +0100714 self._checker.check_art_test_data('art-gtest-jars-VerifierDepsMulti.dex')
David Srbecky4a88a5a2020-05-05 16:21:57 +0100715 self._checker.check_art_test_data('art-gtest-jars-Nested.jar')
716 self._checker.check_art_test_data('art-gtest-jars-MyClass.jar')
717 self._checker.check_art_test_data('art-gtest-jars-ManyMethods.jar')
718 self._checker.check_art_test_data('art-gtest-jars-GetMethodSignature.jar')
719 self._checker.check_art_test_data('art-gtest-jars-Lookup.jar')
720 self._checker.check_art_test_data('art-gtest-jars-Instrumentation.jar')
721 self._checker.check_art_test_data('art-gtest-jars-MainUncompressedAligned.jar')
722 self._checker.check_art_test_data('art-gtest-jars-ForClassLoaderD.jar')
723 self._checker.check_art_test_data('art-gtest-jars-ForClassLoaderC.jar')
724 self._checker.check_art_test_data('art-gtest-jars-ErroneousA.jar')
David Srbecky4a88a5a2020-05-05 16:21:57 +0100725 self._checker.check_art_test_data('art-gtest-jars-HiddenApiSignatures.jar')
726 self._checker.check_art_test_data('art-gtest-jars-ForClassLoaderB.jar')
David Srbeckyedda3ca2020-07-08 00:41:08 +0100727 self._checker.check_art_test_data('art-gtest-jars-LinkageTest.dex')
David Srbecky4a88a5a2020-05-05 16:21:57 +0100728 self._checker.check_art_test_data('art-gtest-jars-MethodTypes.jar')
729 self._checker.check_art_test_data('art-gtest-jars-ErroneousInit.jar')
David Srbeckyedda3ca2020-07-08 00:41:08 +0100730 self._checker.check_art_test_data('art-gtest-jars-VerifierDeps.dex')
David Srbecky4a88a5a2020-05-05 16:21:57 +0100731 self._checker.check_art_test_data('art-gtest-jars-StringLiterals.jar')
732 self._checker.check_art_test_data('art-gtest-jars-XandY.jar')
733 self._checker.check_art_test_data('art-gtest-jars-ExceptionHandle.jar')
734 self._checker.check_art_test_data('art-gtest-jars-ImageLayoutB.jar')
735 self._checker.check_art_test_data('art-gtest-jars-Interfaces.jar')
736 self._checker.check_art_test_data('art-gtest-jars-IMTB.jar')
737 self._checker.check_art_test_data('art-gtest-jars-Extension2.jar')
738 self._checker.check_art_test_data('art-gtest-jars-Extension1.jar')
739 self._checker.check_art_test_data('art-gtest-jars-MainEmptyUncompressedAligned.jar')
740 self._checker.check_art_test_data('art-gtest-jars-ErroneousB.jar')
741 self._checker.check_art_test_data('art-gtest-jars-MultiDexModifiedSecondary.jar')
742 self._checker.check_art_test_data('art-gtest-jars-NonStaticLeafMethods.jar')
743 self._checker.check_art_test_data('art-gtest-jars-DefaultMethods.jar')
744 self._checker.check_art_test_data('art-gtest-jars-MultiDexUncompressedAligned.jar')
745 self._checker.check_art_test_data('art-gtest-jars-StaticsFromCode.jar')
746 self._checker.check_art_test_data('art-gtest-jars-ProfileTestMultiDex.jar')
David Srbeckyedda3ca2020-07-08 00:41:08 +0100747 self._checker.check_art_test_data('art-gtest-jars-VerifySoftFailDuringClinit.dex')
David Srbecky4a88a5a2020-05-05 16:21:57 +0100748 self._checker.check_art_test_data('art-gtest-jars-MainStripped.jar')
749 self._checker.check_art_test_data('art-gtest-jars-ForClassLoaderA.jar')
750 self._checker.check_art_test_data('art-gtest-jars-StaticLeafMethods.jar')
751 self._checker.check_art_test_data('art-gtest-jars-MultiDex.jar')
752 self._checker.check_art_test_data('art-gtest-jars-Packages.jar')
753 self._checker.check_art_test_data('art-gtest-jars-ProtoCompare2.jar')
754 self._checker.check_art_test_data('art-gtest-jars-Statics.jar')
755 self._checker.check_art_test_data('art-gtest-jars-AllFields.jar')
756 self._checker.check_art_test_data('art-gtest-jars-IMTA.jar')
757 self._checker.check_art_test_data('art-gtest-jars-ImageLayoutA.jar')
758 self._checker.check_art_test_data('art-gtest-jars-MainEmptyUncompressed.jar')
Calin Juravle33787682019-07-26 14:27:18 -0700759 self._checker.check_art_test_data('art-gtest-jars-Dex2oatVdexTestDex.jar')
760 self._checker.check_art_test_data('art-gtest-jars-Dex2oatVdexPublicSdkDex.dex')
Nicolas Geoffray4a10dcc2022-08-12 19:18:43 +0100761 self._checker.check_art_test_data('art-gtest-jars-SuperWithAccessChecks.dex')
David Srbecky4a88a5a2020-05-05 16:21:57 +0100762
Roland Levillain61f07162019-06-26 12:44:04 +0100763
Martin Stjernholm2babede2019-03-18 21:04:49 +0000764class NoSuperfluousBinariesChecker:
765 def __init__(self, checker):
766 self._checker = checker
767
768 def __str__(self):
769 return 'No superfluous binaries checker'
770
771 def run(self):
772 self._checker.check_no_superfluous_files('bin')
773
774
775class NoSuperfluousLibrariesChecker:
776 def __init__(self, checker):
777 self._checker = checker
778
779 def __str__(self):
780 return 'No superfluous libraries checker'
781
782 def run(self):
783 self._checker.check_no_superfluous_files('javalib')
784 self._checker.check_no_superfluous_files('lib')
Martin Stjernholm2babede2019-03-18 21:04:49 +0000785 self._checker.check_no_superfluous_files('lib64')
Martin Stjernholm2babede2019-03-18 21:04:49 +0000786
Andreas Gampeb1d55672019-01-29 22:17:02 +0000787
Roland Levillain61f07162019-06-26 12:44:04 +0100788class NoSuperfluousArtTestsChecker:
789 def __init__(self, checker):
790 self._checker = checker
791
792 def __str__(self):
793 return 'No superfluous ART tests checker'
794
795 def run(self):
Victor Hsieh52f7f632021-09-24 11:50:55 -0700796 for arch in self._checker.possible_archs():
Orion Hodsonaf3ed622019-10-03 16:30:54 +0100797 self._checker.check_no_superfluous_files('%s/%s' % (ART_TEST_DIR, arch))
Roland Levillain61f07162019-06-26 12:44:04 +0100798
799
Luca Stefani4e91ee92019-03-06 15:08:16 +0100800class List:
Roland Levillain77251f92019-08-09 15:00:04 +0100801 def __init__(self, provider, print_size=False):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100802 self._provider = provider
Roland Levillaine91d7872019-07-25 18:56:06 +0100803 self._print_size = print_size
Luca Stefani4e91ee92019-03-06 15:08:16 +0100804
805 def print_list(self):
Roland Levillain09744ac2019-06-06 18:23:02 +0100806
807 def print_list_rec(path):
808 apex_map = self._provider.read_dir(path)
809 if apex_map is None:
810 return
811 apex_map = dict(apex_map)
812 if '.' in apex_map:
813 del apex_map['.']
814 if '..' in apex_map:
815 del apex_map['..']
816 for (_, val) in sorted(apex_map.items()):
817 val_path = os.path.join(path, val.name)
Roland Levillaine91d7872019-07-25 18:56:06 +0100818 if self._print_size:
819 if val.size < 0:
820 print('[ n/a ] %s' % val_path)
821 else:
822 print('[%11d] %s' % (val.size, val_path))
823 else:
824 print(val_path)
Roland Levillain09744ac2019-06-06 18:23:02 +0100825 if val.is_dir:
826 print_list_rec(val_path)
827
828 print_list_rec('')
Luca Stefani4e91ee92019-03-06 15:08:16 +0100829
830
831class Tree:
Roland Levillain77251f92019-08-09 15:00:04 +0100832 def __init__(self, provider, title, print_size=False):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100833 print('%s' % title)
834 self._provider = provider
Luca Stefani4e91ee92019-03-06 15:08:16 +0100835 self._has_next_list = []
Roland Levillain88e55692019-07-25 15:57:06 +0100836 self._print_size = print_size
Luca Stefani4e91ee92019-03-06 15:08:16 +0100837
838 @staticmethod
839 def get_vertical(has_next_list):
840 string = ''
841 for v in has_next_list:
842 string += '%s ' % ('│' if v else ' ')
843 return string
844
845 @staticmethod
846 def get_last_vertical(last):
847 return '└── ' if last else '├── '
848
849 def print_tree(self):
Roland Levillain09744ac2019-06-06 18:23:02 +0100850
851 def print_tree_rec(path):
852 apex_map = self._provider.read_dir(path)
853 if apex_map is None:
854 return
855 apex_map = dict(apex_map)
856 if '.' in apex_map:
857 del apex_map['.']
858 if '..' in apex_map:
859 del apex_map['..']
860 key_list = list(sorted(apex_map.keys()))
861 for i, key in enumerate(key_list):
862 prev = self.get_vertical(self._has_next_list)
863 last = self.get_last_vertical(i == len(key_list) - 1)
864 val = apex_map[key]
Roland Levillain88e55692019-07-25 15:57:06 +0100865 if self._print_size:
866 if val.size < 0:
867 print('%s%s[ n/a ] %s' % (prev, last, val.name))
868 else:
869 print('%s%s[%11d] %s' % (prev, last, val.size, val.name))
870 else:
871 print('%s%s%s' % (prev, last, val.name))
Roland Levillain09744ac2019-06-06 18:23:02 +0100872 if val.is_dir:
873 self._has_next_list.append(i < len(key_list) - 1)
874 val_path = os.path.join(path, val.name)
875 print_tree_rec(val_path)
876 self._has_next_list.pop()
877
878 print_tree_rec('')
Luca Stefani4e91ee92019-03-06 15:08:16 +0100879
Andreas Gampeb1d55672019-01-29 22:17:02 +0000880
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000881# Note: do not sys.exit early, for __del__ cleanup.
Luca Stefani4e91ee92019-03-06 15:08:16 +0100882def art_apex_test_main(test_args):
Roland Levillaindd20d002019-07-19 16:09:47 +0100883 if test_args.host and test_args.flattened:
884 logging.error("Both of --host and --flattened set")
885 return 1
Luca Stefani4e91ee92019-03-06 15:08:16 +0100886 if test_args.list and test_args.tree:
Andreas Gampeb1d55672019-01-29 22:17:02 +0000887 logging.error("Both of --list and --tree set")
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000888 return 1
Roland Levillaine91d7872019-07-25 18:56:06 +0100889 if test_args.size and not (test_args.list or test_args.tree):
890 logging.error("--size set but neither --list nor --tree set")
Roland Levillain88e55692019-07-25 15:57:06 +0100891 return 1
Martin Stjernholm3cb59a42019-08-07 17:18:29 +0100892 if not test_args.flattened and not test_args.tmpdir:
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000893 logging.error("Need a tmpdir.")
894 return 1
Martin Stjernholm571a6be2021-05-25 01:16:53 +0100895 if not test_args.flattened and not test_args.host:
896 if not test_args.deapexer:
897 logging.error("Need deapexer.")
898 return 1
899 if not test_args.debugfs:
900 logging.error("Need debugfs.")
901 return 1
Dennis Shenc2320492022-11-02 16:03:42 +0000902 if not test_args.fsckerofs:
903 logging.error("Need fsck.erofs.")
904 return 1
905 if not test_args.blkid:
906 logging.error("Need blkid.")
907 return 1
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000908
Roland Levillainfdbe2072019-11-11 15:52:45 +0000909 if test_args.host:
910 # Host APEX.
911 if test_args.flavor not in [FLAVOR_DEBUG, FLAVOR_AUTO]:
912 logging.error("Using option --host with non-Debug APEX")
Roland Levillaindbd6a142019-10-03 15:08:28 +0100913 return 1
Roland Levillainfdbe2072019-11-11 15:52:45 +0000914 # Host APEX is always a debug flavor (for now).
915 test_args.flavor = FLAVOR_DEBUG
916 else:
917 # Device APEX.
918 if test_args.flavor == FLAVOR_AUTO:
919 logging.warning('--flavor=auto, trying to autodetect. This may be incorrect!')
Roland Levillain0c39de62021-04-14 17:53:20 +0100920 # The order of flavors in the list below matters, as the release tag (empty string) will
921 # match any package name.
922 for flavor in [ FLAVOR_DEBUG, FLAVOR_TESTING, FLAVOR_RELEASE ]:
923 flavor_tag = flavor
924 # Special handling for the release flavor, whose name is no longer part of the Release ART
Roland Levillain2af026d2021-06-14 12:25:04 +0100925 # APEX file name (`com.android.art.capex` / `com.android.art`).
Roland Levillain0c39de62021-04-14 17:53:20 +0100926 if flavor == FLAVOR_RELEASE:
927 flavor_tag = ''
928 flavor_pattern = '*.%s*' % flavor_tag
Roland Levillainfdbe2072019-11-11 15:52:45 +0000929 if fnmatch.fnmatch(test_args.apex, flavor_pattern):
930 test_args.flavor = flavor
Roland Levillain0c39de62021-04-14 17:53:20 +0100931 logging.warning(' Detected %s flavor', flavor)
Roland Levillainfdbe2072019-11-11 15:52:45 +0000932 break
933 if test_args.flavor == FLAVOR_AUTO:
Roland Levillain0c39de62021-04-14 17:53:20 +0100934 logging.error(' Could not detect APEX flavor, neither %s, %s nor %s for \'%s\'',
Roland Levillainfdbe2072019-11-11 15:52:45 +0000935 FLAVOR_RELEASE, FLAVOR_DEBUG, FLAVOR_TESTING, test_args.apex)
936 return 1
Roland Levillaindbd6a142019-10-03 15:08:28 +0100937
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000938 try:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100939 if test_args.host:
940 apex_provider = HostApexProvider(test_args.apex, test_args.tmpdir)
Andreas Gampe09123952019-01-30 13:17:02 -0800941 else:
Martin Stjernholm571a6be2021-05-25 01:16:53 +0100942 apex_dir = test_args.apex
943 if not test_args.flattened:
944 # Extract the apex. It would be nice to use the output from "deapexer list"
945 # to avoid this work, but it doesn't provide info about executable bits.
946 apex_dir = extract_apex(test_args.apex, test_args.deapexer, test_args.debugfs,
Dennis Shenc2320492022-11-02 16:03:42 +0000947 test_args.fsckerofs, test_args.blkid, test_args.tmpdir)
Martin Stjernholm571a6be2021-05-25 01:16:53 +0100948 apex_provider = TargetApexProvider(apex_dir)
Luca Stefani4e91ee92019-03-06 15:08:16 +0100949 except (zipfile.BadZipFile, zipfile.LargeZipFile) as e:
Andreas Gampea0242cf2019-01-29 13:01:23 -0800950 logging.error('Failed to create provider: %s', e)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000951 return 1
952
Luca Stefani4e91ee92019-03-06 15:08:16 +0100953 if test_args.tree:
Roland Levillain88e55692019-07-25 15:57:06 +0100954 Tree(apex_provider, test_args.apex, test_args.size).print_tree()
Andreas Gampeb1d55672019-01-29 22:17:02 +0000955 return 0
Luca Stefani4e91ee92019-03-06 15:08:16 +0100956 if test_args.list:
Roland Levillaine91d7872019-07-25 18:56:06 +0100957 List(apex_provider, test_args.size).print_list()
Andreas Gampeb1d55672019-01-29 22:17:02 +0000958 return 0
959
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000960 checkers = []
Orion Hodsonaf3ed622019-10-03 16:30:54 +0100961 if test_args.bitness == BITNESS_AUTO:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100962 logging.warning('--bitness=auto, trying to autodetect. This may be incorrect!')
Andreas Gampeeb555b82019-01-30 14:47:49 -0800963 has_32 = apex_provider.get('lib') is not None
964 has_64 = apex_provider.get('lib64') is not None
965 if has_32 and has_64:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100966 logging.warning(' Detected multilib')
Orion Hodsonaf3ed622019-10-03 16:30:54 +0100967 test_args.bitness = BITNESS_MULTILIB
Andreas Gampeeb555b82019-01-30 14:47:49 -0800968 elif has_32:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100969 logging.warning(' Detected 32-only')
Orion Hodsonaf3ed622019-10-03 16:30:54 +0100970 test_args.bitness = BITNESS_32
Andreas Gampeeb555b82019-01-30 14:47:49 -0800971 elif has_64:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100972 logging.warning(' Detected 64-only')
Orion Hodsonaf3ed622019-10-03 16:30:54 +0100973 test_args.bitness = BITNESS_64
Andreas Gampeeb555b82019-01-30 14:47:49 -0800974 else:
975 logging.error(' Could not detect bitness, neither lib nor lib64 contained.')
Roland Levillain77251f92019-08-09 15:00:04 +0100976 List(apex_provider).print_list()
Andreas Gampeeb555b82019-01-30 14:47:49 -0800977 return 1
978
Orion Hodsonaf3ed622019-10-03 16:30:54 +0100979 if test_args.bitness == BITNESS_32:
Andreas Gampeeb555b82019-01-30 14:47:49 -0800980 base_checker = Arch32Checker(apex_provider)
Orion Hodsonaf3ed622019-10-03 16:30:54 +0100981 elif test_args.bitness == BITNESS_64:
Andreas Gampeeb555b82019-01-30 14:47:49 -0800982 base_checker = Arch64Checker(apex_provider)
983 else:
Orion Hodsonaf3ed622019-10-03 16:30:54 +0100984 assert test_args.bitness == BITNESS_MULTILIB
Andreas Gampeeb555b82019-01-30 14:47:49 -0800985 base_checker = MultilibChecker(apex_provider)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000986
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800987 checkers.append(ReleaseChecker(base_checker))
Luca Stefani4e91ee92019-03-06 15:08:16 +0100988 if test_args.host:
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800989 checkers.append(ReleaseHostChecker(base_checker))
Andreas Gampe09123952019-01-30 13:17:02 -0800990 else:
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800991 checkers.append(ReleaseTargetChecker(base_checker))
Orion Hodsonaf3ed622019-10-03 16:30:54 +0100992 if test_args.flavor == FLAVOR_DEBUG or test_args.flavor == FLAVOR_TESTING:
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800993 checkers.append(DebugChecker(base_checker))
Roland Levillain61f07162019-06-26 12:44:04 +0100994 if not test_args.host:
995 checkers.append(DebugTargetChecker(base_checker))
Orion Hodsonaf3ed622019-10-03 16:30:54 +0100996 if test_args.flavor == FLAVOR_TESTING:
Roland Levillain61f07162019-06-26 12:44:04 +0100997 checkers.append(TestingTargetChecker(base_checker))
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000998
Martin Stjernholm2babede2019-03-18 21:04:49 +0000999 # These checkers must be last.
1000 checkers.append(NoSuperfluousBinariesChecker(base_checker))
Roland Levillain61f07162019-06-26 12:44:04 +01001001 checkers.append(NoSuperfluousArtTestsChecker(base_checker))
Martin Stjernholm2babede2019-03-18 21:04:49 +00001002 if not test_args.host:
1003 # We only care about superfluous libraries on target, where their absence
1004 # can be vital to ensure they get picked up from the right package.
1005 checkers.append(NoSuperfluousLibrariesChecker(base_checker))
1006
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001007 failed = False
1008 for checker in checkers:
1009 logging.info('%s...', checker)
1010 checker.run()
Andreas Gampe9dc4b052019-01-30 13:47:25 -08001011 if base_checker.error_count() > 0:
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001012 logging.error('%s FAILED', checker)
1013 failed = True
1014 else:
1015 logging.info('%s SUCCEEDED', checker)
Andreas Gampe9dc4b052019-01-30 13:47:25 -08001016 base_checker.reset_errors()
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001017
1018 return 1 if failed else 0
1019
Luca Stefani4e91ee92019-03-06 15:08:16 +01001020
1021def art_apex_test_default(test_parser):
1022 if 'ANDROID_PRODUCT_OUT' not in os.environ:
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001023 logging.error('No-argument use requires ANDROID_PRODUCT_OUT')
1024 sys.exit(1)
1025 product_out = os.environ['ANDROID_PRODUCT_OUT']
Luca Stefani4e91ee92019-03-06 15:08:16 +01001026 if 'ANDROID_HOST_OUT' not in os.environ:
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001027 logging.error('No-argument use requires ANDROID_HOST_OUT')
1028 sys.exit(1)
1029 host_out = os.environ['ANDROID_HOST_OUT']
1030
Roland Levillain4ee567f2020-07-27 17:02:54 +01001031 test_args = test_parser.parse_args(['unused']) # For consistency.
Luca Stefani4e91ee92019-03-06 15:08:16 +01001032 test_args.debugfs = '%s/bin/debugfs' % host_out
Dennis Shenc2320492022-11-02 16:03:42 +00001033 test_args.fsckerofs = '%s/bin/fsck.erofs' % host_out
Dennis Shen32bc4ce2022-12-02 15:35:48 +00001034 test_args.blkid = '%s/bin/blkid_static' % host_out
Luca Stefani4e91ee92019-03-06 15:08:16 +01001035 test_args.tmpdir = '.'
1036 test_args.tree = False
1037 test_args.list = False
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001038 test_args.bitness = BITNESS_AUTO
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001039 failed = False
1040
Luca Stefani4e91ee92019-03-06 15:08:16 +01001041 if not os.path.exists(test_args.debugfs):
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001042 logging.error("Cannot find debugfs (default path %s). Please build it, e.g., m debugfs",
Luca Stefani4e91ee92019-03-06 15:08:16 +01001043 test_args.debugfs)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001044 sys.exit(1)
1045
Roland Levillaind7ea0432019-09-09 16:29:12 +01001046 # TODO: Add host support.
1047 # TODO: Add support for flattened APEX packages.
Luca Stefani4e91ee92019-03-06 15:08:16 +01001048 configs = [
Roland Levillain2af026d2021-06-14 12:25:04 +01001049 {'name': 'com.android.art.capex', 'flavor': FLAVOR_RELEASE, 'host': False},
1050 {'name': 'com.android.art.debug.capex', 'flavor': FLAVOR_DEBUG, 'host': False},
1051 # Note: The Testing ART APEX is not a Compressed APEX.
1052 {'name': 'com.android.art.testing.apex', 'flavor': FLAVOR_TESTING, 'host': False},
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001053 ]
1054
1055 for config in configs:
1056 logging.info(config['name'])
1057 # TODO: Host will need different path.
Roland Levillain2af026d2021-06-14 12:25:04 +01001058 test_args.apex = '%s/system/apex/%s' % (product_out, config['name'])
Luca Stefani4e91ee92019-03-06 15:08:16 +01001059 if not os.path.exists(test_args.apex):
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001060 failed = True
Luca Stefani4e91ee92019-03-06 15:08:16 +01001061 logging.error("Cannot find APEX %s. Please build it first.", test_args.apex)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001062 continue
Roland Levillaind7ea0432019-09-09 16:29:12 +01001063 test_args.flavor = config['flavor']
Luca Stefani4e91ee92019-03-06 15:08:16 +01001064 test_args.host = config['host']
1065 failed = art_apex_test_main(test_args) != 0
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001066
1067 if failed:
1068 sys.exit(1)
1069
Luca Stefani4e91ee92019-03-06 15:08:16 +01001070
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001071if __name__ == "__main__":
Martin Stjernholme58624f2019-09-20 15:53:40 +01001072 parser = argparse.ArgumentParser(description='Check integrity of an ART APEX.')
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001073
Roland Levillaind7ea0432019-09-09 16:29:12 +01001074 parser.add_argument('apex', help='APEX file input')
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001075
Roland Levillaind7ea0432019-09-09 16:29:12 +01001076 parser.add_argument('--host', help='Check as host APEX', action='store_true')
Andreas Gampe09123952019-01-30 13:17:02 -08001077
Roland Levillaind7ea0432019-09-09 16:29:12 +01001078 parser.add_argument('--flattened', help='Check as flattened (target) APEX', action='store_true')
Roland Levillaindd20d002019-07-19 16:09:47 +01001079
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001080 parser.add_argument('--flavor', help='Check as FLAVOR APEX', choices=FLAVORS_ALL,
1081 default=FLAVOR_AUTO)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001082
Andreas Gampeb1d55672019-01-29 22:17:02 +00001083 parser.add_argument('--list', help='List all files', action='store_true')
1084 parser.add_argument('--tree', help='Print directory tree', action='store_true')
Roland Levillaine91d7872019-07-25 18:56:06 +01001085 parser.add_argument('--size', help='Print file sizes', action='store_true')
Andreas Gampeb1d55672019-01-29 22:17:02 +00001086
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001087 parser.add_argument('--tmpdir', help='Directory for temp files')
Martin Stjernholm571a6be2021-05-25 01:16:53 +01001088 parser.add_argument('--deapexer', help='Path to deapexer')
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001089 parser.add_argument('--debugfs', help='Path to debugfs')
Dennis Shenc2320492022-11-02 16:03:42 +00001090 parser.add_argument('--fsckerofs', help='Path to fsck.erofs')
1091 parser.add_argument('--blkid', help='Path to blkid')
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001092
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001093 parser.add_argument('--bitness', help='Bitness to check', choices=BITNESS_ALL,
1094 default=BITNESS_AUTO)
Andreas Gampeeb555b82019-01-30 14:47:49 -08001095
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001096 if len(sys.argv) == 1:
Luca Stefani4e91ee92019-03-06 15:08:16 +01001097 art_apex_test_default(parser)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001098 else:
1099 args = parser.parse_args()
1100
1101 if args is None:
1102 sys.exit(1)
1103
Luca Stefani4e91ee92019-03-06 15:08:16 +01001104 exit_code = art_apex_test_main(args)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001105 sys.exit(exit_code)