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 ART APEX tests.
19
20SCRIPT_DIR=$(dirname $0)
21
22# Status of whole test script.
23exit_status=0
24# Status of current test suite.
25test_status=0
26
27function say {
28  echo "$0: $*"
29}
30
31function die {
32  echo "$0: $*"
33  exit 1
34}
35
36function setup_die {
37  die "You need to source and lunch before you can use this script."
38}
39
40[[ -n "$ANDROID_BUILD_TOP" ]] || setup_die
41[[ -n "$ANDROID_PRODUCT_OUT" ]] || setup_die
42[[ -n "$ANDROID_HOST_OUT" ]] || setup_die
43
44flattened_apex_p=$($ANDROID_BUILD_TOP/build/soong/soong_ui.bash --dumpvar-mode TARGET_FLATTEN_APEX)\
45  || setup_die
46
47# Switch the build system to unbundled mode in the reduced manifest branch.
48# TODO(b/159109002): Clean this up.
49if [ ! -d $ANDROID_BUILD_TOP/frameworks/base ]; then
50  export TARGET_BUILD_UNBUNDLED=true
51fi
52
53have_debugfs_p=false
54if $flattened_apex_p; then :; else
55  if [ ! -e "$ANDROID_HOST_OUT/bin/debugfs" ] ; then
56    say "Could not find debugfs, building now."
57    build/soong/soong_ui.bash --make-mode debugfs-host || die "Cannot build debugfs"
58  fi
59  have_debugfs_p=true
60fi
61
62# Fail early.
63set -e
64
65build_apex_p=true
66list_image_files_p=false
67print_image_tree_p=false
68print_file_sizes_p=false
69
70function usage {
71  cat <<EOF
72Usage: $0 [OPTION]
73Build (optional) and run tests on ART APEX package (on host).
74
75  -B, --skip-build    skip the build step
76  -l, --list-files    list the contents of the ext4 image (\`find\`-like style)
77  -t, --print-tree    list the contents of the ext4 image (\`tree\`-like style)
78  -s, --print-sizes   print the size in bytes of each file when listing contents
79  -h, --help          display this help and exit
80
81EOF
82  exit
83}
84
85while [[ $# -gt 0 ]]; do
86  case "$1" in
87    (-B|--skip-build)  build_apex_p=false;;
88    (-l|--list-files)  list_image_files_p=true;;
89    (-t|--print-tree)  print_image_tree_p=true;;
90    (-s|--print-sizes) print_file_sizes_p=true;;
91    (-h|--help) usage;;
92    (*) die "Unknown option: '$1'
93Try '$0 --help' for more information.";;
94  esac
95  shift
96done
97
98# build_apex APEX_MODULES
99# -----------------------
100# Build APEX packages APEX_MODULES.
101function build_apex {
102  if $build_apex_p; then
103    say "Building $@" && build/soong/soong_ui.bash --make-mode "$@" || die "Cannot build $@"
104  fi
105}
106
107# maybe_list_apex_contents_apex APEX TMPDIR [other]
108function maybe_list_apex_contents_apex {
109  local print_options=()
110  if $print_file_sizes_p; then
111    print_options+=(--size)
112  fi
113
114  # List the contents of the apex in list form.
115  if $list_image_files_p; then
116    say "Listing image files"
117    $SCRIPT_DIR/art_apex_test.py --list ${print_options[@]} $@
118  fi
119
120  # List the contents of the apex in tree form.
121  if $print_image_tree_p; then
122    say "Printing image tree"
123    $SCRIPT_DIR/art_apex_test.py --tree ${print_options[@]} $@
124  fi
125}
126
127function fail_check {
128  echo "$0: FAILED: $*"
129  test_status=1
130  exit_status=1
131}
132
133# Test all modules, if possible.
134
135apex_modules=(
136  "com.android.art.release"
137  "com.android.art.debug"
138  "com.android.art.testing"
139)
140if [[ "$HOST_PREFER_32_BIT" = true ]]; then
141  say "Skipping com.android.art.host, as \`HOST_PREFER_32_BIT\` equals \`true\`"
142else
143  apex_modules+=("com.android.art.host")
144fi
145
146# Build the APEX packages (optional).
147build_apex ${apex_modules[@]}
148
149# Clean-up.
150function cleanup {
151  rm -rf "$work_dir"
152}
153
154# Garbage collection.
155function finish {
156  # Don't fail early during cleanup.
157  set +e
158  cleanup
159}
160
161for apex_module in ${apex_modules[@]}; do
162  test_status=0
163  say "Checking APEX package $apex_module"
164  work_dir=$(mktemp -d)
165  trap finish EXIT
166
167  art_apex_test_args="--tmpdir $work_dir"
168  test_only_args=""
169  if [[ $apex_module = *.host ]]; then
170    apex_path="$ANDROID_HOST_OUT/apex/${apex_module}.zipapex"
171    art_apex_test_args="$art_apex_test_args --host"
172    test_only_args="--flavor debug"
173  else
174    if $flattened_apex_p; then
175      apex_path="$ANDROID_PRODUCT_OUT/system/apex/${apex_module}"
176      art_apex_test_args="$art_apex_test_args --flattened"
177    else
178      apex_path="$ANDROID_PRODUCT_OUT/system/apex/${apex_module}.apex"
179    fi
180    if $have_debugfs_p; then
181      art_apex_test_args="$art_apex_test_args --debugfs $ANDROID_HOST_OUT/bin/debugfs"
182    fi
183    case $apex_module in
184      (*.release) test_only_args="--flavor release";;
185      (*.debug)   test_only_args="--flavor debug";;
186      (*.testing) test_only_args="--flavor testing";;
187    esac
188  fi
189  say "APEX package path: $apex_path"
190
191  # List the contents of the APEX image (optional).
192  maybe_list_apex_contents_apex $art_apex_test_args $apex_path
193
194  # Run tests on APEX package.
195  $SCRIPT_DIR/art_apex_test.py $art_apex_test_args $test_only_args $apex_path \
196    || fail_check "Checks failed on $apex_module"
197
198  # Clean up.
199  trap - EXIT
200  cleanup
201
202  [[ "$test_status" = 0 ]] && say "$apex_module tests passed"
203  echo
204done
205
206[[ "$exit_status" = 0 ]] && say "All ART APEX tests passed"
207
208exit $exit_status
209