Support ART on-device testing in a chroot environment.

This change updates the ART test rules and scripts to allow
installation and ART testing in a chroot directory on device.

All existing ART testing is supported:
- ART gtests (with and without Valgrind).
- ART run-tests.
- libcore tests (with companion CL in external/vogar).
- JDWP tests (with companion CL in external/vogar).

Test: Run ART tests (gtest, run-tests, libcore tests, JDWP tests) in chroot
Bug: 34729697
Bug: 68125496
Change-Id: I398e9bafee61eccd98d827ab8d9b8f6395aaa853
diff --git a/test/run-test b/test/run-test
index 5f85b08..be0a88d 100755
--- a/test/run-test
+++ b/test/run-test
@@ -121,6 +121,8 @@
   export HIDDENAPI="${ANDROID_HOST_OUT}/bin/hiddenapi"
 fi
 
+chroot=
+
 info="info.txt"
 build="build"
 run="run"
@@ -380,6 +382,16 @@
             break
         fi
         shift
+    elif [ "x$1" = "x--chroot" ]; then
+        shift
+        if [ "x$1" = "x" ]; then
+            echo "$0 missing argument to --chroot" 1>&2
+            usage="yes"
+            break
+        fi
+        chroot="$1"
+        run_args="${run_args} --chroot $1"
+        shift
     elif [ "x$1" = "x--android-root" ]; then
         shift
         if [ "x$1" = "x" ]; then
@@ -449,6 +461,9 @@
     fi
 done
 
+# The DEX_LOCATION with the chroot prefix, if any.
+chroot_dex_location="$chroot$DEX_LOCATION"
+
 run_args="${run_args} ${image_args}"
 # Allocate file descriptor real_stderr and redirect it to the shell's error
 # output (fd 2).
@@ -476,7 +491,7 @@
 # tmp_dir may be relative, resolve.
 #
 # Cannot use realpath, as it does not exist on Mac.
-# Cannot us a simple "cd", as the path might not be created yet.
+# Cannot use a simple "cd", as the path might not be created yet.
 # Cannot use readlink -m, as it does not exist on Mac.
 # Fallback to nuclear option:
 noncanonical_tmp_dir=$tmp_dir
@@ -550,7 +565,13 @@
     if [ "$runtime" = "jvm" ]; then
         if [ "$prebuild_mode" = "yes" ]; then
             err_echo "--prebuild with --jvm is unsupported"
-            exit 1;
+            exit 1
+        fi
+    else
+        # ART/Dalvik host mode.
+        if [ -n "$chroot" ]; then
+            err_echo "--chroot with --host is unsupported"
+            exit 1
         fi
     fi
 fi
@@ -628,6 +649,12 @@
     usage="yes"
 fi
 
+# TODO: Chroot-based bisection search is not supported yet (see below); implement it.
+if [ "$bisection_search" = "yes" -a -n "$chroot" ]; then
+  err_echo "--chroot with --bisection-search is unsupported"
+  exit 1
+fi
+
 if [ "$usage" = "no" ]; then
     if [ "x$1" = "x" -o "x$1" = "x-" ]; then
         test_dir=`basename "$oldwd"`
@@ -732,6 +759,7 @@
         echo "                          Run with jvmti method redefinition stress testing"
         echo "    --always-clean        Delete the test files even if the test fails."
         echo "    --never-clean         Keep the test files even if the test succeeds."
+        echo "    --chroot [newroot]    Run with root directory set to newroot."
         echo "    --android-root [path] The path on target for the android root. (/system by default)."
         echo "    --dex2oat-swap        Use a dex2oat swap file."
         echo "    --instruction-set-features [string]"
@@ -866,7 +894,7 @@
         if [ "$run_exit" = "0" ]; then
             if [ "$run_checker" = "yes" ]; then
                 if [ "$target_mode" = "yes" ]; then
-                  adb pull $cfg_output_dir/$cfg_output &> /dev/null
+                  adb pull "$chroot/$cfg_output_dir/$cfg_output" &> /dev/null
                 fi
                 "$checker" $checker_args "$cfg_output" "$tmp_dir" 2>&1
                 checker_exit="$?"
@@ -888,7 +916,7 @@
         "./${run}" $run_args "$@" >"$output" 2>&1
         if [ "$run_checker" = "yes" ]; then
           if [ "$target_mode" = "yes" ]; then
-            adb pull $cfg_output_dir/$cfg_output &> /dev/null
+            adb pull "$chroot/$cfg_output_dir/$cfg_output" &> /dev/null
           fi
           "$checker" -q $checker_args "$cfg_output" "$tmp_dir" >> "$output" 2>&1
         fi
@@ -926,7 +954,7 @@
             good_run="no"
         elif [ "$run_checker" = "yes" ]; then
             if [ "$target_mode" = "yes" ]; then
-              adb pull $cfg_output_dir/$cfg_output &> /dev/null
+              adb pull "$chroot/$cfg_output_dir/$cfg_output" &> /dev/null
             fi
             "$checker" -q $checker_args "$cfg_output" "$tmp_dir" >> "$output" 2>&1
             checker_exit="$?"
@@ -986,6 +1014,7 @@
 ) 2>&${real_stderr} 1>&2
 
 # Attempt bisection only if the test failed.
+# TODO: Implement support for chroot-based bisection search.
 if [ "$bisection_search" = "yes" -a "$good" != "yes" ]; then
     # Bisecting works by skipping different optimization passes which breaks checker assertions.
     if [ "$run_checker" == "yes" ]; then
@@ -997,17 +1026,18 @@
       maybe_device_mode=""
       raw_cmd=""
       if [ "$target_mode" = "yes" ]; then
-        # Produce cmdline.sh in $DEX_LOCATION. "$@" is passed as a runtime option
+        # Produce cmdline.sh in $chroot_dex_location. "$@" is passed as a runtime option
         # so that cmdline.sh forwards its arguments to dalvikvm. invoke-with is set
         # to exec in order to preserve pid when calling dalvikvm. This is required
         # for bisection search to correctly retrieve logs from device.
         "./${run}" $run_args --runtime-option '"$@"' --invoke-with exec --dry-run "$@" &> /dev/null
-        adb shell chmod u+x "$DEX_LOCATION/cmdline.sh"
+        adb shell chmod u+x "$chroot_dex_location/cmdline.sh"
         maybe_device_mode="--device"
         raw_cmd="$DEX_LOCATION/cmdline.sh"
       else
         raw_cmd="$cwd/${run} --external-log-tags $run_args $@"
       fi
+      # TODO: Pass a `--chroot` option to the bisection_search.py script and use it there.
       $ANDROID_BUILD_TOP/art/tools/bisection_search/bisection_search.py \
         $maybe_device_mode \
         --raw-cmd="$raw_cmd" \
@@ -1023,7 +1053,7 @@
     cd "$oldwd"
     rm -rf "$tmp_dir"
     if [ "$target_mode" = "yes" -a "$build_exit" = "0" ]; then
-        adb shell rm -rf $DEX_LOCATION
+        adb shell rm -rf $chroot_dex_location
     fi
     if [ "$good" = "yes" ]; then
         exit 0
@@ -1040,7 +1070,7 @@
     else
         echo "${TEST_NAME} files left in ${tmp_dir} on host"
         if [ "$target_mode" == "yes" ]; then
-            echo "and in ${DEX_LOCATION} on target"
+            echo "and in ${chroot_dex_location} on target"
         fi
     fi