| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python3 | 
|  | 2 |  | 
|  | 3 | # Copyright (C) 2019 The Android Open Source Project | 
|  | 4 | # | 
|  | 5 | # Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | 6 | # you may not use this file except in compliance with the License. | 
|  | 7 | # You may obtain a copy of the License at | 
|  | 8 | # | 
|  | 9 | #      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | 10 | # | 
|  | 11 | # Unless required by applicable law or agreed to in writing, software | 
|  | 12 | # distributed under the License is distributed on an "AS IS" BASIS, | 
|  | 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | 14 | # See the License for the specific language governing permissions and | 
|  | 15 | # limitations under the License. | 
|  | 16 | # | 
|  | 17 |  | 
|  | 18 | import argparse | 
| Martin Stjernholm | 84a32cd | 2019-03-29 16:39:46 +0000 | [diff] [blame] | 19 | import fnmatch | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 20 | import logging | 
|  | 21 | import os | 
| Martin Stjernholm | 84a32cd | 2019-03-29 16:39:46 +0000 | [diff] [blame] | 22 | import os.path | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 23 | import subprocess | 
|  | 24 | import sys | 
|  | 25 | import zipfile | 
|  | 26 |  | 
|  | 27 | logging.basicConfig(format='%(message)s') | 
|  | 28 |  | 
| Roland Levillain | 61f0716 | 2019-06-26 12:44:04 +0100 | [diff] [blame] | 29 | # Architectures supported by APEX packages. | 
|  | 30 | archs = ["arm", "arm64", "x86", "x86_64"] | 
|  | 31 | # Directory containing ART tests within a Runtime APEX (if the package includes | 
|  | 32 | # any). ART test executables are installed in `bin/art/<arch>`. Segregating | 
|  | 33 | # tests by architecture is useful on devices supporting more than one | 
|  | 34 | # architecture, as it permits testing all of them using a single Runtime APEX | 
|  | 35 | # package. | 
| Roland Levillain | d4d6fb5 | 2019-08-05 12:28:39 +0100 | [diff] [blame] | 36 | art_test_dir = 'bin/art' | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 37 |  | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 38 | class FSObject: | 
| Roland Levillain | 88e5569 | 2019-07-25 15:57:06 +0100 | [diff] [blame] | 39 | def __init__(self, name, is_dir, is_exec, is_symlink, size): | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 40 | self.name = name | 
|  | 41 | self.is_dir = is_dir | 
|  | 42 | self.is_exec = is_exec | 
|  | 43 | self.is_symlink = is_symlink | 
| Roland Levillain | 88e5569 | 2019-07-25 15:57:06 +0100 | [diff] [blame] | 44 | self.size = size | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 45 |  | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 46 | def __str__(self): | 
| Roland Levillain | 88e5569 | 2019-07-25 15:57:06 +0100 | [diff] [blame] | 47 | return '%s(dir=%r,exec=%r,symlink=%r,size=%d)' \ | 
|  | 48 | % (self.name, self.is_dir, self.is_exec, self.is_symlink, self.size) | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 49 |  | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 50 |  | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 51 | class TargetApexProvider: | 
|  | 52 | def __init__(self, apex, tmpdir, debugfs): | 
|  | 53 | self._tmpdir = tmpdir | 
|  | 54 | self._debugfs = debugfs | 
|  | 55 | self._folder_cache = {} | 
|  | 56 | self._payload = os.path.join(self._tmpdir, 'apex_payload.img') | 
|  | 57 | # Extract payload to tmpdir. | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 58 | apex_zip = zipfile.ZipFile(apex) | 
|  | 59 | apex_zip.extract('apex_payload.img', tmpdir) | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 60 |  | 
|  | 61 | def __del__(self): | 
|  | 62 | # Delete temps. | 
|  | 63 | if os.path.exists(self._payload): | 
|  | 64 | os.remove(self._payload) | 
|  | 65 |  | 
|  | 66 | def get(self, path): | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 67 | apex_dir, name = os.path.split(path) | 
|  | 68 | if not apex_dir: | 
|  | 69 | apex_dir = '.' | 
|  | 70 | apex_map = self.read_dir(apex_dir) | 
|  | 71 | return apex_map[name] if name in apex_map else None | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 72 |  | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 73 | def read_dir(self, apex_dir): | 
|  | 74 | if apex_dir in self._folder_cache: | 
|  | 75 | return self._folder_cache[apex_dir] | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 76 | # Cannot use check_output as it will annoy with stderr. | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 77 | process = subprocess.Popen([self._debugfs, '-R', 'ls -l -p %s' % apex_dir, self._payload], | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 78 | stdout=subprocess.PIPE, stderr=subprocess.PIPE, | 
|  | 79 | universal_newlines=True) | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 80 | stdout, _ = process.communicate() | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 81 | res = str(stdout) | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 82 | apex_map = {} | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 83 | # Debugfs output looks like this: | 
|  | 84 | #   debugfs 1.44.4 (18-Aug-2018) | 
|  | 85 | #   /12/040755/0/2000/.// | 
|  | 86 | #   /2/040755/1000/1000/..// | 
|  | 87 | #   /13/100755/0/2000/dalvikvm32/28456/ | 
|  | 88 | #   /14/100755/0/2000/dexoptanalyzer/20396/ | 
|  | 89 | #   /15/100755/0/2000/linker/1152724/ | 
|  | 90 | #   /16/100755/0/2000/dex2oat/563508/ | 
|  | 91 | #   /17/100755/0/2000/linker64/1605424/ | 
|  | 92 | #   /18/100755/0/2000/profman/85304/ | 
|  | 93 | #   /19/100755/0/2000/dalvikvm64/28576/ | 
|  | 94 | #    |     |   |   |       |        | | 
|  | 95 | #    |     |   |   #- gid  #- name  #- size | 
|  | 96 | #    |     |   #- uid | 
|  | 97 | #    |     #- type and permission bits | 
|  | 98 | #    #- inode nr (?) | 
|  | 99 | # | 
|  | 100 | # Note: could break just on '/' to avoid names with newlines. | 
|  | 101 | for line in res.split("\n"): | 
|  | 102 | if not line: | 
|  | 103 | continue | 
|  | 104 | comps = line.split('/') | 
|  | 105 | if len(comps) != 8: | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 106 | logging.warning('Could not break and parse line \'%s\'', line) | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 107 | continue | 
|  | 108 | bits = comps[2] | 
|  | 109 | name = comps[5] | 
| Roland Levillain | 88e5569 | 2019-07-25 15:57:06 +0100 | [diff] [blame] | 110 | size_str = comps[6] | 
|  | 111 | # Use a negative value as an indicator of undefined/unknown size. | 
|  | 112 | size = int(size_str) if size_str != '' else -1 | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 113 | if len(bits) != 6: | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 114 | logging.warning('Dont understand bits \'%s\'', bits) | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 115 | continue | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 116 | is_dir = bits[1] == '4' | 
|  | 117 |  | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 118 | def is_exec_bit(ch): | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 119 | return int(ch) & 1 == 1 | 
|  | 120 |  | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 121 | is_exec = is_exec_bit(bits[3]) and is_exec_bit(bits[4]) and is_exec_bit(bits[5]) | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 122 | is_symlink = bits[1] == '2' | 
| Roland Levillain | 88e5569 | 2019-07-25 15:57:06 +0100 | [diff] [blame] | 123 | apex_map[name] = FSObject(name, is_dir, is_exec, is_symlink, size) | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 124 | self._folder_cache[apex_dir] = apex_map | 
|  | 125 | return apex_map | 
|  | 126 |  | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 127 |  | 
| Roland Levillain | dd20d00 | 2019-07-19 16:09:47 +0100 | [diff] [blame] | 128 | class TargetFlattenedApexProvider: | 
|  | 129 | def __init__(self, apex): | 
|  | 130 | self._folder_cache = {} | 
|  | 131 | self._apex = apex | 
|  | 132 |  | 
|  | 133 | def get(self, path): | 
|  | 134 | apex_dir, name = os.path.split(path) | 
|  | 135 | if not apex_dir: | 
|  | 136 | apex_dir = '.' | 
|  | 137 | apex_map = self.read_dir(apex_dir) | 
|  | 138 | return apex_map[name] if name in apex_map else None | 
|  | 139 |  | 
|  | 140 | def read_dir(self, apex_dir): | 
|  | 141 | if apex_dir in self._folder_cache: | 
|  | 142 | return self._folder_cache[apex_dir] | 
|  | 143 | apex_map = {} | 
|  | 144 | dirname = os.path.join(self._apex, apex_dir) | 
|  | 145 | if os.path.exists(dirname): | 
|  | 146 | for basename in os.listdir(dirname): | 
|  | 147 | filepath = os.path.join(dirname, basename) | 
|  | 148 | is_dir = os.path.isdir(filepath) | 
|  | 149 | is_exec = os.access(filepath, os.X_OK) | 
|  | 150 | is_symlink = os.path.islink(filepath) | 
| Roland Levillain | 88e5569 | 2019-07-25 15:57:06 +0100 | [diff] [blame] | 151 | size = os.path.getsize(filepath) | 
|  | 152 | apex_map[basename] = FSObject(basename, is_dir, is_exec, is_symlink, size) | 
| Roland Levillain | dd20d00 | 2019-07-19 16:09:47 +0100 | [diff] [blame] | 153 | self._folder_cache[apex_dir] = apex_map | 
|  | 154 | return apex_map | 
|  | 155 |  | 
|  | 156 |  | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 157 | class HostApexProvider: | 
|  | 158 | def __init__(self, apex, tmpdir): | 
|  | 159 | self._tmpdir = tmpdir | 
| Roland Levillain | 77251f9 | 2019-08-09 15:00:04 +0100 | [diff] [blame] | 160 | self._folder_cache = {} | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 161 | self._payload = os.path.join(self._tmpdir, 'apex_payload.zip') | 
|  | 162 | # Extract payload to tmpdir. | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 163 | apex_zip = zipfile.ZipFile(apex) | 
|  | 164 | apex_zip.extract('apex_payload.zip', tmpdir) | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 165 |  | 
|  | 166 | def __del__(self): | 
|  | 167 | # Delete temps. | 
|  | 168 | if os.path.exists(self._payload): | 
|  | 169 | os.remove(self._payload) | 
|  | 170 |  | 
|  | 171 | def get(self, path): | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 172 | apex_dir, name = os.path.split(path) | 
|  | 173 | if not apex_dir: | 
|  | 174 | apex_dir = '' | 
|  | 175 | apex_map = self.read_dir(apex_dir) | 
|  | 176 | return apex_map[name] if name in apex_map else None | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 177 |  | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 178 | def read_dir(self, apex_dir): | 
| Roland Levillain | 77251f9 | 2019-08-09 15:00:04 +0100 | [diff] [blame] | 179 | if apex_dir in self._folder_cache: | 
|  | 180 | return self._folder_cache[apex_dir] | 
|  | 181 | if not self._folder_cache: | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 182 | self.parse_zip() | 
| Roland Levillain | 77251f9 | 2019-08-09 15:00:04 +0100 | [diff] [blame] | 183 | if apex_dir in self._folder_cache: | 
|  | 184 | return self._folder_cache[apex_dir] | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 185 | return {} | 
|  | 186 |  | 
|  | 187 | def parse_zip(self): | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 188 | apex_zip = zipfile.ZipFile(self._payload) | 
|  | 189 | infos = apex_zip.infolist() | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 190 | for zipinfo in infos: | 
|  | 191 | path = zipinfo.filename | 
|  | 192 |  | 
|  | 193 | # Assume no empty file is stored. | 
|  | 194 | assert path | 
|  | 195 |  | 
|  | 196 | def get_octal(val, index): | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 197 | return (val >> (index * 3)) & 0x7 | 
|  | 198 |  | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 199 | def bits_is_exec(val): | 
|  | 200 | # TODO: Enforce group/other, too? | 
|  | 201 | return get_octal(val, 2) & 1 == 1 | 
|  | 202 |  | 
|  | 203 | is_zipinfo = True | 
|  | 204 | while path: | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 205 | apex_dir, base = os.path.split(path) | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 206 | # TODO: If directories are stored, base will be empty. | 
|  | 207 |  | 
| Roland Levillain | 77251f9 | 2019-08-09 15:00:04 +0100 | [diff] [blame] | 208 | if apex_dir not in self._folder_cache: | 
|  | 209 | self._folder_cache[apex_dir] = {} | 
|  | 210 | dir_map = self._folder_cache[apex_dir] | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 211 | if base not in dir_map: | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 212 | if is_zipinfo: | 
|  | 213 | bits = (zipinfo.external_attr >> 16) & 0xFFFF | 
|  | 214 | is_dir = get_octal(bits, 4) == 4 | 
|  | 215 | is_symlink = get_octal(bits, 4) == 2 | 
|  | 216 | is_exec = bits_is_exec(bits) | 
| Roland Levillain | 88e5569 | 2019-07-25 15:57:06 +0100 | [diff] [blame] | 217 | size = zipinfo.file_size | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 218 | else: | 
|  | 219 | is_exec = False  # Seems we can't get this easily? | 
|  | 220 | is_symlink = False | 
|  | 221 | is_dir = True | 
| Roland Levillain | 88e5569 | 2019-07-25 15:57:06 +0100 | [diff] [blame] | 222 | # Use a negative value as an indicator of undefined/unknown size. | 
|  | 223 | size = -1 | 
|  | 224 | dir_map[base] = FSObject(base, is_dir, is_exec, is_symlink, size) | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 225 | is_zipinfo = False | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 226 | path = apex_dir | 
|  | 227 |  | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 228 |  | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 229 | # DO NOT USE DIRECTLY! This is an "abstract" base class. | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 230 | class Checker: | 
|  | 231 | def __init__(self, provider): | 
|  | 232 | self._provider = provider | 
|  | 233 | self._errors = 0 | 
| Martin Stjernholm | 84a32cd | 2019-03-29 16:39:46 +0000 | [diff] [blame] | 234 | self._expected_file_globs = set() | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 235 |  | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 236 | def fail(self, msg, *fail_args): | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 237 | self._errors += 1 | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 238 | logging.error(msg, *fail_args) | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 239 |  | 
|  | 240 | def error_count(self): | 
|  | 241 | return self._errors | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 242 |  | 
| Andreas Gampe | 9dc4b05 | 2019-01-30 13:47:25 -0800 | [diff] [blame] | 243 | def reset_errors(self): | 
|  | 244 | self._errors = 0 | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 245 |  | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 246 | def is_file(self, path): | 
|  | 247 | fs_object = self._provider.get(path) | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 248 | if fs_object is None: | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 249 | return False, 'Could not find %s' | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 250 | if fs_object.is_dir: | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 251 | return False, '%s is a directory' | 
|  | 252 | return True, '' | 
| Andreas Gampe | a0242cf | 2019-01-29 13:01:23 -0800 | [diff] [blame] | 253 |  | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 254 | def check_file(self, path): | 
|  | 255 | ok, msg = self.is_file(path) | 
|  | 256 | if not ok: | 
|  | 257 | self.fail(msg, path) | 
| Martin Stjernholm | 84a32cd | 2019-03-29 16:39:46 +0000 | [diff] [blame] | 258 | self._expected_file_globs.add(path) | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 259 | return ok | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 260 |  | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 261 | def check_executable(self, filename): | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 262 | path = 'bin/%s' % filename | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 263 | if not self.check_file(path): | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 264 | return | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 265 | if not self._provider.get(path).is_exec: | 
|  | 266 | self.fail('%s is not executable', path) | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 267 |  | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 268 | def check_executable_symlink(self, filename): | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 269 | path = 'bin/%s' % filename | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 270 | fs_object = self._provider.get(path) | 
|  | 271 | if fs_object is None: | 
|  | 272 | self.fail('Could not find %s', path) | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 273 | return | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 274 | if fs_object.is_dir: | 
|  | 275 | self.fail('%s is a directory', path) | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 276 | return | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 277 | if not fs_object.is_symlink: | 
|  | 278 | self.fail('%s is not a symlink', path) | 
| Martin Stjernholm | 84a32cd | 2019-03-29 16:39:46 +0000 | [diff] [blame] | 279 | self._expected_file_globs.add(path) | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 280 |  | 
| Roland Levillain | 61f0716 | 2019-06-26 12:44:04 +0100 | [diff] [blame] | 281 | def check_art_test_executable(self, filename): | 
|  | 282 | # This is a simplistic implementation, as we declare victory as soon as the | 
|  | 283 | # test binary is found for one of the supported (not built) architectures. | 
|  | 284 | # Ideally we would propagate the built architectures from the build system | 
|  | 285 | # to this script and require test binaries for all of them to be present. | 
|  | 286 | # Note that this behavior is not specific to this method: there are other | 
|  | 287 | # places in this script where we rely on this simplified strategy. | 
|  | 288 | # | 
|  | 289 | # TODO: Implement the suggestion above (here and in other places in this | 
|  | 290 | # script). | 
|  | 291 | test_found = False | 
|  | 292 | for arch in archs: | 
|  | 293 | test_path = '%s/%s/%s' % (art_test_dir, arch, filename) | 
|  | 294 | test_is_file, _ = self.is_file(test_path) | 
|  | 295 | if test_is_file: | 
|  | 296 | test_found = True | 
|  | 297 | self._expected_file_globs.add(test_path) | 
|  | 298 | if not self._provider.get(test_path).is_exec: | 
|  | 299 | self.fail('%s is not executable', test_path) | 
|  | 300 | if not test_found: | 
|  | 301 | self.fail('ART test binary missing: %s', filename) | 
|  | 302 |  | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 303 | def check_single_library(self, filename): | 
|  | 304 | lib_path = 'lib/%s' % filename | 
|  | 305 | lib64_path = 'lib64/%s' % filename | 
|  | 306 | lib_is_file, _ = self.is_file(lib_path) | 
|  | 307 | if lib_is_file: | 
| Martin Stjernholm | 84a32cd | 2019-03-29 16:39:46 +0000 | [diff] [blame] | 308 | self._expected_file_globs.add(lib_path) | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 309 | lib64_is_file, _ = self.is_file(lib64_path) | 
|  | 310 | if lib64_is_file: | 
| Martin Stjernholm | 84a32cd | 2019-03-29 16:39:46 +0000 | [diff] [blame] | 311 | self._expected_file_globs.add(lib64_path) | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 312 | if not lib_is_file and not lib64_is_file: | 
|  | 313 | self.fail('Library missing: %s', filename) | 
| Andreas Gampe | a0242cf | 2019-01-29 13:01:23 -0800 | [diff] [blame] | 314 |  | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 315 | def check_java_library(self, basename): | 
|  | 316 | return self.check_file('javalib/%s.jar' % basename) | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 317 |  | 
| Martin Stjernholm | 84a32cd | 2019-03-29 16:39:46 +0000 | [diff] [blame] | 318 | def ignore_path(self, path_glob): | 
|  | 319 | self._expected_file_globs.add(path_glob) | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 320 |  | 
| Roland Levillain | 61f0716 | 2019-06-26 12:44:04 +0100 | [diff] [blame] | 321 | def check_optional_art_test_executable(self, filename): | 
|  | 322 | for arch in archs: | 
|  | 323 | self.ignore_path('%s/%s/%s' % (art_test_dir, arch, filename)) | 
|  | 324 |  | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 325 | def check_no_superfluous_files(self, dir_path): | 
| Martin Stjernholm | 84a32cd | 2019-03-29 16:39:46 +0000 | [diff] [blame] | 326 | paths = [] | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 327 | for name in sorted(self._provider.read_dir(dir_path).keys()): | 
| Martin Stjernholm | 84a32cd | 2019-03-29 16:39:46 +0000 | [diff] [blame] | 328 | if name not in ('.', '..'): | 
|  | 329 | paths.append(os.path.join(dir_path, name)) | 
|  | 330 | expected_paths = set() | 
|  | 331 | dir_prefix = dir_path + '/' | 
|  | 332 | for path_glob in self._expected_file_globs: | 
|  | 333 | expected_paths |= set(fnmatch.filter(paths, path_glob)) | 
|  | 334 | # If there are globs in subdirectories of dir_path we want to match their | 
|  | 335 | # path segments at this directory level. | 
|  | 336 | if path_glob.startswith(dir_prefix): | 
|  | 337 | subpath = path_glob[len(dir_prefix):] | 
|  | 338 | subpath_first_segment, _, _ = subpath.partition('/') | 
|  | 339 | expected_paths |= set(fnmatch.filter(paths, dir_prefix + subpath_first_segment)) | 
|  | 340 | for unexpected_path in set(paths) - expected_paths: | 
|  | 341 | self.fail('Unexpected file \'%s\'', unexpected_path) | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 342 |  | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 343 | # Just here for docs purposes, even if it isn't good Python style. | 
|  | 344 |  | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 345 | def check_symlinked_multilib_executable(self, filename): | 
|  | 346 | """Check bin/filename32, and/or bin/filename64, with symlink bin/filename.""" | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 347 | raise NotImplementedError | 
|  | 348 |  | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 349 | def check_multilib_executable(self, filename): | 
|  | 350 | """Check bin/filename for 32 bit, and/or bin/filename64.""" | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 351 | raise NotImplementedError | 
|  | 352 |  | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 353 | def check_native_library(self, basename): | 
|  | 354 | """Check lib/basename.so, and/or lib64/basename.so.""" | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 355 | raise NotImplementedError | 
|  | 356 |  | 
| Martin Stjernholm | 84a32cd | 2019-03-29 16:39:46 +0000 | [diff] [blame] | 357 | def check_optional_native_library(self, basename_glob): | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 358 | """Allow lib/basename.so and/or lib64/basename.so to exist.""" | 
| Martin Stjernholm | b81fe23 | 2019-03-25 17:38:04 +0000 | [diff] [blame] | 359 | raise NotImplementedError | 
|  | 360 |  | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 361 | def check_prefer64_library(self, basename): | 
|  | 362 | """Check lib64/basename.so, or lib/basename.so on 32 bit only.""" | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 363 | raise NotImplementedError | 
|  | 364 |  | 
|  | 365 |  | 
|  | 366 | class Arch32Checker(Checker): | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 367 | def check_symlinked_multilib_executable(self, filename): | 
|  | 368 | self.check_executable('%s32' % filename) | 
|  | 369 | self.check_executable_symlink(filename) | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 370 |  | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 371 | def check_multilib_executable(self, filename): | 
|  | 372 | self.check_executable(filename) | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 373 |  | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 374 | def check_native_library(self, basename): | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 375 | # TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve | 
|  | 376 | # the precision of this test? | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 377 | self.check_file('lib/%s.so' % basename) | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 378 |  | 
| Martin Stjernholm | 84a32cd | 2019-03-29 16:39:46 +0000 | [diff] [blame] | 379 | def check_optional_native_library(self, basename_glob): | 
|  | 380 | self.ignore_path('lib/%s.so' % basename_glob) | 
| Martin Stjernholm | b81fe23 | 2019-03-25 17:38:04 +0000 | [diff] [blame] | 381 |  | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 382 | def check_prefer64_library(self, basename): | 
|  | 383 | self.check_native_library(basename) | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 384 |  | 
|  | 385 |  | 
|  | 386 | class Arch64Checker(Checker): | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 387 | def check_symlinked_multilib_executable(self, filename): | 
|  | 388 | self.check_executable('%s64' % filename) | 
|  | 389 | self.check_executable_symlink(filename) | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 390 |  | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 391 | def check_multilib_executable(self, filename): | 
|  | 392 | self.check_executable('%s64' % filename) | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 393 |  | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 394 | def check_native_library(self, basename): | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 395 | # TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve | 
|  | 396 | # the precision of this test? | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 397 | self.check_file('lib64/%s.so' % basename) | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 398 |  | 
| Martin Stjernholm | 84a32cd | 2019-03-29 16:39:46 +0000 | [diff] [blame] | 399 | def check_optional_native_library(self, basename_glob): | 
|  | 400 | self.ignore_path('lib64/%s.so' % basename_glob) | 
| Martin Stjernholm | b81fe23 | 2019-03-25 17:38:04 +0000 | [diff] [blame] | 401 |  | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 402 | def check_prefer64_library(self, basename): | 
|  | 403 | self.check_native_library(basename) | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 404 |  | 
|  | 405 |  | 
|  | 406 | class MultilibChecker(Checker): | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 407 | def check_symlinked_multilib_executable(self, filename): | 
|  | 408 | self.check_executable('%s32' % filename) | 
|  | 409 | self.check_executable('%s64' % filename) | 
|  | 410 | self.check_executable_symlink(filename) | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 411 |  | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 412 | def check_multilib_executable(self, filename): | 
|  | 413 | self.check_executable('%s64' % filename) | 
|  | 414 | self.check_executable(filename) | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 415 |  | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 416 | def check_native_library(self, basename): | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 417 | # TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve | 
|  | 418 | # the precision of this test? | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 419 | self.check_file('lib/%s.so' % basename) | 
|  | 420 | self.check_file('lib64/%s.so' % basename) | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 421 |  | 
| Martin Stjernholm | 84a32cd | 2019-03-29 16:39:46 +0000 | [diff] [blame] | 422 | def check_optional_native_library(self, basename_glob): | 
|  | 423 | self.ignore_path('lib/%s.so' % basename_glob) | 
|  | 424 | self.ignore_path('lib64/%s.so' % basename_glob) | 
| Martin Stjernholm | b81fe23 | 2019-03-25 17:38:04 +0000 | [diff] [blame] | 425 |  | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 426 | def check_prefer64_library(self, basename): | 
|  | 427 | self.check_file('lib64/%s.so' % basename) | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 428 |  | 
|  | 429 |  | 
| Andreas Gampe | 9dc4b05 | 2019-01-30 13:47:25 -0800 | [diff] [blame] | 430 | class ReleaseChecker: | 
|  | 431 | def __init__(self, checker): | 
|  | 432 | self._checker = checker | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 433 |  | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 434 | def __str__(self): | 
|  | 435 | return 'Release Checker' | 
|  | 436 |  | 
|  | 437 | def run(self): | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 438 | # Check the APEX manifest. | 
| Andreas Gampe | 9dc4b05 | 2019-01-30 13:47:25 -0800 | [diff] [blame] | 439 | self._checker.check_file('apex_manifest.json') | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 440 |  | 
| Martin Stjernholm | 77f1766 | 2019-04-03 17:08:21 +0100 | [diff] [blame] | 441 | # Check binaries for ART. | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 442 | self._checker.check_executable('dex2oat') | 
| Martin Stjernholm | 77f1766 | 2019-04-03 17:08:21 +0100 | [diff] [blame] | 443 | self._checker.check_executable('dexdump') | 
|  | 444 | self._checker.check_executable('dexlist') | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 445 | self._checker.check_executable('dexoptanalyzer') | 
|  | 446 | self._checker.check_executable('profman') | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 447 | self._checker.check_symlinked_multilib_executable('dalvikvm') | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 448 |  | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 449 | # Check exported libraries for ART. | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 450 | self._checker.check_native_library('libdexfile_external') | 
|  | 451 | self._checker.check_native_library('libnativebridge') | 
|  | 452 | self._checker.check_native_library('libnativehelper') | 
|  | 453 | self._checker.check_native_library('libnativeloader') | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 454 |  | 
|  | 455 | # Check internal libraries for ART. | 
|  | 456 | self._checker.check_native_library('libadbconnection') | 
|  | 457 | self._checker.check_native_library('libart') | 
|  | 458 | self._checker.check_native_library('libart-compiler') | 
|  | 459 | self._checker.check_native_library('libart-dexlayout') | 
|  | 460 | self._checker.check_native_library('libartbase') | 
|  | 461 | self._checker.check_native_library('libartpalette') | 
|  | 462 | self._checker.check_native_library('libdexfile') | 
|  | 463 | self._checker.check_native_library('libdexfile_support') | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 464 | self._checker.check_native_library('libopenjdkjvm') | 
|  | 465 | self._checker.check_native_library('libopenjdkjvmti') | 
|  | 466 | self._checker.check_native_library('libprofile') | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 467 | self._checker.check_native_library('libsigchain') | 
|  | 468 |  | 
|  | 469 | # Check java libraries for Managed Core Library. | 
|  | 470 | self._checker.check_java_library('apache-xml') | 
|  | 471 | self._checker.check_java_library('bouncycastle') | 
| Victor Chang | 759845f | 2019-08-06 16:04:36 +0100 | [diff] [blame^] | 472 | self._checker.check_java_library('core-icu4j') | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 473 | self._checker.check_java_library('core-libart') | 
|  | 474 | self._checker.check_java_library('core-oj') | 
|  | 475 | self._checker.check_java_library('okhttp') | 
|  | 476 |  | 
|  | 477 | # Check internal native libraries for Managed Core Library. | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 478 | self._checker.check_native_library('libjavacore') | 
|  | 479 | self._checker.check_native_library('libopenjdk') | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 480 |  | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 481 | # Check internal native library dependencies. | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 482 | # | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 483 | # Any internal dependency not listed here will cause a failure in | 
|  | 484 | # NoSuperfluousLibrariesChecker. Internal dependencies are generally just | 
|  | 485 | # implementation details, but in the release package we want to track them | 
|  | 486 | # because a) they add to the package size and the RAM usage (in particular | 
|  | 487 | # if the library is also present in /system or another APEX and hence might | 
|  | 488 | # get loaded twice through linker namespace separation), and b) we need to | 
|  | 489 | # catch invalid dependencies on /system or other APEXes that should go | 
|  | 490 | # through an exported library with stubs (b/128708192 tracks implementing a | 
|  | 491 | # better approach for that). | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 492 | self._checker.check_native_library('libbacktrace') | 
|  | 493 | self._checker.check_native_library('libbase') | 
|  | 494 | self._checker.check_native_library('libc++') | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 495 | self._checker.check_native_library('libdt_fd_forward') | 
|  | 496 | self._checker.check_native_library('libdt_socket') | 
|  | 497 | self._checker.check_native_library('libjdwp') | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 498 | self._checker.check_native_library('liblzma') | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 499 | self._checker.check_native_library('libnpt') | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 500 | self._checker.check_native_library('libunwindstack') | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 501 | self._checker.check_native_library('libziparchive') | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 502 | self._checker.check_optional_native_library('libvixl')  # Only on ARM/ARM64 | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 503 |  | 
| Martin Stjernholm | 84a32cd | 2019-03-29 16:39:46 +0000 | [diff] [blame] | 504 | # Allow extra dependencies that appear in ASAN builds. | 
|  | 505 | self._checker.check_optional_native_library('libclang_rt.asan*') | 
|  | 506 | self._checker.check_optional_native_library('libclang_rt.hwasan*') | 
|  | 507 | self._checker.check_optional_native_library('libclang_rt.ubsan*') | 
|  | 508 |  | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 509 |  | 
| Andreas Gampe | 9dc4b05 | 2019-01-30 13:47:25 -0800 | [diff] [blame] | 510 | class ReleaseTargetChecker: | 
|  | 511 | def __init__(self, checker): | 
|  | 512 | self._checker = checker | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 513 |  | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 514 | def __str__(self): | 
|  | 515 | return 'Release (Target) Checker' | 
|  | 516 |  | 
|  | 517 | def run(self): | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 518 | # Check the APEX package scripts. | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 519 | self._checker.check_executable('art_postinstall_hook') | 
|  | 520 | self._checker.check_executable('art_preinstall_hook') | 
|  | 521 | self._checker.check_executable('art_preinstall_hook_boot') | 
|  | 522 | self._checker.check_executable('art_preinstall_hook_system_server') | 
|  | 523 | self._checker.check_executable('art_prepostinstall_utils') | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 524 |  | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 525 | # Check binaries for ART. | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 526 | self._checker.check_executable('oatdump') | 
|  | 527 |  | 
|  | 528 | # Check internal libraries for ART. | 
|  | 529 | self._checker.check_prefer64_library('libart-disassembler') | 
|  | 530 |  | 
|  | 531 | # Check binaries for Bionic. | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 532 | self._checker.check_multilib_executable('linker') | 
|  | 533 | self._checker.check_multilib_executable('linker_asan') | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 534 |  | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 535 | # Check libraries for Bionic. | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 536 | self._checker.check_native_library('bionic/libc') | 
|  | 537 | self._checker.check_native_library('bionic/libdl') | 
|  | 538 | self._checker.check_native_library('bionic/libm') | 
| Jiyong Park | 408f7d0 | 2019-04-02 23:04:42 +0900 | [diff] [blame] | 539 | # ... and its internal dependencies | 
|  | 540 | self._checker.check_native_library('libc_malloc_hooks') | 
|  | 541 | self._checker.check_native_library('libc_malloc_debug') | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 542 |  | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 543 | # Check exported native libraries for Managed Core Library. | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 544 | self._checker.check_native_library('libandroidicu') | 
|  | 545 | self._checker.check_native_library('libandroidio') | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 546 |  | 
|  | 547 | # Check internal native library dependencies. | 
|  | 548 | self._checker.check_native_library('libcrypto') | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 549 | self._checker.check_native_library('libexpat') | 
|  | 550 | self._checker.check_native_library('libicui18n') | 
|  | 551 | self._checker.check_native_library('libicuuc') | 
|  | 552 | self._checker.check_native_library('libpac') | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 553 | self._checker.check_native_library('libz') | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 554 |  | 
| Martin Stjernholm | 4160c12 | 2019-04-23 17:05:39 +0100 | [diff] [blame] | 555 | # Guest architecture proxy libraries currently end up in these | 
|  | 556 | # subdirectories in x86 builds with native bridge. | 
|  | 557 | # TODO(b/131155689): These are unused - fix the build rules to avoid | 
|  | 558 | # creating them. | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 559 | self._checker.ignore_path('lib/arm') | 
| dimitry | 2fb74d3 | 2019-05-23 15:57:09 +0200 | [diff] [blame] | 560 | self._checker.ignore_path('lib64/arm64') | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 561 |  | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 562 |  | 
| Andreas Gampe | 9dc4b05 | 2019-01-30 13:47:25 -0800 | [diff] [blame] | 563 | class ReleaseHostChecker: | 
|  | 564 | def __init__(self, checker): | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 565 | self._checker = checker | 
|  | 566 |  | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 567 | def __str__(self): | 
|  | 568 | return 'Release (Host) Checker' | 
|  | 569 |  | 
|  | 570 | def run(self): | 
| Martin Stjernholm | 84a32cd | 2019-03-29 16:39:46 +0000 | [diff] [blame] | 571 | # Check binaries for ART. | 
|  | 572 | self._checker.check_executable('hprof-conv') | 
|  | 573 | self._checker.check_symlinked_multilib_executable('dex2oatd') | 
|  | 574 |  | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 575 | # Check exported native libraries for Managed Core Library. | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 576 | self._checker.check_native_library('libandroidicu-host') | 
|  | 577 | self._checker.check_native_library('libandroidio') | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 578 |  | 
|  | 579 | # Check internal libraries for Managed Core Library. | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 580 | self._checker.check_native_library('libexpat-host') | 
|  | 581 | self._checker.check_native_library('libicui18n-host') | 
|  | 582 | self._checker.check_native_library('libicuuc-host') | 
|  | 583 | self._checker.check_native_library('libz-host') | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 584 |  | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 585 |  | 
| Andreas Gampe | 9dc4b05 | 2019-01-30 13:47:25 -0800 | [diff] [blame] | 586 | class DebugChecker: | 
|  | 587 | def __init__(self, checker): | 
|  | 588 | self._checker = checker | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 589 |  | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 590 | def __str__(self): | 
|  | 591 | return 'Debug Checker' | 
|  | 592 |  | 
|  | 593 | def run(self): | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 594 | # Check binaries for ART. | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 595 | self._checker.check_executable('dexdiag') | 
| Roland Levillain | 6dd6212 | 2019-06-18 19:10:21 +0100 | [diff] [blame] | 596 | self._checker.check_executable('dexanalyze') | 
|  | 597 | self._checker.check_executable('dexlayout') | 
|  | 598 | self._checker.check_symlinked_multilib_executable('imgdiag') | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 599 |  | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 600 | # Check debug binaries for ART. | 
| Roland Levillain | 6dd6212 | 2019-06-18 19:10:21 +0100 | [diff] [blame] | 601 | self._checker.check_executable('dexlayoutd') | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 602 | self._checker.check_executable('dexoptanalyzerd') | 
| Roland Levillain | 6dd6212 | 2019-06-18 19:10:21 +0100 | [diff] [blame] | 603 | self._checker.check_symlinked_multilib_executable('imgdiagd') | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 604 | self._checker.check_executable('profmand') | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 605 |  | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 606 | # Check internal libraries for ART. | 
|  | 607 | self._checker.check_native_library('libadbconnectiond') | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 608 | self._checker.check_native_library('libartbased') | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 609 | self._checker.check_native_library('libartd') | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 610 | self._checker.check_native_library('libartd-compiler') | 
|  | 611 | self._checker.check_native_library('libartd-dexlayout') | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 612 | self._checker.check_native_library('libdexfiled') | 
|  | 613 | self._checker.check_native_library('libopenjdkjvmd') | 
|  | 614 | self._checker.check_native_library('libopenjdkjvmtid') | 
|  | 615 | self._checker.check_native_library('libprofiled') | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 616 |  | 
|  | 617 | # Check internal libraries for Managed Core Library. | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 618 | self._checker.check_native_library('libopenjdkd') | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 619 |  | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 620 |  | 
| Andreas Gampe | 9dc4b05 | 2019-01-30 13:47:25 -0800 | [diff] [blame] | 621 | class DebugTargetChecker: | 
|  | 622 | def __init__(self, checker): | 
|  | 623 | self._checker = checker | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 624 |  | 
| Andreas Gampe | a0242cf | 2019-01-29 13:01:23 -0800 | [diff] [blame] | 625 | def __str__(self): | 
|  | 626 | return 'Debug (Target) Checker' | 
|  | 627 |  | 
|  | 628 | def run(self): | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 629 | # Check ART debug binaries. | 
| Roland Levillain | 9a45d01 | 2019-06-05 13:54:02 +0100 | [diff] [blame] | 630 | self._checker.check_executable('dex2oatd') | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 631 | self._checker.check_executable('oatdumpd') | 
| Martin Stjernholm | 023c218 | 2019-03-28 15:52:32 +0000 | [diff] [blame] | 632 |  | 
|  | 633 | # Check ART internal libraries. | 
| Martin Stjernholm | 356864a | 2019-04-30 16:22:17 +0100 | [diff] [blame] | 634 | self._checker.check_native_library('libdexfiled_external') | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 635 | self._checker.check_prefer64_library('libartd-disassembler') | 
| Andreas Gampe | a0242cf | 2019-01-29 13:01:23 -0800 | [diff] [blame] | 636 |  | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 637 | # Check internal native library dependencies. | 
|  | 638 | # | 
|  | 639 | # Like in the release package, we check that we don't get other dependencies | 
|  | 640 | # besides those listed here. In this case the concern is not bloat, but | 
|  | 641 | # rather that we don't get behavioural differences between user (release) | 
|  | 642 | # and userdebug/eng builds, which could happen if the debug package has | 
|  | 643 | # duplicate library instances where releases don't. In other words, it's | 
|  | 644 | # uncontroversial to add debug-only dependencies, as long as they don't make | 
|  | 645 | # assumptions on having a single global state (ideally they should have | 
|  | 646 | # double_loadable:true, cf. go/double_loadable). Also, like in the release | 
|  | 647 | # package we need to look out for dependencies that should go through | 
|  | 648 | # exported library stubs (until b/128708192 is fixed). | 
| Martin Stjernholm | c17ace2 | 2019-03-18 21:47:31 +0000 | [diff] [blame] | 649 | self._checker.check_optional_native_library('libvixld')  # Only on ARM/ARM64 | 
| Martin Stjernholm | 77f1766 | 2019-04-03 17:08:21 +0100 | [diff] [blame] | 650 | self._checker.check_prefer64_library('libmeminfo') | 
|  | 651 | self._checker.check_prefer64_library('libprocinfo') | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 652 |  | 
|  | 653 |  | 
| Roland Levillain | 61f0716 | 2019-06-26 12:44:04 +0100 | [diff] [blame] | 654 | class TestingTargetChecker: | 
|  | 655 | def __init__(self, checker): | 
|  | 656 | self._checker = checker | 
|  | 657 |  | 
|  | 658 | def __str__(self): | 
|  | 659 | return 'Testing (Target) Checker' | 
|  | 660 |  | 
|  | 661 | def run(self): | 
|  | 662 | # Check cmdline tests. | 
|  | 663 | self._checker.check_optional_art_test_executable('cmdline_parser_test') | 
|  | 664 |  | 
|  | 665 | # Check compiler tests. | 
|  | 666 | self._checker.check_art_test_executable('atomic_dex_ref_map_test') | 
|  | 667 | self._checker.check_art_test_executable('bounds_check_elimination_test') | 
|  | 668 | self._checker.check_art_test_executable('codegen_test') | 
|  | 669 | self._checker.check_art_test_executable('compiled_method_storage_test') | 
|  | 670 | self._checker.check_art_test_executable('data_type_test') | 
|  | 671 | self._checker.check_art_test_executable('dedupe_set_test') | 
|  | 672 | self._checker.check_art_test_executable('dominator_test') | 
|  | 673 | self._checker.check_art_test_executable('dwarf_test') | 
|  | 674 | self._checker.check_art_test_executable('exception_test') | 
|  | 675 | self._checker.check_art_test_executable('find_loops_test') | 
|  | 676 | self._checker.check_art_test_executable('graph_checker_test') | 
|  | 677 | self._checker.check_art_test_executable('graph_test') | 
|  | 678 | self._checker.check_art_test_executable('gvn_test') | 
|  | 679 | self._checker.check_art_test_executable('induction_var_analysis_test') | 
|  | 680 | self._checker.check_art_test_executable('induction_var_range_test') | 
|  | 681 | self._checker.check_art_test_executable('jni_cfi_test') | 
|  | 682 | self._checker.check_art_test_executable('jni_compiler_test') | 
|  | 683 | self._checker.check_art_test_executable('licm_test') | 
|  | 684 | self._checker.check_art_test_executable('linker_patch_test') | 
|  | 685 | self._checker.check_art_test_executable('live_interval_test') | 
|  | 686 | self._checker.check_art_test_executable('load_store_analysis_test') | 
|  | 687 | self._checker.check_art_test_executable('loop_optimization_test') | 
|  | 688 | self._checker.check_art_test_executable('nodes_test') | 
|  | 689 | self._checker.check_art_test_executable('nodes_vector_test') | 
|  | 690 | self._checker.check_art_test_executable('optimizing_cfi_test') | 
|  | 691 | self._checker.check_art_test_executable('output_stream_test') | 
|  | 692 | self._checker.check_art_test_executable('parallel_move_test') | 
|  | 693 | self._checker.check_art_test_executable('pretty_printer_test') | 
|  | 694 | self._checker.check_art_test_executable('reference_type_propagation_test') | 
|  | 695 | self._checker.check_art_test_executable('scheduler_test') | 
|  | 696 | self._checker.check_art_test_executable('select_generator_test') | 
|  | 697 | self._checker.check_art_test_executable('side_effects_test') | 
|  | 698 | self._checker.check_art_test_executable('src_map_elem_test') | 
|  | 699 | self._checker.check_art_test_executable('ssa_liveness_analysis_test') | 
|  | 700 | self._checker.check_art_test_executable('ssa_test') | 
|  | 701 | self._checker.check_art_test_executable('stack_map_test') | 
|  | 702 | self._checker.check_art_test_executable('superblock_cloner_test') | 
|  | 703 | self._checker.check_art_test_executable('suspend_check_test') | 
|  | 704 | self._checker.check_art_test_executable('swap_space_test') | 
|  | 705 | # These tests depend on a specific code generator and are conditionally included. | 
|  | 706 | self._checker.check_optional_art_test_executable('constant_folding_test') | 
|  | 707 | self._checker.check_optional_art_test_executable('dead_code_elimination_test') | 
|  | 708 | self._checker.check_optional_art_test_executable('linearize_test') | 
|  | 709 | self._checker.check_optional_art_test_executable('live_ranges_test') | 
|  | 710 | self._checker.check_optional_art_test_executable('liveness_test') | 
|  | 711 | self._checker.check_optional_art_test_executable('managed_register_arm64_test') | 
|  | 712 | self._checker.check_optional_art_test_executable('managed_register_arm_test') | 
|  | 713 | self._checker.check_optional_art_test_executable('managed_register_mips64_test') | 
|  | 714 | self._checker.check_optional_art_test_executable('managed_register_x86_64_test') | 
|  | 715 | self._checker.check_optional_art_test_executable('managed_register_x86_test') | 
|  | 716 | self._checker.check_optional_art_test_executable('register_allocator_test') | 
|  | 717 |  | 
|  | 718 | # Check dex2oat tests. | 
|  | 719 | self._checker.check_art_test_executable('compiler_driver_test') | 
|  | 720 | self._checker.check_art_test_executable('dex2oat_image_test') | 
|  | 721 | self._checker.check_art_test_executable('dex2oat_test') | 
|  | 722 | self._checker.check_art_test_executable('dex_to_dex_decompiler_test') | 
|  | 723 | self._checker.check_art_test_executable('elf_writer_test') | 
|  | 724 | self._checker.check_art_test_executable('image_test') | 
|  | 725 | self._checker.check_art_test_executable('image_write_read_test') | 
|  | 726 | self._checker.check_art_test_executable('index_bss_mapping_encoder_test') | 
|  | 727 | self._checker.check_art_test_executable('multi_oat_relative_patcher_test') | 
|  | 728 | self._checker.check_art_test_executable('oat_writer_test') | 
|  | 729 | self._checker.check_art_test_executable('verifier_deps_test') | 
|  | 730 | # These tests depend on a specific code generator and are conditionally included. | 
|  | 731 | self._checker.check_optional_art_test_executable('relative_patcher_arm64_test') | 
|  | 732 | self._checker.check_optional_art_test_executable('relative_patcher_mips32r6_test') | 
|  | 733 | self._checker.check_optional_art_test_executable('relative_patcher_mips64_test') | 
|  | 734 | self._checker.check_optional_art_test_executable('relative_patcher_mips_test') | 
|  | 735 | self._checker.check_optional_art_test_executable('relative_patcher_thumb2_test') | 
|  | 736 | self._checker.check_optional_art_test_executable('relative_patcher_x86_64_test') | 
|  | 737 | self._checker.check_optional_art_test_executable('relative_patcher_x86_test') | 
|  | 738 |  | 
|  | 739 | # Check dexanalyze tests. | 
|  | 740 | self._checker.check_optional_art_test_executable('dexanalyze_test') | 
|  | 741 |  | 
|  | 742 | # Check dexdiag tests. | 
|  | 743 | self._checker.check_optional_art_test_executable('dexdiag_test') | 
|  | 744 |  | 
|  | 745 | # Check dexdump tests. | 
|  | 746 | self._checker.check_art_test_executable('dexdump_test') | 
|  | 747 |  | 
|  | 748 | # Check dexlayout tests. | 
|  | 749 | self._checker.check_optional_art_test_executable('dexlayout_test') | 
|  | 750 |  | 
|  | 751 | # Check dexlist tests. | 
|  | 752 | self._checker.check_art_test_executable('dexlist_test') | 
|  | 753 |  | 
|  | 754 | # Check dexoptanalyzer tests. | 
|  | 755 | self._checker.check_art_test_executable('dexoptanalyzer_test') | 
|  | 756 |  | 
|  | 757 | # Check imgdiag tests. | 
|  | 758 | self._checker.check_art_test_executable('imgdiag_test') | 
|  | 759 |  | 
|  | 760 | # Check libartbase tests. | 
|  | 761 | self._checker.check_art_test_executable('arena_allocator_test') | 
|  | 762 | self._checker.check_art_test_executable('bit_field_test') | 
|  | 763 | self._checker.check_art_test_executable('bit_memory_region_test') | 
|  | 764 | self._checker.check_art_test_executable('bit_string_test') | 
|  | 765 | self._checker.check_art_test_executable('bit_struct_test') | 
|  | 766 | self._checker.check_art_test_executable('bit_table_test') | 
|  | 767 | self._checker.check_art_test_executable('bit_utils_test') | 
|  | 768 | self._checker.check_art_test_executable('bit_vector_test') | 
|  | 769 | self._checker.check_art_test_executable('fd_file_test') | 
|  | 770 | self._checker.check_art_test_executable('file_utils_test') | 
|  | 771 | self._checker.check_art_test_executable('hash_set_test') | 
|  | 772 | self._checker.check_art_test_executable('hex_dump_test') | 
|  | 773 | self._checker.check_art_test_executable('histogram_test') | 
|  | 774 | self._checker.check_art_test_executable('indenter_test') | 
|  | 775 | self._checker.check_art_test_executable('instruction_set_test') | 
|  | 776 | self._checker.check_art_test_executable('intrusive_forward_list_test') | 
|  | 777 | self._checker.check_art_test_executable('leb128_test') | 
|  | 778 | self._checker.check_art_test_executable('logging_test') | 
|  | 779 | self._checker.check_art_test_executable('mem_map_test') | 
|  | 780 | self._checker.check_art_test_executable('membarrier_test') | 
|  | 781 | self._checker.check_art_test_executable('memfd_test') | 
|  | 782 | self._checker.check_art_test_executable('memory_region_test') | 
|  | 783 | self._checker.check_art_test_executable('memory_type_table_test') | 
|  | 784 | self._checker.check_art_test_executable('safe_copy_test') | 
|  | 785 | self._checker.check_art_test_executable('scoped_flock_test') | 
|  | 786 | self._checker.check_art_test_executable('time_utils_test') | 
|  | 787 | self._checker.check_art_test_executable('transform_array_ref_test') | 
|  | 788 | self._checker.check_art_test_executable('transform_iterator_test') | 
|  | 789 | self._checker.check_art_test_executable('utils_test') | 
|  | 790 | self._checker.check_art_test_executable('variant_map_test') | 
|  | 791 | self._checker.check_art_test_executable('zip_archive_test') | 
|  | 792 |  | 
|  | 793 | # Check libartpalette tests. | 
|  | 794 | self._checker.check_art_test_executable('palette_test') | 
|  | 795 |  | 
|  | 796 | # Check libdexfile tests. | 
|  | 797 | self._checker.check_art_test_executable('art_dex_file_loader_test') | 
|  | 798 | self._checker.check_art_test_executable('art_libdexfile_support_tests') | 
|  | 799 | self._checker.check_art_test_executable('class_accessor_test') | 
|  | 800 | self._checker.check_art_test_executable('code_item_accessors_test') | 
|  | 801 | self._checker.check_art_test_executable('compact_dex_file_test') | 
|  | 802 | self._checker.check_art_test_executable('compact_offset_table_test') | 
|  | 803 | self._checker.check_art_test_executable('descriptors_names_test') | 
|  | 804 | self._checker.check_art_test_executable('dex_file_loader_test') | 
|  | 805 | self._checker.check_art_test_executable('dex_file_verifier_test') | 
|  | 806 | self._checker.check_art_test_executable('dex_instruction_test') | 
|  | 807 | self._checker.check_art_test_executable('primitive_test') | 
|  | 808 | self._checker.check_art_test_executable('string_reference_test') | 
|  | 809 | self._checker.check_art_test_executable('test_dex_file_builder_test') | 
|  | 810 | self._checker.check_art_test_executable('type_lookup_table_test') | 
|  | 811 | self._checker.check_art_test_executable('utf_test') | 
|  | 812 |  | 
|  | 813 | # Check libprofile tests. | 
|  | 814 | self._checker.check_optional_art_test_executable('profile_boot_info_test') | 
|  | 815 | self._checker.check_optional_art_test_executable('profile_compilation_info_test') | 
|  | 816 |  | 
|  | 817 | # Check oatdump tests. | 
|  | 818 | self._checker.check_art_test_executable('oatdump_app_test') | 
|  | 819 | self._checker.check_art_test_executable('oatdump_image_test') | 
|  | 820 | self._checker.check_art_test_executable('oatdump_test') | 
|  | 821 |  | 
|  | 822 | # Check profman tests. | 
|  | 823 | self._checker.check_art_test_executable('profile_assistant_test') | 
|  | 824 |  | 
|  | 825 | # Check runtime compiler tests. | 
|  | 826 | self._checker.check_art_test_executable('module_exclusion_test') | 
|  | 827 | self._checker.check_art_test_executable('reflection_test') | 
|  | 828 |  | 
|  | 829 | # Check runtime tests. | 
|  | 830 | self._checker.check_art_test_executable('arch_test') | 
|  | 831 | self._checker.check_art_test_executable('barrier_test') | 
|  | 832 | self._checker.check_art_test_executable('card_table_test') | 
|  | 833 | self._checker.check_art_test_executable('cha_test') | 
|  | 834 | self._checker.check_art_test_executable('class_linker_test') | 
|  | 835 | self._checker.check_art_test_executable('class_loader_context_test') | 
|  | 836 | self._checker.check_art_test_executable('class_table_test') | 
|  | 837 | self._checker.check_art_test_executable('compiler_filter_test') | 
|  | 838 | self._checker.check_art_test_executable('dex_cache_test') | 
|  | 839 | self._checker.check_art_test_executable('dlmalloc_space_random_test') | 
|  | 840 | self._checker.check_art_test_executable('dlmalloc_space_static_test') | 
|  | 841 | self._checker.check_art_test_executable('entrypoints_order_test') | 
|  | 842 | self._checker.check_art_test_executable('exec_utils_test') | 
|  | 843 | self._checker.check_art_test_executable('gtest_test') | 
|  | 844 | self._checker.check_art_test_executable('handle_scope_test') | 
|  | 845 | self._checker.check_art_test_executable('heap_test') | 
|  | 846 | self._checker.check_art_test_executable('heap_verification_test') | 
|  | 847 | self._checker.check_art_test_executable('hidden_api_test') | 
|  | 848 | self._checker.check_art_test_executable('image_space_test') | 
|  | 849 | self._checker.check_art_test_executable('immune_spaces_test') | 
|  | 850 | self._checker.check_art_test_executable('imtable_test') | 
|  | 851 | self._checker.check_art_test_executable('indirect_reference_table_test') | 
|  | 852 | self._checker.check_art_test_executable('instruction_set_features_arm64_test') | 
|  | 853 | self._checker.check_art_test_executable('instruction_set_features_arm_test') | 
|  | 854 | self._checker.check_art_test_executable('instruction_set_features_mips64_test') | 
|  | 855 | self._checker.check_art_test_executable('instruction_set_features_mips_test') | 
|  | 856 | self._checker.check_art_test_executable('instruction_set_features_test') | 
|  | 857 | self._checker.check_art_test_executable('instruction_set_features_x86_64_test') | 
|  | 858 | self._checker.check_art_test_executable('instruction_set_features_x86_test') | 
|  | 859 | self._checker.check_art_test_executable('instrumentation_test') | 
|  | 860 | self._checker.check_art_test_executable('intern_table_test') | 
|  | 861 | self._checker.check_art_test_executable('java_vm_ext_test') | 
|  | 862 | self._checker.check_art_test_executable('jdwp_options_test') | 
|  | 863 | self._checker.check_art_test_executable('jit_memory_region_test') | 
|  | 864 | self._checker.check_art_test_executable('jni_internal_test') | 
|  | 865 | self._checker.check_art_test_executable('large_object_space_test') | 
|  | 866 | self._checker.check_art_test_executable('math_entrypoints_test') | 
|  | 867 | self._checker.check_art_test_executable('memcmp16_test') | 
|  | 868 | self._checker.check_art_test_executable('method_handles_test') | 
|  | 869 | self._checker.check_art_test_executable('method_type_test') | 
|  | 870 | self._checker.check_art_test_executable('method_verifier_test') | 
|  | 871 | self._checker.check_art_test_executable('mod_union_table_test') | 
|  | 872 | self._checker.check_art_test_executable('monitor_pool_test') | 
|  | 873 | self._checker.check_art_test_executable('monitor_test') | 
|  | 874 | self._checker.check_art_test_executable('mutex_test') | 
|  | 875 | self._checker.check_art_test_executable('oat_file_assistant_test') | 
|  | 876 | self._checker.check_art_test_executable('oat_file_test') | 
|  | 877 | self._checker.check_art_test_executable('object_test') | 
|  | 878 | self._checker.check_art_test_executable('parsed_options_test') | 
|  | 879 | self._checker.check_art_test_executable('prebuilt_tools_test') | 
|  | 880 | self._checker.check_art_test_executable('profiling_info_test') | 
|  | 881 | self._checker.check_art_test_executable('proxy_test') | 
|  | 882 | self._checker.check_art_test_executable('quick_trampoline_entrypoints_test') | 
|  | 883 | self._checker.check_art_test_executable('reference_queue_test') | 
|  | 884 | self._checker.check_art_test_executable('reference_table_test') | 
|  | 885 | self._checker.check_art_test_executable('reg_type_test') | 
|  | 886 | self._checker.check_art_test_executable('rosalloc_space_random_test') | 
|  | 887 | self._checker.check_art_test_executable('rosalloc_space_static_test') | 
|  | 888 | self._checker.check_art_test_executable('runtime_callbacks_test') | 
|  | 889 | self._checker.check_art_test_executable('runtime_test') | 
|  | 890 | self._checker.check_art_test_executable('safe_math_test') | 
|  | 891 | self._checker.check_art_test_executable('space_bitmap_test') | 
|  | 892 | self._checker.check_art_test_executable('space_create_test') | 
|  | 893 | self._checker.check_art_test_executable('stub_test') | 
|  | 894 | self._checker.check_art_test_executable('subtype_check_info_test') | 
|  | 895 | self._checker.check_art_test_executable('subtype_check_test') | 
|  | 896 | self._checker.check_art_test_executable('system_weak_test') | 
|  | 897 | self._checker.check_art_test_executable('task_processor_test') | 
|  | 898 | self._checker.check_art_test_executable('thread_pool_test') | 
|  | 899 | self._checker.check_art_test_executable('timing_logger_test') | 
|  | 900 | self._checker.check_art_test_executable('transaction_test') | 
|  | 901 | self._checker.check_art_test_executable('two_runtimes_test') | 
|  | 902 | self._checker.check_art_test_executable('unstarted_runtime_test') | 
|  | 903 | self._checker.check_art_test_executable('var_handle_test') | 
|  | 904 | self._checker.check_art_test_executable('vdex_file_test') | 
|  | 905 |  | 
|  | 906 | # Check sigchainlib tests. | 
|  | 907 | self._checker.check_art_test_executable('sigchain_test') | 
|  | 908 |  | 
|  | 909 | # Check ART test (internal) libraries. | 
|  | 910 | self._checker.check_native_library('libart-gtest') | 
|  | 911 | self._checker.check_native_library('libartd-disassembler') | 
|  | 912 | self._checker.check_native_library('libartd-simulator-container') | 
|  | 913 |  | 
|  | 914 |  | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 915 | class NoSuperfluousBinariesChecker: | 
|  | 916 | def __init__(self, checker): | 
|  | 917 | self._checker = checker | 
|  | 918 |  | 
|  | 919 | def __str__(self): | 
|  | 920 | return 'No superfluous binaries checker' | 
|  | 921 |  | 
|  | 922 | def run(self): | 
|  | 923 | self._checker.check_no_superfluous_files('bin') | 
|  | 924 |  | 
|  | 925 |  | 
|  | 926 | class NoSuperfluousLibrariesChecker: | 
|  | 927 | def __init__(self, checker): | 
|  | 928 | self._checker = checker | 
|  | 929 |  | 
|  | 930 | def __str__(self): | 
|  | 931 | return 'No superfluous libraries checker' | 
|  | 932 |  | 
|  | 933 | def run(self): | 
|  | 934 | self._checker.check_no_superfluous_files('javalib') | 
|  | 935 | self._checker.check_no_superfluous_files('lib') | 
|  | 936 | self._checker.check_no_superfluous_files('lib/bionic') | 
|  | 937 | self._checker.check_no_superfluous_files('lib64') | 
|  | 938 | self._checker.check_no_superfluous_files('lib64/bionic') | 
|  | 939 |  | 
| Andreas Gampe | b1d5567 | 2019-01-29 22:17:02 +0000 | [diff] [blame] | 940 |  | 
| Roland Levillain | 61f0716 | 2019-06-26 12:44:04 +0100 | [diff] [blame] | 941 | class NoSuperfluousArtTestsChecker: | 
|  | 942 | def __init__(self, checker): | 
|  | 943 | self._checker = checker | 
|  | 944 |  | 
|  | 945 | def __str__(self): | 
|  | 946 | return 'No superfluous ART tests checker' | 
|  | 947 |  | 
|  | 948 | def run(self): | 
|  | 949 | for arch in archs: | 
|  | 950 | self._checker.check_no_superfluous_files('%s/%s' % (art_test_dir, arch)) | 
|  | 951 |  | 
|  | 952 |  | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 953 | class List: | 
| Roland Levillain | 77251f9 | 2019-08-09 15:00:04 +0100 | [diff] [blame] | 954 | def __init__(self, provider, print_size=False): | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 955 | self._provider = provider | 
| Roland Levillain | e91d787 | 2019-07-25 18:56:06 +0100 | [diff] [blame] | 956 | self._print_size = print_size | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 957 |  | 
|  | 958 | def print_list(self): | 
| Roland Levillain | 09744ac | 2019-06-06 18:23:02 +0100 | [diff] [blame] | 959 |  | 
|  | 960 | def print_list_rec(path): | 
|  | 961 | apex_map = self._provider.read_dir(path) | 
|  | 962 | if apex_map is None: | 
|  | 963 | return | 
|  | 964 | apex_map = dict(apex_map) | 
|  | 965 | if '.' in apex_map: | 
|  | 966 | del apex_map['.'] | 
|  | 967 | if '..' in apex_map: | 
|  | 968 | del apex_map['..'] | 
|  | 969 | for (_, val) in sorted(apex_map.items()): | 
|  | 970 | val_path = os.path.join(path, val.name) | 
| Roland Levillain | e91d787 | 2019-07-25 18:56:06 +0100 | [diff] [blame] | 971 | if self._print_size: | 
|  | 972 | if val.size < 0: | 
|  | 973 | print('[    n/a    ]  %s' % val_path) | 
|  | 974 | else: | 
|  | 975 | print('[%11d]  %s' % (val.size, val_path)) | 
|  | 976 | else: | 
|  | 977 | print(val_path) | 
| Roland Levillain | 09744ac | 2019-06-06 18:23:02 +0100 | [diff] [blame] | 978 | if val.is_dir: | 
|  | 979 | print_list_rec(val_path) | 
|  | 980 |  | 
|  | 981 | print_list_rec('') | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 982 |  | 
|  | 983 |  | 
|  | 984 | class Tree: | 
| Roland Levillain | 77251f9 | 2019-08-09 15:00:04 +0100 | [diff] [blame] | 985 | def __init__(self, provider, title, print_size=False): | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 986 | print('%s' % title) | 
|  | 987 | self._provider = provider | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 988 | self._has_next_list = [] | 
| Roland Levillain | 88e5569 | 2019-07-25 15:57:06 +0100 | [diff] [blame] | 989 | self._print_size = print_size | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 990 |  | 
|  | 991 | @staticmethod | 
|  | 992 | def get_vertical(has_next_list): | 
|  | 993 | string = '' | 
|  | 994 | for v in has_next_list: | 
|  | 995 | string += '%s   ' % ('│' if v else ' ') | 
|  | 996 | return string | 
|  | 997 |  | 
|  | 998 | @staticmethod | 
|  | 999 | def get_last_vertical(last): | 
|  | 1000 | return '└── ' if last else '├── ' | 
|  | 1001 |  | 
|  | 1002 | def print_tree(self): | 
| Roland Levillain | 09744ac | 2019-06-06 18:23:02 +0100 | [diff] [blame] | 1003 |  | 
|  | 1004 | def print_tree_rec(path): | 
|  | 1005 | apex_map = self._provider.read_dir(path) | 
|  | 1006 | if apex_map is None: | 
|  | 1007 | return | 
|  | 1008 | apex_map = dict(apex_map) | 
|  | 1009 | if '.' in apex_map: | 
|  | 1010 | del apex_map['.'] | 
|  | 1011 | if '..' in apex_map: | 
|  | 1012 | del apex_map['..'] | 
|  | 1013 | key_list = list(sorted(apex_map.keys())) | 
|  | 1014 | for i, key in enumerate(key_list): | 
|  | 1015 | prev = self.get_vertical(self._has_next_list) | 
|  | 1016 | last = self.get_last_vertical(i == len(key_list) - 1) | 
|  | 1017 | val = apex_map[key] | 
| Roland Levillain | 88e5569 | 2019-07-25 15:57:06 +0100 | [diff] [blame] | 1018 | if self._print_size: | 
|  | 1019 | if val.size < 0: | 
|  | 1020 | print('%s%s[    n/a    ]  %s' % (prev, last, val.name)) | 
|  | 1021 | else: | 
|  | 1022 | print('%s%s[%11d]  %s' % (prev, last, val.size, val.name)) | 
|  | 1023 | else: | 
|  | 1024 | print('%s%s%s' % (prev, last, val.name)) | 
| Roland Levillain | 09744ac | 2019-06-06 18:23:02 +0100 | [diff] [blame] | 1025 | if val.is_dir: | 
|  | 1026 | self._has_next_list.append(i < len(key_list) - 1) | 
|  | 1027 | val_path = os.path.join(path, val.name) | 
|  | 1028 | print_tree_rec(val_path) | 
|  | 1029 | self._has_next_list.pop() | 
|  | 1030 |  | 
|  | 1031 | print_tree_rec('') | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1032 |  | 
| Andreas Gampe | b1d5567 | 2019-01-29 22:17:02 +0000 | [diff] [blame] | 1033 |  | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1034 | # Note: do not sys.exit early, for __del__ cleanup. | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1035 | def art_apex_test_main(test_args): | 
| Roland Levillain | dd20d00 | 2019-07-19 16:09:47 +0100 | [diff] [blame] | 1036 | if test_args.host and test_args.flattened: | 
|  | 1037 | logging.error("Both of --host and --flattened set") | 
|  | 1038 | return 1 | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1039 | if test_args.tree and test_args.debug: | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 1040 | logging.error("Both of --tree and --debug set") | 
| Andreas Gampe | b1d5567 | 2019-01-29 22:17:02 +0000 | [diff] [blame] | 1041 | return 1 | 
| Roland Levillain | 61f0716 | 2019-06-26 12:44:04 +0100 | [diff] [blame] | 1042 | if test_args.tree and test_args.testing: | 
|  | 1043 | logging.error("Both of --tree and --testing set") | 
|  | 1044 | return 1 | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1045 | if test_args.list and test_args.debug: | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 1046 | logging.error("Both of --list and --debug set") | 
| Andreas Gampe | b1d5567 | 2019-01-29 22:17:02 +0000 | [diff] [blame] | 1047 | return 1 | 
| Roland Levillain | 61f0716 | 2019-06-26 12:44:04 +0100 | [diff] [blame] | 1048 | if test_args.list and test_args.testing: | 
|  | 1049 | logging.error("Both of --list and --testing set") | 
|  | 1050 | return 1 | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1051 | if test_args.list and test_args.tree: | 
| Andreas Gampe | b1d5567 | 2019-01-29 22:17:02 +0000 | [diff] [blame] | 1052 | logging.error("Both of --list and --tree set") | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1053 | return 1 | 
| Roland Levillain | e91d787 | 2019-07-25 18:56:06 +0100 | [diff] [blame] | 1054 | if test_args.size and not (test_args.list or test_args.tree): | 
|  | 1055 | logging.error("--size set but neither --list nor --tree set") | 
| Roland Levillain | 88e5569 | 2019-07-25 15:57:06 +0100 | [diff] [blame] | 1056 | return 1 | 
| Roland Levillain | 61f0716 | 2019-06-26 12:44:04 +0100 | [diff] [blame] | 1057 | if test_args.host and test_args.testing: | 
|  | 1058 | logging.error("Both of --host and --testing set") | 
|  | 1059 | return 1 | 
| Martin Stjernholm | 3cb59a4 | 2019-08-07 17:18:29 +0100 | [diff] [blame] | 1060 | if not test_args.flattened and not test_args.tmpdir: | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1061 | logging.error("Need a tmpdir.") | 
|  | 1062 | return 1 | 
| Martin Stjernholm | 3cb59a4 | 2019-08-07 17:18:29 +0100 | [diff] [blame] | 1063 | if not test_args.flattened and not test_args.host and not test_args.debugfs: | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1064 | logging.error("Need debugfs.") | 
|  | 1065 | return 1 | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1066 | if test_args.bitness not in ['32', '64', 'multilib', 'auto']: | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 1067 | logging.error('--bitness needs to be one of 32|64|multilib|auto') | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1068 |  | 
|  | 1069 | try: | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1070 | if test_args.host: | 
|  | 1071 | apex_provider = HostApexProvider(test_args.apex, test_args.tmpdir) | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 1072 | else: | 
| Roland Levillain | dd20d00 | 2019-07-19 16:09:47 +0100 | [diff] [blame] | 1073 | if test_args.flattened: | 
|  | 1074 | apex_provider = TargetFlattenedApexProvider(test_args.apex) | 
|  | 1075 | else: | 
|  | 1076 | apex_provider = TargetApexProvider(test_args.apex, test_args.tmpdir, test_args.debugfs) | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1077 | except (zipfile.BadZipFile, zipfile.LargeZipFile) as e: | 
| Andreas Gampe | a0242cf | 2019-01-29 13:01:23 -0800 | [diff] [blame] | 1078 | logging.error('Failed to create provider: %s', e) | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1079 | return 1 | 
|  | 1080 |  | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1081 | if test_args.tree: | 
| Roland Levillain | 88e5569 | 2019-07-25 15:57:06 +0100 | [diff] [blame] | 1082 | Tree(apex_provider, test_args.apex, test_args.size).print_tree() | 
| Andreas Gampe | b1d5567 | 2019-01-29 22:17:02 +0000 | [diff] [blame] | 1083 | return 0 | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1084 | if test_args.list: | 
| Roland Levillain | e91d787 | 2019-07-25 18:56:06 +0100 | [diff] [blame] | 1085 | List(apex_provider, test_args.size).print_list() | 
| Andreas Gampe | b1d5567 | 2019-01-29 22:17:02 +0000 | [diff] [blame] | 1086 | return 0 | 
|  | 1087 |  | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1088 | checkers = [] | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1089 | if test_args.bitness == 'auto': | 
|  | 1090 | logging.warning('--bitness=auto, trying to autodetect. This may be incorrect!') | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 1091 | has_32 = apex_provider.get('lib') is not None | 
|  | 1092 | has_64 = apex_provider.get('lib64') is not None | 
|  | 1093 | if has_32 and has_64: | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1094 | logging.warning('  Detected multilib') | 
|  | 1095 | test_args.bitness = 'multilib' | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 1096 | elif has_32: | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1097 | logging.warning('  Detected 32-only') | 
|  | 1098 | test_args.bitness = '32' | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 1099 | elif has_64: | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1100 | logging.warning('  Detected 64-only') | 
|  | 1101 | test_args.bitness = '64' | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 1102 | else: | 
|  | 1103 | logging.error('  Could not detect bitness, neither lib nor lib64 contained.') | 
| Roland Levillain | 77251f9 | 2019-08-09 15:00:04 +0100 | [diff] [blame] | 1104 | List(apex_provider).print_list() | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 1105 | return 1 | 
|  | 1106 |  | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1107 | if test_args.bitness == '32': | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 1108 | base_checker = Arch32Checker(apex_provider) | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1109 | elif test_args.bitness == '64': | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 1110 | base_checker = Arch64Checker(apex_provider) | 
|  | 1111 | else: | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1112 | assert test_args.bitness == 'multilib' | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 1113 | base_checker = MultilibChecker(apex_provider) | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1114 |  | 
| Andreas Gampe | 9dc4b05 | 2019-01-30 13:47:25 -0800 | [diff] [blame] | 1115 | checkers.append(ReleaseChecker(base_checker)) | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1116 | if test_args.host: | 
| Andreas Gampe | 9dc4b05 | 2019-01-30 13:47:25 -0800 | [diff] [blame] | 1117 | checkers.append(ReleaseHostChecker(base_checker)) | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 1118 | else: | 
| Andreas Gampe | 9dc4b05 | 2019-01-30 13:47:25 -0800 | [diff] [blame] | 1119 | checkers.append(ReleaseTargetChecker(base_checker)) | 
| Roland Levillain | 61f0716 | 2019-06-26 12:44:04 +0100 | [diff] [blame] | 1120 | if test_args.debug or test_args.testing: | 
| Andreas Gampe | 9dc4b05 | 2019-01-30 13:47:25 -0800 | [diff] [blame] | 1121 | checkers.append(DebugChecker(base_checker)) | 
| Roland Levillain | 61f0716 | 2019-06-26 12:44:04 +0100 | [diff] [blame] | 1122 | if not test_args.host: | 
|  | 1123 | checkers.append(DebugTargetChecker(base_checker)) | 
|  | 1124 | if test_args.testing: | 
|  | 1125 | checkers.append(TestingTargetChecker(base_checker)) | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1126 |  | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 1127 | # These checkers must be last. | 
|  | 1128 | checkers.append(NoSuperfluousBinariesChecker(base_checker)) | 
| Roland Levillain | 61f0716 | 2019-06-26 12:44:04 +0100 | [diff] [blame] | 1129 | checkers.append(NoSuperfluousArtTestsChecker(base_checker)) | 
| Martin Stjernholm | 2babede | 2019-03-18 21:04:49 +0000 | [diff] [blame] | 1130 | if not test_args.host: | 
|  | 1131 | # We only care about superfluous libraries on target, where their absence | 
|  | 1132 | # can be vital to ensure they get picked up from the right package. | 
|  | 1133 | checkers.append(NoSuperfluousLibrariesChecker(base_checker)) | 
|  | 1134 |  | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1135 | failed = False | 
|  | 1136 | for checker in checkers: | 
|  | 1137 | logging.info('%s...', checker) | 
|  | 1138 | checker.run() | 
| Andreas Gampe | 9dc4b05 | 2019-01-30 13:47:25 -0800 | [diff] [blame] | 1139 | if base_checker.error_count() > 0: | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1140 | logging.error('%s FAILED', checker) | 
|  | 1141 | failed = True | 
|  | 1142 | else: | 
|  | 1143 | logging.info('%s SUCCEEDED', checker) | 
| Andreas Gampe | 9dc4b05 | 2019-01-30 13:47:25 -0800 | [diff] [blame] | 1144 | base_checker.reset_errors() | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1145 |  | 
|  | 1146 | return 1 if failed else 0 | 
|  | 1147 |  | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1148 |  | 
|  | 1149 | def art_apex_test_default(test_parser): | 
|  | 1150 | if 'ANDROID_PRODUCT_OUT' not in os.environ: | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1151 | logging.error('No-argument use requires ANDROID_PRODUCT_OUT') | 
|  | 1152 | sys.exit(1) | 
|  | 1153 | product_out = os.environ['ANDROID_PRODUCT_OUT'] | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1154 | if 'ANDROID_HOST_OUT' not in os.environ: | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1155 | logging.error('No-argument use requires ANDROID_HOST_OUT') | 
|  | 1156 | sys.exit(1) | 
|  | 1157 | host_out = os.environ['ANDROID_HOST_OUT'] | 
|  | 1158 |  | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1159 | test_args = test_parser.parse_args(['dummy'])  # For consistency. | 
|  | 1160 | test_args.debugfs = '%s/bin/debugfs' % host_out | 
|  | 1161 | test_args.tmpdir = '.' | 
|  | 1162 | test_args.tree = False | 
|  | 1163 | test_args.list = False | 
|  | 1164 | test_args.bitness = 'auto' | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1165 | failed = False | 
|  | 1166 |  | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1167 | if not os.path.exists(test_args.debugfs): | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1168 | logging.error("Cannot find debugfs (default path %s). Please build it, e.g., m debugfs", | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1169 | test_args.debugfs) | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1170 | sys.exit(1) | 
|  | 1171 |  | 
|  | 1172 | # TODO: Add host support | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1173 | configs = [ | 
| Roland Levillain | 61f0716 | 2019-06-26 12:44:04 +0100 | [diff] [blame] | 1174 | {'name': 'com.android.runtime.release', 'debug': False, 'testing': False, 'host': False}, | 
|  | 1175 | {'name': 'com.android.runtime.debug',   'debug': True,  'testing': False, 'host': False}, | 
|  | 1176 | {'name': 'com.android.runtime.testing', 'debug': False, 'testing': True,  'host': False}, | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1177 | ] | 
|  | 1178 |  | 
|  | 1179 | for config in configs: | 
|  | 1180 | logging.info(config['name']) | 
|  | 1181 | # TODO: Host will need different path. | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1182 | test_args.apex = '%s/system/apex/%s.apex' % (product_out, config['name']) | 
|  | 1183 | if not os.path.exists(test_args.apex): | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1184 | failed = True | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1185 | logging.error("Cannot find APEX %s. Please build it first.", test_args.apex) | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1186 | continue | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1187 | test_args.debug = config['debug'] | 
| Roland Levillain | 61f0716 | 2019-06-26 12:44:04 +0100 | [diff] [blame] | 1188 | test_args.testing = config['testing'] | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1189 | test_args.host = config['host'] | 
|  | 1190 | failed = art_apex_test_main(test_args) != 0 | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1191 |  | 
|  | 1192 | if failed: | 
|  | 1193 | sys.exit(1) | 
|  | 1194 |  | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1195 |  | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1196 | if __name__ == "__main__": | 
|  | 1197 | parser = argparse.ArgumentParser(description='Check integrity of a Runtime APEX.') | 
|  | 1198 |  | 
|  | 1199 | parser.add_argument('apex', help='apex file input') | 
|  | 1200 |  | 
|  | 1201 | parser.add_argument('--host', help='Check as host apex', action='store_true') | 
| Andreas Gampe | 0912395 | 2019-01-30 13:17:02 -0800 | [diff] [blame] | 1202 |  | 
| Roland Levillain | dd20d00 | 2019-07-19 16:09:47 +0100 | [diff] [blame] | 1203 | parser.add_argument('--flattened', help='Check as flattened (target) apex', action='store_true') | 
|  | 1204 |  | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1205 | parser.add_argument('--debug', help='Check as debug apex', action='store_true') | 
| Roland Levillain | 61f0716 | 2019-06-26 12:44:04 +0100 | [diff] [blame] | 1206 | parser.add_argument('--testing', help='Check as testing apex', action='store_true') | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1207 |  | 
| Andreas Gampe | b1d5567 | 2019-01-29 22:17:02 +0000 | [diff] [blame] | 1208 | parser.add_argument('--list', help='List all files', action='store_true') | 
|  | 1209 | parser.add_argument('--tree', help='Print directory tree', action='store_true') | 
| Roland Levillain | e91d787 | 2019-07-25 18:56:06 +0100 | [diff] [blame] | 1210 | parser.add_argument('--size', help='Print file sizes', action='store_true') | 
| Andreas Gampe | b1d5567 | 2019-01-29 22:17:02 +0000 | [diff] [blame] | 1211 |  | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1212 | parser.add_argument('--tmpdir', help='Directory for temp files') | 
|  | 1213 | parser.add_argument('--debugfs', help='Path to debugfs') | 
|  | 1214 |  | 
| Andreas Gampe | eb555b8 | 2019-01-30 14:47:49 -0800 | [diff] [blame] | 1215 | parser.add_argument('--bitness', help='Bitness to check, 32|64|multilib|auto', default='auto') | 
|  | 1216 |  | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1217 | if len(sys.argv) == 1: | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1218 | art_apex_test_default(parser) | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1219 | else: | 
|  | 1220 | args = parser.parse_args() | 
|  | 1221 |  | 
|  | 1222 | if args is None: | 
|  | 1223 | sys.exit(1) | 
|  | 1224 |  | 
| Luca Stefani | 4e91ee9 | 2019-03-06 15:08:16 +0100 | [diff] [blame] | 1225 | exit_code = art_apex_test_main(args) | 
| Andreas Gampe | 2c846cd | 2019-01-29 22:06:46 +0000 | [diff] [blame] | 1226 | sys.exit(exit_code) |