blob: 8295a547afc3fe16d3857c52863ca088d2c586b6 [file] [log] [blame]
#!/bin/bash
# Copyright (C) 2018 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Run Android Runtime APEX tests.
# Status of whole test script.
exit_status=0
# Status of current test suite.
test_status=0
function say {
echo "$0: $*"
}
function die {
echo "$0: $*"
exit 1
}
which guestmount >/dev/null && which guestunmount >/dev/null && which virt-filesystems >/dev/null \
|| die "This script requires 'guestmount', 'guestunmount',
and 'virt-filesystems' from libguestfs. On Debian-based systems, these tools
can be installed with:
sudo apt-get install libguestfs-tools
"
[[ -n "$ANDROID_PRODUCT_OUT" ]] \
|| die "You need to source and lunch before you can use this script."
# Fail early.
set -e
build_apex_p=true
list_image_files_p=false
print_image_tree_p=false
function usage {
cat <<EOF
Usage: $0 [OPTION]
Build (optional) and run tests on Android Runtime APEX package (on host).
-s, --skip-build skip the build step
-l, --list-files list the contents of the ext4 image using `find`
-t, --print-tree list the contents of the ext4 image using `tree`
-h, --help display this help and exit
EOF
exit
}
while [[ $# -gt 0 ]]; do
case "$1" in
(-s|--skip-build) build_apex_p=false;;
(-l|--list-files) list_image_files_p=true;;
(-t|--print-tree) print_image_tree_p=true;;
(-h|--help) usage;;
(*) die "Unknown option: '$1'
Try '$0 --help' for more information.";;
esac
shift
done
if $print_image_tree_p; then
which tree >/dev/null || die "This script requires the 'tree' tool.
On Debian-based systems, this can be installed with:
sudo apt-get install tree
"
fi
# build_apex APEX_MODULE
# ----------------------
# Build APEX package APEX_MODULE.
function build_apex {
if $build_apex_p; then
local apex_module=$1
say "Building package $apex_module" && make "$apex_module" || die "Cannot build $apex_module"
fi
}
# maybe_list_apex_contents MOUNT_POINT
# ------------------------------------
# If any listing/printing option was used, honor them and display the contents
# of the APEX payload at MOUNT_POINT.
function maybe_list_apex_contents {
local mount_point=$1
# List the contents of the mounted image using `find` (optional).
if $list_image_files_p; then
say "Listing image files" && find "$mount_point"
fi
# List the contents of the mounted image using `tree` (optional).
if $print_image_tree_p; then
say "Printing image tree" && ls -ld "$mount_point" && tree -aph --du "$mount_point"
fi
}
function fail_check {
echo "$0: FAILED: $*"
test_status=1
exit_status=1
}
function check_file {
[[ -f "$mount_point/$1" ]] || fail_check "Cannot find file '$1' in mounted image"
}
function check_binary {
[[ -x "$mount_point/bin/$1" ]] || fail_check "Cannot find binary '$1' in mounted image"
}
function check_multilib_binary {
# TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve
# the precision of this test?
if ! [[ -L "$mount_point/bin/${1}" ]]; then
fail_check "Cannot find symlink for multilib binary '$1' in mounted image"
fi
[[ -x "$mount_point/bin/${1}32" ]] || [[ -x "$mount_point/bin/${1}64" ]] \
|| fail_check "Cannot find binary '$1' in mounted image"
}
function check_binary_symlink {
[[ -h "$mount_point/bin/$1" ]] || fail_check "Cannot find symbolic link '$1' in mounted image"
}
function check_library {
# TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve
# the precision of this test?
[[ -f "$mount_point/lib/$1" ]] || [[ -f "$mount_point/lib64/$1" ]] \
|| fail_check "Cannot find library '$1' in mounted image"
}
function check_no_library {
# TODO: Use $TARGET_ARCH (e.g. check whether it is "arm" or "arm64") to improve
# the precision of this test?
[[ ! -f "$mount_point/lib/$1" && ! -f "$mount_point/lib64/$1" ]] \
|| die "Found unwanted library '$1' in mounted image"
}
function check_java_library {
[[ -x "$mount_point/javalib/$1" ]] || fail_check "Cannot find java library '$1' in mounted image"
}
# Check contents of APEX payload located in `$mount_point`.
function check_release_contents {
# Check that the mounted image contains an APEX manifest.
check_file apex_manifest.json
# Check that the mounted image contains ART base binaries.
check_multilib_binary dalvikvm
# TODO: Does not work yet (b/119942078).
: check_binary_symlink dalvikvm
check_binary dex2oat
check_binary dexoptanalyzer
check_binary profman
# oatdump is only in device apex's due to build rules
# TODO: Check for it when it is also built for host.
: check_binary oatdump
# Check that the mounted image contains Android Runtime libraries.
check_library libart-compiler.so
check_library libart-dexlayout.so
check_library libart.so
check_library libartbase.so
check_library libartpalette.so
check_no_library libartpalette-system.so
check_library libdexfile.so
check_library libopenjdkjvm.so
check_library libopenjdkjvmti.so
check_library libprofile.so
# Check that the mounted image contains Android Core libraries.
check_library "libexpat${host_suffix}.so"
check_library libjavacore.so
check_library libjavacrypto.so
check_library libopenjdk.so
check_library "libz${host_suffix}.so"
check_library libziparchive.so
# Check that the mounted image contains additional required libraries.
check_library libadbconnection.so
# TODO: Should we check for other libraries, such as:
#
# libbacktrace.so
# libbase.so
# liblog.so
# libsigchain.so
# libtombstoned_client.so
# libunwindstack.so
# libvixl.so
# libvixld.so
# ...
#
# ?
# TODO: Enable for host
if [ $1 != "com.android.runtime.host" ]; then
check_java_library core-oj.jar
check_java_library core-libart.jar
check_java_library okhttp.jar
check_java_library bouncycastle.jar
check_java_library apache-xml.jar
fi
}
# Check debug contents of APEX payload located in `$mount_point`.
function check_debug_contents {
# Check that the mounted image contains ART tools binaries.
check_binary dexdiag
check_binary dexdump
check_binary dexlist
# Check that the mounted image contains ART debug binaries.
check_binary dex2oatd
check_binary dexoptanalyzerd
check_binary profmand
# Check that the mounted image contains Android Runtime debug libraries.
check_library libartbased.so
check_library libartd-compiler.so
check_library libartd-dexlayout.so
check_library libartd.so
check_library libdexfiled.so
check_library libopenjdkjvmd.so
check_library libopenjdkjvmtid.so
check_library libprofiled.so
# Check that the mounted image contains Android Core debug libraries.
check_library libopenjdkd.so
# Check that the mounted image contains additional required debug libraries.
check_library libadbconnectiond.so
}
# Testing target (device) APEX packages.
# ======================================
# Clean-up.
function cleanup_target {
guestunmount "$mount_point"
rm -rf "$work_dir"
}
# Garbage collection.
function finish_target {
# Don't fail early during cleanup.
set +e
cleanup_target
}
# setup_target_apex APEX_MODULE MOUNT_POINT
# -----------------------------------------
# Extract image from target APEX_MODULE and mount it in MOUNT_POINT.
function setup_target_apex {
local apex_module=$1
local mount_point=$2
local system_apexdir="$ANDROID_PRODUCT_OUT/system/apex"
local apex_package="$system_apexdir/$apex_module.apex"
say "Extracting and mounting image"
# Extract the payload from the Android Runtime APEX.
local image_filename="apex_payload.img"
unzip -q "$apex_package" "$image_filename" -d "$work_dir"
mkdir "$mount_point"
local image_file="$work_dir/$image_filename"
# Check filesystems in the image.
local image_filesystems="$work_dir/image_filesystems"
virt-filesystems -a "$image_file" >"$image_filesystems"
# We expect a single partition (/dev/sda) in the image.
local partition="/dev/sda"
echo "$partition" | cmp "$image_filesystems" -
# Mount the image from the Android Runtime APEX.
guestmount -a "$image_file" -m "$partition" --ro "$mount_point"
}
# Testing release APEX package (com.android.runtime.release).
# -----------------------------------------------------------
apex_module="com.android.runtime.release"
test_status=0
say "Processing APEX package $apex_module"
work_dir=$(mktemp -d)
mount_point="$work_dir/image"
host_suffix=""
trap finish_target EXIT
# Build the APEX package (optional).
build_apex "$apex_module"
# Set up APEX package.
setup_target_apex "$apex_module" "$mount_point"
# List the contents of the APEX image (optional).
maybe_list_apex_contents "$mount_point"
# Run tests on APEX package.
say "Checking APEX package $apex_module"
check_release_contents "$apex_module"
# Clean up.
trap - EXIT
cleanup_target
[[ "$test_status" = 0 ]] && say "$apex_module tests passed"
echo
# Testing debug APEX package (com.android.runtime.debug).
# -------------------------------------------------------
apex_module="com.android.runtime.debug"
test_status=0
say "Processing APEX package $apex_module"
work_dir=$(mktemp -d)
mount_point="$work_dir/image"
host_suffix=""
trap finish_target EXIT
# Build the APEX package (optional).
build_apex "$apex_module"
# Set up APEX package.
setup_target_apex "$apex_module" "$mount_point"
# List the contents of the APEX image (optional).
maybe_list_apex_contents "$mount_point"
# Run tests on APEX package.
say "Checking APEX package $apex_module"
check_release_contents "$apex_module"
check_debug_contents
# Check for files pulled in from debug target-only oatdump.
check_binary oatdump
check_library libart-disassembler.so
# Clean up.
trap - EXIT
cleanup_target
[[ "$test_status" = 0 ]] && say "$apex_module tests passed"
echo
# Testing host APEX package (com.android.runtime.host).
# =====================================================
# Clean-up.
function cleanup_host {
rm -rf "$work_dir"
}
# Garbage collection.
function finish_host {
# Don't fail early during cleanup.
set +e
cleanup_host
}
# setup_host_apex APEX_MODULE MOUNT_POINT
# ---------------------------------------
# Extract Zip file from host APEX_MODULE and extract it in MOUNT_POINT.
function setup_host_apex {
local apex_module=$1
local mount_point=$2
local system_apexdir="$ANDROID_HOST_OUT/apex"
local apex_package="$system_apexdir/$apex_module.zipapex"
say "Extracting payload"
# Extract the payload from the Android Runtime APEX.
local image_filename="apex_payload.zip"
unzip -q "$apex_package" "$image_filename" -d "$work_dir"
mkdir "$mount_point"
local image_file="$work_dir/$image_filename"
# Unzipping the payload
unzip -q "$image_file" -d "$mount_point"
}
apex_module="com.android.runtime.host"
test_status=0
say "Processing APEX package $apex_module"
work_dir=$(mktemp -d)
mount_point="$work_dir/zip"
host_suffix="-host"
trap finish_host EXIT
# Build the APEX package (optional).
build_apex "$apex_module"
# Set up APEX package.
setup_host_apex "$apex_module" "$mount_point"
# List the contents of the APEX image (optional).
maybe_list_apex_contents "$mount_point"
# Run tests on APEX package.
say "Checking APEX package $apex_module"
check_release_contents "$apex_module"
check_debug_contents
# Clean up.
trap - EXIT
cleanup_host
[[ "$test_status" = 0 ]] && say "$apex_module tests passed"
[[ "$exit_status" = 0 ]] && say "All Android Runtime APEX tests passed"
exit $exit_status