ART: Move target APEX checks

Move testing and printing from runtests.sh to art_apex_test.py.
Add previously missed target-debug-only checks. Add runtests.sh
debugfs check/building. Remove guestfs code.

Test: art/build/apex/runtests.sh
Test: art/build/apex/runtests.sh -l
Test: art/build/apex/runtests.sh -t
Change-Id: Id0485a090d190ed7a1c3103b7edf01c1dc28e0ed
diff --git a/build/apex/art_apex_test.py b/build/apex/art_apex_test.py
index 2d6b370..e636a72 100755
--- a/build/apex/art_apex_test.py
+++ b/build/apex/art_apex_test.py
@@ -117,15 +117,19 @@
   def error_count(self):
     return self._errors
 
-  def check_file(self, file):
+  def is_file(self, file):
     fs_object = self._provider.get(file)
     if fs_object is None:
-      self.fail('Could not find %s', file)
-      return False
+      return (False, 'Could not find %s')
     if fs_object.is_dir:
-      self.fail('%s is a directory', file)
-      return False
-    return True
+      return (False, '%s is a directory')
+    return (True, '')
+
+  def check_file(self, file):
+    chk = self.is_file(file)
+    if not chk[0]:
+      self.fail(chk[1], file)
+    return chk[0]
 
   def check_binary(self, file):
     path = 'bin/%s' % (file)
@@ -165,6 +169,14 @@
       res = self.check_file('lib64/%s' % (file)) and res
     return res
 
+  def check_single_library(self, file):
+    res1 = self.is_file('lib/%s' % (file))
+    res2 = self.is_file('lib64/%s' % (file))
+    if not res1[0] and not res2[0]:
+      self.fail('Library missing: %s', file)
+      return False
+    return True
+
   def check_java_library(self, file):
     return self.check_file('javalib/%s' % (file))
 
@@ -258,6 +270,17 @@
     # Check that the mounted image contains additional required debug libraries.
     self.check_library('libadbconnectiond.so')
 
+class DebugTargetChecker(Checker):
+  def __init__(self, provider):
+    super().__init__(provider)
+  def __str__(self):
+    return 'Debug (Target) Checker'
+
+  def run(self):
+    # Check for files pulled in from debug target-only oatdump.
+    self.check_binary('oatdump')
+    self.check_single_library('libart-disassembler.so')
+
 def print_list(provider):
     def print_list_impl(provider, path):
       map = provider.read_dir(path)
@@ -333,8 +356,8 @@
 
   try:
     apex_provider = TargetApexProvider(args.apex, args.tmpdir, args.debugfs)
-  except:
-    logging.error('Failed to create provider')
+  except Exception as e:
+    logging.error('Failed to create provider: %s', e)
     return 1
 
   if args.tree:
@@ -352,6 +375,8 @@
   checkers.append(ReleaseChecker(apex_provider))
   if args.debug:
     checkers.append(DebugChecker(apex_provider))
+  if args.debug and args.target:
+    checkers.append(DebugTargetChecker(apex_provider))
 
   failed = False
   for checker in checkers:
diff --git a/build/apex/runtests.sh b/build/apex/runtests.sh
index 155709a..aa04054 100755
--- a/build/apex/runtests.sh
+++ b/build/apex/runtests.sh
@@ -17,6 +17,8 @@
 
 # Run Android Runtime APEX tests.
 
+SCRIPT_DIR=$(dirname $0)
+
 # Status of whole test script.
 exit_status=0
 # Status of current test suite.
@@ -31,17 +33,17 @@
   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."
 
+[[ -n "$ANDROID_HOST_OUT" ]] \
+  || die "You need to source and lunch before you can use this script."
+
+if [ ! -e "$ANDROID_HOST_OUT/bin/debugfs" ] ; then
+  say "Could not find debugfs, building now."
+  make debugfs-host || die "Cannot build debugfs"
+fi
+
 # Fail early.
 set -e
 
@@ -112,6 +114,25 @@
   fi
 }
 
+# maybe_list_apex_contents_apex APEX TMPDIR [other]
+function maybe_list_apex_contents_apex {
+  local apex=$1
+  local tmpdir=$2
+  shift 2
+
+  # List the contents of the apex in list form.
+  if $list_image_files_p; then
+    say "Listing image files"
+    $SCRIPT_DIR/art_apex_test.py --list --tmpdir "$tmpdir" $@ $apex
+  fi
+
+  # List the contents of the apex in tree form.
+  if $print_image_tree_p; then
+    say "Printing image tree"
+    $SCRIPT_DIR/art_apex_test.py --tree --tmpdir "$tmpdir" $@ $apex
+  fi
+}
+
 function fail_check {
   echo "$0: FAILED: $*"
   test_status=1
@@ -151,6 +172,8 @@
   [[ -x "$mount_point/javalib/$1" ]] || fail_check "Cannot find java library '$1' in mounted image"
 }
 
+# !!! NOTE: Please also update art_apex_test.py !!!
+
 # Check contents of APEX payload located in `$mount_point`.
 function check_release_contents {
   # Check that the mounted image contains an APEX manifest.
@@ -243,7 +266,6 @@
 
 # Clean-up.
 function cleanup_target {
-  guestunmount "$mount_point"
   rm -rf "$work_dir"
 }
 
@@ -254,34 +276,6 @@
   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).
 # -----------------------------------------------------------
 
@@ -291,23 +285,24 @@
 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"
+apex_path="$ANDROID_PRODUCT_OUT/system/apex/${apex_module}.apex"
 
 # List the contents of the APEX image (optional).
-maybe_list_apex_contents "$mount_point"
+maybe_list_apex_contents_apex $apex_path $work_dir --target --debugfs $ANDROID_HOST_OUT/bin/debugfs
 
 # Run tests on APEX package.
 say "Checking APEX package $apex_module"
-check_release_contents "$apex_module"
+$SCRIPT_DIR/art_apex_test.py \
+  --tmpdir $work_dir \
+  --debugfs $ANDROID_HOST_OUT/bin/debugfs \
+  --target \
+  $apex_path \
+    || fail_check "Release checks failed"
 
 # Clean up.
 trap - EXIT
@@ -325,27 +320,25 @@
 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"
+apex_path="$ANDROID_PRODUCT_OUT/system/apex/${apex_module}.apex"
 
 # List the contents of the APEX image (optional).
-maybe_list_apex_contents "$mount_point"
+maybe_list_apex_contents_apex $apex_path $work_dir --target --debugfs $ANDROID_HOST_OUT/bin/debugfs
 
 # 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
+$SCRIPT_DIR/art_apex_test.py \
+  --tmpdir $work_dir \
+  --debugfs $ANDROID_HOST_OUT/bin/debugfs \
+  --target \
+  --debug \
+  $apex_path \
+    || fail_check "Debug checks failed"
 
 # Clean up.
 trap - EXIT