blob: b4fbf04cf13babb7f03de585d3673c80b336edf3 [file] [log] [blame]
#!/usr/bin/env python
#
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import logging
import os
from vts.runners.host import keys
from vts.runners.host import test_runner
from vts.utils.python.controllers import adb
from vts.utils.python.controllers import android_device
from vts.utils.python.common import vts_spec_utils
from vts.testcases.fuzz.template.libfuzzer_test import libfuzzer_test_config as config
from vts.testcases.fuzz.template.libfuzzer_test import libfuzzer_test
from vts.testcases.fuzz.template.libfuzzer_test import libfuzzer_test_case
class FuncFuzzerTest(libfuzzer_test.LibFuzzerTest):
"""Runs function fuzzer tests on target.
Attributes:
_dut: AndroidDevice, the device under test as config.
_test_cases: LibFuzzerTestCase list, list of test cases to run.
_vts_spec_parser: VtsSpecParser, used to parse .vts files.
"""
def setUpClass(self):
"""Creates a remote shell instance, and copies data files."""
required_params = [
keys.ConfigKeys.IKEY_DATA_FILE_PATH,
keys.ConfigKeys.IKEY_HAL_HIDL_PACKAGE_NAME,
]
self.getUserParams(required_params)
logging.info('%s: %s', keys.ConfigKeys.IKEY_DATA_FILE_PATH,
self.data_file_path)
logging.info('%s: %s', keys.ConfigKeys.IKEY_HAL_HIDL_PACKAGE_NAME,
self.hal_hidl_package_name)
self._dut = self.registerController(android_device, False)[0]
self._dut.startAdbLogcat()
self._dut.adb.shell('mkdir %s -p' % config.FUZZER_TEST_DIR)
self._vts_spec_parser = vts_spec_utils.VtsSpecParser(
self.data_file_path)
def _RegisteredInterfaces(self, hal_package):
"""Returns a list of registered interfaces for a given hal package.
Args:
hal_package: string, name of hal package,
e.g. android.hardware.nfc@1.0
Returns:
list of string, list of interfaces from this package that are
registered on device under test.
"""
# TODO: find a more robust way to query registered interfaces.
cmd = '"lshal | grep -v \* | grep -o %s::[[:alpha:]]* | sort -u"' % hal_package
out = str(self._dut.adb.shell(cmd)).split()
interfaces = map(lambda x: x.split('::')[-1], out)
return interfaces
def _FuzzerBinHostPath(self, hal_package, vts_spec_name):
"""Returns path to fuzzer binary on host."""
vts_spec_name = vts_spec_name.replace('.vts', '')
bin_name = hal_package + '-vts.func_fuzzer.' + vts_spec_name
bin_host_path = os.path.join(self.data_file_path, 'DATA', 'bin',
bin_name)
return str(bin_host_path)
def _CreateTestCasesFromSpec(self, hal_package, vts_spec_name,
vts_spec_proto):
"""Creates LibFuzzerTestCases.
Args:
hal_package: string, name of hal package,
e.g. android.hardware.nfc@1.0
vts_spec_name: string, e.g. 'Nfc.vts'.
Returns:
LibFuzzerTestCase list, one per function of interface corresponding
to vts_spec_name.
"""
test_cases = []
for api in vts_spec_proto.interface.api:
additional_params = {'vts_target_func': api.name}
libfuzzer_params = config.FUZZER_DEFAULT_PARAMS
bin_host_path = self._FuzzerBinHostPath(hal_package, vts_spec_name)
test_case = libfuzzer_test_case.LibFuzzerTestCase(
bin_host_path, libfuzzer_params, additional_params)
test_case.test_name = api.name
test_cases.append(test_case)
return test_cases
# Override
def CreateTestCases(self):
"""See base class."""
hal_package = self.hal_hidl_package_name
hal_name, hal_version = vts_spec_utils.HalPackageToNameAndVersion(
hal_package)
vts_spec_names = self._vts_spec_parser.VtsSpecNames(hal_name,
hal_version)
registered_interfaces = self._RegisteredInterfaces(
self.hal_hidl_package_name)
test_cases = []
for vts_spec_name in vts_spec_names:
vts_spec_proto = self._vts_spec_parser.VtsSpecProto(
hal_name, hal_version, vts_spec_name)
if not vts_spec_proto.component_name in registered_interfaces:
continue
test_cases += self._CreateTestCasesFromSpec(
hal_package, vts_spec_name, vts_spec_proto)
return test_cases
if __name__ == '__main__':
test_runner.main()