Add support for running ART tests on a Linux virtual machine.

Test: setup a local VM and run ART tests on it:
  lunch aosp_arm64-userdebug

  export ART_TEST_SSH_USER=ubuntu
  export ART_TEST_SSH_HOST=localhost
  export ART_TEST_SSH_PORT=10001
  export ART_TEST_ON_VM=true

  . art/tools/buildbot-utils.sh
  art/tools/buildbot-build.sh --target

  # Create, boot and configure the VM.
  art/tools/buildbot-vm.sh create
  art/tools/buildbot-vm.sh boot
  art/tools/buildbot-vm.sh setup-ssh  # password: 'ubuntu'

  art/tools/buildbot-cleanup-device.sh
  art/tools/buildbot-setup-device.sh
  art/tools/buildbot-sync.sh

  art/test.py --target -r 001-HelloWorld
  art/tools/run-gtests.sh

Test: check that non-VM testing still works:
  lunch aosp_arm32-userdebug

  . art/tools/buildbot-utils.sh
  art/tools/buildbot-build.sh --target

  export ART_TEST_CHROOT=/data/local/art-test-chroot

  art/tools/buildbot-cleanup-device.sh
  art/tools/buildbot-setup-device.sh
  art/tools/buildbot-sync.sh

  art/test.py --target -r --32 001-HelloWorld

Change-Id: I1393f8132b0b5d6ad10e291504550a5e7751f8e2
diff --git a/tools/buildbot-utils.sh b/tools/buildbot-utils.sh
index 32ed234..5bc58af 100755
--- a/tools/buildbot-utils.sh
+++ b/tools/buildbot-utils.sh
@@ -53,7 +53,43 @@
   echo -e "${boldred}Error: ${nc}${message}"
 }
 
+function msgfatal() {
+  local message="$*"
+  echo -e "${boldred}Fatal: ${nc}${message}"
+  exit 1
+}
+
 function msgnote() {
   local message="$*"
   echo -e "${boldcyan}Note: ${nc}${message}"
 }
+
+export TARGET_ARCH=$(build/soong/soong_ui.bash --dumpvar-mode TARGET_ARCH)
+
+# Do some checks and prepare environment for tests that run on Linux (not on Android).
+if [[ -n "$ART_TEST_ON_VM" ]]; then
+  if [[ -z $ANDROID_BUILD_TOP ]]; then
+    msgfatal "ANDROID_BUILD_TOP is not set"
+  elif [[ -z "$ART_TEST_SSH_USER" ]]; then
+    msgfatal "ART_TEST_SSH_USER not set"
+  elif [[ -z "$ART_TEST_SSH_HOST" ]]; then
+    msgfatal "ART_TEST_SSH_HOST not set"
+  elif [[ -z "$ART_TEST_SSH_PORT" ]]; then
+    msgfatal "ART_TEST_SSH_PORT not set"
+  fi
+
+  export ART_TEST_CHROOT="/home/$ART_TEST_SSH_USER/art-test-chroot"
+  export ART_CHROOT_CMD="unshare --user --map-root-user chroot art-test-chroot"
+  export ART_SSH_CMD="ssh -q -p $ART_TEST_SSH_PORT $ART_TEST_SSH_USER@$ART_TEST_SSH_HOST"
+  export ART_SCP_CMD="scp -P $ART_TEST_SSH_PORT -p -r"
+  export ART_RSYNC_CMD="rsync -az"
+  export RSYNC_RSH="ssh -p $ART_TEST_SSH_PORT" # don't prefix with "ART_", rsync expects this name
+
+  if [[ "$TARGET_ARCH" =~ ^(arm64|riscv64)$ ]]; then
+    export ART_TEST_VM_IMG="ubuntu-22.04-server-cloudimg-$TARGET_ARCH.img"
+    export ART_TEST_VM_DIR="$ANDROID_BUILD_TOP/vm/$TARGET_ARCH"
+    export ART_TEST_VM="$ART_TEST_VM_DIR/$ART_TEST_VM_IMG"
+  else
+    msgfatal "unexpected TARGET_ARCH=$TARGET_ARCH; expected one of {arm64,riscv64}"
+  fi
+fi