Home | History | Annotate | Download | only in hal_hidl_replay_test
      1 #
      2 # Copyright (C) 2017 The Android Open Source Project
      3 #
      4 # Licensed under the Apache License, Version 2.0 (the "License");
      5 # you may not use this file except in compliance with the License.
      6 # You may obtain a copy of the License at
      7 #
      8 #      http://www.apache.org/licenses/LICENSE-2.0
      9 #
     10 # Unless required by applicable law or agreed to in writing, software
     11 # distributed under the License is distributed on an "AS IS" BASIS,
     12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 # See the License for the specific language governing permissions and
     14 # limitations under the License.
     15 #
     16 
     17 import logging
     18 import os
     19 
     20 from vts.runners.host import asserts
     21 from vts.runners.host import const
     22 from vts.runners.host import keys
     23 from vts.runners.host import test_runner
     24 from vts.testcases.template.binary_test import binary_test
     25 from vts.utils.python.hal import hal_service_name_utils
     26 from vts.utils.python.os import path_utils
     27 
     28 
     29 class HalHidlReplayTest(binary_test.BinaryTest):
     30     """Base class to run a HAL HIDL replay test on a target device.
     31 
     32     Attributes:
     33         _dut: AndroidDevice, the device under test as config
     34         DEVICE_TMP_DIR: string, target device's tmp directory path.
     35         DEVICE_VTS_SPEC_FILE_PATH: string, target device's directory for storing
     36                                    HAL spec files.
     37     """
     38 
     39     DEVICE_TMP_DIR = "/data/local/tmp"
     40     DEVICE_VTS_SPEC_FILE_PATH = "/data/local/tmp/spec"
     41     DEVICE_VTS_TRACE_FILE_PATH = "/data/local/tmp/vts_replay_trace"
     42 
     43     def setUpClass(self):
     44         """Prepares class and initializes a target device."""
     45         self._test_hal_services = set()
     46         super(HalHidlReplayTest, self).setUpClass()
     47 
     48         if self.isSkipAllTests():
     49             return
     50 
     51         if self.coverage.enabled and self._test_hal_services is not None:
     52             self.coverage.SetHalNames(self._test_hal_services)
     53 
     54     # @Override
     55     def CreateTestCases(self):
     56         """Create a list of HalHidlReplayTestCase objects."""
     57         required_params = [
     58             keys.ConfigKeys.IKEY_HAL_HIDL_REPLAY_TEST_TRACE_PATHS,
     59             keys.ConfigKeys.IKEY_ABI_BITNESS
     60         ]
     61         opt_params = [keys.ConfigKeys.IKEY_BINARY_TEST_DISABLE_FRAMEWORK]
     62         self.getUserParams(
     63             req_param_names=required_params, opt_param_names=opt_params)
     64         self.abi_bitness = str(self.abi_bitness)
     65         self.trace_paths = map(str, self.hal_hidl_replay_test_trace_paths)
     66 
     67         self.replayer_binary_path = path_utils.JoinTargetPath(
     68             self.DEVICE_TMP_DIR, self.abi_bitness,
     69             "vts_hal_replayer%s" % self.abi_bitness)
     70         self.custom_ld_library_path = path_utils.JoinTargetPath(
     71             self.DEVICE_TMP_DIR, self.abi_bitness)
     72 
     73         for trace_path in self.trace_paths:
     74             trace_file_name = str(os.path.basename(trace_path))
     75             target_trace_path = path_utils.JoinTargetPath(
     76                 self.DEVICE_VTS_TRACE_FILE_PATH, trace_file_name)
     77             self._dut.adb.push(
     78                 path_utils.JoinTargetPath(self.data_file_path,
     79                                           "hal-hidl-trace", trace_path),
     80                 target_trace_path)
     81             service_instance_combinations = self._GetServiceInstanceCombinations(
     82                 target_trace_path)
     83 
     84             if service_instance_combinations:
     85                 for instance_combination in service_instance_combinations:
     86                     test_case = self.CreateReplayTestCase(
     87                         trace_file_name, target_trace_path)
     88                     service_name_list = []
     89                     for instance in instance_combination:
     90                         test_case.args += " --hal_service_instance=" + instance
     91                         service_name_list.append(
     92                             instance[instance.find('/') + 1:])
     93                     name_appendix = "({0})".format(",".join(service_name_list))
     94                     test_case.name_appendix = name_appendix
     95                     self.testcases.append(test_case)
     96             else:
     97                 test_case = self.CreateReplayTestCase(trace_file_name,
     98                                                       target_trace_path)
     99                 self.testcases.append(test_case)
    100 
    101     def CreateReplayTestCase(self, trace_file_name, target_trace_path):
    102         """Create a replay test case object.
    103 
    104         Args:
    105             trace_file_name: string, name of the trace file used in the test.
    106             target_trace_path: string, full path of the trace file or the target device.
    107         """
    108         test_case = super(HalHidlReplayTest, self).CreateTestCase(
    109             self.replayer_binary_path, '')
    110         test_case.envp += "LD_LIBRARY_PATH=%s:$LD_LIBRARY_PATH" % self.custom_ld_library_path
    111         test_case.args += " --spec_dir_path=" + self.DEVICE_VTS_SPEC_FILE_PATH
    112         test_case.args += " " + target_trace_path
    113         test_case.test_name = "replay_test_" + trace_file_name
    114         return test_case
    115 
    116     def VerifyTestResult(self, test_case, command_results):
    117         """Parse Gtest xml result output.
    118 
    119         Args:
    120             test_case: BinaryTestCase object, the test being run. This param
    121                        is not currently used in this method.
    122             command_results: dict of lists, shell command result
    123         """
    124         asserts.assertTrue(command_results, 'Empty command response.')
    125         asserts.assertEqual(
    126             len(command_results), 3, 'Abnormal command response.')
    127 
    128         for stdout in command_results[const.STDOUT]:
    129             if stdout and stdout.strip():
    130                 for line in stdout.split('\n'):
    131                     logging.info(line)
    132 
    133         if any(command_results[const.EXIT_CODE]):
    134             # print stderr only when test fails.
    135             for stderr in command_results[const.STDERR]:
    136                 if stderr and stderr.strip():
    137                     for line in stderr.split('\n'):
    138                         logging.error(line)
    139             asserts.fail(
    140                 'Test {} failed with the following results: {}'.format(
    141                     test_case, command_results))
    142 
    143     def tearDownClass(self):
    144         """Performs clean-up tasks."""
    145         # Delete the pushed file.
    146         if not self.isSkipAllTests():
    147             for trace_path in self.trace_paths:
    148                 trace_file_name = str(os.path.basename(trace_path))
    149                 target_trace_path = path_utils.JoinTargetPath(
    150                     self.DEVICE_TMP_DIR, "vts_replay_trace", trace_file_name)
    151                 cmd_results = self.shell.Execute(
    152                     "rm -f %s" % target_trace_path)
    153                 if not cmd_results or any(cmd_results[const.EXIT_CODE]):
    154                     logging.warning("Failed to remove: %s", cmd_results)
    155 
    156         super(HalHidlReplayTest, self).tearDownClass()
    157 
    158     def setUp(self):
    159         """Setup for code coverage for each test case."""
    160         super(HalHidlReplayTest, self).setUp()
    161         if self.coverage.enabled and not self.coverage.global_coverage:
    162             self.coverage.SetCoverageReportFilePrefix(
    163                 self._current_record.test_name.replace('/', '_'))
    164             self.coverage.InitializeDeviceCoverage(self._dut)
    165 
    166     def tearDown(self):
    167         """Generate the coverage data for each test case."""
    168         if self.coverage.enabled and not self.coverage.global_coverage:
    169             self.coverage.SetCoverageData(dut=self._dut, isGlobal=False)
    170 
    171         super(HalHidlReplayTest, self).tearDown()
    172 
    173     def _GetServiceInstanceCombinations(self, trace_path):
    174         """Create all combinations of instances for all services recorded in
    175         the trace file.
    176 
    177         Args:
    178             trace_path: string, full path of a given trace file
    179         Returns:
    180             A list of all service instance combinations.
    181         """
    182         registered_services = []
    183         service_instances = {}
    184         self.shell.Execute("chmod 755 %s" % self.replayer_binary_path)
    185         results = self.shell.Execute(
    186             "LD_LIBRARY_PATH=%s:$LD_LIBRARY_PATH %s --list_service %s" %
    187             (self.custom_ld_library_path, self.replayer_binary_path,
    188              trace_path))
    189 
    190         asserts.assertFalse(
    191             results[const.EXIT_CODE][0],
    192             'Failed to list test cases. EXIT_CODE: %s\n STDOUT: %s\n STDERR: %s\n'
    193             % (results[const.EXIT_CODE][0], results[const.STDOUT][0],
    194                results[const.STDERR][0]))
    195 
    196         # parse the results to get the registered service list.
    197         for line in results[const.STDOUT][0].split('\n'):
    198             line = str(line)
    199             if line.startswith('hal_service: '):
    200                 service = line[len('hal_service: '):]
    201                 registered_services.append(service)
    202 
    203         for service in registered_services:
    204             testable, service_names = hal_service_name_utils.GetHalServiceName(
    205                 self.shell, service, self.abi_bitness,
    206                 self.run_as_compliance_test)
    207             if not testable:
    208                 self.skipAllTests("Hal: %s is not testable, "
    209                                   "skip all tests." % service)
    210                 return []
    211             if service_names:
    212                 service_instances[service] = service_names
    213                 self._test_hal_services.add(service)
    214             else:
    215                 self.skipAllTests("No service name found for: %s, "
    216                                   "skip all tests." % service)
    217                 return []
    218         logging.info("registered service instances: %s", service_instances)
    219 
    220         service_instance_combinations = \
    221             hal_service_name_utils.GetServiceInstancesCombinations(
    222                 registered_services, service_instances)
    223 
    224         return service_instance_combinations
    225 
    226 
    227 if __name__ == "__main__":
    228     test_runner.main()
    229