| Roland Levillain | 38a938e | 2018-09-21 10:55:51 +0100 | [diff] [blame] | 1 | #!/bin/bash | 
|  | 2 |  | 
|  | 3 | # Copyright (C) 2018 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 | # Run Android Runtime APEX tests. | 
|  | 19 |  | 
|  | 20 | function say { | 
|  | 21 | echo "$0: $*" | 
|  | 22 | } | 
|  | 23 |  | 
|  | 24 | function die { | 
|  | 25 | echo "$0: $*" | 
|  | 26 | exit 1 | 
|  | 27 | } | 
|  | 28 |  | 
|  | 29 | which guestmount >/dev/null && which guestunmount >/dev/null && which virt-filesystems >/dev/null \ | 
|  | 30 | || die "This script requires 'guestmount', 'guestunmount', | 
|  | 31 | and 'virt-filesystems' from libguestfs. On Debian-based systems, these tools | 
|  | 32 | can be installed with: | 
|  | 33 |  | 
|  | 34 | sudo apt-get install libguestfs-tools | 
|  | 35 | " | 
| Pete Bentley | f34e743 | 2018-12-11 18:12:25 +0000 | [diff] [blame^] | 36 | which tree > /dev/null || die "This script requires the 'tree' tool. | 
|  | 37 | On Debian-based systems, this can be installed with: | 
|  | 38 |  | 
|  | 39 | sudo apt-get install tree | 
|  | 40 | " | 
| Roland Levillain | 38a938e | 2018-09-21 10:55:51 +0100 | [diff] [blame] | 41 | [[ -n "$ANDROID_PRODUCT_OUT" ]] \ | 
|  | 42 | || die "You need to source and lunch before you can use this script." | 
|  | 43 |  | 
|  | 44 | # Fail early. | 
|  | 45 | set -e | 
|  | 46 |  | 
|  | 47 | build_apex_p=true | 
|  | 48 | list_image_files_p=false | 
|  | 49 |  | 
|  | 50 | function usage { | 
|  | 51 | cat <<EOF | 
|  | 52 | Usage: $0 [OPTION] | 
|  | 53 | Build (optional) and run tests on Android Runtime APEX package (on host). | 
|  | 54 |  | 
|  | 55 | -s, --skip-build    skip the build step | 
|  | 56 | -l, --list-files    list the contents of the ext4 image | 
|  | 57 | -h, --help          display this help and exit | 
|  | 58 |  | 
|  | 59 | EOF | 
|  | 60 | exit | 
|  | 61 | } | 
|  | 62 |  | 
|  | 63 | while [[ $# -gt 0 ]]; do | 
|  | 64 | case "$1" in | 
|  | 65 | (-s|--skip-build) build_apex_p=false;; | 
|  | 66 | (-l|--list-files) list_image_files_p=true;; | 
|  | 67 | (-h|--help) usage;; | 
|  | 68 | (*) die "Unknown option: '$1' | 
|  | 69 | Try '$0 --help' for more information.";; | 
|  | 70 | esac | 
|  | 71 | shift | 
|  | 72 | done | 
|  | 73 |  | 
|  | 74 | work_dir=$(mktemp -d) | 
|  | 75 | mount_point="$work_dir/image" | 
|  | 76 |  | 
| Roland Levillain | 38a938e | 2018-09-21 10:55:51 +0100 | [diff] [blame] | 77 | function check_binary { | 
|  | 78 | [[ -x "$mount_point/bin/$1" ]] || die "Cannot find binary '$1' in mounted image" | 
|  | 79 | } | 
|  | 80 |  | 
|  | 81 | function check_multilib_binary { | 
|  | 82 | # TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve | 
|  | 83 | # the precision of this test? | 
|  | 84 | [[ -x "$mount_point/bin/${1}32" ]] || [[ -x "$mount_point/bin/${1}64" ]] \ | 
|  | 85 | || die "Cannot find binary '$1' in mounted image" | 
|  | 86 | } | 
|  | 87 |  | 
|  | 88 | function check_binary_symlink { | 
|  | 89 | [[ -h "$mount_point/bin/$1" ]] || die "Cannot find symbolic link '$1' in mounted image" | 
|  | 90 | } | 
|  | 91 |  | 
|  | 92 | function check_library { | 
|  | 93 | # TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve | 
|  | 94 | # the precision of this test? | 
|  | 95 | [[ -f "$mount_point/lib/$1" ]] || [[ -f "$mount_point/lib64/$1" ]] \ | 
|  | 96 | || die "Cannot find library '$1' in mounted image" | 
|  | 97 | } | 
|  | 98 |  | 
| Alex Light | da948ce | 2018-12-06 17:05:41 +0000 | [diff] [blame] | 99 | function build_apex { | 
|  | 100 | if $build_apex_p; then | 
|  | 101 | say "Building package $1" && make "$1" || die "Cannot build $1" | 
|  | 102 | fi | 
|  | 103 | } | 
| Roland Levillain | 38a938e | 2018-09-21 10:55:51 +0100 | [diff] [blame] | 104 |  | 
| Alex Light | da948ce | 2018-12-06 17:05:41 +0000 | [diff] [blame] | 105 | function check_contents { | 
|  | 106 |  | 
|  | 107 | # Check that the mounted image contains a manifest. | 
|  | 108 | [[ -f "$mount_point/apex_manifest.json" ]] || die "no manifest" | 
|  | 109 |  | 
|  | 110 | # Check that the mounted image contains ART base binaries. | 
|  | 111 | check_multilib_binary dalvikvm | 
|  | 112 | # TODO: Does not work yet. | 
|  | 113 | : check_binary_symlink dalvikvm | 
|  | 114 | check_binary dex2oat | 
|  | 115 | check_binary dexoptanalyzer | 
|  | 116 | check_binary profman | 
|  | 117 |  | 
|  | 118 | # Check that the mounted image contains ART tools binaries. | 
|  | 119 | check_binary dexdiag | 
|  | 120 | check_binary dexdump | 
|  | 121 | check_binary dexlist | 
|  | 122 | # oatdump is only in device apex's due to build rules | 
|  | 123 | # check_binary oatdump | 
|  | 124 |  | 
|  | 125 | # Check that the mounted image contains ART debug binaries. | 
|  | 126 | check_binary dex2oatd | 
|  | 127 | check_binary dexoptanalyzerd | 
|  | 128 | check_binary profmand | 
|  | 129 |  | 
|  | 130 | # Check that the mounted image contains ART libraries. | 
|  | 131 | check_library libart-compiler.so | 
|  | 132 | check_library libart.so | 
|  | 133 | check_library libopenjdkjvm.so | 
|  | 134 | check_library libopenjdkjvmti.so | 
|  | 135 | check_library libadbconnection.so | 
|  | 136 | # TODO: Should we check for these libraries too, even if they are not explicitly | 
|  | 137 | # listed as dependencies in the Android Runtime APEX module rule? | 
|  | 138 | check_library libartbase.so | 
|  | 139 | check_library libart-dexlayout.so | 
|  | 140 | check_library libdexfile.so | 
|  | 141 | check_library libprofile.so | 
|  | 142 |  | 
|  | 143 | # Check that the mounted image contains ART debug libraries. | 
|  | 144 | check_library libartd-compiler.so | 
|  | 145 | check_library libartd.so | 
|  | 146 | check_library libopenjdkd.so | 
|  | 147 | check_library libopenjdkjvmd.so | 
|  | 148 | check_library libopenjdkjvmtid.so | 
|  | 149 | check_library libadbconnectiond.so | 
|  | 150 | # TODO: Should we check for these libraries too, even if they are not explicitly | 
|  | 151 | # listed as dependencies in the Android Runtime APEX module rule? | 
|  | 152 | check_library libdexfiled.so | 
|  | 153 | check_library libartbased.so | 
|  | 154 | check_library libartd-dexlayout.so | 
|  | 155 | check_library libprofiled.so | 
|  | 156 |  | 
|  | 157 | # TODO: Should we check for other libraries, such as: | 
|  | 158 | # | 
|  | 159 | #   libbacktrace.so | 
|  | 160 | #   libbase.so | 
|  | 161 | #   liblog.so | 
|  | 162 | #   libsigchain.so | 
|  | 163 | #   libtombstoned_client.so | 
|  | 164 | #   libunwindstack.so | 
|  | 165 | #   libvixl.so | 
|  | 166 | #   libvixld.so | 
|  | 167 | #   ... | 
|  | 168 | # | 
|  | 169 | # ? | 
|  | 170 | } | 
|  | 171 |  | 
|  | 172 |  | 
|  | 173 | # ***************************************** | 
|  | 174 | # * Testing for com.android.runtime.debug * | 
|  | 175 | # ***************************************** | 
|  | 176 |  | 
|  | 177 | # Garbage collection. | 
|  | 178 | function finish_device_debug { | 
|  | 179 | # Don't fail early during cleanup. | 
|  | 180 | set +e | 
|  | 181 | guestunmount "$mount_point" | 
|  | 182 | rm -rf "$work_dir" | 
|  | 183 | } | 
|  | 184 |  | 
|  | 185 | trap finish_device_debug EXIT | 
|  | 186 |  | 
|  | 187 | # TODO: Also exercise the Release Runtime APEX (`com.android.runtime.release`). | 
|  | 188 | apex_module="com.android.runtime.debug" | 
|  | 189 |  | 
|  | 190 | # Build the Android Runtime APEX package (optional). | 
|  | 191 | build_apex $apex_module | 
|  | 192 |  | 
|  | 193 | system_apexdir="$ANDROID_PRODUCT_OUT/system/apex" | 
|  | 194 | apex_package="$system_apexdir/$apex_module.apex" | 
|  | 195 |  | 
|  | 196 | say "Extracting and mounting image" | 
|  | 197 |  | 
|  | 198 | # Extract the payload from the Android Runtime APEX. | 
|  | 199 | image_filename="apex_payload.img" | 
|  | 200 | unzip -q "$apex_package" "$image_filename" -d "$work_dir" | 
|  | 201 | mkdir "$mount_point" | 
|  | 202 | image_file="$work_dir/$image_filename" | 
|  | 203 |  | 
|  | 204 | # Check filesystems in the image. | 
|  | 205 | image_filesystems="$work_dir/image_filesystems" | 
|  | 206 | virt-filesystems -a "$image_file" >"$image_filesystems" | 
|  | 207 | # We expect a single partition (/dev/sda) in the image. | 
|  | 208 | partition="/dev/sda" | 
|  | 209 | echo "$partition" | cmp "$image_filesystems" - | 
|  | 210 |  | 
|  | 211 | # Mount the image from the Android Runtime APEX. | 
|  | 212 | guestmount -a "$image_file" -m "$partition" "$mount_point" | 
|  | 213 |  | 
|  | 214 | # List the contents of the mounted image (optional). | 
|  | 215 | $list_image_files_p && say "Listing image files" && ls -ld "$mount_point" && tree -ap "$mount_point" | 
|  | 216 |  | 
|  | 217 | say "Running tests" | 
|  | 218 |  | 
|  | 219 | check_contents | 
|  | 220 |  | 
|  | 221 | # Check for files pulled in from device-only oatdump. | 
| Roland Levillain | 38a938e | 2018-09-21 10:55:51 +0100 | [diff] [blame] | 222 | check_binary oatdump | 
| Roland Levillain | 38a938e | 2018-09-21 10:55:51 +0100 | [diff] [blame] | 223 | check_library libart-disassembler.so | 
| Roland Levillain | 38a938e | 2018-09-21 10:55:51 +0100 | [diff] [blame] | 224 |  | 
| Alex Light | da948ce | 2018-12-06 17:05:41 +0000 | [diff] [blame] | 225 | # Cleanup | 
|  | 226 | trap - EXIT | 
|  | 227 | guestunmount "$mount_point" | 
|  | 228 | rm -rf "$work_dir" | 
| Roland Levillain | 38a938e | 2018-09-21 10:55:51 +0100 | [diff] [blame] | 229 |  | 
| Alex Light | da948ce | 2018-12-06 17:05:41 +0000 | [diff] [blame] | 230 | say "$apex_module Tests passed" | 
|  | 231 |  | 
|  | 232 | # **************************************** | 
|  | 233 | # * Testing for com.android.runtime.host * | 
|  | 234 | # **************************************** | 
|  | 235 |  | 
|  | 236 | # Garbage collection. | 
|  | 237 | function finish_host { | 
|  | 238 | # Don't fail early during cleanup. | 
|  | 239 | set +e | 
|  | 240 | rm -rf "$work_dir" | 
|  | 241 | } | 
|  | 242 |  | 
|  | 243 | work_dir=$(mktemp -d) | 
|  | 244 | mount_point="$work_dir/zip" | 
|  | 245 |  | 
|  | 246 | trap finish_host EXIT | 
|  | 247 |  | 
|  | 248 | apex_module="com.android.runtime.host" | 
|  | 249 |  | 
|  | 250 | # Build the Android Runtime APEX package (optional). | 
|  | 251 | build_apex $apex_module | 
|  | 252 |  | 
|  | 253 | system_apexdir="$ANDROID_HOST_OUT/apex" | 
|  | 254 | apex_package="$system_apexdir/$apex_module.zipapex" | 
|  | 255 |  | 
|  | 256 | say "Extracting payload" | 
|  | 257 |  | 
|  | 258 | # Extract the payload from the Android Runtime APEX. | 
|  | 259 | image_filename="apex_payload.zip" | 
|  | 260 | unzip -q "$apex_package" "$image_filename" -d "$work_dir" | 
|  | 261 | mkdir "$mount_point" | 
|  | 262 | image_file="$work_dir/$image_filename" | 
|  | 263 |  | 
|  | 264 | # Unzipping the payload | 
|  | 265 | unzip -q "$image_file" -d "$mount_point" | 
|  | 266 |  | 
|  | 267 | say "Running tests" | 
|  | 268 |  | 
|  | 269 | check_contents | 
|  | 270 |  | 
|  | 271 | say "$apex_module Tests passed" | 
| Roland Levillain | 38a938e | 2018-09-21 10:55:51 +0100 | [diff] [blame] | 272 |  | 
|  | 273 | say "Tests passed" |