summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-03-13 02:55:24 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-03-13 02:55:24 +0000
commit387f2d62ca7f274213d6d5512cc6156d8d05a951 (patch)
treeeb76d329a7b4e071686cb2d753f3449e914eba81
parent661fa1f6f4d74b85266e84a77627d94f57fb08db (diff)
parent88f44c8998ff2514bc39916afec916bb3a8fccd1 (diff)
downloadvndk-387f2d62ca7f274213d6d5512cc6156d8d05a951.tar.gz
Convert vts_vndk_dependency_test to a host test am: 88f44c8998
Change-Id: I429c8f0c3b571b74595d3bfab0b673fbd7a017a1
-rw-r--r--Android.bp4
-rw-r--r--dependency/vts_vndk_dependency_test.py51
-rw-r--r--utils.py15
3 files changed, 51 insertions, 19 deletions
diff --git a/Android.bp b/Android.bp
index 18a2b91..df43d92 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-python_library {
+python_library_host {
name: "vts_vndk_utils",
pkg_path: "vts/testcases/vndk",
srcs: [
@@ -50,7 +50,7 @@ python_defaults {
}
}
-python_test {
+python_test_host {
name: "vts_vndk_dependency_test",
defaults: ["vts_vndk_default"],
main: "dependency/vts_vndk_dependency_test.py",
diff --git a/dependency/vts_vndk_dependency_test.py b/dependency/vts_vndk_dependency_test.py
index 6541a80..65d62c8 100644
--- a/dependency/vts_vndk_dependency_test.py
+++ b/dependency/vts_vndk_dependency_test.py
@@ -20,7 +20,10 @@
import collections
import logging
import os
+import posixpath as target_path_module
import re
+import shutil
+import tempfile
import unittest
from vts.testcases.vndk import utils
@@ -34,6 +37,8 @@ class VtsVndkDependencyTest(unittest.TestCase):
Attributes:
_dut: The AndroidDevice under test.
+ _temp_dir: The temporary directory to which the odm and vendor
+ partitions are copied.
_ll_ndk: Set of strings. The names of low-level NDK libraries in
/system/lib[64].
_sp_hal: List of patterns. The names of the same-process HAL libraries
@@ -44,6 +49,7 @@ class VtsVndkDependencyTest(unittest.TestCase):
_VENDOR_LINK_PATHS: Format strings of vendor processes' link paths.
"""
_TARGET_DIR_SEP = "/"
+ _TARGET_ROOT_DIR = "/"
_TARGET_ODM_DIR = "/odm"
_TARGET_VENDOR_DIR = "/vendor"
@@ -74,8 +80,8 @@ class VtsVndkDependencyTest(unittest.TestCase):
def __init__(self, target_path, bitness, deps, runpaths):
self.target_path = target_path
- self.name = os.path.basename(target_path)
- self.target_dir = os.path.dirname(target_path)
+ self.name = target_path_module.basename(target_path)
+ self.target_dir = target_path_module.dirname(target_path)
self.bitness = bitness
self.deps = deps
# Format runpaths
@@ -90,9 +96,19 @@ class VtsVndkDependencyTest(unittest.TestCase):
def setUp(self):
"""Initializes device, temporary directory, and VNDK lists."""
- self._dut = utils.AndroidDevice()
+ serial_number = os.environ.get("ANDROID_SERIAL")
+ self.assertTrue(serial_number, "$ANDROID_SERIAL is empty.")
+ self._dut = utils.AndroidDevice(serial_number)
self.assertTrue(self._dut.IsRoot(), "This test requires adb root.")
+ self._temp_dir = tempfile.mkdtemp()
+ for target_dir in (self._TARGET_ODM_DIR, self._TARGET_VENDOR_DIR):
+ if self._dut.IsDirectory(target_dir):
+ logging.info("adb pull %s %s", target_dir, self._temp_dir)
+ self._dut.AdbPull(target_dir, self._temp_dir)
+ else:
+ logging.info("Skip adb pull %s", target_dir)
+
vndk_lists = vndk_data.LoadVndkLibraryListsFromResources(
self._dut.GetVndkVersion(),
vndk_data.SP_HAL,
@@ -110,6 +126,11 @@ class VtsVndkDependencyTest(unittest.TestCase):
logging.debug("VNDK: %s", self._vndk)
logging.debug("VNDK_SP: %s", self._vndk_sp)
+ def tearDown(self):
+ """Deletes the temporary directory."""
+ logging.info("Delete %s", self._temp_dir)
+ shutil.rmtree(self._temp_dir, ignore_errors=True)
+
def _IsElfObjectForAp(self, elf, target_path, abi_list):
"""Checks whether an ELF object is for application processor.
@@ -192,23 +213,28 @@ class VtsVndkDependencyTest(unittest.TestCase):
for file_name in file_names:
yield os.path.join(root_dir, file_name)
- def _LoadElfObjects(self, target_dir, abi_list, elf_error_handler):
+ def _LoadElfObjects(self, host_dir, target_dir, abi_list,
+ elf_error_handler):
"""Scans a host directory recursively and loads all ELF files in it.
Args:
- target_dir: The host directory to scan.
+ host_dir: The host directory to scan.
+ target_dir: The path from which host_dir is copied.
abi_list: A list of strings, the ABIs of the ELF files to load.
elf_error_handler: A function that takes 2 arguments
- (path, exception). It is called when
+ (target_path, exception). It is called when
the parser fails to read an ELF file.
Returns:
List of ElfObject.
"""
objs = []
- for target_path in self._IterateFiles(target_dir):
+ for full_path in self._IterateFiles(host_dir):
+ rel_path = os.path.relpath(full_path, host_dir)
+ target_path = target_path_module.join(
+ target_dir, *rel_path.split(os.path.sep))
try:
- elf = elf_parser.ElfParser(target_path)
+ elf = elf_parser.ElfParser(full_path)
except elf_parser.ElfError:
logging.debug("%s is not an ELF file", target_path)
continue
@@ -404,12 +430,9 @@ class VtsVndkDependencyTest(unittest.TestCase):
"""Tests vendor libraries/executables and SP-HAL dependencies."""
read_errors = []
abi_list = self._dut.GetCpuAbiList()
- objs = []
- for target_dir in (self._TARGET_ODM_DIR, self._TARGET_VENDOR_DIR):
- if self._dut.IsDirectory(target_dir):
- objs.extend(self._LoadElfObjects(
- target_dir, abi_list,
- lambda p, e: read_errors.append((p, str(e)))))
+ objs = self._LoadElfObjects(
+ self._temp_dir, self._TARGET_ROOT_DIR, abi_list,
+ lambda p, e: read_errors.append((p, str(e))))
dep_errors = self._TestElfDependency(32, objs)
if self._dut.GetCpuAbiList(64):
diff --git a/utils.py b/utils.py
index 8e6cc52..45a5951 100644
--- a/utils.py
+++ b/utils.py
@@ -24,7 +24,15 @@ import subprocess
class AndroidDevice(object):
"""This class controls the device via adb commands."""
- def _ExecuteCommand(self, *cmd):
+ def __init__(self, serial_number):
+ self._serial_number = serial_number
+
+ def AdbPull(self, src, dst):
+ cmd = ["adb", "-s", self._serial_number, "pull", src, dst]
+ subprocess.check_call(cmd, shell=False, stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+ def _ExecuteCommand(self, *args):
"""Executes a command.
Args:
@@ -34,6 +42,8 @@ class AndroidDevice(object):
Stdout as a string, stderr as a string, and return code as an
integer.
"""
+ cmd = ["adb", "-s", self._serial_number, "shell"]
+ cmd.extend(args)
proc = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = proc.communicate()
@@ -140,8 +150,7 @@ class AndroidDevice(object):
def _Test(self, *args):
"""Tests file types and status."""
- out, err, return_code = self._ExecuteCommand("sh", "-c",
- "test " + " ".join(args))
+ out, err, return_code = self._ExecuteCommand("test", *args)
if out.strip() or err.strip():
raise IOError("`test` args: %s\nstdout: %s\nstderr: %s" %
(args, out, err))