Support a chroot-based environment in ART Buildbot's target harness.
When ART_TEST_CHROOT is defined, instead of having the ART Buildbot
install ART into a local path (set with ART_TEST_ANDROID_ROOT) and
hijack the linker (using CUSTOM_TARGET_LINKER), prepare and use a
chroot environment (set with ART_TEST_CHROOT).
In this scenario, ART and its dependencies can be built and used
normally (in particular, when building from the master-art Android
manifest) and still be executed as a standalone runtime outside of
the device's /system path, for testing purposes.
Test: Have the ART Buildbot build and run ART on device with chroot.
Bug: 34729697
Bug: 68125496
Change-Id: I08f1acd0d2813584f703fedb84e69df954cbdbda
diff --git a/tools/buildbot-build.sh b/tools/buildbot-build.sh
index 31bddd5..10eb936 100755
--- a/tools/buildbot-build.sh
+++ b/tools/buildbot-build.sh
@@ -83,6 +83,10 @@
make_command+=" debuggerd su"
make_command+=" ${out_dir}/host/linux-x86/bin/adb libstdc++ "
make_command+=" ${out_dir}/target/product/${TARGET_PRODUCT}/system/etc/public.libraries.txt"
+ if [[ -n "$ART_TEST_CHROOT" ]]; then
+ # These targets are needed for the chroot environment.
+ make_command+=" crash_dump event-log-tags"
+ fi
mode_suffix="-target"
fi
diff --git a/tools/cleanup-buildbot-device.sh b/tools/cleanup-buildbot-device.sh
new file mode 100755
index 0000000..53072ae
--- /dev/null
+++ b/tools/cleanup-buildbot-device.sh
@@ -0,0 +1,64 @@
+#!/bin/bash
+#
+# Copyright (C) 2017 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.
+
+green='\033[0;32m'
+nc='\033[0m'
+
+# Setup as root, as device cleanup requires it.
+adb root
+adb wait-for-device
+
+if [[ -n "$ART_TEST_CHROOT" ]]; then
+ # Check that ART_TEST_CHROOT is correctly defined.
+ if [[ "x$ART_TEST_CHROOT" != x/* ]]; then
+ echo "$ART_TEST_CHROOT is not an absolute path"
+ exit 1
+ fi
+
+ echo -e "${green}Clean up /system in chroot${nc}"
+ # Remove all files under /system except the potential property_contexts file.
+ #
+ # The current ART Buildbot set-up runs the "setup device" step
+ # (performed by script tools/setup-buildbot-device.sh) before the
+ # "device cleanup" step (implemented by this script). As
+ # property_contexts file aliases are created during the former step,
+ # we need this exception to prevent the property_contexts file under
+ # /system in the chroot from being removed by the latter step.
+ #
+ # TODO: Reorder ART Buildbot steps so that "device cleanup" happens
+ # before "setup device" and remove this special case.
+ #
+ # TODO: Also consider adding a "tear down device" step on the ART
+ # Buildbot (at the very end of a build) undoing (some of) the work
+ # done in the "device setup" step.
+ adb shell find "$ART_TEST_CHROOT/system" \
+ ! -path "$ART_TEST_CHROOT/system/etc/selinux/plat_property_contexts" \
+ ! -type d \
+ -exec rm -f \{\} +
+
+ echo -e "${green}Clean up some subdirs in /data in chroot${nc}"
+ adb shell rm -rf \
+ "$ART_TEST_CHROOT/data/local/tmp/*" \
+ "$ART_TEST_CHROOT/data/art-test" \
+ "$ART_TEST_CHROOT/data/nativetest" \
+ "$ART_TEST_CHROOT/data/nativetest64" \
+ "$ART_TEST_CHROOT/data/run-test" \
+ "$ART_TEST_CHROOT/data/dalvik-cache/*" \
+ "$ART_TEST_CHROOT/data/misc/trace/*"
+else
+ adb shell rm -rf \
+ /data/local/tmp /data/art-test /data/nativetest /data/nativetest64 '/data/misc/trace/*'
+fi
diff --git a/tools/run-jdwp-tests.sh b/tools/run-jdwp-tests.sh
index 56d412b..d376cad 100755
--- a/tools/run-jdwp-tests.sh
+++ b/tools/run-jdwp-tests.sh
@@ -68,6 +68,8 @@
mode="target"
# Use JIT compiling by default.
use_jit=true
+# Don't use chroot by default.
+use_chroot=false
variant_cmdline_parameter="--variant=X32"
dump_command="/bin/true"
# Timeout of JDWP test in ms.
@@ -110,6 +112,15 @@
# We don't care about jit with the RI
use_jit=false
shift
+ elif [[ "$1" == "--chroot" ]]; then
+ use_chroot=true
+ # Adjust settings for chroot environment.
+ art="/system/bin/art"
+ art_debugee="sh /system/bin/art"
+ vm_command="--vm-command=$art"
+ device_dir="--device-dir=/tmp"
+ # Shift the "--chroot" flag and its argument.
+ shift 2
elif [[ $1 == --test-timeout-ms ]]; then
# Remove the --test-timeout-ms from the arguments.
args=${args/$1}
@@ -191,6 +202,12 @@
fi
done
+if $use_chroot && [[ $mode == "host" ]]; then
+ # Chroot-based testing is not supported on host.
+ echo "Cannot use --chroot with --mode=host"
+ exit 1
+fi
+
if [[ $has_gdb = "yes" ]]; then
if [[ $explicit_debug = "no" ]]; then
debug="yes"
diff --git a/tools/run-libcore-tests.sh b/tools/run-libcore-tests.sh
index 26b5c0a..3537c1b 100755
--- a/tools/run-libcore-tests.sh
+++ b/tools/run-libcore-tests.sh
@@ -104,10 +104,14 @@
gcstress=false
debug=false
+# Don't use device mode by default.
+device_mode=false
+# Don't use chroot by default.
+use_chroot=false
+
while true; do
if [[ "$1" == "--mode=device" ]]; then
- vogar_args="$vogar_args --device-dir=/data/local/tmp"
- vogar_args="$vogar_args --vm-command=$android_root/bin/art"
+ device_mode=true
vogar_args="$vogar_args --vm-arg -Ximage:/data/art-test/core.art"
shift
elif [[ "$1" == "--mode=host" ]]; then
@@ -131,6 +135,10 @@
elif [[ "$1" == "-Xgc:gcstress" ]]; then
gcstress=true
shift
+ elif [[ "$1" == "--chroot" ]]; then
+ use_chroot=true
+ # Shift the "--chroot" flag and its argument.
+ shift 2
elif [[ "$1" == "" ]]; then
break
else
@@ -138,6 +146,23 @@
fi
done
+if $device_mode; then
+ if $use_chroot; then
+ vogar_args="$vogar_args --device-dir=/tmp"
+ vogar_args="$vogar_args --vm-command=/system/bin/art"
+ else
+ vogar_args="$vogar_args --device-dir=/data/local/tmp"
+ vogar_args="$vogar_args --vm-command=$android_root/bin/art"
+ fi
+else
+ # Host mode.
+ if $use_chroot; then
+ # Chroot-based testing is not supported on host.
+ echo "Cannot use --chroot with --mode=host"
+ exit 1
+ fi
+fi
+
# Increase the timeout, as vogar cannot set individual test
# timeout when being asked to run packages, and some tests go above
# the default timeout.
diff --git a/tools/setup-buildbot-device.sh b/tools/setup-buildbot-device.sh
index 5ce7f52..f71d973 100755
--- a/tools/setup-buildbot-device.sh
+++ b/tools/setup-buildbot-device.sh
@@ -17,8 +17,7 @@
green='\033[0;32m'
nc='\033[0m'
-# Setup as root, as the next buildbot step (device cleanup) requires it.
-# This is also required to set the date, if needed.
+# Setup as root, as some actions performed here (e.g. setting the date) requires it.
adb root
adb wait-for-device
@@ -100,3 +99,58 @@
processes=$(adb shell "ps" | grep dalvikvm | awk '{print $2}')
for i in $processes; do adb shell kill -9 $i; done
fi
+
+if [[ -n "$ART_TEST_CHROOT" ]]; then
+ # Prepare the chroot dir.
+ echo -e "${green}Prepare the chroot dir in $ART_TEST_CHROOT${nc}"
+
+ # Check that ART_TEST_CHROOT is correctly defined.
+ [[ "x$ART_TEST_CHROOT" = x/* ]] || { echo "$ART_TEST_CHROOT is not an absolute path"; exit 1; }
+
+ # Create chroot.
+ adb shell mkdir -p "$ART_TEST_CHROOT"
+
+ # Provide property_contexts file(s) in chroot.
+ # This is required to have Android system properties work from the chroot.
+ # Notes:
+ # - In Android N, only '/property_contexts' is expected.
+ # - In Android O, property_context files are expected under /system and /vendor.
+ # (See bionic/libc/bionic/system_properties.cpp for more information.)
+ property_context_files="/property_contexts \
+ /system/etc/selinux/plat_property_contexts \
+ /vendor/etc/selinux/nonplat_property_context \
+ /plat_property_contexts \
+ /nonplat_property_contexts"
+ for f in $property_context_files; do
+ adb shell test -f "$f" \
+ "&&" mkdir -p "$ART_TEST_CHROOT$(dirname $f)" \
+ "&&" cp -f "$f" "$ART_TEST_CHROOT$f"
+ done
+
+ # Create directories required for ART testing in chroot.
+ adb shell mkdir -p "$ART_TEST_CHROOT/tmp"
+ adb shell mkdir -p "$ART_TEST_CHROOT/data/dalvik-cache"
+ adb shell mkdir -p "$ART_TEST_CHROOT/data/local/tmp"
+
+ # Populate /etc in chroot with required files.
+ adb shell mkdir -p "$ART_TEST_CHROOT/system/etc"
+ adb shell "cd $ART_TEST_CHROOT && ln -s system/etc etc"
+
+ # Provide /proc in chroot.
+ adb shell mkdir -p "$ART_TEST_CHROOT/proc"
+ adb shell mount | grep -q "^proc on $ART_TEST_CHROOT/proc type proc " \
+ || adb shell mount -t proc proc "$ART_TEST_CHROOT/proc"
+
+ # Provide /sys in chroot.
+ adb shell mkdir -p "$ART_TEST_CHROOT/sys"
+ adb shell mount | grep -q "^sysfs on $ART_TEST_CHROOT/sys type sysfs " \
+ || adb shell mount -t sysfs sysfs "$ART_TEST_CHROOT/sys"
+ # Provide /sys/kernel/debug in chroot.
+ adb shell mount | grep -q "^debugfs on $ART_TEST_CHROOT/sys/kernel/debug type debugfs " \
+ || adb shell mount -t debugfs debugfs "$ART_TEST_CHROOT/sys/kernel/debug"
+
+ # Provide /dev in chroot.
+ adb shell mkdir -p "$ART_TEST_CHROOT/dev"
+ adb shell mount | grep -q "^tmpfs on $ART_TEST_CHROOT/dev type tmpfs " \
+ || adb shell mount -o bind /dev "$ART_TEST_CHROOT/dev"
+fi