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 17import os 18import sys 19 20from importlib import import_module 21 22 23class FuzzerType(object): 24 """Types of fuzzers.""" 25 FUNC_FUZZER = 0 26 IFACE_FUZZER = 1 27 28 29class ConfigGen(object): 30 """Config generator for test/vts-testcase/fuzz. 31 32 Attributes: 33 _android_build_top: string, equal to environment variable ANDROID_BUILD_TOP. 34 _project_path: string, path to test/vts-testcase/fuzz. 35 _template_dir: string, path to directory containig templates. 36 _utils: test/vts-testcase/hal/script/build/config_gen_utils module. 37 _vts_spec_parser: tools that generates and parses vts spec with hidl-gen. 38 """ 39 40 def __init__(self): 41 """ConfigGen constructor. """ 42 self._android_build_top = os.environ.get('ANDROID_BUILD_TOP') 43 if not self._android_build_top: 44 print 'Run "lunch" command first.' 45 sys.exit(1) 46 self._project_path = os.path.join(self._android_build_top, 'test', 47 'vts-testcase', 'fuzz') 48 self._template_dir = os.path.join(self._project_path, 'script', 49 'config', 'template') 50 sys.path.append( 51 os.path.join(self._android_build_top, 'test', 'vts-testcase', 'hal', 52 'script', 'build')) 53 vts_spec_parser = import_module('vts_spec_parser') 54 self._utils = import_module('build_rule_gen_utils') 55 self._vts_spec_parser = vts_spec_parser.VtsSpecParser() 56 57 def UpdateFuzzerConfigs(self): 58 """Updates build rules for fuzzers. 59 60 Updates fuzzer configs for each pair of (hal_name, hal_version). 61 """ 62 config_dir = os.path.join(self._project_path, 'config') 63 self._utils.RemoveFilesInDirIf( 64 config_dir, lambda x: x == 'AndroidTest.xml' or 'Android.mk') 65 66 self.UpdateFuzzerConfigsForType(FuzzerType.FUNC_FUZZER) 67 self.UpdateFuzzerConfigsForType(FuzzerType.IFACE_FUZZER) 68 69 def UpdateFuzzerConfigsForType(self, fuzzer_type): 70 """Updates build rules for fuzzers. 71 72 Updates fuzzer configs for given fuzzer type. 73 74 Args: 75 fuzzer_type: FuzzerType, type of fuzzer. 76 """ 77 mk_template_path = os.path.join(self._template_dir, 'template.mk') 78 xml_template_path = os.path.join(self._template_dir, 'template.xml') 79 with open(mk_template_path) as template_file: 80 mk_template = str(template_file.read()) 81 with open(xml_template_path) as template_file: 82 xml_template = str(template_file.read()) 83 84 hal_list = self._vts_spec_parser.HalNamesAndVersions() 85 for hal_name, hal_version in hal_list: 86 if not self._IsTestable(hal_name, hal_version): 87 continue 88 fuzzer_type_subdir = self._FuzzerTypeUnderscore(fuzzer_type) 89 config_dir = os.path.join( 90 self._project_path, 'config', self._utils.HalNameDir(hal_name), 91 self._utils.HalVerDir(hal_version), fuzzer_type_subdir) 92 mk_file_path = os.path.join(config_dir, 'Android.mk') 93 xml_file_path = os.path.join(config_dir, 'AndroidTest.xml') 94 mk_string = self._FillOutTemplate(hal_name, hal_version, 95 fuzzer_type, mk_template) 96 97 xml_string = self._FillOutTemplate(hal_name, hal_version, 98 fuzzer_type, xml_template) 99 100 self._utils.WriteBuildRule(mk_file_path, mk_string) 101 self._utils.WriteBuildRule(xml_file_path, xml_string) 102 103 def _FuzzerTestName(self, hal_name, hal_version, fuzzer_type): 104 """Returns vts hal fuzzer test module name. 105 106 Args: 107 hal_name: string, name of the hal, e.g. 'vibrator'. 108 hal_version: string, version of the hal, e.g '7.4' 109 fuzzer_type: FuzzerType, type of fuzzer. 110 111 Returns: 112 string, test module name, e.g. VtsHalVibratorV7_4FuncFuzzer 113 """ 114 test_name = 'VtsHal' 115 test_name += ''.join(map(lambda x: x.title(), hal_name.split('.'))) 116 test_name += self._utils.HalVerDir(hal_version) 117 test_name += self._FuzzerTypeCamel(fuzzer_type) 118 return test_name 119 120 def _FuzzerTypeUnderscore(self, fuzzer_type): 121 """Returns vts hal fuzzer type string in underscore case. 122 123 Args: 124 fuzzer_type: FuzzerType, type of fuzzer. 125 126 Returns: 127 string, fuzzer type, e.g. "iface_fuzzer" 128 """ 129 if fuzzer_type == FuzzerType.FUNC_FUZZER: 130 test_type = 'func_fuzzer' 131 else: 132 test_type = 'iface_fuzzer' 133 return test_type 134 135 def _FuzzerTypeCamel(self, fuzzer_type): 136 """Returns vts hal fuzzer type string in camel case. 137 138 Args: 139 fuzzer_type: FuzzerType, type of fuzzer. 140 141 Returns: 142 string, fuzzer type, e.g. "IfaceFuzzer" 143 """ 144 if fuzzer_type == FuzzerType.FUNC_FUZZER: 145 test_type = 'FuncFuzzer' 146 else: 147 test_type = 'IfaceFuzzer' 148 return test_type 149 150 def _FillOutTemplate(self, hal_name, hal_version, fuzzer_type, template): 151 """Returns build rules in string form by filling out given template. 152 153 Args: 154 hal_name: string, name of the hal, e.g. 'vibrator'. 155 hal_version: string, version of the hal, e.g '7.4' 156 fuzzer_type: FuzzerType, type of fuzzer. 157 template: string, build rule template to fill out. 158 159 Returns: 160 string, complete build rule in string form. 161 """ 162 config = template 163 config = config.replace('{TEST_NAME}', self._FuzzerTestName( 164 hal_name, hal_version, fuzzer_type)) 165 config = config.replace('{HAL_NAME}', hal_name) 166 config = config.replace('{HAL_VERSION}', hal_version) 167 config = config.replace('{TEST_TYPE_CAMEL}', 168 self._FuzzerTypeCamel(fuzzer_type)) 169 config = config.replace('{TEST_TYPE_UNDERSCORE}', 170 self._FuzzerTypeUnderscore(fuzzer_type)) 171 return config 172 173 def _IsTestable(self, hal_name, hal_version): 174 """Returns true iff hal can be tested.""" 175 if 'tests' in hal_name: 176 return False 177 return True 178