Use more specific arch candidates per bitness

Additionally, let check_art_test_executable accept "multilib" option to
select only relevant directories. This will be used in the next change.

Bug: 193668901
Test: art/build/apex/runtests.sh

Change-Id: I1b268220392ea1845aeb0a0f6087dca26a3ec743
diff --git a/build/apex/art_apex_test.py b/build/apex/art_apex_test.py
index 0f87901..7b1bf8a 100755
--- a/build/apex/art_apex_test.py
+++ b/build/apex/art_apex_test.py
@@ -43,7 +43,14 @@
 BITNESS_ALL = [BITNESS_32, BITNESS_64, BITNESS_MULTILIB, BITNESS_AUTO]
 
 # Architectures supported by APEX packages.
-ARCHS = ["arm", "arm64", "x86", "x86_64"]
+ARCHS_32 = ["arm", "x86"]
+ARCHS_64 = ["arm64", "x86_64"]
+
+# Multilib options
+MULTILIB_32 = '32'
+MULTILIB_64 = '64'
+MULTILIB_BOTH = 'both'
+MULTILIB_FIRST = 'first'
 
 # Directory containing ART tests within an ART APEX (if the package includes
 # any). ART test executables are installed in `bin/art/<arch>`. Segregating
@@ -247,7 +254,7 @@
       self.fail('%s is not a symlink', path)
     self._expected_file_globs.add(path)
 
-  def arch_dirs_for_path(self, path):
+  def arch_dirs_for_path(self, path, multilib=None):
     # Look for target-specific subdirectories for the given directory path.
     # This is needed because the list of build targets is not propagated
     # to this script.
@@ -255,15 +262,15 @@
     # TODO(b/123602136): Pass build target information to this script and fix
     # all places where this function in used (or similar workarounds).
     dirs = []
-    for arch in ARCHS:
+    for arch in self.possible_archs(multilib):
       dir = '%s/%s' % (path, arch)
       found, _ = self.is_dir(dir)
       if found:
         dirs.append(dir)
     return dirs
 
-  def check_art_test_executable(self, filename):
-    dirs = self.arch_dirs_for_path(ART_TEST_DIR)
+  def check_art_test_executable(self, filename, multilib=None):
+    dirs = self.arch_dirs_for_path(ART_TEST_DIR, multilib)
     if not dirs:
       self.fail('ART test binary missing: %s', filename)
     for dir in dirs:
@@ -305,7 +312,7 @@
     self._expected_file_globs.add(path_glob)
 
   def check_optional_art_test_executable(self, filename):
-    for arch in ARCHS:
+    for arch in self.possible_archs():
       self.ignore_path('%s/%s/%s' % (ART_TEST_DIR, arch, filename))
 
   def check_no_superfluous_files(self, dir_path):
@@ -356,6 +363,9 @@
     """Check lib64/basename.so, or lib/basename.so on 32 bit only."""
     raise NotImplementedError
 
+  def possible_archs(self, multilib=None):
+    """Returns names of possible archs."""
+    raise NotImplementedError
 
 class Arch32Checker(Checker):
   def check_symlinked_multilib_executable(self, filename):
@@ -383,6 +393,8 @@
   def check_prefer64_library(self, basename):
     self.check_native_library(basename)
 
+  def possible_archs(self, multilib=None):
+    return ARCHS_32
 
 class Arch64Checker(Checker):
   def check_symlinked_multilib_executable(self, filename):
@@ -410,6 +422,9 @@
   def check_prefer64_library(self, basename):
     self.check_native_library(basename)
 
+  def possible_archs(self, multilib=None):
+    return ARCHS_64
+
 
 class MultilibChecker(Checker):
   def check_symlinked_multilib_executable(self, filename):
@@ -441,6 +456,15 @@
   def check_prefer64_library(self, basename):
     self.check_file('lib64/%s.so' % basename)
 
+  def possible_archs(self, multilib=None):
+    if multilib is None or multilib == MULTILIB_BOTH:
+      return ARCHS_32 + ARCHS_64
+    if multilib == MULTILIB_FIRST or multilib == MULTILIB_64:
+      return ARCHS_64
+    elif multilib == MULTILIB_32:
+      return ARCHS_32
+    self.fail('Unrecognized multilib option "%s"', multilib)
+
 
 class ReleaseChecker:
   def __init__(self, checker):
@@ -788,7 +812,7 @@
     return 'No superfluous ART tests checker'
 
   def run(self):
-    for arch in ARCHS:
+    for arch in self._checker.possible_archs():
       self._checker.check_no_superfluous_files('%s/%s' % (ART_TEST_DIR, arch))