Home | History | Annotate | Download | only in func_fuzzer_test
      1 #!/usr/bin/env python
      2 #
      3 # Copyright (C) 2017 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the 'License');
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #      http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an 'AS IS' BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 #
     17 
     18 import logging
     19 import os
     20 
     21 from vts.runners.host import keys
     22 from vts.runners.host import test_runner
     23 from vts.utils.python.controllers import adb
     24 from vts.utils.python.controllers import android_device
     25 from vts.utils.python.common import vts_spec_utils
     26 
     27 from vts.testcases.fuzz.template.libfuzzer_test import libfuzzer_test_config as config
     28 from vts.testcases.fuzz.template.libfuzzer_test import libfuzzer_test
     29 from vts.testcases.fuzz.template.libfuzzer_test import libfuzzer_test_case
     30 
     31 
     32 class FuncFuzzerTest(libfuzzer_test.LibFuzzerTest):
     33     """Runs function fuzzer tests on target.
     34 
     35     Attributes:
     36         _dut: AndroidDevice, the device under test as config.
     37         _test_cases: LibFuzzerTestCase list, list of test cases to run.
     38         _vts_spec_parser: VtsSpecParser, used to parse .vts files.
     39     """
     40 
     41     def setUpClass(self):
     42         """Creates a remote shell instance, and copies data files."""
     43         required_params = [
     44             keys.ConfigKeys.IKEY_DATA_FILE_PATH,
     45             keys.ConfigKeys.IKEY_HAL_HIDL_PACKAGE_NAME,
     46         ]
     47         self.getUserParams(required_params)
     48         logging.info('%s: %s', keys.ConfigKeys.IKEY_DATA_FILE_PATH,
     49                      self.data_file_path)
     50         logging.info('%s: %s', keys.ConfigKeys.IKEY_HAL_HIDL_PACKAGE_NAME,
     51                      self.hal_hidl_package_name)
     52 
     53         self._dut = self.registerController(android_device, False)[0]
     54         self._dut.adb.shell('mkdir %s -p' % config.FUZZER_TEST_DIR)
     55         self._vts_spec_parser = vts_spec_utils.VtsSpecParser(
     56             self.data_file_path)
     57 
     58     def _RegisteredInterfaces(self, hal_package):
     59         """Returns a list of registered interfaces for a given hal package.
     60 
     61         Args:
     62             hal_package: string, name of hal package,
     63                 e.g. android.hardware.nfc (at] 1.0
     64 
     65         Returns:
     66             list of string, list of interfaces from this package that are
     67                 registered on device under test.
     68         """
     69         # TODO: find a more robust way to query registered interfaces.
     70         cmd = '"lshal | grep -v \* | grep -o %s::[[:alpha:]]* | sort -u"' % hal_package
     71         out = str(self._dut.adb.shell(cmd)).split()
     72         interfaces = map(lambda x: x.split('::')[-1], out)
     73         return interfaces
     74 
     75     def _FuzzerBinHostPath(self, hal_package, vts_spec_name):
     76         """Returns path to fuzzer binary on host."""
     77         vts_spec_name = vts_spec_name.replace('.vts', '')
     78         bin_name = hal_package + '-vts.func_fuzzer.' + vts_spec_name
     79         bin_host_path = os.path.join(self.data_file_path, 'DATA', 'bin',
     80                                        bin_name)
     81         return str(bin_host_path)
     82 
     83     def _CreateTestCasesFromSpec(self, hal_package, vts_spec_name,
     84                                  vts_spec_proto):
     85         """Creates LibFuzzerTestCases.
     86 
     87         Args:
     88             hal_package: string, name of hal package,
     89                 e.g. android.hardware.nfc (at] 1.0
     90             vts_spec_name: string, e.g. 'Nfc.vts'.
     91 
     92         Returns:
     93             LibFuzzerTestCase list, one per function of interface corresponding
     94                 to vts_spec_name.
     95         """
     96         test_cases = []
     97         for api in vts_spec_proto.interface.api:
     98             additional_params = {'vts_target_func': api.name}
     99             libfuzzer_params = config.FUZZER_DEFAULT_PARAMS
    100             bin_host_path = self._FuzzerBinHostPath(hal_package, vts_spec_name)
    101             test_case = libfuzzer_test_case.LibFuzzerTestCase(
    102                 bin_host_path, libfuzzer_params, additional_params)
    103             test_case.test_name = api.name
    104             test_cases.append(test_case)
    105         return test_cases
    106 
    107     # Override
    108     def CreateTestCases(self):
    109         """See base class."""
    110         hal_package = self.hal_hidl_package_name
    111         hal_name, hal_version = vts_spec_utils.HalPackageToNameAndVersion(
    112             hal_package)
    113         vts_spec_names = self._vts_spec_parser.VtsSpecNames(hal_name,
    114                                                             hal_version)
    115 
    116         registered_interfaces = self._RegisteredInterfaces(
    117             self.hal_hidl_package_name)
    118         test_cases = []
    119         for vts_spec_name in vts_spec_names:
    120             vts_spec_proto = self._vts_spec_parser.VtsSpecProto(
    121                 hal_name, hal_version, vts_spec_name)
    122             if not vts_spec_proto.component_name in registered_interfaces:
    123                 continue
    124             test_cases += self._CreateTestCasesFromSpec(
    125                 hal_package, vts_spec_name, vts_spec_proto)
    126         return test_cases
    127 
    128 
    129 if __name__ == '__main__':
    130     test_runner.main()
    131