1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 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 20import fnmatch 21import logging 22import os 23import os.path 24import subprocess 25import sys 26import zipfile 27 28logging.basicConfig(format='%(message)s') 29 30# 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 44# Architectures supported by APEX packages. 45ARCHS = ["arm", "arm64", "x86", "x86_64"] 46 47# Directory containing ART tests within an ART APEX (if the package includes 48# any). ART test executables are installed in `bin/art/<arch>`. Segregating 49# tests by architecture is useful on devices supporting more than one 50# architecture, as it permits testing all of them using a single ART APEX 51# package. 52ART_TEST_DIR = 'bin/art' 53 54 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 60class FSObject: 61 def __init__(self, name, is_dir, is_exec, is_symlink, size): 62 self.name = name 63 self.is_dir = is_dir 64 self.is_exec = is_exec 65 self.is_symlink = is_symlink 66 self.size = size 67 68 def __str__(self): 69 return '%s(dir=%r,exec=%r,symlink=%r,size=%d)' \ 70 % (self.name, self.is_dir, self.is_exec, self.is_symlink, self.size) 71 72 73class 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. 80 apex_zip = zipfile.ZipFile(apex) 81 apex_zip.extract('apex_payload.img', tmpdir) 82 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): 89 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 94 95 def read_dir(self, apex_dir): 96 if apex_dir in self._folder_cache: 97 return self._folder_cache[apex_dir] 98 # Cannot use check_output as it will annoy with stderr. 99 process = subprocess.Popen([self._debugfs, '-R', 'ls -l -p %s' % apex_dir, self._payload], 100 stdout=subprocess.PIPE, stderr=subprocess.PIPE, 101 universal_newlines=True) 102 stdout, _ = process.communicate() 103 res = str(stdout) 104 apex_map = {} 105 # 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: 128 logging.warning('Could not break and parse line \'%s\'', line) 129 continue 130 bits = comps[2] 131 name = comps[5] 132 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 135 if len(bits) != 6: 136 logging.warning('Dont understand bits \'%s\'', bits) 137 continue 138 is_dir = bits[1] == '4' 139 140 def is_exec_bit(ch): 141 return int(ch) & 1 == 1 142 143 is_exec = is_exec_bit(bits[3]) and is_exec_bit(bits[4]) and is_exec_bit(bits[5]) 144 is_symlink = bits[1] == '2' 145 apex_map[name] = FSObject(name, is_dir, is_exec, is_symlink, size) 146 self._folder_cache[apex_dir] = apex_map 147 return apex_map 148 149 150class 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) 173 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) 178 apex_map[basename] = FSObject(basename, is_dir, is_exec, is_symlink, size) 179 self._folder_cache[apex_dir] = apex_map 180 return apex_map 181 182 183class HostApexProvider: 184 def __init__(self, apex, tmpdir): 185 self._tmpdir = tmpdir 186 self._folder_cache = {} 187 self._payload = os.path.join(self._tmpdir, 'apex_payload.zip') 188 # Extract payload to tmpdir. 189 apex_zip = zipfile.ZipFile(apex) 190 apex_zip.extract('apex_payload.zip', tmpdir) 191 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): 198 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 203 204 def read_dir(self, apex_dir): 205 if apex_dir in self._folder_cache: 206 return self._folder_cache[apex_dir] 207 if not self._folder_cache: 208 self.parse_zip() 209 if apex_dir in self._folder_cache: 210 return self._folder_cache[apex_dir] 211 return {} 212 213 def parse_zip(self): 214 apex_zip = zipfile.ZipFile(self._payload) 215 infos = apex_zip.infolist() 216 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): 223 return (val >> (index * 3)) & 0x7 224 225 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: 231 apex_dir, base = os.path.split(path) 232 # TODO: If directories are stored, base will be empty. 233 234 if apex_dir not in self._folder_cache: 235 self._folder_cache[apex_dir] = {} 236 dir_map = self._folder_cache[apex_dir] 237 if base not in dir_map: 238 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) 243 size = zipinfo.file_size 244 else: 245 is_exec = False # Seems we can't get this easily? 246 is_symlink = False 247 is_dir = True 248 # 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) 251 is_zipinfo = False 252 path = apex_dir 253 254 255# DO NOT USE DIRECTLY! This is an "abstract" base class. 256class Checker: 257 def __init__(self, provider): 258 self._provider = provider 259 self._errors = 0 260 self._expected_file_globs = set() 261 262 def fail(self, msg, *fail_args): 263 self._errors += 1 264 logging.error(msg, *fail_args) 265 266 def error_count(self): 267 return self._errors 268 269 def reset_errors(self): 270 self._errors = 0 271 272 def is_file(self, path): 273 fs_object = self._provider.get(path) 274 if fs_object is None: 275 return False, 'Could not find %s' 276 if fs_object.is_dir: 277 return False, '%s is a directory' 278 return True, '' 279 280 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 288 def check_file(self, path): 289 ok, msg = self.is_file(path) 290 if not ok: 291 self.fail(msg, path) 292 self._expected_file_globs.add(path) 293 return ok 294 295 def check_executable(self, filename): 296 path = 'bin/%s' % filename 297 if not self.check_file(path): 298 return 299 if not self._provider.get(path).is_exec: 300 self.fail('%s is not executable', path) 301 302 def check_executable_symlink(self, filename): 303 path = 'bin/%s' % filename 304 fs_object = self._provider.get(path) 305 if fs_object is None: 306 self.fail('Could not find %s', path) 307 return 308 if fs_object.is_dir: 309 self.fail('%s is a directory', path) 310 return 311 if not fs_object.is_symlink: 312 self.fail('%s is not a symlink', path) 313 self._expected_file_globs.add(path) 314 315 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. 319 # 320 # TODO(b/123602136): Pass build target information to this script and fix 321 # all places where this function in used (or similar workarounds). 322 dirs = [] 323 for arch in ARCHS: 324 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: 333 self.fail('ART test binary missing: %s', filename) 334 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) 339 340 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: 345 self._expected_file_globs.add(lib_path) 346 lib64_is_file, _ = self.is_file(lib64_path) 347 if lib64_is_file: 348 self._expected_file_globs.add(lib64_path) 349 if not lib_is_file and not lib64_is_file: 350 self.fail('Library missing: %s', filename) 351 352 def check_dexpreopt(self, basename): 353 dirs = self.arch_dirs_for_path('javalib') 354 for dir in dirs: 355 for ext in ['art', 'oat', 'vdex']: 356 self.check_file('%s/%s.%s' % (dir, basename, ext)) 357 358 def check_java_library(self, basename): 359 return self.check_file('javalib/%s.jar' % basename) 360 361 def ignore_path(self, path_glob): 362 self._expected_file_globs.add(path_glob) 363 364 def check_optional_art_test_executable(self, filename): 365 for arch in ARCHS: 366 self.ignore_path('%s/%s/%s' % (ART_TEST_DIR, arch, filename)) 367 368 def check_no_superfluous_files(self, dir_path): 369 paths = [] 370 for name in sorted(self._provider.read_dir(dir_path).keys()): 371 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) 385 386 # Just here for docs purposes, even if it isn't good Python style. 387 388 def check_symlinked_multilib_executable(self, filename): 389 """Check bin/filename32, and/or bin/filename64, with symlink bin/filename.""" 390 raise NotImplementedError 391 392 def check_symlinked_first_executable(self, filename): 393 """Check bin/filename32, and/or bin/filename64, with symlink bin/filename.""" 394 raise NotImplementedError 395 396 def check_multilib_executable(self, filename): 397 """Check bin/filename for 32 bit, and/or bin/filename64.""" 398 raise NotImplementedError 399 400 def check_first_executable(self, filename): 401 """Check bin/filename for 32 bit, and/or bin/filename64.""" 402 raise NotImplementedError 403 404 def check_native_library(self, basename): 405 """Check lib/basename.so, and/or lib64/basename.so.""" 406 raise NotImplementedError 407 408 def check_optional_native_library(self, basename_glob): 409 """Allow lib/basename.so and/or lib64/basename.so to exist.""" 410 raise NotImplementedError 411 412 def check_prefer64_library(self, basename): 413 """Check lib64/basename.so, or lib/basename.so on 32 bit only.""" 414 raise NotImplementedError 415 416 417class Arch32Checker(Checker): 418 def check_symlinked_multilib_executable(self, filename): 419 self.check_executable('%s32' % filename) 420 self.check_executable_symlink(filename) 421 422 def check_symlinked_first_executable(self, filename): 423 self.check_executable('%s32' % filename) 424 self.check_executable_symlink(filename) 425 426 def check_multilib_executable(self, filename): 427 self.check_executable('%s32' % filename) 428 429 def check_first_executable(self, filename): 430 self.check_executable('%s32' % filename) 431 432 def check_native_library(self, basename): 433 # TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve 434 # the precision of this test? 435 self.check_file('lib/%s.so' % basename) 436 437 def check_optional_native_library(self, basename_glob): 438 self.ignore_path('lib/%s.so' % basename_glob) 439 440 def check_prefer64_library(self, basename): 441 self.check_native_library(basename) 442 443 444class Arch64Checker(Checker): 445 def check_symlinked_multilib_executable(self, filename): 446 self.check_executable('%s64' % filename) 447 self.check_executable_symlink(filename) 448 449 def check_symlinked_first_executable(self, filename): 450 self.check_executable('%s64' % filename) 451 self.check_executable_symlink(filename) 452 453 def check_multilib_executable(self, filename): 454 self.check_executable('%s64' % filename) 455 456 def check_first_executable(self, filename): 457 self.check_executable('%s64' % filename) 458 459 def check_native_library(self, basename): 460 # TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve 461 # the precision of this test? 462 self.check_file('lib64/%s.so' % basename) 463 464 def check_optional_native_library(self, basename_glob): 465 self.ignore_path('lib64/%s.so' % basename_glob) 466 467 def check_prefer64_library(self, basename): 468 self.check_native_library(basename) 469 470 471class MultilibChecker(Checker): 472 def check_symlinked_multilib_executable(self, filename): 473 self.check_executable('%s32' % filename) 474 self.check_executable('%s64' % filename) 475 self.check_executable_symlink(filename) 476 477 def check_symlinked_first_executable(self, filename): 478 self.check_executable('%s64' % filename) 479 self.check_executable_symlink(filename) 480 481 def check_multilib_executable(self, filename): 482 self.check_executable('%s64' % filename) 483 self.check_executable('%s32' % filename) 484 485 def check_first_executable(self, filename): 486 self.check_executable('%s64' % filename) 487 488 def check_native_library(self, basename): 489 # TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve 490 # the precision of this test? 491 self.check_file('lib/%s.so' % basename) 492 self.check_file('lib64/%s.so' % basename) 493 494 def check_optional_native_library(self, basename_glob): 495 self.ignore_path('lib/%s.so' % basename_glob) 496 self.ignore_path('lib64/%s.so' % basename_glob) 497 498 def check_prefer64_library(self, basename): 499 self.check_file('lib64/%s.so' % basename) 500 501 502class ReleaseChecker: 503 def __init__(self, checker): 504 self._checker = checker 505 506 def __str__(self): 507 return 'Release Checker' 508 509 def run(self): 510 # Check the Protocol Buffers APEX manifest. 511 self._checker.check_file('apex_manifest.pb') 512 513 # Check binaries for ART. 514 self._checker.check_first_executable('dex2oat') 515 self._checker.check_executable('dexdump') 516 self._checker.check_executable('dexlist') 517 self._checker.check_executable('dexoptanalyzer') 518 self._checker.check_executable('profman') 519 self._checker.check_symlinked_multilib_executable('dalvikvm') 520 521 # Check exported libraries for ART. 522 self._checker.check_native_library('libdexfile_external') 523 self._checker.check_native_library('libnativebridge') 524 self._checker.check_native_library('libnativehelper') 525 self._checker.check_native_library('libnativeloader') 526 527 # Check internal libraries for ART. 528 self._checker.check_native_library('libadbconnection') 529 self._checker.check_native_library('libart') 530 self._checker.check_native_library('libart-compiler') 531 self._checker.check_native_library('libart-dexlayout') 532 self._checker.check_native_library('libart-disassembler') 533 self._checker.check_native_library('libartbase') 534 self._checker.check_native_library('libartpalette') 535 self._checker.check_native_library('libdexfile') 536 self._checker.check_native_library('libdexfile_support') 537 self._checker.check_native_library('libopenjdkjvm') 538 self._checker.check_native_library('libopenjdkjvmti') 539 self._checker.check_native_library('libprofile') 540 self._checker.check_native_library('libsigchain') 541 542 # Check java libraries for Managed Core Library. 543 self._checker.check_java_library('apache-xml') 544 self._checker.check_java_library('bouncycastle') 545 self._checker.check_java_library('core-icu4j') 546 self._checker.check_java_library('core-libart') 547 self._checker.check_java_library('core-oj') 548 self._checker.check_java_library('okhttp') 549 if isEnvTrue('EMMA_INSTRUMENT_FRAMEWORK'): 550 # In coverage builds jacoco is added to the list of ART apex jars. 551 self._checker.check_java_library('jacocoagent') 552 553 # Check internal native libraries for Managed Core Library. 554 self._checker.check_native_library('libjavacore') 555 self._checker.check_native_library('libopenjdk') 556 557 # Check internal native library dependencies. 558 # 559 # Any internal dependency not listed here will cause a failure in 560 # NoSuperfluousLibrariesChecker. Internal dependencies are generally just 561 # implementation details, but in the release package we want to track them 562 # because a) they add to the package size and the RAM usage (in particular 563 # if the library is also present in /system or another APEX and hence might 564 # get loaded twice through linker namespace separation), and b) we need to 565 # catch invalid dependencies on /system or other APEXes that should go 566 # through an exported library with stubs (b/128708192 tracks implementing a 567 # better approach for that). 568 self._checker.check_native_library('libbacktrace') 569 self._checker.check_native_library('libbase') 570 self._checker.check_native_library('libc++') 571 self._checker.check_native_library('libdt_fd_forward') 572 self._checker.check_native_library('libdt_socket') 573 self._checker.check_native_library('libjdwp') 574 self._checker.check_native_library('liblzma') 575 self._checker.check_native_library('libnpt') 576 self._checker.check_native_library('libunwindstack') 577 self._checker.check_native_library('libziparchive') 578 self._checker.check_optional_native_library('libvixl') # Only on ARM/ARM64 579 580 # Allow extra dependencies that appear in ASAN builds. 581 self._checker.check_optional_native_library('libclang_rt.asan*') 582 self._checker.check_optional_native_library('libclang_rt.hwasan*') 583 self._checker.check_optional_native_library('libclang_rt.ubsan*') 584 585 # Check dexpreopt files for libcore bootclasspath jars. 586 self._checker.check_dexpreopt('boot') 587 self._checker.check_dexpreopt('boot-apache-xml') 588 self._checker.check_dexpreopt('boot-bouncycastle') 589 self._checker.check_dexpreopt('boot-core-icu4j') 590 self._checker.check_dexpreopt('boot-core-libart') 591 self._checker.check_dexpreopt('boot-okhttp') 592 if isEnvTrue('EMMA_INSTRUMENT_FRAMEWORK'): 593 # In coverage builds the ART boot image includes jacoco. 594 self._checker.check_dexpreopt('boot-jacocoagent') 595 596class ReleaseTargetChecker: 597 def __init__(self, checker): 598 self._checker = checker 599 600 def __str__(self): 601 return 'Release (Target) Checker' 602 603 def run(self): 604 # We don't check for the presence of the JSON APEX manifest (file 605 # `apex_manifest.json`, only present in target APEXes), as it is only 606 # included for compatibility reasons with Android Q and will likely be 607 # removed in Android R. 608 609 # Check binaries for ART. 610 self._checker.check_executable('oatdump') 611 self._checker.check_multilib_executable('dex2oat') 612 613 # Check internal libraries for ART. 614 self._checker.check_prefer64_library('libart-disassembler') 615 self._checker.check_native_library('libperfetto_hprof') 616 617 # Check exported native libraries for Managed Core Library. 618 self._checker.check_native_library('libandroidicu') 619 self._checker.check_native_library('libandroidio') 620 621 # Check internal native library dependencies. 622 self._checker.check_native_library('libcrypto') 623 self._checker.check_native_library('libexpat') 624 self._checker.check_native_library('libicui18n') 625 self._checker.check_native_library('libicuuc') 626 self._checker.check_native_library('libicu_jni') 627 self._checker.check_native_library('libpac') 628 self._checker.check_native_library('libz') 629 630 # TODO(b/139046641): Fix proper 2nd arch checks. For now, just ignore these 631 # directories. 632 self._checker.ignore_path('bin/arm') 633 self._checker.ignore_path('lib/arm') 634 self._checker.ignore_path('lib64/arm') 635 636 637class ReleaseHostChecker: 638 def __init__(self, checker): 639 self._checker = checker 640 641 def __str__(self): 642 return 'Release (Host) Checker' 643 644 def run(self): 645 # Check binaries for ART. 646 self._checker.check_executable('hprof-conv') 647 self._checker.check_symlinked_first_executable('dex2oatd') 648 self._checker.check_symlinked_first_executable('dex2oat') 649 650 # Check exported native libraries for Managed Core Library. 651 self._checker.check_native_library('libandroidicu-host') 652 self._checker.check_native_library('libandroidio') 653 654 # Check internal libraries for Managed Core Library. 655 self._checker.check_native_library('libexpat-host') 656 self._checker.check_native_library('libicui18n-host') 657 self._checker.check_native_library('libicuuc-host') 658 self._checker.check_native_library('libicu_jni') 659 self._checker.check_native_library('libz-host') 660 661 662class DebugChecker: 663 def __init__(self, checker): 664 self._checker = checker 665 666 def __str__(self): 667 return 'Debug Checker' 668 669 def run(self): 670 # Check binaries for ART. 671 self._checker.check_executable('dexdiag') 672 self._checker.check_executable('dexanalyze') 673 self._checker.check_executable('dexlayout') 674 self._checker.check_symlinked_multilib_executable('imgdiag') 675 676 # Check debug binaries for ART. 677 self._checker.check_executable('dexlayoutd') 678 self._checker.check_executable('dexoptanalyzerd') 679 self._checker.check_symlinked_multilib_executable('imgdiagd') 680 self._checker.check_executable('profmand') 681 682 # Check internal libraries for ART. 683 self._checker.check_native_library('libadbconnectiond') 684 self._checker.check_native_library('libart-disassembler') 685 self._checker.check_native_library('libartbased') 686 self._checker.check_native_library('libartd') 687 self._checker.check_native_library('libartd-compiler') 688 self._checker.check_native_library('libartd-dexlayout') 689 self._checker.check_native_library('libartd-disassembler') 690 self._checker.check_native_library('libdexfiled') 691 self._checker.check_native_library('libopenjdkjvmd') 692 self._checker.check_native_library('libopenjdkjvmtid') 693 self._checker.check_native_library('libprofiled') 694 695 # Check internal libraries for Managed Core Library. 696 self._checker.check_native_library('libopenjdkd') 697 698 699class DebugTargetChecker: 700 def __init__(self, checker): 701 self._checker = checker 702 703 def __str__(self): 704 return 'Debug (Target) Checker' 705 706 def run(self): 707 # Check ART debug binaries. 708 self._checker.check_multilib_executable('dex2oatd') 709 self._checker.check_multilib_executable('dex2oat') 710 self._checker.check_executable('oatdumpd') 711 712 # Check ART internal libraries. 713 self._checker.check_native_library('libdexfiled_external') 714 self._checker.check_native_library('libperfetto_hprofd') 715 716 # Check internal native library dependencies. 717 # 718 # Like in the release package, we check that we don't get other dependencies 719 # besides those listed here. In this case the concern is not bloat, but 720 # rather that we don't get behavioural differences between user (release) 721 # and userdebug/eng builds, which could happen if the debug package has 722 # duplicate library instances where releases don't. In other words, it's 723 # uncontroversial to add debug-only dependencies, as long as they don't make 724 # assumptions on having a single global state (ideally they should have 725 # double_loadable:true, cf. go/double_loadable). Also, like in the release 726 # package we need to look out for dependencies that should go through 727 # exported library stubs (until b/128708192 is fixed). 728 self._checker.check_optional_native_library('libvixld') # Only on ARM/ARM64 729 self._checker.check_prefer64_library('libmeminfo') 730 self._checker.check_prefer64_library('libprocinfo') 731 732 733class TestingTargetChecker: 734 def __init__(self, checker): 735 self._checker = checker 736 737 def __str__(self): 738 return 'Testing (Target) Checker' 739 740 def run(self): 741 # Check cmdline tests. 742 self._checker.check_optional_art_test_executable('cmdline_parser_test') 743 744 # Check compiler tests. 745 self._checker.check_art_test_executable('atomic_dex_ref_map_test') 746 self._checker.check_art_test_executable('bounds_check_elimination_test') 747 self._checker.check_art_test_executable('codegen_test') 748 self._checker.check_art_test_executable('compiled_method_storage_test') 749 self._checker.check_art_test_executable('data_type_test') 750 self._checker.check_art_test_executable('dedupe_set_test') 751 self._checker.check_art_test_executable('dominator_test') 752 self._checker.check_art_test_executable('dwarf_test') 753 self._checker.check_art_test_executable('exception_test') 754 self._checker.check_art_test_executable('find_loops_test') 755 self._checker.check_art_test_executable('graph_checker_test') 756 self._checker.check_art_test_executable('graph_test') 757 self._checker.check_art_test_executable('gvn_test') 758 self._checker.check_art_test_executable('induction_var_analysis_test') 759 self._checker.check_art_test_executable('induction_var_range_test') 760 self._checker.check_art_test_executable('jni_cfi_test') 761 self._checker.check_art_test_executable('jni_compiler_test') 762 self._checker.check_art_test_executable('licm_test') 763 self._checker.check_art_test_executable('linker_patch_test') 764 self._checker.check_art_test_executable('live_interval_test') 765 self._checker.check_art_test_executable('load_store_analysis_test') 766 self._checker.check_art_test_executable('load_store_elimination_test') 767 self._checker.check_art_test_executable('loop_optimization_test') 768 self._checker.check_art_test_executable('nodes_test') 769 self._checker.check_art_test_executable('nodes_vector_test') 770 self._checker.check_art_test_executable('optimizing_cfi_test') 771 self._checker.check_art_test_executable('output_stream_test') 772 self._checker.check_art_test_executable('parallel_move_test') 773 self._checker.check_art_test_executable('pretty_printer_test') 774 self._checker.check_art_test_executable('reference_type_propagation_test') 775 self._checker.check_art_test_executable('scheduler_test') 776 self._checker.check_art_test_executable('select_generator_test') 777 self._checker.check_art_test_executable('side_effects_test') 778 self._checker.check_art_test_executable('src_map_elem_test') 779 self._checker.check_art_test_executable('ssa_liveness_analysis_test') 780 self._checker.check_art_test_executable('ssa_test') 781 self._checker.check_art_test_executable('stack_map_test') 782 self._checker.check_art_test_executable('superblock_cloner_test') 783 self._checker.check_art_test_executable('suspend_check_test') 784 self._checker.check_art_test_executable('swap_space_test') 785 # These tests depend on a specific code generator and are conditionally included. 786 self._checker.check_optional_art_test_executable('constant_folding_test') 787 self._checker.check_optional_art_test_executable('dead_code_elimination_test') 788 self._checker.check_optional_art_test_executable('linearize_test') 789 self._checker.check_optional_art_test_executable('live_ranges_test') 790 self._checker.check_optional_art_test_executable('liveness_test') 791 self._checker.check_optional_art_test_executable('managed_register_arm64_test') 792 self._checker.check_optional_art_test_executable('managed_register_arm_test') 793 self._checker.check_optional_art_test_executable('managed_register_x86_64_test') 794 self._checker.check_optional_art_test_executable('managed_register_x86_test') 795 self._checker.check_optional_art_test_executable('register_allocator_test') 796 797 # Check dex2oat tests. 798 self._checker.check_art_test_executable('compiler_driver_test') 799 self._checker.check_art_test_executable('dex2oat_image_test') 800 self._checker.check_art_test_executable('dex2oat_test') 801 self._checker.check_art_test_executable('dex_to_dex_decompiler_test') 802 self._checker.check_art_test_executable('elf_writer_test') 803 self._checker.check_art_test_executable('image_test') 804 self._checker.check_art_test_executable('image_write_read_test') 805 self._checker.check_art_test_executable('index_bss_mapping_encoder_test') 806 self._checker.check_art_test_executable('multi_oat_relative_patcher_test') 807 self._checker.check_art_test_executable('oat_writer_test') 808 self._checker.check_art_test_executable('verifier_deps_test') 809 # These tests depend on a specific code generator and are conditionally included. 810 self._checker.check_optional_art_test_executable('relative_patcher_arm64_test') 811 self._checker.check_optional_art_test_executable('relative_patcher_thumb2_test') 812 self._checker.check_optional_art_test_executable('relative_patcher_x86_64_test') 813 self._checker.check_optional_art_test_executable('relative_patcher_x86_test') 814 815 # Check dexanalyze tests. 816 self._checker.check_optional_art_test_executable('dexanalyze_test') 817 818 # Check dexdiag tests. 819 self._checker.check_optional_art_test_executable('dexdiag_test') 820 821 # Check dexdump tests. 822 self._checker.check_art_test_executable('dexdump_test') 823 824 # Check dexlayout tests. 825 self._checker.check_optional_art_test_executable('dexlayout_test') 826 827 # Check dexlist tests. 828 self._checker.check_art_test_executable('dexlist_test') 829 830 # Check dexoptanalyzer tests. 831 self._checker.check_art_test_executable('dexoptanalyzer_test') 832 833 # Check imgdiag tests. 834 self._checker.check_art_test_executable('imgdiag_test') 835 836 # Check libartbase tests. 837 self._checker.check_art_test_executable('arena_allocator_test') 838 self._checker.check_art_test_executable('bit_field_test') 839 self._checker.check_art_test_executable('bit_memory_region_test') 840 self._checker.check_art_test_executable('bit_string_test') 841 self._checker.check_art_test_executable('bit_struct_test') 842 self._checker.check_art_test_executable('bit_table_test') 843 self._checker.check_art_test_executable('bit_utils_test') 844 self._checker.check_art_test_executable('bit_vector_test') 845 self._checker.check_art_test_executable('fd_file_test') 846 self._checker.check_art_test_executable('file_utils_test') 847 self._checker.check_art_test_executable('hash_set_test') 848 self._checker.check_art_test_executable('hex_dump_test') 849 self._checker.check_art_test_executable('histogram_test') 850 self._checker.check_art_test_executable('indenter_test') 851 self._checker.check_art_test_executable('instruction_set_test') 852 self._checker.check_art_test_executable('intrusive_forward_list_test') 853 self._checker.check_art_test_executable('leb128_test') 854 self._checker.check_art_test_executable('logging_test') 855 self._checker.check_art_test_executable('mem_map_test') 856 self._checker.check_art_test_executable('membarrier_test') 857 self._checker.check_art_test_executable('memfd_test') 858 self._checker.check_art_test_executable('memory_region_test') 859 self._checker.check_art_test_executable('safe_copy_test') 860 self._checker.check_art_test_executable('scoped_flock_test') 861 self._checker.check_art_test_executable('time_utils_test') 862 self._checker.check_art_test_executable('transform_array_ref_test') 863 self._checker.check_art_test_executable('transform_iterator_test') 864 self._checker.check_art_test_executable('utils_test') 865 self._checker.check_art_test_executable('variant_map_test') 866 self._checker.check_art_test_executable('zip_archive_test') 867 868 # Check libartpalette tests. 869 self._checker.check_art_test_executable('palette_test') 870 871 # Check libdexfile tests. 872 self._checker.check_art_test_executable('art_dex_file_loader_test') 873 self._checker.check_art_test_executable('art_libdexfile_support_tests') 874 self._checker.check_art_test_executable('class_accessor_test') 875 self._checker.check_art_test_executable('code_item_accessors_test') 876 self._checker.check_art_test_executable('compact_dex_file_test') 877 self._checker.check_art_test_executable('compact_offset_table_test') 878 self._checker.check_art_test_executable('descriptors_names_test') 879 self._checker.check_art_test_executable('dex_file_loader_test') 880 self._checker.check_art_test_executable('dex_file_verifier_test') 881 self._checker.check_art_test_executable('dex_instruction_test') 882 self._checker.check_art_test_executable('primitive_test') 883 self._checker.check_art_test_executable('string_reference_test') 884 self._checker.check_art_test_executable('test_dex_file_builder_test') 885 self._checker.check_art_test_executable('type_lookup_table_test') 886 self._checker.check_art_test_executable('utf_test') 887 888 # Check libprofile tests. 889 self._checker.check_optional_art_test_executable('profile_boot_info_test') 890 self._checker.check_optional_art_test_executable('profile_compilation_info_test') 891 892 # Check oatdump tests. 893 self._checker.check_art_test_executable('oatdump_app_test') 894 self._checker.check_art_test_executable('oatdump_image_test') 895 self._checker.check_art_test_executable('oatdump_test') 896 897 # Check profman tests. 898 self._checker.check_art_test_executable('profile_assistant_test') 899 900 # Check runtime compiler tests. 901 self._checker.check_art_test_executable('module_exclusion_test') 902 self._checker.check_art_test_executable('reflection_test') 903 904 # Check runtime tests. 905 self._checker.check_art_test_executable('arch_test') 906 self._checker.check_art_test_executable('barrier_test') 907 self._checker.check_art_test_executable('card_table_test') 908 self._checker.check_art_test_executable('cha_test') 909 self._checker.check_art_test_executable('class_linker_test') 910 self._checker.check_art_test_executable('class_loader_context_test') 911 self._checker.check_art_test_executable('class_table_test') 912 self._checker.check_art_test_executable('compiler_filter_test') 913 self._checker.check_art_test_executable('dex_cache_test') 914 self._checker.check_art_test_executable('dlmalloc_space_random_test') 915 self._checker.check_art_test_executable('dlmalloc_space_static_test') 916 self._checker.check_art_test_executable('entrypoints_order_test') 917 self._checker.check_art_test_executable('exec_utils_test') 918 self._checker.check_art_test_executable('gtest_test') 919 self._checker.check_art_test_executable('handle_scope_test') 920 self._checker.check_art_test_executable('heap_test') 921 self._checker.check_art_test_executable('heap_verification_test') 922 self._checker.check_art_test_executable('hidden_api_test') 923 self._checker.check_art_test_executable('image_space_test') 924 self._checker.check_art_test_executable('immune_spaces_test') 925 self._checker.check_art_test_executable('imtable_test') 926 self._checker.check_art_test_executable('indirect_reference_table_test') 927 self._checker.check_art_test_executable('instruction_set_features_arm64_test') 928 self._checker.check_art_test_executable('instruction_set_features_arm_test') 929 self._checker.check_art_test_executable('instruction_set_features_test') 930 self._checker.check_art_test_executable('instruction_set_features_x86_64_test') 931 self._checker.check_art_test_executable('instruction_set_features_x86_test') 932 self._checker.check_art_test_executable('instrumentation_test') 933 self._checker.check_art_test_executable('intern_table_test') 934 self._checker.check_art_test_executable('java_vm_ext_test') 935 self._checker.check_art_test_executable('jit_memory_region_test') 936 self._checker.check_art_test_executable('jni_internal_test') 937 self._checker.check_art_test_executable('large_object_space_test') 938 self._checker.check_art_test_executable('math_entrypoints_test') 939 self._checker.check_art_test_executable('memcmp16_test') 940 self._checker.check_art_test_executable('method_handles_test') 941 self._checker.check_art_test_executable('method_type_test') 942 self._checker.check_art_test_executable('method_verifier_test') 943 self._checker.check_art_test_executable('mod_union_table_test') 944 self._checker.check_art_test_executable('monitor_pool_test') 945 self._checker.check_art_test_executable('monitor_test') 946 self._checker.check_art_test_executable('mutex_test') 947 self._checker.check_art_test_executable('oat_file_assistant_test') 948 self._checker.check_art_test_executable('oat_file_test') 949 self._checker.check_art_test_executable('object_test') 950 self._checker.check_art_test_executable('parsed_options_test') 951 self._checker.check_art_test_executable('prebuilt_tools_test') 952 self._checker.check_art_test_executable('profiling_info_test') 953 self._checker.check_art_test_executable('profile_saver_test') 954 self._checker.check_art_test_executable('proxy_test') 955 self._checker.check_art_test_executable('quick_trampoline_entrypoints_test') 956 self._checker.check_art_test_executable('reference_queue_test') 957 self._checker.check_art_test_executable('reference_table_test') 958 self._checker.check_art_test_executable('reg_type_test') 959 self._checker.check_art_test_executable('rosalloc_space_random_test') 960 self._checker.check_art_test_executable('rosalloc_space_static_test') 961 self._checker.check_art_test_executable('runtime_callbacks_test') 962 self._checker.check_art_test_executable('runtime_test') 963 self._checker.check_art_test_executable('safe_math_test') 964 self._checker.check_art_test_executable('space_bitmap_test') 965 self._checker.check_art_test_executable('space_create_test') 966 self._checker.check_art_test_executable('stub_test') 967 self._checker.check_art_test_executable('subtype_check_info_test') 968 self._checker.check_art_test_executable('subtype_check_test') 969 self._checker.check_art_test_executable('system_weak_test') 970 self._checker.check_art_test_executable('task_processor_test') 971 self._checker.check_art_test_executable('thread_pool_test') 972 self._checker.check_art_test_executable('timing_logger_test') 973 self._checker.check_art_test_executable('transaction_test') 974 self._checker.check_art_test_executable('two_runtimes_test') 975 self._checker.check_art_test_executable('unstarted_runtime_test') 976 self._checker.check_art_test_executable('var_handle_test') 977 self._checker.check_art_test_executable('vdex_file_test') 978 979 # Check sigchainlib tests. 980 self._checker.check_art_test_executable('sigchain_test') 981 982 # Check ART test (internal) libraries. 983 self._checker.check_native_library('libart-gtest') 984 self._checker.check_native_library('libartd-simulator-container') 985 986 # Check ART test tools. 987 self._checker.check_executable('signal_dumper') 988 989 990class NoSuperfluousBinariesChecker: 991 def __init__(self, checker): 992 self._checker = checker 993 994 def __str__(self): 995 return 'No superfluous binaries checker' 996 997 def run(self): 998 self._checker.check_no_superfluous_files('bin') 999 1000 1001class NoSuperfluousLibrariesChecker: 1002 def __init__(self, checker): 1003 self._checker = checker 1004 1005 def __str__(self): 1006 return 'No superfluous libraries checker' 1007 1008 def run(self): 1009 self._checker.check_no_superfluous_files('javalib') 1010 self._checker.check_no_superfluous_files('lib') 1011 self._checker.check_no_superfluous_files('lib64') 1012 1013 1014class NoSuperfluousArtTestsChecker: 1015 def __init__(self, checker): 1016 self._checker = checker 1017 1018 def __str__(self): 1019 return 'No superfluous ART tests checker' 1020 1021 def run(self): 1022 for arch in ARCHS: 1023 self._checker.check_no_superfluous_files('%s/%s' % (ART_TEST_DIR, arch)) 1024 1025 1026class List: 1027 def __init__(self, provider, print_size=False): 1028 self._provider = provider 1029 self._print_size = print_size 1030 1031 def print_list(self): 1032 1033 def print_list_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 for (_, val) in sorted(apex_map.items()): 1043 val_path = os.path.join(path, val.name) 1044 if self._print_size: 1045 if val.size < 0: 1046 print('[ n/a ] %s' % val_path) 1047 else: 1048 print('[%11d] %s' % (val.size, val_path)) 1049 else: 1050 print(val_path) 1051 if val.is_dir: 1052 print_list_rec(val_path) 1053 1054 print_list_rec('') 1055 1056 1057class Tree: 1058 def __init__(self, provider, title, print_size=False): 1059 print('%s' % title) 1060 self._provider = provider 1061 self._has_next_list = [] 1062 self._print_size = print_size 1063 1064 @staticmethod 1065 def get_vertical(has_next_list): 1066 string = '' 1067 for v in has_next_list: 1068 string += '%s ' % ('│' if v else ' ') 1069 return string 1070 1071 @staticmethod 1072 def get_last_vertical(last): 1073 return '└── ' if last else '├── ' 1074 1075 def print_tree(self): 1076 1077 def print_tree_rec(path): 1078 apex_map = self._provider.read_dir(path) 1079 if apex_map is None: 1080 return 1081 apex_map = dict(apex_map) 1082 if '.' in apex_map: 1083 del apex_map['.'] 1084 if '..' in apex_map: 1085 del apex_map['..'] 1086 key_list = list(sorted(apex_map.keys())) 1087 for i, key in enumerate(key_list): 1088 prev = self.get_vertical(self._has_next_list) 1089 last = self.get_last_vertical(i == len(key_list) - 1) 1090 val = apex_map[key] 1091 if self._print_size: 1092 if val.size < 0: 1093 print('%s%s[ n/a ] %s' % (prev, last, val.name)) 1094 else: 1095 print('%s%s[%11d] %s' % (prev, last, val.size, val.name)) 1096 else: 1097 print('%s%s%s' % (prev, last, val.name)) 1098 if val.is_dir: 1099 self._has_next_list.append(i < len(key_list) - 1) 1100 val_path = os.path.join(path, val.name) 1101 print_tree_rec(val_path) 1102 self._has_next_list.pop() 1103 1104 print_tree_rec('') 1105 1106 1107# Note: do not sys.exit early, for __del__ cleanup. 1108def art_apex_test_main(test_args): 1109 if test_args.host and test_args.flattened: 1110 logging.error("Both of --host and --flattened set") 1111 return 1 1112 if test_args.list and test_args.tree: 1113 logging.error("Both of --list and --tree set") 1114 return 1 1115 if test_args.size and not (test_args.list or test_args.tree): 1116 logging.error("--size set but neither --list nor --tree set") 1117 return 1 1118 if not test_args.flattened and not test_args.tmpdir: 1119 logging.error("Need a tmpdir.") 1120 return 1 1121 if not test_args.flattened and not test_args.host and not test_args.debugfs: 1122 logging.error("Need debugfs.") 1123 return 1 1124 1125 if test_args.host: 1126 # Host APEX. 1127 if test_args.flavor not in [FLAVOR_DEBUG, FLAVOR_AUTO]: 1128 logging.error("Using option --host with non-Debug APEX") 1129 return 1 1130 # Host APEX is always a debug flavor (for now). 1131 test_args.flavor = FLAVOR_DEBUG 1132 else: 1133 # Device APEX. 1134 if test_args.flavor == FLAVOR_AUTO: 1135 logging.warning('--flavor=auto, trying to autodetect. This may be incorrect!') 1136 for flavor in [ FLAVOR_RELEASE, FLAVOR_DEBUG, FLAVOR_TESTING ]: 1137 flavor_pattern = '*.%s*' % flavor 1138 if fnmatch.fnmatch(test_args.apex, flavor_pattern): 1139 test_args.flavor = flavor 1140 break 1141 if test_args.flavor == FLAVOR_AUTO: 1142 logging.error(' Could not detect APEX flavor, neither \'%s\', \'%s\' nor \'%s\' in \'%s\'', 1143 FLAVOR_RELEASE, FLAVOR_DEBUG, FLAVOR_TESTING, test_args.apex) 1144 return 1 1145 1146 try: 1147 if test_args.host: 1148 apex_provider = HostApexProvider(test_args.apex, test_args.tmpdir) 1149 else: 1150 if test_args.flattened: 1151 apex_provider = TargetFlattenedApexProvider(test_args.apex) 1152 else: 1153 apex_provider = TargetApexProvider(test_args.apex, test_args.tmpdir, test_args.debugfs) 1154 except (zipfile.BadZipFile, zipfile.LargeZipFile) as e: 1155 logging.error('Failed to create provider: %s', e) 1156 return 1 1157 1158 if test_args.tree: 1159 Tree(apex_provider, test_args.apex, test_args.size).print_tree() 1160 return 0 1161 if test_args.list: 1162 List(apex_provider, test_args.size).print_list() 1163 return 0 1164 1165 checkers = [] 1166 if test_args.bitness == BITNESS_AUTO: 1167 logging.warning('--bitness=auto, trying to autodetect. This may be incorrect!') 1168 has_32 = apex_provider.get('lib') is not None 1169 has_64 = apex_provider.get('lib64') is not None 1170 if has_32 and has_64: 1171 logging.warning(' Detected multilib') 1172 test_args.bitness = BITNESS_MULTILIB 1173 elif has_32: 1174 logging.warning(' Detected 32-only') 1175 test_args.bitness = BITNESS_32 1176 elif has_64: 1177 logging.warning(' Detected 64-only') 1178 test_args.bitness = BITNESS_64 1179 else: 1180 logging.error(' Could not detect bitness, neither lib nor lib64 contained.') 1181 List(apex_provider).print_list() 1182 return 1 1183 1184 if test_args.bitness == BITNESS_32: 1185 base_checker = Arch32Checker(apex_provider) 1186 elif test_args.bitness == BITNESS_64: 1187 base_checker = Arch64Checker(apex_provider) 1188 else: 1189 assert test_args.bitness == BITNESS_MULTILIB 1190 base_checker = MultilibChecker(apex_provider) 1191 1192 checkers.append(ReleaseChecker(base_checker)) 1193 if test_args.host: 1194 checkers.append(ReleaseHostChecker(base_checker)) 1195 else: 1196 checkers.append(ReleaseTargetChecker(base_checker)) 1197 if test_args.flavor == FLAVOR_DEBUG or test_args.flavor == FLAVOR_TESTING: 1198 checkers.append(DebugChecker(base_checker)) 1199 if not test_args.host: 1200 checkers.append(DebugTargetChecker(base_checker)) 1201 if test_args.flavor == FLAVOR_TESTING: 1202 checkers.append(TestingTargetChecker(base_checker)) 1203 1204 # These checkers must be last. 1205 checkers.append(NoSuperfluousBinariesChecker(base_checker)) 1206 checkers.append(NoSuperfluousArtTestsChecker(base_checker)) 1207 if not test_args.host: 1208 # We only care about superfluous libraries on target, where their absence 1209 # can be vital to ensure they get picked up from the right package. 1210 checkers.append(NoSuperfluousLibrariesChecker(base_checker)) 1211 1212 failed = False 1213 for checker in checkers: 1214 logging.info('%s...', checker) 1215 checker.run() 1216 if base_checker.error_count() > 0: 1217 logging.error('%s FAILED', checker) 1218 failed = True 1219 else: 1220 logging.info('%s SUCCEEDED', checker) 1221 base_checker.reset_errors() 1222 1223 return 1 if failed else 0 1224 1225 1226def art_apex_test_default(test_parser): 1227 if 'ANDROID_PRODUCT_OUT' not in os.environ: 1228 logging.error('No-argument use requires ANDROID_PRODUCT_OUT') 1229 sys.exit(1) 1230 product_out = os.environ['ANDROID_PRODUCT_OUT'] 1231 if 'ANDROID_HOST_OUT' not in os.environ: 1232 logging.error('No-argument use requires ANDROID_HOST_OUT') 1233 sys.exit(1) 1234 host_out = os.environ['ANDROID_HOST_OUT'] 1235 1236 test_args = test_parser.parse_args(['dummy']) # For consistency. 1237 test_args.debugfs = '%s/bin/debugfs' % host_out 1238 test_args.tmpdir = '.' 1239 test_args.tree = False 1240 test_args.list = False 1241 test_args.bitness = BITNESS_AUTO 1242 failed = False 1243 1244 if not os.path.exists(test_args.debugfs): 1245 logging.error("Cannot find debugfs (default path %s). Please build it, e.g., m debugfs", 1246 test_args.debugfs) 1247 sys.exit(1) 1248 1249 # TODO: Add host support. 1250 # TODO: Add support for flattened APEX packages. 1251 configs = [ 1252 {'name': 'com.android.art.release', 'flavor': FLAVOR_RELEASE, 'host': False}, 1253 {'name': 'com.android.art.debug', 'flavor': FLAVOR_DEBUG, 'host': False}, 1254 {'name': 'com.android.art.testing', 'flavor': FLAVOR_TESTING, 'host': False}, 1255 ] 1256 1257 for config in configs: 1258 logging.info(config['name']) 1259 # TODO: Host will need different path. 1260 test_args.apex = '%s/system/apex/%s.apex' % (product_out, config['name']) 1261 if not os.path.exists(test_args.apex): 1262 failed = True 1263 logging.error("Cannot find APEX %s. Please build it first.", test_args.apex) 1264 continue 1265 test_args.flavor = config['flavor'] 1266 test_args.host = config['host'] 1267 failed = art_apex_test_main(test_args) != 0 1268 1269 if failed: 1270 sys.exit(1) 1271 1272 1273if __name__ == "__main__": 1274 parser = argparse.ArgumentParser(description='Check integrity of an ART APEX.') 1275 1276 parser.add_argument('apex', help='APEX file input') 1277 1278 parser.add_argument('--host', help='Check as host APEX', action='store_true') 1279 1280 parser.add_argument('--flattened', help='Check as flattened (target) APEX', action='store_true') 1281 1282 parser.add_argument('--flavor', help='Check as FLAVOR APEX', choices=FLAVORS_ALL, 1283 default=FLAVOR_AUTO) 1284 1285 parser.add_argument('--list', help='List all files', action='store_true') 1286 parser.add_argument('--tree', help='Print directory tree', action='store_true') 1287 parser.add_argument('--size', help='Print file sizes', action='store_true') 1288 1289 parser.add_argument('--tmpdir', help='Directory for temp files') 1290 parser.add_argument('--debugfs', help='Path to debugfs') 1291 1292 parser.add_argument('--bitness', help='Bitness to check', choices=BITNESS_ALL, 1293 default=BITNESS_AUTO) 1294 1295 if len(sys.argv) == 1: 1296 art_apex_test_default(parser) 1297 else: 1298 args = parser.parse_args() 1299 1300 if args is None: 1301 sys.exit(1) 1302 1303 exit_code = art_apex_test_main(args) 1304 sys.exit(exit_code) 1305