blob: 98a2963e4b86e66fe2ff687d4fa44c22501005a0 [file] [log] [blame]
Roland Levillain29e740f2019-08-20 15:31:37 +01001#!/usr/bin/env python
2# -*- 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
Andreas Gampe2c846cd2019-01-29 22:06:46 +000024import subprocess
25import sys
26import zipfile
27
28logging.basicConfig(format='%(message)s')
29
Orion Hodsonaf3ed622019-10-03 16:30:54 +010030# Flavors of ART APEX package.
31FLAVOR_RELEASE = 'release'
32FLAVOR_DEBUG = 'debug'
33FLAVOR_TESTING = 'testing'
34FLAVOR_AUTO = 'auto'
35FLAVORS_ALL = [FLAVOR_RELEASE, FLAVOR_DEBUG, FLAVOR_TESTING, FLAVOR_AUTO]
36
37# Bitness options for APEX package
38BITNESS_32 = '32'
39BITNESS_64 = '64'
40BITNESS_MULTILIB = 'multilib'
41BITNESS_AUTO = 'auto'
42BITNESS_ALL = [BITNESS_32, BITNESS_64, BITNESS_MULTILIB, BITNESS_AUTO]
43
Roland Levillain61f07162019-06-26 12:44:04 +010044# Architectures supported by APEX packages.
Orion Hodsonaf3ed622019-10-03 16:30:54 +010045ARCHS = ["arm", "arm64", "x86", "x86_64"]
46
Martin Stjernholme58624f2019-09-20 15:53:40 +010047# Directory containing ART tests within an ART APEX (if the package includes
Roland Levillain61f07162019-06-26 12:44:04 +010048# any). ART test executables are installed in `bin/art/<arch>`. Segregating
49# tests by architecture is useful on devices supporting more than one
Martin Stjernholme58624f2019-09-20 15:53:40 +010050# architecture, as it permits testing all of them using a single ART APEX
Roland Levillain61f07162019-06-26 12:44:04 +010051# package.
Orion Hodsonaf3ed622019-10-03 16:30:54 +010052ART_TEST_DIR = 'bin/art'
Luca Stefani4e91ee92019-03-06 15:08:16 +010053
Andreas Gampe2c846cd2019-01-29 22:06:46 +000054class FSObject:
Roland Levillain88e55692019-07-25 15:57:06 +010055 def __init__(self, name, is_dir, is_exec, is_symlink, size):
Andreas Gampe2c846cd2019-01-29 22:06:46 +000056 self.name = name
57 self.is_dir = is_dir
58 self.is_exec = is_exec
59 self.is_symlink = is_symlink
Roland Levillain88e55692019-07-25 15:57:06 +010060 self.size = size
Luca Stefani4e91ee92019-03-06 15:08:16 +010061
Andreas Gampe2c846cd2019-01-29 22:06:46 +000062 def __str__(self):
Roland Levillain88e55692019-07-25 15:57:06 +010063 return '%s(dir=%r,exec=%r,symlink=%r,size=%d)' \
64 % (self.name, self.is_dir, self.is_exec, self.is_symlink, self.size)
Andreas Gampe2c846cd2019-01-29 22:06:46 +000065
Luca Stefani4e91ee92019-03-06 15:08:16 +010066
Andreas Gampe2c846cd2019-01-29 22:06:46 +000067class TargetApexProvider:
68 def __init__(self, apex, tmpdir, debugfs):
69 self._tmpdir = tmpdir
70 self._debugfs = debugfs
71 self._folder_cache = {}
72 self._payload = os.path.join(self._tmpdir, 'apex_payload.img')
73 # Extract payload to tmpdir.
Luca Stefani4e91ee92019-03-06 15:08:16 +010074 apex_zip = zipfile.ZipFile(apex)
75 apex_zip.extract('apex_payload.img', tmpdir)
Andreas Gampe2c846cd2019-01-29 22:06:46 +000076
77 def __del__(self):
78 # Delete temps.
79 if os.path.exists(self._payload):
80 os.remove(self._payload)
81
82 def get(self, path):
Luca Stefani4e91ee92019-03-06 15:08:16 +010083 apex_dir, name = os.path.split(path)
84 if not apex_dir:
85 apex_dir = '.'
86 apex_map = self.read_dir(apex_dir)
87 return apex_map[name] if name in apex_map else None
Andreas Gampe2c846cd2019-01-29 22:06:46 +000088
Luca Stefani4e91ee92019-03-06 15:08:16 +010089 def read_dir(self, apex_dir):
90 if apex_dir in self._folder_cache:
91 return self._folder_cache[apex_dir]
Andreas Gampe2c846cd2019-01-29 22:06:46 +000092 # Cannot use check_output as it will annoy with stderr.
Luca Stefani4e91ee92019-03-06 15:08:16 +010093 process = subprocess.Popen([self._debugfs, '-R', 'ls -l -p %s' % apex_dir, self._payload],
Andreas Gampe2c846cd2019-01-29 22:06:46 +000094 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
95 universal_newlines=True)
Luca Stefani4e91ee92019-03-06 15:08:16 +010096 stdout, _ = process.communicate()
Andreas Gampe2c846cd2019-01-29 22:06:46 +000097 res = str(stdout)
Luca Stefani4e91ee92019-03-06 15:08:16 +010098 apex_map = {}
Andreas Gampe2c846cd2019-01-29 22:06:46 +000099 # Debugfs output looks like this:
100 # debugfs 1.44.4 (18-Aug-2018)
101 # /12/040755/0/2000/.//
102 # /2/040755/1000/1000/..//
103 # /13/100755/0/2000/dalvikvm32/28456/
104 # /14/100755/0/2000/dexoptanalyzer/20396/
105 # /15/100755/0/2000/linker/1152724/
106 # /16/100755/0/2000/dex2oat/563508/
107 # /17/100755/0/2000/linker64/1605424/
108 # /18/100755/0/2000/profman/85304/
109 # /19/100755/0/2000/dalvikvm64/28576/
110 # | | | | | |
111 # | | | #- gid #- name #- size
112 # | | #- uid
113 # | #- type and permission bits
114 # #- inode nr (?)
115 #
116 # Note: could break just on '/' to avoid names with newlines.
117 for line in res.split("\n"):
118 if not line:
119 continue
120 comps = line.split('/')
121 if len(comps) != 8:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100122 logging.warning('Could not break and parse line \'%s\'', line)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000123 continue
124 bits = comps[2]
125 name = comps[5]
Roland Levillain88e55692019-07-25 15:57:06 +0100126 size_str = comps[6]
127 # Use a negative value as an indicator of undefined/unknown size.
128 size = int(size_str) if size_str != '' else -1
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000129 if len(bits) != 6:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100130 logging.warning('Dont understand bits \'%s\'', bits)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000131 continue
Luca Stefani4e91ee92019-03-06 15:08:16 +0100132 is_dir = bits[1] == '4'
133
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000134 def is_exec_bit(ch):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100135 return int(ch) & 1 == 1
136
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000137 is_exec = is_exec_bit(bits[3]) and is_exec_bit(bits[4]) and is_exec_bit(bits[5])
Luca Stefani4e91ee92019-03-06 15:08:16 +0100138 is_symlink = bits[1] == '2'
Roland Levillain88e55692019-07-25 15:57:06 +0100139 apex_map[name] = FSObject(name, is_dir, is_exec, is_symlink, size)
Luca Stefani4e91ee92019-03-06 15:08:16 +0100140 self._folder_cache[apex_dir] = apex_map
141 return apex_map
142
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000143
Roland Levillaindd20d002019-07-19 16:09:47 +0100144class TargetFlattenedApexProvider:
145 def __init__(self, apex):
146 self._folder_cache = {}
147 self._apex = apex
148
149 def get(self, path):
150 apex_dir, name = os.path.split(path)
151 if not apex_dir:
152 apex_dir = '.'
153 apex_map = self.read_dir(apex_dir)
154 return apex_map[name] if name in apex_map else None
155
156 def read_dir(self, apex_dir):
157 if apex_dir in self._folder_cache:
158 return self._folder_cache[apex_dir]
159 apex_map = {}
160 dirname = os.path.join(self._apex, apex_dir)
161 if os.path.exists(dirname):
162 for basename in os.listdir(dirname):
163 filepath = os.path.join(dirname, basename)
164 is_dir = os.path.isdir(filepath)
165 is_exec = os.access(filepath, os.X_OK)
166 is_symlink = os.path.islink(filepath)
Roland Levillain88e55692019-07-25 15:57:06 +0100167 size = os.path.getsize(filepath)
168 apex_map[basename] = FSObject(basename, is_dir, is_exec, is_symlink, size)
Roland Levillaindd20d002019-07-19 16:09:47 +0100169 self._folder_cache[apex_dir] = apex_map
170 return apex_map
171
172
Andreas Gampe09123952019-01-30 13:17:02 -0800173class HostApexProvider:
174 def __init__(self, apex, tmpdir):
175 self._tmpdir = tmpdir
Roland Levillain77251f92019-08-09 15:00:04 +0100176 self._folder_cache = {}
Andreas Gampe09123952019-01-30 13:17:02 -0800177 self._payload = os.path.join(self._tmpdir, 'apex_payload.zip')
178 # Extract payload to tmpdir.
Luca Stefani4e91ee92019-03-06 15:08:16 +0100179 apex_zip = zipfile.ZipFile(apex)
180 apex_zip.extract('apex_payload.zip', tmpdir)
Andreas Gampe09123952019-01-30 13:17:02 -0800181
182 def __del__(self):
183 # Delete temps.
184 if os.path.exists(self._payload):
185 os.remove(self._payload)
186
187 def get(self, path):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100188 apex_dir, name = os.path.split(path)
189 if not apex_dir:
190 apex_dir = ''
191 apex_map = self.read_dir(apex_dir)
192 return apex_map[name] if name in apex_map else None
Andreas Gampe09123952019-01-30 13:17:02 -0800193
Luca Stefani4e91ee92019-03-06 15:08:16 +0100194 def read_dir(self, apex_dir):
Roland Levillain77251f92019-08-09 15:00:04 +0100195 if apex_dir in self._folder_cache:
196 return self._folder_cache[apex_dir]
197 if not self._folder_cache:
Andreas Gampe09123952019-01-30 13:17:02 -0800198 self.parse_zip()
Roland Levillain77251f92019-08-09 15:00:04 +0100199 if apex_dir in self._folder_cache:
200 return self._folder_cache[apex_dir]
Andreas Gampe09123952019-01-30 13:17:02 -0800201 return {}
202
203 def parse_zip(self):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100204 apex_zip = zipfile.ZipFile(self._payload)
205 infos = apex_zip.infolist()
Andreas Gampe09123952019-01-30 13:17:02 -0800206 for zipinfo in infos:
207 path = zipinfo.filename
208
209 # Assume no empty file is stored.
210 assert path
211
212 def get_octal(val, index):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100213 return (val >> (index * 3)) & 0x7
214
Andreas Gampe09123952019-01-30 13:17:02 -0800215 def bits_is_exec(val):
216 # TODO: Enforce group/other, too?
217 return get_octal(val, 2) & 1 == 1
218
219 is_zipinfo = True
220 while path:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100221 apex_dir, base = os.path.split(path)
Andreas Gampe09123952019-01-30 13:17:02 -0800222 # TODO: If directories are stored, base will be empty.
223
Roland Levillain77251f92019-08-09 15:00:04 +0100224 if apex_dir not in self._folder_cache:
225 self._folder_cache[apex_dir] = {}
226 dir_map = self._folder_cache[apex_dir]
Luca Stefani4e91ee92019-03-06 15:08:16 +0100227 if base not in dir_map:
Andreas Gampe09123952019-01-30 13:17:02 -0800228 if is_zipinfo:
229 bits = (zipinfo.external_attr >> 16) & 0xFFFF
230 is_dir = get_octal(bits, 4) == 4
231 is_symlink = get_octal(bits, 4) == 2
232 is_exec = bits_is_exec(bits)
Roland Levillain88e55692019-07-25 15:57:06 +0100233 size = zipinfo.file_size
Andreas Gampe09123952019-01-30 13:17:02 -0800234 else:
235 is_exec = False # Seems we can't get this easily?
236 is_symlink = False
237 is_dir = True
Roland Levillain88e55692019-07-25 15:57:06 +0100238 # Use a negative value as an indicator of undefined/unknown size.
239 size = -1
240 dir_map[base] = FSObject(base, is_dir, is_exec, is_symlink, size)
Andreas Gampe09123952019-01-30 13:17:02 -0800241 is_zipinfo = False
Luca Stefani4e91ee92019-03-06 15:08:16 +0100242 path = apex_dir
243
Andreas Gampe09123952019-01-30 13:17:02 -0800244
Andreas Gampeeb555b82019-01-30 14:47:49 -0800245# DO NOT USE DIRECTLY! This is an "abstract" base class.
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000246class Checker:
247 def __init__(self, provider):
248 self._provider = provider
249 self._errors = 0
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000250 self._expected_file_globs = set()
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000251
Luca Stefani4e91ee92019-03-06 15:08:16 +0100252 def fail(self, msg, *fail_args):
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000253 self._errors += 1
Martin Stjernholm2babede2019-03-18 21:04:49 +0000254 logging.error(msg, *fail_args)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000255
256 def error_count(self):
257 return self._errors
Luca Stefani4e91ee92019-03-06 15:08:16 +0100258
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800259 def reset_errors(self):
260 self._errors = 0
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000261
Martin Stjernholm2babede2019-03-18 21:04:49 +0000262 def is_file(self, path):
263 fs_object = self._provider.get(path)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000264 if fs_object is None:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100265 return False, 'Could not find %s'
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000266 if fs_object.is_dir:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100267 return False, '%s is a directory'
268 return True, ''
Andreas Gampea0242cf2019-01-29 13:01:23 -0800269
Ulyana Trafimovichfa2b2d32019-11-07 10:47:34 +0000270 def is_dir(self, path):
271 fs_object = self._provider.get(path)
272 if fs_object is None:
273 return False, 'Could not find %s'
274 if not fs_object.is_dir:
275 return False, '%s is not a directory'
276 return True, ''
277
Martin Stjernholm2babede2019-03-18 21:04:49 +0000278 def check_file(self, path):
279 ok, msg = self.is_file(path)
280 if not ok:
281 self.fail(msg, path)
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000282 self._expected_file_globs.add(path)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000283 return ok
Luca Stefani4e91ee92019-03-06 15:08:16 +0100284
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000285 def check_executable(self, filename):
Martin Stjernholm2babede2019-03-18 21:04:49 +0000286 path = 'bin/%s' % filename
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000287 if not self.check_file(path):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100288 return
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000289 if not self._provider.get(path).is_exec:
290 self.fail('%s is not executable', path)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000291
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000292 def check_executable_symlink(self, filename):
Martin Stjernholm2babede2019-03-18 21:04:49 +0000293 path = 'bin/%s' % filename
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000294 fs_object = self._provider.get(path)
295 if fs_object is None:
296 self.fail('Could not find %s', path)
Luca Stefani4e91ee92019-03-06 15:08:16 +0100297 return
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000298 if fs_object.is_dir:
299 self.fail('%s is a directory', path)
Luca Stefani4e91ee92019-03-06 15:08:16 +0100300 return
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000301 if not fs_object.is_symlink:
302 self.fail('%s is not a symlink', path)
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000303 self._expected_file_globs.add(path)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000304
Ulyana Trafimovichfa2b2d32019-11-07 10:47:34 +0000305 def arch_dirs_for_path(self, path):
306 # Look for target-specific subdirectories for the given directory path.
307 # This is needed because the list of build targets is not propagated
308 # to this script.
Nicolas Geoffray0c63f762019-10-30 11:26:31 +0000309 #
Ulyana Trafimovichfa2b2d32019-11-07 10:47:34 +0000310 # TODO: Pass build target information to this script and fix all places
311 # where this function in used (or similar workarounds).
312 dirs = []
Nicolas Geoffray0c63f762019-10-30 11:26:31 +0000313 for arch in ARCHS:
Ulyana Trafimovichfa2b2d32019-11-07 10:47:34 +0000314 dir = '%s/%s' % (path, arch)
315 found, _ = self.is_dir(dir)
316 if found:
317 dirs.append(dir)
318 return dirs
319
320 def check_art_test_executable(self, filename):
321 dirs = self.arch_dirs_for_path(ART_TEST_DIR)
322 if not dirs:
Roland Levillain61f07162019-06-26 12:44:04 +0100323 self.fail('ART test binary missing: %s', filename)
Ulyana Trafimovichfa2b2d32019-11-07 10:47:34 +0000324 for dir in dirs:
325 test_path = '%s/%s' % (dir, filename)
326 self._expected_file_globs.add(test_path)
327 if not self._provider.get(test_path).is_exec:
328 self.fail('%s is not executable', test_path)
Roland Levillain61f07162019-06-26 12:44:04 +0100329
Martin Stjernholm2babede2019-03-18 21:04:49 +0000330 def check_single_library(self, filename):
331 lib_path = 'lib/%s' % filename
332 lib64_path = 'lib64/%s' % filename
333 lib_is_file, _ = self.is_file(lib_path)
334 if lib_is_file:
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000335 self._expected_file_globs.add(lib_path)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000336 lib64_is_file, _ = self.is_file(lib64_path)
337 if lib64_is_file:
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000338 self._expected_file_globs.add(lib64_path)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000339 if not lib_is_file and not lib64_is_file:
340 self.fail('Library missing: %s', filename)
Andreas Gampea0242cf2019-01-29 13:01:23 -0800341
Ulyana Trafimovichfa2b2d32019-11-07 10:47:34 +0000342 def check_dexpreopt(self, basename):
343 dirs = self.arch_dirs_for_path('javalib')
344 if not dirs:
345 self.fail('Could not find javalib directory for any arch.')
346 for dir in dirs:
347 for ext in ['art', 'oat', 'vdex']:
348 self.check_file('%s/%s.%s' % (dir, basename, ext))
349
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000350 def check_java_library(self, basename):
351 return self.check_file('javalib/%s.jar' % basename)
Andreas Gampe09123952019-01-30 13:17:02 -0800352
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000353 def ignore_path(self, path_glob):
354 self._expected_file_globs.add(path_glob)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000355
Roland Levillain61f07162019-06-26 12:44:04 +0100356 def check_optional_art_test_executable(self, filename):
Orion Hodsonaf3ed622019-10-03 16:30:54 +0100357 for arch in ARCHS:
358 self.ignore_path('%s/%s/%s' % (ART_TEST_DIR, arch, filename))
Roland Levillain61f07162019-06-26 12:44:04 +0100359
Martin Stjernholm2babede2019-03-18 21:04:49 +0000360 def check_no_superfluous_files(self, dir_path):
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000361 paths = []
Martin Stjernholm2babede2019-03-18 21:04:49 +0000362 for name in sorted(self._provider.read_dir(dir_path).keys()):
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000363 if name not in ('.', '..'):
364 paths.append(os.path.join(dir_path, name))
365 expected_paths = set()
366 dir_prefix = dir_path + '/'
367 for path_glob in self._expected_file_globs:
368 expected_paths |= set(fnmatch.filter(paths, path_glob))
369 # If there are globs in subdirectories of dir_path we want to match their
370 # path segments at this directory level.
371 if path_glob.startswith(dir_prefix):
372 subpath = path_glob[len(dir_prefix):]
373 subpath_first_segment, _, _ = subpath.partition('/')
374 expected_paths |= set(fnmatch.filter(paths, dir_prefix + subpath_first_segment))
375 for unexpected_path in set(paths) - expected_paths:
376 self.fail('Unexpected file \'%s\'', unexpected_path)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000377
Andreas Gampeeb555b82019-01-30 14:47:49 -0800378 # Just here for docs purposes, even if it isn't good Python style.
379
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000380 def check_symlinked_multilib_executable(self, filename):
381 """Check bin/filename32, and/or bin/filename64, with symlink bin/filename."""
Andreas Gampeeb555b82019-01-30 14:47:49 -0800382 raise NotImplementedError
383
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000384 def check_multilib_executable(self, filename):
385 """Check bin/filename for 32 bit, and/or bin/filename64."""
Andreas Gampeeb555b82019-01-30 14:47:49 -0800386 raise NotImplementedError
387
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000388 def check_native_library(self, basename):
389 """Check lib/basename.so, and/or lib64/basename.so."""
Martin Stjernholm2babede2019-03-18 21:04:49 +0000390 raise NotImplementedError
391
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000392 def check_optional_native_library(self, basename_glob):
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000393 """Allow lib/basename.so and/or lib64/basename.so to exist."""
Martin Stjernholmb81fe232019-03-25 17:38:04 +0000394 raise NotImplementedError
395
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000396 def check_prefer64_library(self, basename):
397 """Check lib64/basename.so, or lib/basename.so on 32 bit only."""
Andreas Gampeeb555b82019-01-30 14:47:49 -0800398 raise NotImplementedError
399
400
401class Arch32Checker(Checker):
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000402 def check_symlinked_multilib_executable(self, filename):
403 self.check_executable('%s32' % filename)
404 self.check_executable_symlink(filename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800405
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000406 def check_multilib_executable(self, filename):
407 self.check_executable(filename)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000408
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000409 def check_native_library(self, basename):
Andreas Gampeeb555b82019-01-30 14:47:49 -0800410 # TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve
411 # the precision of this test?
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000412 self.check_file('lib/%s.so' % basename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800413
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000414 def check_optional_native_library(self, basename_glob):
415 self.ignore_path('lib/%s.so' % basename_glob)
Martin Stjernholmb81fe232019-03-25 17:38:04 +0000416
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000417 def check_prefer64_library(self, basename):
418 self.check_native_library(basename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800419
420
421class Arch64Checker(Checker):
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000422 def check_symlinked_multilib_executable(self, filename):
423 self.check_executable('%s64' % filename)
424 self.check_executable_symlink(filename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800425
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000426 def check_multilib_executable(self, filename):
427 self.check_executable('%s64' % filename)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000428
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000429 def check_native_library(self, basename):
Andreas Gampeeb555b82019-01-30 14:47:49 -0800430 # TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve
431 # the precision of this test?
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000432 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('lib64/%s.so' % basename_glob)
Martin Stjernholmb81fe232019-03-25 17:38:04 +0000436
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000437 def check_prefer64_library(self, basename):
438 self.check_native_library(basename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800439
440
441class MultilibChecker(Checker):
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000442 def check_symlinked_multilib_executable(self, filename):
443 self.check_executable('%s32' % filename)
444 self.check_executable('%s64' % filename)
445 self.check_executable_symlink(filename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800446
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000447 def check_multilib_executable(self, filename):
448 self.check_executable('%s64' % filename)
449 self.check_executable(filename)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000450
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000451 def check_native_library(self, basename):
Andreas Gampeeb555b82019-01-30 14:47:49 -0800452 # TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve
453 # the precision of this test?
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000454 self.check_file('lib/%s.so' % basename)
455 self.check_file('lib64/%s.so' % basename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800456
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000457 def check_optional_native_library(self, basename_glob):
458 self.ignore_path('lib/%s.so' % basename_glob)
459 self.ignore_path('lib64/%s.so' % basename_glob)
Martin Stjernholmb81fe232019-03-25 17:38:04 +0000460
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000461 def check_prefer64_library(self, basename):
462 self.check_file('lib64/%s.so' % basename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800463
464
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800465class ReleaseChecker:
466 def __init__(self, checker):
467 self._checker = checker
Luca Stefani4e91ee92019-03-06 15:08:16 +0100468
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000469 def __str__(self):
470 return 'Release Checker'
471
472 def run(self):
Martin Stjernholm023c2182019-03-28 15:52:32 +0000473 # Check the APEX manifest.
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800474 self._checker.check_file('apex_manifest.json')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000475
Martin Stjernholm77f17662019-04-03 17:08:21 +0100476 # Check binaries for ART.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000477 self._checker.check_executable('dex2oat')
Martin Stjernholm77f17662019-04-03 17:08:21 +0100478 self._checker.check_executable('dexdump')
479 self._checker.check_executable('dexlist')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000480 self._checker.check_executable('dexoptanalyzer')
481 self._checker.check_executable('profman')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000482 self._checker.check_symlinked_multilib_executable('dalvikvm')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000483
Martin Stjernholm023c2182019-03-28 15:52:32 +0000484 # Check exported libraries for ART.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000485 self._checker.check_native_library('libdexfile_external')
486 self._checker.check_native_library('libnativebridge')
487 self._checker.check_native_library('libnativehelper')
488 self._checker.check_native_library('libnativeloader')
Josh Gao77e61872019-10-17 12:24:34 -0700489 self._checker.check_native_library('libadbconnection_server')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000490
491 # Check internal libraries for ART.
492 self._checker.check_native_library('libadbconnection')
493 self._checker.check_native_library('libart')
494 self._checker.check_native_library('libart-compiler')
495 self._checker.check_native_library('libart-dexlayout')
496 self._checker.check_native_library('libartbase')
497 self._checker.check_native_library('libartpalette')
498 self._checker.check_native_library('libdexfile')
499 self._checker.check_native_library('libdexfile_support')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000500 self._checker.check_native_library('libopenjdkjvm')
501 self._checker.check_native_library('libopenjdkjvmti')
502 self._checker.check_native_library('libprofile')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000503 self._checker.check_native_library('libsigchain')
504
505 # Check java libraries for Managed Core Library.
506 self._checker.check_java_library('apache-xml')
507 self._checker.check_java_library('bouncycastle')
Victor Chang759845f2019-08-06 16:04:36 +0100508 self._checker.check_java_library('core-icu4j')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000509 self._checker.check_java_library('core-libart')
510 self._checker.check_java_library('core-oj')
511 self._checker.check_java_library('okhttp')
512
513 # Check internal native libraries for Managed Core Library.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000514 self._checker.check_native_library('libjavacore')
515 self._checker.check_native_library('libopenjdk')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000516
Martin Stjernholm2babede2019-03-18 21:04:49 +0000517 # Check internal native library dependencies.
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000518 #
Martin Stjernholm2babede2019-03-18 21:04:49 +0000519 # Any internal dependency not listed here will cause a failure in
520 # NoSuperfluousLibrariesChecker. Internal dependencies are generally just
521 # implementation details, but in the release package we want to track them
522 # because a) they add to the package size and the RAM usage (in particular
523 # if the library is also present in /system or another APEX and hence might
524 # get loaded twice through linker namespace separation), and b) we need to
525 # catch invalid dependencies on /system or other APEXes that should go
526 # through an exported library with stubs (b/128708192 tracks implementing a
527 # better approach for that).
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000528 self._checker.check_native_library('libbacktrace')
529 self._checker.check_native_library('libbase')
530 self._checker.check_native_library('libc++')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000531 self._checker.check_native_library('libdt_fd_forward')
532 self._checker.check_native_library('libdt_socket')
533 self._checker.check_native_library('libjdwp')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000534 self._checker.check_native_library('liblzma')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000535 self._checker.check_native_library('libnpt')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000536 self._checker.check_native_library('libunwindstack')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000537 self._checker.check_native_library('libziparchive')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000538 self._checker.check_optional_native_library('libvixl') # Only on ARM/ARM64
Martin Stjernholm2babede2019-03-18 21:04:49 +0000539
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000540 # Allow extra dependencies that appear in ASAN builds.
541 self._checker.check_optional_native_library('libclang_rt.asan*')
542 self._checker.check_optional_native_library('libclang_rt.hwasan*')
543 self._checker.check_optional_native_library('libclang_rt.ubsan*')
544
Ulyana Trafimovichfa2b2d32019-11-07 10:47:34 +0000545 # Check dexpreopt files for libcore bootclasspath jars
546 self._checker.check_dexpreopt('boot')
547 self._checker.check_dexpreopt('boot-apache-xml')
548 self._checker.check_dexpreopt('boot-bouncycastle')
549 self._checker.check_dexpreopt('boot-core-icu4j')
550 self._checker.check_dexpreopt('boot-core-libart')
551 self._checker.check_dexpreopt('boot-okhttp')
Luca Stefani4e91ee92019-03-06 15:08:16 +0100552
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800553class ReleaseTargetChecker:
554 def __init__(self, checker):
555 self._checker = checker
Luca Stefani4e91ee92019-03-06 15:08:16 +0100556
Andreas Gampe09123952019-01-30 13:17:02 -0800557 def __str__(self):
558 return 'Release (Target) Checker'
559
560 def run(self):
Martin Stjernholm023c2182019-03-28 15:52:32 +0000561 # Check binaries for ART.
Martin Stjernholm023c2182019-03-28 15:52:32 +0000562 self._checker.check_executable('oatdump')
563
564 # Check internal libraries for ART.
565 self._checker.check_prefer64_library('libart-disassembler')
Florian Mayer07710c52019-09-16 15:53:38 +0000566 self._checker.check_native_library('libperfetto_hprof')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000567
Martin Stjernholm023c2182019-03-28 15:52:32 +0000568 # Check exported native libraries for Managed Core Library.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000569 self._checker.check_native_library('libandroidicu')
570 self._checker.check_native_library('libandroidio')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000571
572 # Check internal native library dependencies.
573 self._checker.check_native_library('libcrypto')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000574 self._checker.check_native_library('libexpat')
575 self._checker.check_native_library('libicui18n')
576 self._checker.check_native_library('libicuuc')
Victor Chang65ae6692019-10-11 14:17:21 +0100577 self._checker.check_native_library('libicu_jni')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000578 self._checker.check_native_library('libpac')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000579 self._checker.check_native_library('libz')
Martin Stjernholm2babede2019-03-18 21:04:49 +0000580
Martin Stjernholmec2db5f2019-09-04 20:54:57 +0100581 # TODO(b/139046641): Fix proper 2nd arch checks. For now, just ignore these
582 # directories.
583 self._checker.ignore_path('bin/arm')
584 self._checker.ignore_path('lib/arm')
585 self._checker.ignore_path('lib64/arm')
586
Luca Stefani4e91ee92019-03-06 15:08:16 +0100587
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800588class ReleaseHostChecker:
589 def __init__(self, checker):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100590 self._checker = checker
591
Andreas Gampe09123952019-01-30 13:17:02 -0800592 def __str__(self):
593 return 'Release (Host) Checker'
594
595 def run(self):
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000596 # Check binaries for ART.
597 self._checker.check_executable('hprof-conv')
598 self._checker.check_symlinked_multilib_executable('dex2oatd')
599
Martin Stjernholm023c2182019-03-28 15:52:32 +0000600 # Check exported native libraries for Managed Core Library.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000601 self._checker.check_native_library('libandroidicu-host')
602 self._checker.check_native_library('libandroidio')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000603
604 # Check internal libraries for Managed Core Library.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000605 self._checker.check_native_library('libexpat-host')
606 self._checker.check_native_library('libicui18n-host')
607 self._checker.check_native_library('libicuuc-host')
Victor Chang65ae6692019-10-11 14:17:21 +0100608 self._checker.check_native_library('libicu_jni')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000609 self._checker.check_native_library('libz-host')
Andreas Gampe09123952019-01-30 13:17:02 -0800610
Luca Stefani4e91ee92019-03-06 15:08:16 +0100611
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800612class DebugChecker:
613 def __init__(self, checker):
614 self._checker = checker
Luca Stefani4e91ee92019-03-06 15:08:16 +0100615
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000616 def __str__(self):
617 return 'Debug Checker'
618
619 def run(self):
Martin Stjernholm023c2182019-03-28 15:52:32 +0000620 # Check binaries for ART.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000621 self._checker.check_executable('dexdiag')
Roland Levillain6dd62122019-06-18 19:10:21 +0100622 self._checker.check_executable('dexanalyze')
623 self._checker.check_executable('dexlayout')
624 self._checker.check_symlinked_multilib_executable('imgdiag')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000625
Martin Stjernholm023c2182019-03-28 15:52:32 +0000626 # Check debug binaries for ART.
Roland Levillain6dd62122019-06-18 19:10:21 +0100627 self._checker.check_executable('dexlayoutd')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000628 self._checker.check_executable('dexoptanalyzerd')
Roland Levillain6dd62122019-06-18 19:10:21 +0100629 self._checker.check_symlinked_multilib_executable('imgdiagd')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000630 self._checker.check_executable('profmand')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000631
Martin Stjernholm023c2182019-03-28 15:52:32 +0000632 # Check internal libraries for ART.
633 self._checker.check_native_library('libadbconnectiond')
Roland Levillain4d6f24d2019-10-02 16:47:36 +0100634 self._checker.check_native_library('libart-disassembler')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000635 self._checker.check_native_library('libartbased')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000636 self._checker.check_native_library('libartd')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000637 self._checker.check_native_library('libartd-compiler')
638 self._checker.check_native_library('libartd-dexlayout')
Roland Levillain4d6f24d2019-10-02 16:47:36 +0100639 self._checker.check_native_library('libartd-disassembler')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000640 self._checker.check_native_library('libdexfiled')
641 self._checker.check_native_library('libopenjdkjvmd')
642 self._checker.check_native_library('libopenjdkjvmtid')
643 self._checker.check_native_library('libprofiled')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000644
645 # Check internal libraries for Managed Core Library.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000646 self._checker.check_native_library('libopenjdkd')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000647
Luca Stefani4e91ee92019-03-06 15:08:16 +0100648
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800649class DebugTargetChecker:
650 def __init__(self, checker):
651 self._checker = checker
Luca Stefani4e91ee92019-03-06 15:08:16 +0100652
Andreas Gampea0242cf2019-01-29 13:01:23 -0800653 def __str__(self):
654 return 'Debug (Target) Checker'
655
656 def run(self):
Martin Stjernholm023c2182019-03-28 15:52:32 +0000657 # Check ART debug binaries.
Roland Levillain9a45d012019-06-05 13:54:02 +0100658 self._checker.check_executable('dex2oatd')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000659 self._checker.check_executable('oatdumpd')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000660
661 # Check ART internal libraries.
Martin Stjernholm356864a2019-04-30 16:22:17 +0100662 self._checker.check_native_library('libdexfiled_external')
Florian Mayer07710c52019-09-16 15:53:38 +0000663 self._checker.check_native_library('libperfetto_hprofd')
Andreas Gampea0242cf2019-01-29 13:01:23 -0800664
Martin Stjernholm2babede2019-03-18 21:04:49 +0000665 # Check internal native library dependencies.
666 #
667 # Like in the release package, we check that we don't get other dependencies
668 # besides those listed here. In this case the concern is not bloat, but
669 # rather that we don't get behavioural differences between user (release)
670 # and userdebug/eng builds, which could happen if the debug package has
671 # duplicate library instances where releases don't. In other words, it's
672 # uncontroversial to add debug-only dependencies, as long as they don't make
673 # assumptions on having a single global state (ideally they should have
674 # double_loadable:true, cf. go/double_loadable). Also, like in the release
675 # package we need to look out for dependencies that should go through
676 # exported library stubs (until b/128708192 is fixed).
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000677 self._checker.check_optional_native_library('libvixld') # Only on ARM/ARM64
Martin Stjernholm77f17662019-04-03 17:08:21 +0100678 self._checker.check_prefer64_library('libmeminfo')
679 self._checker.check_prefer64_library('libprocinfo')
Martin Stjernholm2babede2019-03-18 21:04:49 +0000680
681
Roland Levillain61f07162019-06-26 12:44:04 +0100682class TestingTargetChecker:
683 def __init__(self, checker):
684 self._checker = checker
685
686 def __str__(self):
687 return 'Testing (Target) Checker'
688
689 def run(self):
690 # Check cmdline tests.
691 self._checker.check_optional_art_test_executable('cmdline_parser_test')
692
693 # Check compiler tests.
694 self._checker.check_art_test_executable('atomic_dex_ref_map_test')
695 self._checker.check_art_test_executable('bounds_check_elimination_test')
696 self._checker.check_art_test_executable('codegen_test')
697 self._checker.check_art_test_executable('compiled_method_storage_test')
698 self._checker.check_art_test_executable('data_type_test')
699 self._checker.check_art_test_executable('dedupe_set_test')
700 self._checker.check_art_test_executable('dominator_test')
701 self._checker.check_art_test_executable('dwarf_test')
702 self._checker.check_art_test_executable('exception_test')
703 self._checker.check_art_test_executable('find_loops_test')
704 self._checker.check_art_test_executable('graph_checker_test')
705 self._checker.check_art_test_executable('graph_test')
706 self._checker.check_art_test_executable('gvn_test')
707 self._checker.check_art_test_executable('induction_var_analysis_test')
708 self._checker.check_art_test_executable('induction_var_range_test')
709 self._checker.check_art_test_executable('jni_cfi_test')
710 self._checker.check_art_test_executable('jni_compiler_test')
711 self._checker.check_art_test_executable('licm_test')
712 self._checker.check_art_test_executable('linker_patch_test')
713 self._checker.check_art_test_executable('live_interval_test')
714 self._checker.check_art_test_executable('load_store_analysis_test')
715 self._checker.check_art_test_executable('loop_optimization_test')
716 self._checker.check_art_test_executable('nodes_test')
717 self._checker.check_art_test_executable('nodes_vector_test')
718 self._checker.check_art_test_executable('optimizing_cfi_test')
719 self._checker.check_art_test_executable('output_stream_test')
720 self._checker.check_art_test_executable('parallel_move_test')
721 self._checker.check_art_test_executable('pretty_printer_test')
722 self._checker.check_art_test_executable('reference_type_propagation_test')
723 self._checker.check_art_test_executable('scheduler_test')
724 self._checker.check_art_test_executable('select_generator_test')
725 self._checker.check_art_test_executable('side_effects_test')
726 self._checker.check_art_test_executable('src_map_elem_test')
727 self._checker.check_art_test_executable('ssa_liveness_analysis_test')
728 self._checker.check_art_test_executable('ssa_test')
729 self._checker.check_art_test_executable('stack_map_test')
730 self._checker.check_art_test_executable('superblock_cloner_test')
731 self._checker.check_art_test_executable('suspend_check_test')
732 self._checker.check_art_test_executable('swap_space_test')
733 # These tests depend on a specific code generator and are conditionally included.
734 self._checker.check_optional_art_test_executable('constant_folding_test')
735 self._checker.check_optional_art_test_executable('dead_code_elimination_test')
736 self._checker.check_optional_art_test_executable('linearize_test')
737 self._checker.check_optional_art_test_executable('live_ranges_test')
738 self._checker.check_optional_art_test_executable('liveness_test')
739 self._checker.check_optional_art_test_executable('managed_register_arm64_test')
740 self._checker.check_optional_art_test_executable('managed_register_arm_test')
741 self._checker.check_optional_art_test_executable('managed_register_mips64_test')
742 self._checker.check_optional_art_test_executable('managed_register_x86_64_test')
743 self._checker.check_optional_art_test_executable('managed_register_x86_test')
744 self._checker.check_optional_art_test_executable('register_allocator_test')
745
746 # Check dex2oat tests.
747 self._checker.check_art_test_executable('compiler_driver_test')
748 self._checker.check_art_test_executable('dex2oat_image_test')
749 self._checker.check_art_test_executable('dex2oat_test')
750 self._checker.check_art_test_executable('dex_to_dex_decompiler_test')
751 self._checker.check_art_test_executable('elf_writer_test')
752 self._checker.check_art_test_executable('image_test')
753 self._checker.check_art_test_executable('image_write_read_test')
754 self._checker.check_art_test_executable('index_bss_mapping_encoder_test')
755 self._checker.check_art_test_executable('multi_oat_relative_patcher_test')
756 self._checker.check_art_test_executable('oat_writer_test')
757 self._checker.check_art_test_executable('verifier_deps_test')
758 # These tests depend on a specific code generator and are conditionally included.
759 self._checker.check_optional_art_test_executable('relative_patcher_arm64_test')
760 self._checker.check_optional_art_test_executable('relative_patcher_mips32r6_test')
761 self._checker.check_optional_art_test_executable('relative_patcher_mips64_test')
762 self._checker.check_optional_art_test_executable('relative_patcher_mips_test')
763 self._checker.check_optional_art_test_executable('relative_patcher_thumb2_test')
764 self._checker.check_optional_art_test_executable('relative_patcher_x86_64_test')
765 self._checker.check_optional_art_test_executable('relative_patcher_x86_test')
766
767 # Check dexanalyze tests.
768 self._checker.check_optional_art_test_executable('dexanalyze_test')
769
770 # Check dexdiag tests.
771 self._checker.check_optional_art_test_executable('dexdiag_test')
772
773 # Check dexdump tests.
774 self._checker.check_art_test_executable('dexdump_test')
775
776 # Check dexlayout tests.
777 self._checker.check_optional_art_test_executable('dexlayout_test')
778
779 # Check dexlist tests.
780 self._checker.check_art_test_executable('dexlist_test')
781
782 # Check dexoptanalyzer tests.
783 self._checker.check_art_test_executable('dexoptanalyzer_test')
784
785 # Check imgdiag tests.
786 self._checker.check_art_test_executable('imgdiag_test')
787
788 # Check libartbase tests.
789 self._checker.check_art_test_executable('arena_allocator_test')
790 self._checker.check_art_test_executable('bit_field_test')
791 self._checker.check_art_test_executable('bit_memory_region_test')
792 self._checker.check_art_test_executable('bit_string_test')
793 self._checker.check_art_test_executable('bit_struct_test')
794 self._checker.check_art_test_executable('bit_table_test')
795 self._checker.check_art_test_executable('bit_utils_test')
796 self._checker.check_art_test_executable('bit_vector_test')
797 self._checker.check_art_test_executable('fd_file_test')
798 self._checker.check_art_test_executable('file_utils_test')
799 self._checker.check_art_test_executable('hash_set_test')
800 self._checker.check_art_test_executable('hex_dump_test')
801 self._checker.check_art_test_executable('histogram_test')
802 self._checker.check_art_test_executable('indenter_test')
803 self._checker.check_art_test_executable('instruction_set_test')
804 self._checker.check_art_test_executable('intrusive_forward_list_test')
805 self._checker.check_art_test_executable('leb128_test')
806 self._checker.check_art_test_executable('logging_test')
807 self._checker.check_art_test_executable('mem_map_test')
808 self._checker.check_art_test_executable('membarrier_test')
809 self._checker.check_art_test_executable('memfd_test')
810 self._checker.check_art_test_executable('memory_region_test')
811 self._checker.check_art_test_executable('memory_type_table_test')
812 self._checker.check_art_test_executable('safe_copy_test')
813 self._checker.check_art_test_executable('scoped_flock_test')
814 self._checker.check_art_test_executable('time_utils_test')
815 self._checker.check_art_test_executable('transform_array_ref_test')
816 self._checker.check_art_test_executable('transform_iterator_test')
817 self._checker.check_art_test_executable('utils_test')
818 self._checker.check_art_test_executable('variant_map_test')
819 self._checker.check_art_test_executable('zip_archive_test')
820
821 # Check libartpalette tests.
822 self._checker.check_art_test_executable('palette_test')
823
824 # Check libdexfile tests.
825 self._checker.check_art_test_executable('art_dex_file_loader_test')
826 self._checker.check_art_test_executable('art_libdexfile_support_tests')
827 self._checker.check_art_test_executable('class_accessor_test')
828 self._checker.check_art_test_executable('code_item_accessors_test')
829 self._checker.check_art_test_executable('compact_dex_file_test')
830 self._checker.check_art_test_executable('compact_offset_table_test')
831 self._checker.check_art_test_executable('descriptors_names_test')
832 self._checker.check_art_test_executable('dex_file_loader_test')
833 self._checker.check_art_test_executable('dex_file_verifier_test')
834 self._checker.check_art_test_executable('dex_instruction_test')
835 self._checker.check_art_test_executable('primitive_test')
836 self._checker.check_art_test_executable('string_reference_test')
837 self._checker.check_art_test_executable('test_dex_file_builder_test')
838 self._checker.check_art_test_executable('type_lookup_table_test')
839 self._checker.check_art_test_executable('utf_test')
840
841 # Check libprofile tests.
842 self._checker.check_optional_art_test_executable('profile_boot_info_test')
843 self._checker.check_optional_art_test_executable('profile_compilation_info_test')
844
845 # Check oatdump tests.
846 self._checker.check_art_test_executable('oatdump_app_test')
847 self._checker.check_art_test_executable('oatdump_image_test')
848 self._checker.check_art_test_executable('oatdump_test')
849
850 # Check profman tests.
851 self._checker.check_art_test_executable('profile_assistant_test')
852
853 # Check runtime compiler tests.
854 self._checker.check_art_test_executable('module_exclusion_test')
855 self._checker.check_art_test_executable('reflection_test')
856
857 # Check runtime tests.
858 self._checker.check_art_test_executable('arch_test')
859 self._checker.check_art_test_executable('barrier_test')
860 self._checker.check_art_test_executable('card_table_test')
861 self._checker.check_art_test_executable('cha_test')
862 self._checker.check_art_test_executable('class_linker_test')
863 self._checker.check_art_test_executable('class_loader_context_test')
864 self._checker.check_art_test_executable('class_table_test')
865 self._checker.check_art_test_executable('compiler_filter_test')
866 self._checker.check_art_test_executable('dex_cache_test')
867 self._checker.check_art_test_executable('dlmalloc_space_random_test')
868 self._checker.check_art_test_executable('dlmalloc_space_static_test')
869 self._checker.check_art_test_executable('entrypoints_order_test')
870 self._checker.check_art_test_executable('exec_utils_test')
871 self._checker.check_art_test_executable('gtest_test')
872 self._checker.check_art_test_executable('handle_scope_test')
873 self._checker.check_art_test_executable('heap_test')
874 self._checker.check_art_test_executable('heap_verification_test')
875 self._checker.check_art_test_executable('hidden_api_test')
876 self._checker.check_art_test_executable('image_space_test')
877 self._checker.check_art_test_executable('immune_spaces_test')
878 self._checker.check_art_test_executable('imtable_test')
879 self._checker.check_art_test_executable('indirect_reference_table_test')
880 self._checker.check_art_test_executable('instruction_set_features_arm64_test')
881 self._checker.check_art_test_executable('instruction_set_features_arm_test')
882 self._checker.check_art_test_executable('instruction_set_features_mips64_test')
883 self._checker.check_art_test_executable('instruction_set_features_mips_test')
884 self._checker.check_art_test_executable('instruction_set_features_test')
885 self._checker.check_art_test_executable('instruction_set_features_x86_64_test')
886 self._checker.check_art_test_executable('instruction_set_features_x86_test')
887 self._checker.check_art_test_executable('instrumentation_test')
888 self._checker.check_art_test_executable('intern_table_test')
889 self._checker.check_art_test_executable('java_vm_ext_test')
890 self._checker.check_art_test_executable('jdwp_options_test')
891 self._checker.check_art_test_executable('jit_memory_region_test')
892 self._checker.check_art_test_executable('jni_internal_test')
893 self._checker.check_art_test_executable('large_object_space_test')
894 self._checker.check_art_test_executable('math_entrypoints_test')
895 self._checker.check_art_test_executable('memcmp16_test')
896 self._checker.check_art_test_executable('method_handles_test')
897 self._checker.check_art_test_executable('method_type_test')
898 self._checker.check_art_test_executable('method_verifier_test')
899 self._checker.check_art_test_executable('mod_union_table_test')
900 self._checker.check_art_test_executable('monitor_pool_test')
901 self._checker.check_art_test_executable('monitor_test')
902 self._checker.check_art_test_executable('mutex_test')
903 self._checker.check_art_test_executable('oat_file_assistant_test')
904 self._checker.check_art_test_executable('oat_file_test')
905 self._checker.check_art_test_executable('object_test')
906 self._checker.check_art_test_executable('parsed_options_test')
907 self._checker.check_art_test_executable('prebuilt_tools_test')
908 self._checker.check_art_test_executable('profiling_info_test')
Calin Juravlef70dfec2019-10-02 18:58:19 -0700909 self._checker.check_art_test_executable('profile_saver_test')
Roland Levillain61f07162019-06-26 12:44:04 +0100910 self._checker.check_art_test_executable('proxy_test')
911 self._checker.check_art_test_executable('quick_trampoline_entrypoints_test')
912 self._checker.check_art_test_executable('reference_queue_test')
913 self._checker.check_art_test_executable('reference_table_test')
914 self._checker.check_art_test_executable('reg_type_test')
915 self._checker.check_art_test_executable('rosalloc_space_random_test')
916 self._checker.check_art_test_executable('rosalloc_space_static_test')
917 self._checker.check_art_test_executable('runtime_callbacks_test')
918 self._checker.check_art_test_executable('runtime_test')
919 self._checker.check_art_test_executable('safe_math_test')
920 self._checker.check_art_test_executable('space_bitmap_test')
921 self._checker.check_art_test_executable('space_create_test')
922 self._checker.check_art_test_executable('stub_test')
923 self._checker.check_art_test_executable('subtype_check_info_test')
924 self._checker.check_art_test_executable('subtype_check_test')
925 self._checker.check_art_test_executable('system_weak_test')
926 self._checker.check_art_test_executable('task_processor_test')
927 self._checker.check_art_test_executable('thread_pool_test')
928 self._checker.check_art_test_executable('timing_logger_test')
929 self._checker.check_art_test_executable('transaction_test')
930 self._checker.check_art_test_executable('two_runtimes_test')
931 self._checker.check_art_test_executable('unstarted_runtime_test')
932 self._checker.check_art_test_executable('var_handle_test')
933 self._checker.check_art_test_executable('vdex_file_test')
934
935 # Check sigchainlib tests.
936 self._checker.check_art_test_executable('sigchain_test')
937
938 # Check ART test (internal) libraries.
939 self._checker.check_native_library('libart-gtest')
Roland Levillain61f07162019-06-26 12:44:04 +0100940 self._checker.check_native_library('libartd-simulator-container')
941
Andreas Gampe816a5522019-09-11 11:29:49 -0700942 # Check ART test tools.
943 self._checker.check_executable('signal_dumper')
944
Roland Levillain61f07162019-06-26 12:44:04 +0100945
Martin Stjernholm2babede2019-03-18 21:04:49 +0000946class NoSuperfluousBinariesChecker:
947 def __init__(self, checker):
948 self._checker = checker
949
950 def __str__(self):
951 return 'No superfluous binaries checker'
952
953 def run(self):
954 self._checker.check_no_superfluous_files('bin')
955
956
957class NoSuperfluousLibrariesChecker:
958 def __init__(self, checker):
959 self._checker = checker
960
961 def __str__(self):
962 return 'No superfluous libraries checker'
963
964 def run(self):
965 self._checker.check_no_superfluous_files('javalib')
966 self._checker.check_no_superfluous_files('lib')
Martin Stjernholm2babede2019-03-18 21:04:49 +0000967 self._checker.check_no_superfluous_files('lib64')
Martin Stjernholm2babede2019-03-18 21:04:49 +0000968
Andreas Gampeb1d55672019-01-29 22:17:02 +0000969
Roland Levillain61f07162019-06-26 12:44:04 +0100970class NoSuperfluousArtTestsChecker:
971 def __init__(self, checker):
972 self._checker = checker
973
974 def __str__(self):
975 return 'No superfluous ART tests checker'
976
977 def run(self):
Orion Hodsonaf3ed622019-10-03 16:30:54 +0100978 for arch in ARCHS:
979 self._checker.check_no_superfluous_files('%s/%s' % (ART_TEST_DIR, arch))
Roland Levillain61f07162019-06-26 12:44:04 +0100980
981
Luca Stefani4e91ee92019-03-06 15:08:16 +0100982class List:
Roland Levillain77251f92019-08-09 15:00:04 +0100983 def __init__(self, provider, print_size=False):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100984 self._provider = provider
Roland Levillaine91d7872019-07-25 18:56:06 +0100985 self._print_size = print_size
Luca Stefani4e91ee92019-03-06 15:08:16 +0100986
987 def print_list(self):
Roland Levillain09744ac2019-06-06 18:23:02 +0100988
989 def print_list_rec(path):
990 apex_map = self._provider.read_dir(path)
991 if apex_map is None:
992 return
993 apex_map = dict(apex_map)
994 if '.' in apex_map:
995 del apex_map['.']
996 if '..' in apex_map:
997 del apex_map['..']
998 for (_, val) in sorted(apex_map.items()):
999 val_path = os.path.join(path, val.name)
Roland Levillaine91d7872019-07-25 18:56:06 +01001000 if self._print_size:
1001 if val.size < 0:
1002 print('[ n/a ] %s' % val_path)
1003 else:
1004 print('[%11d] %s' % (val.size, val_path))
1005 else:
1006 print(val_path)
Roland Levillain09744ac2019-06-06 18:23:02 +01001007 if val.is_dir:
1008 print_list_rec(val_path)
1009
1010 print_list_rec('')
Luca Stefani4e91ee92019-03-06 15:08:16 +01001011
1012
1013class Tree:
Roland Levillain77251f92019-08-09 15:00:04 +01001014 def __init__(self, provider, title, print_size=False):
Luca Stefani4e91ee92019-03-06 15:08:16 +01001015 print('%s' % title)
1016 self._provider = provider
Luca Stefani4e91ee92019-03-06 15:08:16 +01001017 self._has_next_list = []
Roland Levillain88e55692019-07-25 15:57:06 +01001018 self._print_size = print_size
Luca Stefani4e91ee92019-03-06 15:08:16 +01001019
1020 @staticmethod
1021 def get_vertical(has_next_list):
1022 string = ''
1023 for v in has_next_list:
1024 string += '%s ' % ('│' if v else ' ')
1025 return string
1026
1027 @staticmethod
1028 def get_last_vertical(last):
1029 return '└── ' if last else '├── '
1030
1031 def print_tree(self):
Roland Levillain09744ac2019-06-06 18:23:02 +01001032
1033 def print_tree_rec(path):
1034 apex_map = self._provider.read_dir(path)
1035 if apex_map is None:
1036 return
1037 apex_map = dict(apex_map)
1038 if '.' in apex_map:
1039 del apex_map['.']
1040 if '..' in apex_map:
1041 del apex_map['..']
1042 key_list = list(sorted(apex_map.keys()))
1043 for i, key in enumerate(key_list):
1044 prev = self.get_vertical(self._has_next_list)
1045 last = self.get_last_vertical(i == len(key_list) - 1)
1046 val = apex_map[key]
Roland Levillain88e55692019-07-25 15:57:06 +01001047 if self._print_size:
1048 if val.size < 0:
1049 print('%s%s[ n/a ] %s' % (prev, last, val.name))
1050 else:
1051 print('%s%s[%11d] %s' % (prev, last, val.size, val.name))
1052 else:
1053 print('%s%s%s' % (prev, last, val.name))
Roland Levillain09744ac2019-06-06 18:23:02 +01001054 if val.is_dir:
1055 self._has_next_list.append(i < len(key_list) - 1)
1056 val_path = os.path.join(path, val.name)
1057 print_tree_rec(val_path)
1058 self._has_next_list.pop()
1059
1060 print_tree_rec('')
Luca Stefani4e91ee92019-03-06 15:08:16 +01001061
Andreas Gampeb1d55672019-01-29 22:17:02 +00001062
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001063# Note: do not sys.exit early, for __del__ cleanup.
Luca Stefani4e91ee92019-03-06 15:08:16 +01001064def art_apex_test_main(test_args):
Roland Levillaindd20d002019-07-19 16:09:47 +01001065 if test_args.host and test_args.flattened:
1066 logging.error("Both of --host and --flattened set")
1067 return 1
Luca Stefani4e91ee92019-03-06 15:08:16 +01001068 if test_args.list and test_args.tree:
Andreas Gampeb1d55672019-01-29 22:17:02 +00001069 logging.error("Both of --list and --tree set")
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001070 return 1
Roland Levillaine91d7872019-07-25 18:56:06 +01001071 if test_args.size and not (test_args.list or test_args.tree):
1072 logging.error("--size set but neither --list nor --tree set")
Roland Levillain88e55692019-07-25 15:57:06 +01001073 return 1
Martin Stjernholm3cb59a42019-08-07 17:18:29 +01001074 if not test_args.flattened and not test_args.tmpdir:
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001075 logging.error("Need a tmpdir.")
1076 return 1
Martin Stjernholm3cb59a42019-08-07 17:18:29 +01001077 if not test_args.flattened and not test_args.host and not test_args.debugfs:
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001078 logging.error("Need debugfs.")
1079 return 1
1080
Roland Levillaindbd6a142019-10-03 15:08:28 +01001081 if test_args.flavor == FLAVOR_AUTO:
1082 logging.warning('--flavor=auto, trying to autodetect. This may be incorrect!')
1083 for flavor in [ FLAVOR_RELEASE, FLAVOR_DEBUG, FLAVOR_TESTING ]:
1084 flavor_pattern = '*.%s*' % flavor
1085 if fnmatch.fnmatch(test_args.apex, flavor_pattern):
1086 test_args.flavor = flavor
1087 break
1088 if test_args.flavor == FLAVOR_AUTO:
1089 logging.error(' Could not detect APEX flavor, neither \'%s\', \'%s\' nor \'%s\' in \'%s\'',
1090 FLAVOR_RELEASE, FLAVOR_DEBUG, FLAVOR_TESTING, test_args.apex)
1091 return 1
1092
1093 if test_args.host and test_args.flavor == FLAVOR_RELEASE:
1094 logging.error("Using option --host with Release APEX")
1095 return 1
1096 if test_args.host and test_args.flavor == FLAVOR_TESTING:
1097 logging.error("Using option --host with Testing APEX")
1098 return 1
1099
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001100 try:
Luca Stefani4e91ee92019-03-06 15:08:16 +01001101 if test_args.host:
1102 apex_provider = HostApexProvider(test_args.apex, test_args.tmpdir)
Andreas Gampe09123952019-01-30 13:17:02 -08001103 else:
Roland Levillaindd20d002019-07-19 16:09:47 +01001104 if test_args.flattened:
1105 apex_provider = TargetFlattenedApexProvider(test_args.apex)
1106 else:
1107 apex_provider = TargetApexProvider(test_args.apex, test_args.tmpdir, test_args.debugfs)
Luca Stefani4e91ee92019-03-06 15:08:16 +01001108 except (zipfile.BadZipFile, zipfile.LargeZipFile) as e:
Andreas Gampea0242cf2019-01-29 13:01:23 -08001109 logging.error('Failed to create provider: %s', e)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001110 return 1
1111
Luca Stefani4e91ee92019-03-06 15:08:16 +01001112 if test_args.tree:
Roland Levillain88e55692019-07-25 15:57:06 +01001113 Tree(apex_provider, test_args.apex, test_args.size).print_tree()
Andreas Gampeb1d55672019-01-29 22:17:02 +00001114 return 0
Luca Stefani4e91ee92019-03-06 15:08:16 +01001115 if test_args.list:
Roland Levillaine91d7872019-07-25 18:56:06 +01001116 List(apex_provider, test_args.size).print_list()
Andreas Gampeb1d55672019-01-29 22:17:02 +00001117 return 0
1118
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001119 checkers = []
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001120 if test_args.bitness == BITNESS_AUTO:
Luca Stefani4e91ee92019-03-06 15:08:16 +01001121 logging.warning('--bitness=auto, trying to autodetect. This may be incorrect!')
Andreas Gampeeb555b82019-01-30 14:47:49 -08001122 has_32 = apex_provider.get('lib') is not None
1123 has_64 = apex_provider.get('lib64') is not None
1124 if has_32 and has_64:
Luca Stefani4e91ee92019-03-06 15:08:16 +01001125 logging.warning(' Detected multilib')
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001126 test_args.bitness = BITNESS_MULTILIB
Andreas Gampeeb555b82019-01-30 14:47:49 -08001127 elif has_32:
Luca Stefani4e91ee92019-03-06 15:08:16 +01001128 logging.warning(' Detected 32-only')
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001129 test_args.bitness = BITNESS_32
Andreas Gampeeb555b82019-01-30 14:47:49 -08001130 elif has_64:
Luca Stefani4e91ee92019-03-06 15:08:16 +01001131 logging.warning(' Detected 64-only')
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001132 test_args.bitness = BITNESS_64
Andreas Gampeeb555b82019-01-30 14:47:49 -08001133 else:
1134 logging.error(' Could not detect bitness, neither lib nor lib64 contained.')
Roland Levillain77251f92019-08-09 15:00:04 +01001135 List(apex_provider).print_list()
Andreas Gampeeb555b82019-01-30 14:47:49 -08001136 return 1
1137
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001138 if test_args.bitness == BITNESS_32:
Andreas Gampeeb555b82019-01-30 14:47:49 -08001139 base_checker = Arch32Checker(apex_provider)
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001140 elif test_args.bitness == BITNESS_64:
Andreas Gampeeb555b82019-01-30 14:47:49 -08001141 base_checker = Arch64Checker(apex_provider)
1142 else:
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001143 assert test_args.bitness == BITNESS_MULTILIB
Andreas Gampeeb555b82019-01-30 14:47:49 -08001144 base_checker = MultilibChecker(apex_provider)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001145
Andreas Gampe9dc4b052019-01-30 13:47:25 -08001146 checkers.append(ReleaseChecker(base_checker))
Luca Stefani4e91ee92019-03-06 15:08:16 +01001147 if test_args.host:
Andreas Gampe9dc4b052019-01-30 13:47:25 -08001148 checkers.append(ReleaseHostChecker(base_checker))
Andreas Gampe09123952019-01-30 13:17:02 -08001149 else:
Andreas Gampe9dc4b052019-01-30 13:47:25 -08001150 checkers.append(ReleaseTargetChecker(base_checker))
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001151 if test_args.flavor == FLAVOR_DEBUG or test_args.flavor == FLAVOR_TESTING:
Andreas Gampe9dc4b052019-01-30 13:47:25 -08001152 checkers.append(DebugChecker(base_checker))
Roland Levillain61f07162019-06-26 12:44:04 +01001153 if not test_args.host:
1154 checkers.append(DebugTargetChecker(base_checker))
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001155 if test_args.flavor == FLAVOR_TESTING:
Roland Levillain61f07162019-06-26 12:44:04 +01001156 checkers.append(TestingTargetChecker(base_checker))
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001157
Martin Stjernholm2babede2019-03-18 21:04:49 +00001158 # These checkers must be last.
1159 checkers.append(NoSuperfluousBinariesChecker(base_checker))
Roland Levillain61f07162019-06-26 12:44:04 +01001160 checkers.append(NoSuperfluousArtTestsChecker(base_checker))
Martin Stjernholm2babede2019-03-18 21:04:49 +00001161 if not test_args.host:
1162 # We only care about superfluous libraries on target, where their absence
1163 # can be vital to ensure they get picked up from the right package.
1164 checkers.append(NoSuperfluousLibrariesChecker(base_checker))
1165
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001166 failed = False
1167 for checker in checkers:
1168 logging.info('%s...', checker)
1169 checker.run()
Andreas Gampe9dc4b052019-01-30 13:47:25 -08001170 if base_checker.error_count() > 0:
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001171 logging.error('%s FAILED', checker)
1172 failed = True
1173 else:
1174 logging.info('%s SUCCEEDED', checker)
Andreas Gampe9dc4b052019-01-30 13:47:25 -08001175 base_checker.reset_errors()
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001176
1177 return 1 if failed else 0
1178
Luca Stefani4e91ee92019-03-06 15:08:16 +01001179
1180def art_apex_test_default(test_parser):
1181 if 'ANDROID_PRODUCT_OUT' not in os.environ:
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001182 logging.error('No-argument use requires ANDROID_PRODUCT_OUT')
1183 sys.exit(1)
1184 product_out = os.environ['ANDROID_PRODUCT_OUT']
Luca Stefani4e91ee92019-03-06 15:08:16 +01001185 if 'ANDROID_HOST_OUT' not in os.environ:
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001186 logging.error('No-argument use requires ANDROID_HOST_OUT')
1187 sys.exit(1)
1188 host_out = os.environ['ANDROID_HOST_OUT']
1189
Luca Stefani4e91ee92019-03-06 15:08:16 +01001190 test_args = test_parser.parse_args(['dummy']) # For consistency.
1191 test_args.debugfs = '%s/bin/debugfs' % host_out
1192 test_args.tmpdir = '.'
1193 test_args.tree = False
1194 test_args.list = False
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001195 test_args.bitness = BITNESS_AUTO
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001196 failed = False
1197
Luca Stefani4e91ee92019-03-06 15:08:16 +01001198 if not os.path.exists(test_args.debugfs):
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001199 logging.error("Cannot find debugfs (default path %s). Please build it, e.g., m debugfs",
Luca Stefani4e91ee92019-03-06 15:08:16 +01001200 test_args.debugfs)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001201 sys.exit(1)
1202
Roland Levillaind7ea0432019-09-09 16:29:12 +01001203 # TODO: Add host support.
1204 # TODO: Add support for flattened APEX packages.
Luca Stefani4e91ee92019-03-06 15:08:16 +01001205 configs = [
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001206 {'name': 'com.android.art.release', 'flavor': FLAVOR_RELEASE, 'host': False},
1207 {'name': 'com.android.art.debug', 'flavor': FLAVOR_DEBUG, 'host': False},
1208 {'name': 'com.android.art.testing', 'flavor': FLAVOR_TESTING, 'host': False},
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001209 ]
1210
1211 for config in configs:
1212 logging.info(config['name'])
1213 # TODO: Host will need different path.
Luca Stefani4e91ee92019-03-06 15:08:16 +01001214 test_args.apex = '%s/system/apex/%s.apex' % (product_out, config['name'])
1215 if not os.path.exists(test_args.apex):
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001216 failed = True
Luca Stefani4e91ee92019-03-06 15:08:16 +01001217 logging.error("Cannot find APEX %s. Please build it first.", test_args.apex)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001218 continue
Roland Levillaind7ea0432019-09-09 16:29:12 +01001219 test_args.flavor = config['flavor']
Luca Stefani4e91ee92019-03-06 15:08:16 +01001220 test_args.host = config['host']
1221 failed = art_apex_test_main(test_args) != 0
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001222
1223 if failed:
1224 sys.exit(1)
1225
Luca Stefani4e91ee92019-03-06 15:08:16 +01001226
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001227if __name__ == "__main__":
Martin Stjernholme58624f2019-09-20 15:53:40 +01001228 parser = argparse.ArgumentParser(description='Check integrity of an ART APEX.')
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001229
Roland Levillaind7ea0432019-09-09 16:29:12 +01001230 parser.add_argument('apex', help='APEX file input')
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001231
Roland Levillaind7ea0432019-09-09 16:29:12 +01001232 parser.add_argument('--host', help='Check as host APEX', action='store_true')
Andreas Gampe09123952019-01-30 13:17:02 -08001233
Roland Levillaind7ea0432019-09-09 16:29:12 +01001234 parser.add_argument('--flattened', help='Check as flattened (target) APEX', action='store_true')
Roland Levillaindd20d002019-07-19 16:09:47 +01001235
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001236 parser.add_argument('--flavor', help='Check as FLAVOR APEX', choices=FLAVORS_ALL,
1237 default=FLAVOR_AUTO)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001238
Andreas Gampeb1d55672019-01-29 22:17:02 +00001239 parser.add_argument('--list', help='List all files', action='store_true')
1240 parser.add_argument('--tree', help='Print directory tree', action='store_true')
Roland Levillaine91d7872019-07-25 18:56:06 +01001241 parser.add_argument('--size', help='Print file sizes', action='store_true')
Andreas Gampeb1d55672019-01-29 22:17:02 +00001242
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001243 parser.add_argument('--tmpdir', help='Directory for temp files')
1244 parser.add_argument('--debugfs', help='Path to debugfs')
1245
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001246 parser.add_argument('--bitness', help='Bitness to check', choices=BITNESS_ALL,
1247 default=BITNESS_AUTO)
Andreas Gampeeb555b82019-01-30 14:47:49 -08001248
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001249 if len(sys.argv) == 1:
Luca Stefani4e91ee92019-03-06 15:08:16 +01001250 art_apex_test_default(parser)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001251 else:
1252 args = parser.parse_args()
1253
1254 if args is None:
1255 sys.exit(1)
1256
Luca Stefani4e91ee92019-03-06 15:08:16 +01001257 exit_code = art_apex_test_main(args)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001258 sys.exit(exit_code)