blob: aa07fe2a24e139046632ae42163a4a38dc68d48e [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
Ulya Trafimovich7b0df592020-01-03 13:29:00 +000054
55# Test if a given variable is set to a string "true".
56def isEnvTrue(var):
57 return var in os.environ and os.environ[var] == 'true'
58
59
Andreas Gampe2c846cd2019-01-29 22:06:46 +000060class FSObject:
Roland Levillain88e55692019-07-25 15:57:06 +010061 def __init__(self, name, is_dir, is_exec, is_symlink, size):
Andreas Gampe2c846cd2019-01-29 22:06:46 +000062 self.name = name
63 self.is_dir = is_dir
64 self.is_exec = is_exec
65 self.is_symlink = is_symlink
Roland Levillain88e55692019-07-25 15:57:06 +010066 self.size = size
Luca Stefani4e91ee92019-03-06 15:08:16 +010067
Andreas Gampe2c846cd2019-01-29 22:06:46 +000068 def __str__(self):
Roland Levillain88e55692019-07-25 15:57:06 +010069 return '%s(dir=%r,exec=%r,symlink=%r,size=%d)' \
70 % (self.name, self.is_dir, self.is_exec, self.is_symlink, self.size)
Andreas Gampe2c846cd2019-01-29 22:06:46 +000071
Luca Stefani4e91ee92019-03-06 15:08:16 +010072
Andreas Gampe2c846cd2019-01-29 22:06:46 +000073class TargetApexProvider:
74 def __init__(self, apex, tmpdir, debugfs):
75 self._tmpdir = tmpdir
76 self._debugfs = debugfs
77 self._folder_cache = {}
78 self._payload = os.path.join(self._tmpdir, 'apex_payload.img')
79 # Extract payload to tmpdir.
Luca Stefani4e91ee92019-03-06 15:08:16 +010080 apex_zip = zipfile.ZipFile(apex)
81 apex_zip.extract('apex_payload.img', tmpdir)
Andreas Gampe2c846cd2019-01-29 22:06:46 +000082
83 def __del__(self):
84 # Delete temps.
85 if os.path.exists(self._payload):
86 os.remove(self._payload)
87
88 def get(self, path):
Luca Stefani4e91ee92019-03-06 15:08:16 +010089 apex_dir, name = os.path.split(path)
90 if not apex_dir:
91 apex_dir = '.'
92 apex_map = self.read_dir(apex_dir)
93 return apex_map[name] if name in apex_map else None
Andreas Gampe2c846cd2019-01-29 22:06:46 +000094
Luca Stefani4e91ee92019-03-06 15:08:16 +010095 def read_dir(self, apex_dir):
96 if apex_dir in self._folder_cache:
97 return self._folder_cache[apex_dir]
Andreas Gampe2c846cd2019-01-29 22:06:46 +000098 # Cannot use check_output as it will annoy with stderr.
Luca Stefani4e91ee92019-03-06 15:08:16 +010099 process = subprocess.Popen([self._debugfs, '-R', 'ls -l -p %s' % apex_dir, self._payload],
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000100 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
101 universal_newlines=True)
Luca Stefani4e91ee92019-03-06 15:08:16 +0100102 stdout, _ = process.communicate()
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000103 res = str(stdout)
Luca Stefani4e91ee92019-03-06 15:08:16 +0100104 apex_map = {}
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000105 # Debugfs output looks like this:
106 # debugfs 1.44.4 (18-Aug-2018)
107 # /12/040755/0/2000/.//
108 # /2/040755/1000/1000/..//
109 # /13/100755/0/2000/dalvikvm32/28456/
110 # /14/100755/0/2000/dexoptanalyzer/20396/
111 # /15/100755/0/2000/linker/1152724/
112 # /16/100755/0/2000/dex2oat/563508/
113 # /17/100755/0/2000/linker64/1605424/
114 # /18/100755/0/2000/profman/85304/
115 # /19/100755/0/2000/dalvikvm64/28576/
116 # | | | | | |
117 # | | | #- gid #- name #- size
118 # | | #- uid
119 # | #- type and permission bits
120 # #- inode nr (?)
121 #
122 # Note: could break just on '/' to avoid names with newlines.
123 for line in res.split("\n"):
124 if not line:
125 continue
126 comps = line.split('/')
127 if len(comps) != 8:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100128 logging.warning('Could not break and parse line \'%s\'', line)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000129 continue
130 bits = comps[2]
131 name = comps[5]
Roland Levillain88e55692019-07-25 15:57:06 +0100132 size_str = comps[6]
133 # Use a negative value as an indicator of undefined/unknown size.
134 size = int(size_str) if size_str != '' else -1
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000135 if len(bits) != 6:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100136 logging.warning('Dont understand bits \'%s\'', bits)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000137 continue
Luca Stefani4e91ee92019-03-06 15:08:16 +0100138 is_dir = bits[1] == '4'
139
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000140 def is_exec_bit(ch):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100141 return int(ch) & 1 == 1
142
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000143 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 +0100144 is_symlink = bits[1] == '2'
Roland Levillain88e55692019-07-25 15:57:06 +0100145 apex_map[name] = FSObject(name, is_dir, is_exec, is_symlink, size)
Luca Stefani4e91ee92019-03-06 15:08:16 +0100146 self._folder_cache[apex_dir] = apex_map
147 return apex_map
148
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000149
Roland Levillaindd20d002019-07-19 16:09:47 +0100150class TargetFlattenedApexProvider:
151 def __init__(self, apex):
152 self._folder_cache = {}
153 self._apex = apex
154
155 def get(self, path):
156 apex_dir, name = os.path.split(path)
157 if not apex_dir:
158 apex_dir = '.'
159 apex_map = self.read_dir(apex_dir)
160 return apex_map[name] if name in apex_map else None
161
162 def read_dir(self, apex_dir):
163 if apex_dir in self._folder_cache:
164 return self._folder_cache[apex_dir]
165 apex_map = {}
166 dirname = os.path.join(self._apex, apex_dir)
167 if os.path.exists(dirname):
168 for basename in os.listdir(dirname):
169 filepath = os.path.join(dirname, basename)
170 is_dir = os.path.isdir(filepath)
171 is_exec = os.access(filepath, os.X_OK)
172 is_symlink = os.path.islink(filepath)
Roland Levillain3cd802e2020-02-20 15:31:20 +0000173 if is_symlink:
174 # Report the length of the symlink's target's path as file size, like `ls`.
175 size = len(os.readlink(filepath))
176 else:
177 size = os.path.getsize(filepath)
Roland Levillain88e55692019-07-25 15:57:06 +0100178 apex_map[basename] = FSObject(basename, is_dir, is_exec, is_symlink, size)
Roland Levillaindd20d002019-07-19 16:09:47 +0100179 self._folder_cache[apex_dir] = apex_map
180 return apex_map
181
182
Andreas Gampe09123952019-01-30 13:17:02 -0800183class HostApexProvider:
184 def __init__(self, apex, tmpdir):
185 self._tmpdir = tmpdir
Roland Levillain77251f92019-08-09 15:00:04 +0100186 self._folder_cache = {}
Andreas Gampe09123952019-01-30 13:17:02 -0800187 self._payload = os.path.join(self._tmpdir, 'apex_payload.zip')
188 # Extract payload to tmpdir.
Luca Stefani4e91ee92019-03-06 15:08:16 +0100189 apex_zip = zipfile.ZipFile(apex)
190 apex_zip.extract('apex_payload.zip', tmpdir)
Andreas Gampe09123952019-01-30 13:17:02 -0800191
192 def __del__(self):
193 # Delete temps.
194 if os.path.exists(self._payload):
195 os.remove(self._payload)
196
197 def get(self, path):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100198 apex_dir, name = os.path.split(path)
199 if not apex_dir:
200 apex_dir = ''
201 apex_map = self.read_dir(apex_dir)
202 return apex_map[name] if name in apex_map else None
Andreas Gampe09123952019-01-30 13:17:02 -0800203
Luca Stefani4e91ee92019-03-06 15:08:16 +0100204 def read_dir(self, apex_dir):
Roland Levillain77251f92019-08-09 15:00:04 +0100205 if apex_dir in self._folder_cache:
206 return self._folder_cache[apex_dir]
207 if not self._folder_cache:
Andreas Gampe09123952019-01-30 13:17:02 -0800208 self.parse_zip()
Roland Levillain77251f92019-08-09 15:00:04 +0100209 if apex_dir in self._folder_cache:
210 return self._folder_cache[apex_dir]
Andreas Gampe09123952019-01-30 13:17:02 -0800211 return {}
212
213 def parse_zip(self):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100214 apex_zip = zipfile.ZipFile(self._payload)
215 infos = apex_zip.infolist()
Andreas Gampe09123952019-01-30 13:17:02 -0800216 for zipinfo in infos:
217 path = zipinfo.filename
218
219 # Assume no empty file is stored.
220 assert path
221
222 def get_octal(val, index):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100223 return (val >> (index * 3)) & 0x7
224
Andreas Gampe09123952019-01-30 13:17:02 -0800225 def bits_is_exec(val):
226 # TODO: Enforce group/other, too?
227 return get_octal(val, 2) & 1 == 1
228
229 is_zipinfo = True
230 while path:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100231 apex_dir, base = os.path.split(path)
Andreas Gampe09123952019-01-30 13:17:02 -0800232 # TODO: If directories are stored, base will be empty.
233
Roland Levillain77251f92019-08-09 15:00:04 +0100234 if apex_dir not in self._folder_cache:
235 self._folder_cache[apex_dir] = {}
236 dir_map = self._folder_cache[apex_dir]
Luca Stefani4e91ee92019-03-06 15:08:16 +0100237 if base not in dir_map:
Andreas Gampe09123952019-01-30 13:17:02 -0800238 if is_zipinfo:
239 bits = (zipinfo.external_attr >> 16) & 0xFFFF
240 is_dir = get_octal(bits, 4) == 4
241 is_symlink = get_octal(bits, 4) == 2
242 is_exec = bits_is_exec(bits)
Roland Levillain88e55692019-07-25 15:57:06 +0100243 size = zipinfo.file_size
Andreas Gampe09123952019-01-30 13:17:02 -0800244 else:
245 is_exec = False # Seems we can't get this easily?
246 is_symlink = False
247 is_dir = True
Roland Levillain88e55692019-07-25 15:57:06 +0100248 # Use a negative value as an indicator of undefined/unknown size.
249 size = -1
250 dir_map[base] = FSObject(base, is_dir, is_exec, is_symlink, size)
Andreas Gampe09123952019-01-30 13:17:02 -0800251 is_zipinfo = False
Luca Stefani4e91ee92019-03-06 15:08:16 +0100252 path = apex_dir
253
Andreas Gampe09123952019-01-30 13:17:02 -0800254
Andreas Gampeeb555b82019-01-30 14:47:49 -0800255# DO NOT USE DIRECTLY! This is an "abstract" base class.
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000256class Checker:
257 def __init__(self, provider):
258 self._provider = provider
259 self._errors = 0
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000260 self._expected_file_globs = set()
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000261
Luca Stefani4e91ee92019-03-06 15:08:16 +0100262 def fail(self, msg, *fail_args):
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000263 self._errors += 1
Martin Stjernholm2babede2019-03-18 21:04:49 +0000264 logging.error(msg, *fail_args)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000265
266 def error_count(self):
267 return self._errors
Luca Stefani4e91ee92019-03-06 15:08:16 +0100268
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800269 def reset_errors(self):
270 self._errors = 0
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000271
Martin Stjernholm2babede2019-03-18 21:04:49 +0000272 def is_file(self, path):
273 fs_object = self._provider.get(path)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000274 if fs_object is None:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100275 return False, 'Could not find %s'
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000276 if fs_object.is_dir:
Luca Stefani4e91ee92019-03-06 15:08:16 +0100277 return False, '%s is a directory'
278 return True, ''
Andreas Gampea0242cf2019-01-29 13:01:23 -0800279
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000280 def is_dir(self, path):
281 fs_object = self._provider.get(path)
282 if fs_object is None:
283 return False, 'Could not find %s'
284 if not fs_object.is_dir:
285 return False, '%s is not a directory'
286 return True, ''
287
Martin Stjernholm2babede2019-03-18 21:04:49 +0000288 def check_file(self, path):
289 ok, msg = self.is_file(path)
290 if not ok:
291 self.fail(msg, path)
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000292 self._expected_file_globs.add(path)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000293 return ok
Luca Stefani4e91ee92019-03-06 15:08:16 +0100294
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000295 def check_executable(self, filename):
Martin Stjernholm2babede2019-03-18 21:04:49 +0000296 path = 'bin/%s' % filename
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000297 if not self.check_file(path):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100298 return
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000299 if not self._provider.get(path).is_exec:
300 self.fail('%s is not executable', path)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000301
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000302 def check_executable_symlink(self, filename):
Martin Stjernholm2babede2019-03-18 21:04:49 +0000303 path = 'bin/%s' % filename
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000304 fs_object = self._provider.get(path)
305 if fs_object is None:
306 self.fail('Could not find %s', path)
Luca Stefani4e91ee92019-03-06 15:08:16 +0100307 return
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000308 if fs_object.is_dir:
309 self.fail('%s is a directory', path)
Luca Stefani4e91ee92019-03-06 15:08:16 +0100310 return
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000311 if not fs_object.is_symlink:
312 self.fail('%s is not a symlink', path)
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000313 self._expected_file_globs.add(path)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000314
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000315 def arch_dirs_for_path(self, path):
316 # Look for target-specific subdirectories for the given directory path.
317 # This is needed because the list of build targets is not propagated
318 # to this script.
Ulyana Trafimovich0f7c7922019-11-07 16:12:09 +0000319 #
Roland Levillain48136182019-11-15 13:39:03 +0000320 # TODO(b/123602136): Pass build target information to this script and fix
321 # all places where this function in used (or similar workarounds).
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000322 dirs = []
Ulyana Trafimovich0f7c7922019-11-07 16:12:09 +0000323 for arch in ARCHS:
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000324 dir = '%s/%s' % (path, arch)
325 found, _ = self.is_dir(dir)
326 if found:
327 dirs.append(dir)
328 return dirs
329
330 def check_art_test_executable(self, filename):
331 dirs = self.arch_dirs_for_path(ART_TEST_DIR)
332 if not dirs:
Roland Levillain61f07162019-06-26 12:44:04 +0100333 self.fail('ART test binary missing: %s', filename)
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000334 for dir in dirs:
335 test_path = '%s/%s' % (dir, filename)
336 self._expected_file_globs.add(test_path)
337 if not self._provider.get(test_path).is_exec:
338 self.fail('%s is not executable', test_path)
Roland Levillain61f07162019-06-26 12:44:04 +0100339
Martin Stjernholm2babede2019-03-18 21:04:49 +0000340 def check_single_library(self, filename):
341 lib_path = 'lib/%s' % filename
342 lib64_path = 'lib64/%s' % filename
343 lib_is_file, _ = self.is_file(lib_path)
344 if lib_is_file:
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000345 self._expected_file_globs.add(lib_path)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000346 lib64_is_file, _ = self.is_file(lib64_path)
347 if lib64_is_file:
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000348 self._expected_file_globs.add(lib64_path)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000349 if not lib_is_file and not lib64_is_file:
350 self.fail('Library missing: %s', filename)
Andreas Gampea0242cf2019-01-29 13:01:23 -0800351
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000352 def check_dexpreopt(self, basename):
353 dirs = self.arch_dirs_for_path('javalib')
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000354 for dir in dirs:
Tim Joinesbe50bc32020-03-18 18:00:41 +0000355 for ext in ['art', 'oat', 'vdex']:
Ulyana Trafimovich7a20cbd2019-11-08 11:27:31 +0000356 self.check_file('%s/%s.%s' % (dir, basename, ext))
357
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000358 def check_java_library(self, basename):
359 return self.check_file('javalib/%s.jar' % basename)
Andreas Gampe09123952019-01-30 13:17:02 -0800360
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000361 def ignore_path(self, path_glob):
362 self._expected_file_globs.add(path_glob)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000363
Roland Levillain61f07162019-06-26 12:44:04 +0100364 def check_optional_art_test_executable(self, filename):
Orion Hodsonaf3ed622019-10-03 16:30:54 +0100365 for arch in ARCHS:
366 self.ignore_path('%s/%s/%s' % (ART_TEST_DIR, arch, filename))
Roland Levillain61f07162019-06-26 12:44:04 +0100367
Martin Stjernholm2babede2019-03-18 21:04:49 +0000368 def check_no_superfluous_files(self, dir_path):
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000369 paths = []
Martin Stjernholm2babede2019-03-18 21:04:49 +0000370 for name in sorted(self._provider.read_dir(dir_path).keys()):
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000371 if name not in ('.', '..'):
372 paths.append(os.path.join(dir_path, name))
373 expected_paths = set()
374 dir_prefix = dir_path + '/'
375 for path_glob in self._expected_file_globs:
376 expected_paths |= set(fnmatch.filter(paths, path_glob))
377 # If there are globs in subdirectories of dir_path we want to match their
378 # path segments at this directory level.
379 if path_glob.startswith(dir_prefix):
380 subpath = path_glob[len(dir_prefix):]
381 subpath_first_segment, _, _ = subpath.partition('/')
382 expected_paths |= set(fnmatch.filter(paths, dir_prefix + subpath_first_segment))
383 for unexpected_path in set(paths) - expected_paths:
384 self.fail('Unexpected file \'%s\'', unexpected_path)
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000385
Andreas Gampeeb555b82019-01-30 14:47:49 -0800386 # Just here for docs purposes, even if it isn't good Python style.
387
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000388 def check_symlinked_multilib_executable(self, filename):
389 """Check bin/filename32, and/or bin/filename64, with symlink bin/filename."""
Andreas Gampeeb555b82019-01-30 14:47:49 -0800390 raise NotImplementedError
391
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000392 def check_multilib_executable(self, filename):
393 """Check bin/filename for 32 bit, and/or bin/filename64."""
Andreas Gampeeb555b82019-01-30 14:47:49 -0800394 raise NotImplementedError
395
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000396 def check_native_library(self, basename):
397 """Check lib/basename.so, and/or lib64/basename.so."""
Martin Stjernholm2babede2019-03-18 21:04:49 +0000398 raise NotImplementedError
399
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000400 def check_optional_native_library(self, basename_glob):
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000401 """Allow lib/basename.so and/or lib64/basename.so to exist."""
Martin Stjernholmb81fe232019-03-25 17:38:04 +0000402 raise NotImplementedError
403
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000404 def check_prefer64_library(self, basename):
405 """Check lib64/basename.so, or lib/basename.so on 32 bit only."""
Andreas Gampeeb555b82019-01-30 14:47:49 -0800406 raise NotImplementedError
407
408
409class Arch32Checker(Checker):
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000410 def check_symlinked_multilib_executable(self, filename):
411 self.check_executable('%s32' % filename)
412 self.check_executable_symlink(filename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800413
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000414 def check_multilib_executable(self, filename):
415 self.check_executable(filename)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000416
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000417 def check_native_library(self, basename):
Andreas Gampeeb555b82019-01-30 14:47:49 -0800418 # TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve
419 # the precision of this test?
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000420 self.check_file('lib/%s.so' % basename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800421
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000422 def check_optional_native_library(self, basename_glob):
423 self.ignore_path('lib/%s.so' % basename_glob)
Martin Stjernholmb81fe232019-03-25 17:38:04 +0000424
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000425 def check_prefer64_library(self, basename):
426 self.check_native_library(basename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800427
428
429class Arch64Checker(Checker):
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000430 def check_symlinked_multilib_executable(self, filename):
431 self.check_executable('%s64' % filename)
432 self.check_executable_symlink(filename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800433
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000434 def check_multilib_executable(self, filename):
435 self.check_executable('%s64' % filename)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000436
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000437 def check_native_library(self, basename):
Andreas Gampeeb555b82019-01-30 14:47:49 -0800438 # TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve
439 # the precision of this test?
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000440 self.check_file('lib64/%s.so' % basename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800441
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000442 def check_optional_native_library(self, basename_glob):
443 self.ignore_path('lib64/%s.so' % basename_glob)
Martin Stjernholmb81fe232019-03-25 17:38:04 +0000444
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000445 def check_prefer64_library(self, basename):
446 self.check_native_library(basename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800447
448
449class MultilibChecker(Checker):
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000450 def check_symlinked_multilib_executable(self, filename):
451 self.check_executable('%s32' % filename)
452 self.check_executable('%s64' % filename)
453 self.check_executable_symlink(filename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800454
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000455 def check_multilib_executable(self, filename):
456 self.check_executable('%s64' % filename)
457 self.check_executable(filename)
Martin Stjernholm2babede2019-03-18 21:04:49 +0000458
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000459 def check_native_library(self, basename):
Andreas Gampeeb555b82019-01-30 14:47:49 -0800460 # TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve
461 # the precision of this test?
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000462 self.check_file('lib/%s.so' % basename)
463 self.check_file('lib64/%s.so' % basename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800464
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000465 def check_optional_native_library(self, basename_glob):
466 self.ignore_path('lib/%s.so' % basename_glob)
467 self.ignore_path('lib64/%s.so' % basename_glob)
Martin Stjernholmb81fe232019-03-25 17:38:04 +0000468
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000469 def check_prefer64_library(self, basename):
470 self.check_file('lib64/%s.so' % basename)
Andreas Gampeeb555b82019-01-30 14:47:49 -0800471
472
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800473class ReleaseChecker:
474 def __init__(self, checker):
475 self._checker = checker
Luca Stefani4e91ee92019-03-06 15:08:16 +0100476
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000477 def __str__(self):
478 return 'Release Checker'
479
480 def run(self):
Roland Levillaindf66de02019-11-11 23:22:15 +0000481 # Check the Protocol Buffers APEX manifest.
482 self._checker.check_file('apex_manifest.pb')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000483
Martin Stjernholm77f17662019-04-03 17:08:21 +0100484 # Check binaries for ART.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000485 self._checker.check_executable('dex2oat')
Martin Stjernholm77f17662019-04-03 17:08:21 +0100486 self._checker.check_executable('dexdump')
487 self._checker.check_executable('dexlist')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000488 self._checker.check_executable('dexoptanalyzer')
489 self._checker.check_executable('profman')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000490 self._checker.check_symlinked_multilib_executable('dalvikvm')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000491
Martin Stjernholm023c2182019-03-28 15:52:32 +0000492 # Check exported libraries for ART.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000493 self._checker.check_native_library('libdexfile_external')
494 self._checker.check_native_library('libnativebridge')
495 self._checker.check_native_library('libnativehelper')
496 self._checker.check_native_library('libnativeloader')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000497
498 # Check internal libraries for ART.
499 self._checker.check_native_library('libadbconnection')
500 self._checker.check_native_library('libart')
501 self._checker.check_native_library('libart-compiler')
502 self._checker.check_native_library('libart-dexlayout')
Roland Levillain5b768892020-02-19 15:49:02 +0000503 self._checker.check_native_library('libart-disassembler')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000504 self._checker.check_native_library('libartbase')
505 self._checker.check_native_library('libartpalette')
506 self._checker.check_native_library('libdexfile')
507 self._checker.check_native_library('libdexfile_support')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000508 self._checker.check_native_library('libopenjdkjvm')
509 self._checker.check_native_library('libopenjdkjvmti')
510 self._checker.check_native_library('libprofile')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000511 self._checker.check_native_library('libsigchain')
512
513 # Check java libraries for Managed Core Library.
514 self._checker.check_java_library('apache-xml')
515 self._checker.check_java_library('bouncycastle')
Victor Chang759845f2019-08-06 16:04:36 +0100516 self._checker.check_java_library('core-icu4j')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000517 self._checker.check_java_library('core-libart')
518 self._checker.check_java_library('core-oj')
519 self._checker.check_java_library('okhttp')
Ulya Trafimovich7b0df592020-01-03 13:29:00 +0000520 if isEnvTrue('EMMA_INSTRUMENT_FRAMEWORK'):
521 # In coverage builds jacoco is added to the list of ART apex jars.
522 self._checker.check_java_library('jacocoagent')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000523
524 # Check internal native libraries for Managed Core Library.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000525 self._checker.check_native_library('libjavacore')
526 self._checker.check_native_library('libopenjdk')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000527
Martin Stjernholm2babede2019-03-18 21:04:49 +0000528 # Check internal native library dependencies.
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000529 #
Martin Stjernholm2babede2019-03-18 21:04:49 +0000530 # Any internal dependency not listed here will cause a failure in
531 # NoSuperfluousLibrariesChecker. Internal dependencies are generally just
532 # implementation details, but in the release package we want to track them
533 # because a) they add to the package size and the RAM usage (in particular
534 # if the library is also present in /system or another APEX and hence might
535 # get loaded twice through linker namespace separation), and b) we need to
536 # catch invalid dependencies on /system or other APEXes that should go
537 # through an exported library with stubs (b/128708192 tracks implementing a
538 # better approach for that).
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000539 self._checker.check_native_library('libbacktrace')
540 self._checker.check_native_library('libbase')
541 self._checker.check_native_library('libc++')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000542 self._checker.check_native_library('libdt_fd_forward')
543 self._checker.check_native_library('libdt_socket')
544 self._checker.check_native_library('libjdwp')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000545 self._checker.check_native_library('liblzma')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000546 self._checker.check_native_library('libnpt')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000547 self._checker.check_native_library('libunwindstack')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000548 self._checker.check_native_library('libziparchive')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000549 self._checker.check_optional_native_library('libvixl') # Only on ARM/ARM64
Martin Stjernholm2babede2019-03-18 21:04:49 +0000550
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000551 # Allow extra dependencies that appear in ASAN builds.
552 self._checker.check_optional_native_library('libclang_rt.asan*')
553 self._checker.check_optional_native_library('libclang_rt.hwasan*')
554 self._checker.check_optional_native_library('libclang_rt.ubsan*')
555
Ulya Trafimovich7b0df592020-01-03 13:29:00 +0000556 # Check dexpreopt files for libcore bootclasspath jars.
557 self._checker.check_dexpreopt('boot')
558 self._checker.check_dexpreopt('boot-apache-xml')
559 self._checker.check_dexpreopt('boot-bouncycastle')
560 self._checker.check_dexpreopt('boot-core-icu4j')
561 self._checker.check_dexpreopt('boot-core-libart')
562 self._checker.check_dexpreopt('boot-okhttp')
563 if isEnvTrue('EMMA_INSTRUMENT_FRAMEWORK'):
564 # In coverage builds the ART boot image includes jacoco.
565 self._checker.check_dexpreopt('boot-jacocoagent')
Luca Stefani4e91ee92019-03-06 15:08:16 +0100566
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800567class ReleaseTargetChecker:
568 def __init__(self, checker):
569 self._checker = checker
Luca Stefani4e91ee92019-03-06 15:08:16 +0100570
Andreas Gampe09123952019-01-30 13:17:02 -0800571 def __str__(self):
572 return 'Release (Target) Checker'
573
574 def run(self):
Roland Levillaindf66de02019-11-11 23:22:15 +0000575 # We don't check for the presence of the JSON APEX manifest (file
576 # `apex_manifest.json`, only present in target APEXes), as it is only
577 # included for compatibility reasons with Android Q and will likely be
578 # removed in Android R.
579
Martin Stjernholm023c2182019-03-28 15:52:32 +0000580 # Check binaries for ART.
Martin Stjernholm023c2182019-03-28 15:52:32 +0000581 self._checker.check_executable('oatdump')
582
583 # Check internal libraries for ART.
584 self._checker.check_prefer64_library('libart-disassembler')
Florian Mayer07710c52019-09-16 15:53:38 +0000585 self._checker.check_native_library('libperfetto_hprof')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000586
Martin Stjernholm023c2182019-03-28 15:52:32 +0000587 # Check exported native libraries for Managed Core Library.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000588 self._checker.check_native_library('libandroidicu')
589 self._checker.check_native_library('libandroidio')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000590
591 # Check internal native library dependencies.
592 self._checker.check_native_library('libcrypto')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000593 self._checker.check_native_library('libexpat')
594 self._checker.check_native_library('libicui18n')
595 self._checker.check_native_library('libicuuc')
Victor Chang65ae6692019-10-11 14:17:21 +0100596 self._checker.check_native_library('libicu_jni')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000597 self._checker.check_native_library('libpac')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000598 self._checker.check_native_library('libz')
Martin Stjernholm2babede2019-03-18 21:04:49 +0000599
Martin Stjernholmec2db5f2019-09-04 20:54:57 +0100600 # TODO(b/139046641): Fix proper 2nd arch checks. For now, just ignore these
601 # directories.
602 self._checker.ignore_path('bin/arm')
603 self._checker.ignore_path('lib/arm')
604 self._checker.ignore_path('lib64/arm')
605
Luca Stefani4e91ee92019-03-06 15:08:16 +0100606
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800607class ReleaseHostChecker:
608 def __init__(self, checker):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100609 self._checker = checker
610
Andreas Gampe09123952019-01-30 13:17:02 -0800611 def __str__(self):
612 return 'Release (Host) Checker'
613
614 def run(self):
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000615 # Check binaries for ART.
616 self._checker.check_executable('hprof-conv')
Martin Stjernholmc42db832020-02-25 16:02:07 +0000617 self._checker.check_executable('dex2oatd')
Martin Stjernholm84a32cd2019-03-29 16:39:46 +0000618
Martin Stjernholm023c2182019-03-28 15:52:32 +0000619 # Check exported native libraries for Managed Core Library.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000620 self._checker.check_native_library('libandroidicu-host')
621 self._checker.check_native_library('libandroidio')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000622
623 # Check internal libraries for Managed Core Library.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000624 self._checker.check_native_library('libexpat-host')
625 self._checker.check_native_library('libicui18n-host')
626 self._checker.check_native_library('libicuuc-host')
Victor Chang65ae6692019-10-11 14:17:21 +0100627 self._checker.check_native_library('libicu_jni')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000628 self._checker.check_native_library('libz-host')
Andreas Gampe09123952019-01-30 13:17:02 -0800629
Luca Stefani4e91ee92019-03-06 15:08:16 +0100630
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800631class DebugChecker:
632 def __init__(self, checker):
633 self._checker = checker
Luca Stefani4e91ee92019-03-06 15:08:16 +0100634
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000635 def __str__(self):
636 return 'Debug Checker'
637
638 def run(self):
Martin Stjernholm023c2182019-03-28 15:52:32 +0000639 # Check binaries for ART.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000640 self._checker.check_executable('dexdiag')
Roland Levillain6dd62122019-06-18 19:10:21 +0100641 self._checker.check_executable('dexanalyze')
642 self._checker.check_executable('dexlayout')
643 self._checker.check_symlinked_multilib_executable('imgdiag')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000644
Martin Stjernholm023c2182019-03-28 15:52:32 +0000645 # Check debug binaries for ART.
Roland Levillain6dd62122019-06-18 19:10:21 +0100646 self._checker.check_executable('dexlayoutd')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000647 self._checker.check_executable('dexoptanalyzerd')
Roland Levillain6dd62122019-06-18 19:10:21 +0100648 self._checker.check_symlinked_multilib_executable('imgdiagd')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000649 self._checker.check_executable('profmand')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000650
Martin Stjernholm023c2182019-03-28 15:52:32 +0000651 # Check internal libraries for ART.
652 self._checker.check_native_library('libadbconnectiond')
Roland Levillain4d6f24d2019-10-02 16:47:36 +0100653 self._checker.check_native_library('libart-disassembler')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000654 self._checker.check_native_library('libartbased')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000655 self._checker.check_native_library('libartd')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000656 self._checker.check_native_library('libartd-compiler')
657 self._checker.check_native_library('libartd-dexlayout')
Roland Levillain4d6f24d2019-10-02 16:47:36 +0100658 self._checker.check_native_library('libartd-disassembler')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000659 self._checker.check_native_library('libdexfiled')
660 self._checker.check_native_library('libopenjdkjvmd')
661 self._checker.check_native_library('libopenjdkjvmtid')
662 self._checker.check_native_library('libprofiled')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000663
664 # Check internal libraries for Managed Core Library.
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000665 self._checker.check_native_library('libopenjdkd')
Andreas Gampe2c846cd2019-01-29 22:06:46 +0000666
Luca Stefani4e91ee92019-03-06 15:08:16 +0100667
Andreas Gampe9dc4b052019-01-30 13:47:25 -0800668class DebugTargetChecker:
669 def __init__(self, checker):
670 self._checker = checker
Luca Stefani4e91ee92019-03-06 15:08:16 +0100671
Andreas Gampea0242cf2019-01-29 13:01:23 -0800672 def __str__(self):
673 return 'Debug (Target) Checker'
674
675 def run(self):
Martin Stjernholm023c2182019-03-28 15:52:32 +0000676 # Check ART debug binaries.
Roland Levillain9a45d012019-06-05 13:54:02 +0100677 self._checker.check_executable('dex2oatd')
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000678 self._checker.check_executable('oatdumpd')
Martin Stjernholm023c2182019-03-28 15:52:32 +0000679
680 # Check ART internal libraries.
Martin Stjernholm356864a2019-04-30 16:22:17 +0100681 self._checker.check_native_library('libdexfiled_external')
Florian Mayer07710c52019-09-16 15:53:38 +0000682 self._checker.check_native_library('libperfetto_hprofd')
Andreas Gampea0242cf2019-01-29 13:01:23 -0800683
Martin Stjernholm2babede2019-03-18 21:04:49 +0000684 # Check internal native library dependencies.
685 #
686 # Like in the release package, we check that we don't get other dependencies
687 # besides those listed here. In this case the concern is not bloat, but
688 # rather that we don't get behavioural differences between user (release)
689 # and userdebug/eng builds, which could happen if the debug package has
690 # duplicate library instances where releases don't. In other words, it's
691 # uncontroversial to add debug-only dependencies, as long as they don't make
692 # assumptions on having a single global state (ideally they should have
693 # double_loadable:true, cf. go/double_loadable). Also, like in the release
694 # package we need to look out for dependencies that should go through
695 # exported library stubs (until b/128708192 is fixed).
Martin Stjernholmc17ace22019-03-18 21:47:31 +0000696 self._checker.check_optional_native_library('libvixld') # Only on ARM/ARM64
Martin Stjernholm77f17662019-04-03 17:08:21 +0100697 self._checker.check_prefer64_library('libmeminfo')
698 self._checker.check_prefer64_library('libprocinfo')
Martin Stjernholm2babede2019-03-18 21:04:49 +0000699
700
Roland Levillain61f07162019-06-26 12:44:04 +0100701class TestingTargetChecker:
702 def __init__(self, checker):
703 self._checker = checker
704
705 def __str__(self):
706 return 'Testing (Target) Checker'
707
708 def run(self):
709 # Check cmdline tests.
710 self._checker.check_optional_art_test_executable('cmdline_parser_test')
711
712 # Check compiler tests.
713 self._checker.check_art_test_executable('atomic_dex_ref_map_test')
714 self._checker.check_art_test_executable('bounds_check_elimination_test')
715 self._checker.check_art_test_executable('codegen_test')
716 self._checker.check_art_test_executable('compiled_method_storage_test')
717 self._checker.check_art_test_executable('data_type_test')
718 self._checker.check_art_test_executable('dedupe_set_test')
719 self._checker.check_art_test_executable('dominator_test')
720 self._checker.check_art_test_executable('dwarf_test')
721 self._checker.check_art_test_executable('exception_test')
722 self._checker.check_art_test_executable('find_loops_test')
723 self._checker.check_art_test_executable('graph_checker_test')
724 self._checker.check_art_test_executable('graph_test')
725 self._checker.check_art_test_executable('gvn_test')
726 self._checker.check_art_test_executable('induction_var_analysis_test')
727 self._checker.check_art_test_executable('induction_var_range_test')
728 self._checker.check_art_test_executable('jni_cfi_test')
729 self._checker.check_art_test_executable('jni_compiler_test')
730 self._checker.check_art_test_executable('licm_test')
731 self._checker.check_art_test_executable('linker_patch_test')
732 self._checker.check_art_test_executable('live_interval_test')
733 self._checker.check_art_test_executable('load_store_analysis_test')
xueliang.zhongd71f1dc2018-01-24 17:24:16 +0000734 self._checker.check_art_test_executable('load_store_elimination_test')
Roland Levillain61f07162019-06-26 12:44:04 +0100735 self._checker.check_art_test_executable('loop_optimization_test')
736 self._checker.check_art_test_executable('nodes_test')
737 self._checker.check_art_test_executable('nodes_vector_test')
738 self._checker.check_art_test_executable('optimizing_cfi_test')
739 self._checker.check_art_test_executable('output_stream_test')
740 self._checker.check_art_test_executable('parallel_move_test')
741 self._checker.check_art_test_executable('pretty_printer_test')
742 self._checker.check_art_test_executable('reference_type_propagation_test')
743 self._checker.check_art_test_executable('scheduler_test')
744 self._checker.check_art_test_executable('select_generator_test')
745 self._checker.check_art_test_executable('side_effects_test')
746 self._checker.check_art_test_executable('src_map_elem_test')
747 self._checker.check_art_test_executable('ssa_liveness_analysis_test')
748 self._checker.check_art_test_executable('ssa_test')
749 self._checker.check_art_test_executable('stack_map_test')
750 self._checker.check_art_test_executable('superblock_cloner_test')
751 self._checker.check_art_test_executable('suspend_check_test')
752 self._checker.check_art_test_executable('swap_space_test')
753 # These tests depend on a specific code generator and are conditionally included.
754 self._checker.check_optional_art_test_executable('constant_folding_test')
755 self._checker.check_optional_art_test_executable('dead_code_elimination_test')
756 self._checker.check_optional_art_test_executable('linearize_test')
757 self._checker.check_optional_art_test_executable('live_ranges_test')
758 self._checker.check_optional_art_test_executable('liveness_test')
759 self._checker.check_optional_art_test_executable('managed_register_arm64_test')
760 self._checker.check_optional_art_test_executable('managed_register_arm_test')
Roland Levillain61f07162019-06-26 12:44:04 +0100761 self._checker.check_optional_art_test_executable('managed_register_x86_64_test')
762 self._checker.check_optional_art_test_executable('managed_register_x86_test')
763 self._checker.check_optional_art_test_executable('register_allocator_test')
764
765 # Check dex2oat tests.
766 self._checker.check_art_test_executable('compiler_driver_test')
767 self._checker.check_art_test_executable('dex2oat_image_test')
768 self._checker.check_art_test_executable('dex2oat_test')
769 self._checker.check_art_test_executable('dex_to_dex_decompiler_test')
770 self._checker.check_art_test_executable('elf_writer_test')
771 self._checker.check_art_test_executable('image_test')
772 self._checker.check_art_test_executable('image_write_read_test')
773 self._checker.check_art_test_executable('index_bss_mapping_encoder_test')
774 self._checker.check_art_test_executable('multi_oat_relative_patcher_test')
775 self._checker.check_art_test_executable('oat_writer_test')
776 self._checker.check_art_test_executable('verifier_deps_test')
777 # These tests depend on a specific code generator and are conditionally included.
778 self._checker.check_optional_art_test_executable('relative_patcher_arm64_test')
Roland Levillain61f07162019-06-26 12:44:04 +0100779 self._checker.check_optional_art_test_executable('relative_patcher_thumb2_test')
780 self._checker.check_optional_art_test_executable('relative_patcher_x86_64_test')
781 self._checker.check_optional_art_test_executable('relative_patcher_x86_test')
782
783 # Check dexanalyze tests.
784 self._checker.check_optional_art_test_executable('dexanalyze_test')
785
786 # Check dexdiag tests.
787 self._checker.check_optional_art_test_executable('dexdiag_test')
788
789 # Check dexdump tests.
790 self._checker.check_art_test_executable('dexdump_test')
791
792 # Check dexlayout tests.
793 self._checker.check_optional_art_test_executable('dexlayout_test')
794
795 # Check dexlist tests.
796 self._checker.check_art_test_executable('dexlist_test')
797
798 # Check dexoptanalyzer tests.
799 self._checker.check_art_test_executable('dexoptanalyzer_test')
800
801 # Check imgdiag tests.
802 self._checker.check_art_test_executable('imgdiag_test')
803
804 # Check libartbase tests.
805 self._checker.check_art_test_executable('arena_allocator_test')
806 self._checker.check_art_test_executable('bit_field_test')
807 self._checker.check_art_test_executable('bit_memory_region_test')
808 self._checker.check_art_test_executable('bit_string_test')
809 self._checker.check_art_test_executable('bit_struct_test')
810 self._checker.check_art_test_executable('bit_table_test')
811 self._checker.check_art_test_executable('bit_utils_test')
812 self._checker.check_art_test_executable('bit_vector_test')
813 self._checker.check_art_test_executable('fd_file_test')
814 self._checker.check_art_test_executable('file_utils_test')
815 self._checker.check_art_test_executable('hash_set_test')
816 self._checker.check_art_test_executable('hex_dump_test')
817 self._checker.check_art_test_executable('histogram_test')
818 self._checker.check_art_test_executable('indenter_test')
819 self._checker.check_art_test_executable('instruction_set_test')
820 self._checker.check_art_test_executable('intrusive_forward_list_test')
821 self._checker.check_art_test_executable('leb128_test')
822 self._checker.check_art_test_executable('logging_test')
823 self._checker.check_art_test_executable('mem_map_test')
824 self._checker.check_art_test_executable('membarrier_test')
825 self._checker.check_art_test_executable('memfd_test')
826 self._checker.check_art_test_executable('memory_region_test')
Roland Levillain61f07162019-06-26 12:44:04 +0100827 self._checker.check_art_test_executable('safe_copy_test')
828 self._checker.check_art_test_executable('scoped_flock_test')
829 self._checker.check_art_test_executable('time_utils_test')
830 self._checker.check_art_test_executable('transform_array_ref_test')
831 self._checker.check_art_test_executable('transform_iterator_test')
832 self._checker.check_art_test_executable('utils_test')
833 self._checker.check_art_test_executable('variant_map_test')
834 self._checker.check_art_test_executable('zip_archive_test')
835
836 # Check libartpalette tests.
837 self._checker.check_art_test_executable('palette_test')
838
839 # Check libdexfile tests.
840 self._checker.check_art_test_executable('art_dex_file_loader_test')
841 self._checker.check_art_test_executable('art_libdexfile_support_tests')
842 self._checker.check_art_test_executable('class_accessor_test')
843 self._checker.check_art_test_executable('code_item_accessors_test')
844 self._checker.check_art_test_executable('compact_dex_file_test')
845 self._checker.check_art_test_executable('compact_offset_table_test')
846 self._checker.check_art_test_executable('descriptors_names_test')
847 self._checker.check_art_test_executable('dex_file_loader_test')
848 self._checker.check_art_test_executable('dex_file_verifier_test')
849 self._checker.check_art_test_executable('dex_instruction_test')
850 self._checker.check_art_test_executable('primitive_test')
851 self._checker.check_art_test_executable('string_reference_test')
852 self._checker.check_art_test_executable('test_dex_file_builder_test')
853 self._checker.check_art_test_executable('type_lookup_table_test')
854 self._checker.check_art_test_executable('utf_test')
855
856 # Check libprofile tests.
857 self._checker.check_optional_art_test_executable('profile_boot_info_test')
858 self._checker.check_optional_art_test_executable('profile_compilation_info_test')
859
860 # Check oatdump tests.
861 self._checker.check_art_test_executable('oatdump_app_test')
862 self._checker.check_art_test_executable('oatdump_image_test')
863 self._checker.check_art_test_executable('oatdump_test')
864
865 # Check profman tests.
866 self._checker.check_art_test_executable('profile_assistant_test')
867
868 # Check runtime compiler tests.
869 self._checker.check_art_test_executable('module_exclusion_test')
870 self._checker.check_art_test_executable('reflection_test')
871
872 # Check runtime tests.
873 self._checker.check_art_test_executable('arch_test')
874 self._checker.check_art_test_executable('barrier_test')
875 self._checker.check_art_test_executable('card_table_test')
876 self._checker.check_art_test_executable('cha_test')
877 self._checker.check_art_test_executable('class_linker_test')
878 self._checker.check_art_test_executable('class_loader_context_test')
879 self._checker.check_art_test_executable('class_table_test')
880 self._checker.check_art_test_executable('compiler_filter_test')
881 self._checker.check_art_test_executable('dex_cache_test')
882 self._checker.check_art_test_executable('dlmalloc_space_random_test')
883 self._checker.check_art_test_executable('dlmalloc_space_static_test')
884 self._checker.check_art_test_executable('entrypoints_order_test')
885 self._checker.check_art_test_executable('exec_utils_test')
886 self._checker.check_art_test_executable('gtest_test')
887 self._checker.check_art_test_executable('handle_scope_test')
888 self._checker.check_art_test_executable('heap_test')
889 self._checker.check_art_test_executable('heap_verification_test')
890 self._checker.check_art_test_executable('hidden_api_test')
891 self._checker.check_art_test_executable('image_space_test')
892 self._checker.check_art_test_executable('immune_spaces_test')
893 self._checker.check_art_test_executable('imtable_test')
894 self._checker.check_art_test_executable('indirect_reference_table_test')
895 self._checker.check_art_test_executable('instruction_set_features_arm64_test')
896 self._checker.check_art_test_executable('instruction_set_features_arm_test')
Roland Levillain61f07162019-06-26 12:44:04 +0100897 self._checker.check_art_test_executable('instruction_set_features_test')
898 self._checker.check_art_test_executable('instruction_set_features_x86_64_test')
899 self._checker.check_art_test_executable('instruction_set_features_x86_test')
900 self._checker.check_art_test_executable('instrumentation_test')
901 self._checker.check_art_test_executable('intern_table_test')
902 self._checker.check_art_test_executable('java_vm_ext_test')
Roland Levillain61f07162019-06-26 12:44:04 +0100903 self._checker.check_art_test_executable('jit_memory_region_test')
904 self._checker.check_art_test_executable('jni_internal_test')
905 self._checker.check_art_test_executable('large_object_space_test')
906 self._checker.check_art_test_executable('math_entrypoints_test')
907 self._checker.check_art_test_executable('memcmp16_test')
908 self._checker.check_art_test_executable('method_handles_test')
909 self._checker.check_art_test_executable('method_type_test')
910 self._checker.check_art_test_executable('method_verifier_test')
911 self._checker.check_art_test_executable('mod_union_table_test')
912 self._checker.check_art_test_executable('monitor_pool_test')
913 self._checker.check_art_test_executable('monitor_test')
914 self._checker.check_art_test_executable('mutex_test')
915 self._checker.check_art_test_executable('oat_file_assistant_test')
916 self._checker.check_art_test_executable('oat_file_test')
917 self._checker.check_art_test_executable('object_test')
918 self._checker.check_art_test_executable('parsed_options_test')
919 self._checker.check_art_test_executable('prebuilt_tools_test')
920 self._checker.check_art_test_executable('profiling_info_test')
Calin Juravlef70dfec2019-10-02 18:58:19 -0700921 self._checker.check_art_test_executable('profile_saver_test')
Roland Levillain61f07162019-06-26 12:44:04 +0100922 self._checker.check_art_test_executable('proxy_test')
923 self._checker.check_art_test_executable('quick_trampoline_entrypoints_test')
924 self._checker.check_art_test_executable('reference_queue_test')
925 self._checker.check_art_test_executable('reference_table_test')
926 self._checker.check_art_test_executable('reg_type_test')
927 self._checker.check_art_test_executable('rosalloc_space_random_test')
928 self._checker.check_art_test_executable('rosalloc_space_static_test')
929 self._checker.check_art_test_executable('runtime_callbacks_test')
930 self._checker.check_art_test_executable('runtime_test')
931 self._checker.check_art_test_executable('safe_math_test')
932 self._checker.check_art_test_executable('space_bitmap_test')
933 self._checker.check_art_test_executable('space_create_test')
934 self._checker.check_art_test_executable('stub_test')
935 self._checker.check_art_test_executable('subtype_check_info_test')
936 self._checker.check_art_test_executable('subtype_check_test')
937 self._checker.check_art_test_executable('system_weak_test')
938 self._checker.check_art_test_executable('task_processor_test')
939 self._checker.check_art_test_executable('thread_pool_test')
940 self._checker.check_art_test_executable('timing_logger_test')
941 self._checker.check_art_test_executable('transaction_test')
942 self._checker.check_art_test_executable('two_runtimes_test')
943 self._checker.check_art_test_executable('unstarted_runtime_test')
944 self._checker.check_art_test_executable('var_handle_test')
945 self._checker.check_art_test_executable('vdex_file_test')
946
947 # Check sigchainlib tests.
948 self._checker.check_art_test_executable('sigchain_test')
949
950 # Check ART test (internal) libraries.
951 self._checker.check_native_library('libart-gtest')
Roland Levillain61f07162019-06-26 12:44:04 +0100952 self._checker.check_native_library('libartd-simulator-container')
953
Andreas Gampe816a5522019-09-11 11:29:49 -0700954 # Check ART test tools.
955 self._checker.check_executable('signal_dumper')
956
Roland Levillain61f07162019-06-26 12:44:04 +0100957
Martin Stjernholm2babede2019-03-18 21:04:49 +0000958class NoSuperfluousBinariesChecker:
959 def __init__(self, checker):
960 self._checker = checker
961
962 def __str__(self):
963 return 'No superfluous binaries checker'
964
965 def run(self):
966 self._checker.check_no_superfluous_files('bin')
967
968
969class NoSuperfluousLibrariesChecker:
970 def __init__(self, checker):
971 self._checker = checker
972
973 def __str__(self):
974 return 'No superfluous libraries checker'
975
976 def run(self):
977 self._checker.check_no_superfluous_files('javalib')
978 self._checker.check_no_superfluous_files('lib')
Martin Stjernholm2babede2019-03-18 21:04:49 +0000979 self._checker.check_no_superfluous_files('lib64')
Martin Stjernholm2babede2019-03-18 21:04:49 +0000980
Andreas Gampeb1d55672019-01-29 22:17:02 +0000981
Roland Levillain61f07162019-06-26 12:44:04 +0100982class NoSuperfluousArtTestsChecker:
983 def __init__(self, checker):
984 self._checker = checker
985
986 def __str__(self):
987 return 'No superfluous ART tests checker'
988
989 def run(self):
Orion Hodsonaf3ed622019-10-03 16:30:54 +0100990 for arch in ARCHS:
991 self._checker.check_no_superfluous_files('%s/%s' % (ART_TEST_DIR, arch))
Roland Levillain61f07162019-06-26 12:44:04 +0100992
993
Luca Stefani4e91ee92019-03-06 15:08:16 +0100994class List:
Roland Levillain77251f92019-08-09 15:00:04 +0100995 def __init__(self, provider, print_size=False):
Luca Stefani4e91ee92019-03-06 15:08:16 +0100996 self._provider = provider
Roland Levillaine91d7872019-07-25 18:56:06 +0100997 self._print_size = print_size
Luca Stefani4e91ee92019-03-06 15:08:16 +0100998
999 def print_list(self):
Roland Levillain09744ac2019-06-06 18:23:02 +01001000
1001 def print_list_rec(path):
1002 apex_map = self._provider.read_dir(path)
1003 if apex_map is None:
1004 return
1005 apex_map = dict(apex_map)
1006 if '.' in apex_map:
1007 del apex_map['.']
1008 if '..' in apex_map:
1009 del apex_map['..']
1010 for (_, val) in sorted(apex_map.items()):
1011 val_path = os.path.join(path, val.name)
Roland Levillaine91d7872019-07-25 18:56:06 +01001012 if self._print_size:
1013 if val.size < 0:
1014 print('[ n/a ] %s' % val_path)
1015 else:
1016 print('[%11d] %s' % (val.size, val_path))
1017 else:
1018 print(val_path)
Roland Levillain09744ac2019-06-06 18:23:02 +01001019 if val.is_dir:
1020 print_list_rec(val_path)
1021
1022 print_list_rec('')
Luca Stefani4e91ee92019-03-06 15:08:16 +01001023
1024
1025class Tree:
Roland Levillain77251f92019-08-09 15:00:04 +01001026 def __init__(self, provider, title, print_size=False):
Luca Stefani4e91ee92019-03-06 15:08:16 +01001027 print('%s' % title)
1028 self._provider = provider
Luca Stefani4e91ee92019-03-06 15:08:16 +01001029 self._has_next_list = []
Roland Levillain88e55692019-07-25 15:57:06 +01001030 self._print_size = print_size
Luca Stefani4e91ee92019-03-06 15:08:16 +01001031
1032 @staticmethod
1033 def get_vertical(has_next_list):
1034 string = ''
1035 for v in has_next_list:
1036 string += '%s ' % ('│' if v else ' ')
1037 return string
1038
1039 @staticmethod
1040 def get_last_vertical(last):
1041 return '└── ' if last else '├── '
1042
1043 def print_tree(self):
Roland Levillain09744ac2019-06-06 18:23:02 +01001044
1045 def print_tree_rec(path):
1046 apex_map = self._provider.read_dir(path)
1047 if apex_map is None:
1048 return
1049 apex_map = dict(apex_map)
1050 if '.' in apex_map:
1051 del apex_map['.']
1052 if '..' in apex_map:
1053 del apex_map['..']
1054 key_list = list(sorted(apex_map.keys()))
1055 for i, key in enumerate(key_list):
1056 prev = self.get_vertical(self._has_next_list)
1057 last = self.get_last_vertical(i == len(key_list) - 1)
1058 val = apex_map[key]
Roland Levillain88e55692019-07-25 15:57:06 +01001059 if self._print_size:
1060 if val.size < 0:
1061 print('%s%s[ n/a ] %s' % (prev, last, val.name))
1062 else:
1063 print('%s%s[%11d] %s' % (prev, last, val.size, val.name))
1064 else:
1065 print('%s%s%s' % (prev, last, val.name))
Roland Levillain09744ac2019-06-06 18:23:02 +01001066 if val.is_dir:
1067 self._has_next_list.append(i < len(key_list) - 1)
1068 val_path = os.path.join(path, val.name)
1069 print_tree_rec(val_path)
1070 self._has_next_list.pop()
1071
1072 print_tree_rec('')
Luca Stefani4e91ee92019-03-06 15:08:16 +01001073
Andreas Gampeb1d55672019-01-29 22:17:02 +00001074
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001075# Note: do not sys.exit early, for __del__ cleanup.
Luca Stefani4e91ee92019-03-06 15:08:16 +01001076def art_apex_test_main(test_args):
Roland Levillaindd20d002019-07-19 16:09:47 +01001077 if test_args.host and test_args.flattened:
1078 logging.error("Both of --host and --flattened set")
1079 return 1
Luca Stefani4e91ee92019-03-06 15:08:16 +01001080 if test_args.list and test_args.tree:
Andreas Gampeb1d55672019-01-29 22:17:02 +00001081 logging.error("Both of --list and --tree set")
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001082 return 1
Roland Levillaine91d7872019-07-25 18:56:06 +01001083 if test_args.size and not (test_args.list or test_args.tree):
1084 logging.error("--size set but neither --list nor --tree set")
Roland Levillain88e55692019-07-25 15:57:06 +01001085 return 1
Martin Stjernholm3cb59a42019-08-07 17:18:29 +01001086 if not test_args.flattened and not test_args.tmpdir:
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001087 logging.error("Need a tmpdir.")
1088 return 1
Martin Stjernholm3cb59a42019-08-07 17:18:29 +01001089 if not test_args.flattened and not test_args.host and not test_args.debugfs:
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001090 logging.error("Need debugfs.")
1091 return 1
1092
Roland Levillainfdbe2072019-11-11 15:52:45 +00001093 if test_args.host:
1094 # Host APEX.
1095 if test_args.flavor not in [FLAVOR_DEBUG, FLAVOR_AUTO]:
1096 logging.error("Using option --host with non-Debug APEX")
Roland Levillaindbd6a142019-10-03 15:08:28 +01001097 return 1
Roland Levillainfdbe2072019-11-11 15:52:45 +00001098 # Host APEX is always a debug flavor (for now).
1099 test_args.flavor = FLAVOR_DEBUG
1100 else:
1101 # Device APEX.
1102 if test_args.flavor == FLAVOR_AUTO:
1103 logging.warning('--flavor=auto, trying to autodetect. This may be incorrect!')
1104 for flavor in [ FLAVOR_RELEASE, FLAVOR_DEBUG, FLAVOR_TESTING ]:
1105 flavor_pattern = '*.%s*' % flavor
1106 if fnmatch.fnmatch(test_args.apex, flavor_pattern):
1107 test_args.flavor = flavor
1108 break
1109 if test_args.flavor == FLAVOR_AUTO:
1110 logging.error(' Could not detect APEX flavor, neither \'%s\', \'%s\' nor \'%s\' in \'%s\'',
1111 FLAVOR_RELEASE, FLAVOR_DEBUG, FLAVOR_TESTING, test_args.apex)
1112 return 1
Roland Levillaindbd6a142019-10-03 15:08:28 +01001113
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001114 try:
Luca Stefani4e91ee92019-03-06 15:08:16 +01001115 if test_args.host:
1116 apex_provider = HostApexProvider(test_args.apex, test_args.tmpdir)
Andreas Gampe09123952019-01-30 13:17:02 -08001117 else:
Roland Levillaindd20d002019-07-19 16:09:47 +01001118 if test_args.flattened:
1119 apex_provider = TargetFlattenedApexProvider(test_args.apex)
1120 else:
1121 apex_provider = TargetApexProvider(test_args.apex, test_args.tmpdir, test_args.debugfs)
Luca Stefani4e91ee92019-03-06 15:08:16 +01001122 except (zipfile.BadZipFile, zipfile.LargeZipFile) as e:
Andreas Gampea0242cf2019-01-29 13:01:23 -08001123 logging.error('Failed to create provider: %s', e)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001124 return 1
1125
Luca Stefani4e91ee92019-03-06 15:08:16 +01001126 if test_args.tree:
Roland Levillain88e55692019-07-25 15:57:06 +01001127 Tree(apex_provider, test_args.apex, test_args.size).print_tree()
Andreas Gampeb1d55672019-01-29 22:17:02 +00001128 return 0
Luca Stefani4e91ee92019-03-06 15:08:16 +01001129 if test_args.list:
Roland Levillaine91d7872019-07-25 18:56:06 +01001130 List(apex_provider, test_args.size).print_list()
Andreas Gampeb1d55672019-01-29 22:17:02 +00001131 return 0
1132
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001133 checkers = []
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001134 if test_args.bitness == BITNESS_AUTO:
Luca Stefani4e91ee92019-03-06 15:08:16 +01001135 logging.warning('--bitness=auto, trying to autodetect. This may be incorrect!')
Andreas Gampeeb555b82019-01-30 14:47:49 -08001136 has_32 = apex_provider.get('lib') is not None
1137 has_64 = apex_provider.get('lib64') is not None
1138 if has_32 and has_64:
Luca Stefani4e91ee92019-03-06 15:08:16 +01001139 logging.warning(' Detected multilib')
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001140 test_args.bitness = BITNESS_MULTILIB
Andreas Gampeeb555b82019-01-30 14:47:49 -08001141 elif has_32:
Luca Stefani4e91ee92019-03-06 15:08:16 +01001142 logging.warning(' Detected 32-only')
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001143 test_args.bitness = BITNESS_32
Andreas Gampeeb555b82019-01-30 14:47:49 -08001144 elif has_64:
Luca Stefani4e91ee92019-03-06 15:08:16 +01001145 logging.warning(' Detected 64-only')
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001146 test_args.bitness = BITNESS_64
Andreas Gampeeb555b82019-01-30 14:47:49 -08001147 else:
1148 logging.error(' Could not detect bitness, neither lib nor lib64 contained.')
Roland Levillain77251f92019-08-09 15:00:04 +01001149 List(apex_provider).print_list()
Andreas Gampeeb555b82019-01-30 14:47:49 -08001150 return 1
1151
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001152 if test_args.bitness == BITNESS_32:
Andreas Gampeeb555b82019-01-30 14:47:49 -08001153 base_checker = Arch32Checker(apex_provider)
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001154 elif test_args.bitness == BITNESS_64:
Andreas Gampeeb555b82019-01-30 14:47:49 -08001155 base_checker = Arch64Checker(apex_provider)
1156 else:
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001157 assert test_args.bitness == BITNESS_MULTILIB
Andreas Gampeeb555b82019-01-30 14:47:49 -08001158 base_checker = MultilibChecker(apex_provider)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001159
Andreas Gampe9dc4b052019-01-30 13:47:25 -08001160 checkers.append(ReleaseChecker(base_checker))
Luca Stefani4e91ee92019-03-06 15:08:16 +01001161 if test_args.host:
Andreas Gampe9dc4b052019-01-30 13:47:25 -08001162 checkers.append(ReleaseHostChecker(base_checker))
Andreas Gampe09123952019-01-30 13:17:02 -08001163 else:
Andreas Gampe9dc4b052019-01-30 13:47:25 -08001164 checkers.append(ReleaseTargetChecker(base_checker))
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001165 if test_args.flavor == FLAVOR_DEBUG or test_args.flavor == FLAVOR_TESTING:
Andreas Gampe9dc4b052019-01-30 13:47:25 -08001166 checkers.append(DebugChecker(base_checker))
Roland Levillain61f07162019-06-26 12:44:04 +01001167 if not test_args.host:
1168 checkers.append(DebugTargetChecker(base_checker))
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001169 if test_args.flavor == FLAVOR_TESTING:
Roland Levillain61f07162019-06-26 12:44:04 +01001170 checkers.append(TestingTargetChecker(base_checker))
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001171
Martin Stjernholm2babede2019-03-18 21:04:49 +00001172 # These checkers must be last.
1173 checkers.append(NoSuperfluousBinariesChecker(base_checker))
Roland Levillain61f07162019-06-26 12:44:04 +01001174 checkers.append(NoSuperfluousArtTestsChecker(base_checker))
Martin Stjernholm2babede2019-03-18 21:04:49 +00001175 if not test_args.host:
1176 # We only care about superfluous libraries on target, where their absence
1177 # can be vital to ensure they get picked up from the right package.
1178 checkers.append(NoSuperfluousLibrariesChecker(base_checker))
1179
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001180 failed = False
1181 for checker in checkers:
1182 logging.info('%s...', checker)
1183 checker.run()
Andreas Gampe9dc4b052019-01-30 13:47:25 -08001184 if base_checker.error_count() > 0:
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001185 logging.error('%s FAILED', checker)
1186 failed = True
1187 else:
1188 logging.info('%s SUCCEEDED', checker)
Andreas Gampe9dc4b052019-01-30 13:47:25 -08001189 base_checker.reset_errors()
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001190
1191 return 1 if failed else 0
1192
Luca Stefani4e91ee92019-03-06 15:08:16 +01001193
1194def art_apex_test_default(test_parser):
1195 if 'ANDROID_PRODUCT_OUT' not in os.environ:
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001196 logging.error('No-argument use requires ANDROID_PRODUCT_OUT')
1197 sys.exit(1)
1198 product_out = os.environ['ANDROID_PRODUCT_OUT']
Luca Stefani4e91ee92019-03-06 15:08:16 +01001199 if 'ANDROID_HOST_OUT' not in os.environ:
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001200 logging.error('No-argument use requires ANDROID_HOST_OUT')
1201 sys.exit(1)
1202 host_out = os.environ['ANDROID_HOST_OUT']
1203
Luca Stefani4e91ee92019-03-06 15:08:16 +01001204 test_args = test_parser.parse_args(['dummy']) # For consistency.
1205 test_args.debugfs = '%s/bin/debugfs' % host_out
1206 test_args.tmpdir = '.'
1207 test_args.tree = False
1208 test_args.list = False
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001209 test_args.bitness = BITNESS_AUTO
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001210 failed = False
1211
Luca Stefani4e91ee92019-03-06 15:08:16 +01001212 if not os.path.exists(test_args.debugfs):
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001213 logging.error("Cannot find debugfs (default path %s). Please build it, e.g., m debugfs",
Luca Stefani4e91ee92019-03-06 15:08:16 +01001214 test_args.debugfs)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001215 sys.exit(1)
1216
Roland Levillaind7ea0432019-09-09 16:29:12 +01001217 # TODO: Add host support.
1218 # TODO: Add support for flattened APEX packages.
Luca Stefani4e91ee92019-03-06 15:08:16 +01001219 configs = [
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001220 {'name': 'com.android.art.release', 'flavor': FLAVOR_RELEASE, 'host': False},
1221 {'name': 'com.android.art.debug', 'flavor': FLAVOR_DEBUG, 'host': False},
1222 {'name': 'com.android.art.testing', 'flavor': FLAVOR_TESTING, 'host': False},
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001223 ]
1224
1225 for config in configs:
1226 logging.info(config['name'])
1227 # TODO: Host will need different path.
Luca Stefani4e91ee92019-03-06 15:08:16 +01001228 test_args.apex = '%s/system/apex/%s.apex' % (product_out, config['name'])
1229 if not os.path.exists(test_args.apex):
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001230 failed = True
Luca Stefani4e91ee92019-03-06 15:08:16 +01001231 logging.error("Cannot find APEX %s. Please build it first.", test_args.apex)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001232 continue
Roland Levillaind7ea0432019-09-09 16:29:12 +01001233 test_args.flavor = config['flavor']
Luca Stefani4e91ee92019-03-06 15:08:16 +01001234 test_args.host = config['host']
1235 failed = art_apex_test_main(test_args) != 0
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001236
1237 if failed:
1238 sys.exit(1)
1239
Luca Stefani4e91ee92019-03-06 15:08:16 +01001240
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001241if __name__ == "__main__":
Martin Stjernholme58624f2019-09-20 15:53:40 +01001242 parser = argparse.ArgumentParser(description='Check integrity of an ART APEX.')
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001243
Roland Levillaind7ea0432019-09-09 16:29:12 +01001244 parser.add_argument('apex', help='APEX file input')
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001245
Roland Levillaind7ea0432019-09-09 16:29:12 +01001246 parser.add_argument('--host', help='Check as host APEX', action='store_true')
Andreas Gampe09123952019-01-30 13:17:02 -08001247
Roland Levillaind7ea0432019-09-09 16:29:12 +01001248 parser.add_argument('--flattened', help='Check as flattened (target) APEX', action='store_true')
Roland Levillaindd20d002019-07-19 16:09:47 +01001249
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001250 parser.add_argument('--flavor', help='Check as FLAVOR APEX', choices=FLAVORS_ALL,
1251 default=FLAVOR_AUTO)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001252
Andreas Gampeb1d55672019-01-29 22:17:02 +00001253 parser.add_argument('--list', help='List all files', action='store_true')
1254 parser.add_argument('--tree', help='Print directory tree', action='store_true')
Roland Levillaine91d7872019-07-25 18:56:06 +01001255 parser.add_argument('--size', help='Print file sizes', action='store_true')
Andreas Gampeb1d55672019-01-29 22:17:02 +00001256
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001257 parser.add_argument('--tmpdir', help='Directory for temp files')
1258 parser.add_argument('--debugfs', help='Path to debugfs')
1259
Orion Hodsonaf3ed622019-10-03 16:30:54 +01001260 parser.add_argument('--bitness', help='Bitness to check', choices=BITNESS_ALL,
1261 default=BITNESS_AUTO)
Andreas Gampeeb555b82019-01-30 14:47:49 -08001262
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001263 if len(sys.argv) == 1:
Luca Stefani4e91ee92019-03-06 15:08:16 +01001264 art_apex_test_default(parser)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001265 else:
1266 args = parser.parse_args()
1267
1268 if args is None:
1269 sys.exit(1)
1270
Luca Stefani4e91ee92019-03-06 15:08:16 +01001271 exit_code = art_apex_test_main(args)
Andreas Gampe2c846cd2019-01-29 22:06:46 +00001272 sys.exit(exit_code)