1#!/usr/bin/env python 2# 3# Copyright 2016 - 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 18import os 19import argparse 20import math 21 22 23class Module(object): 24 """class used to represent a ltp module 25 26 Attribute: 27 _lines: list of string, lines of module text 28 _header: list of string, first line of module splited by := 29 _type: string, type of module 30 _path: string, path of module 31 _output_dir: string, output directory of module 32 """ 33 _lines = None 34 _header = None 35 _type = None 36 _path = None 37 _output_dir = None 38 39 def __init__(self, output_dir): 40 self._output_dir = output_dir 41 42 def parse(self, module_text): 43 """parse a module text 44 45 Args: 46 module_text: string, one block of ltp module build rule. 47 output_dir: string, ltp compile output directory 48 49 Return: 50 None if the input text is not a ltp module 51 Self if parsed succesfully 52 """ 53 self._lines = module_text.splitlines() 54 if len(self._lines) < 2: 55 self._type = None 56 return None 57 self._header = self._lines[0].split(' := ') 58 if len(self._header) < 2: 59 self._type = None 60 return None 61 self._type = self._header[0] 62 self._path = self._header[1] 63 return self 64 65 def IsBuildSuccess(self, counts): 66 """Check whether a given module specified in Android.mk file 67 is succesfully built 68 69 Returns: 70 True if success 71 """ 72 if self._type is None: 73 return False 74 75 counts[self._type] = counts.get(self._type, 0) + 1 76 77 success = {"module_testname": self.IsBuildSuccessModuleTestname, 78 "module_libname": self.IsBuildSuccessModuleLibname, 79 "module_prebuilt": self.IsBuildSuccessModulePrebuilt, 80 }[self._type]() 81 82 if not success: 83 print " Module build failed: " + os.path.basename(self._path) 84 return success 85 86 def IsBuildSuccessModuleTestname(self): 87 """Check whether a given ltp test module in Android.mk file 88 is succesfully built 89 90 Args: 91 module_path: string, the path of module on the first 92 line of the block 93 94 Returns: 95 True if success 96 """ 97 98 return os.path.isfile(self._output_dir + \ 99 "testcases/bin/" + \ 100 os.path.basename(self._path)) 101 102 def IsBuildSuccessModuleLibname(self): 103 """Check whether a given ltp lib module in Android.mk file 104 is succesfully built 105 106 Args: 107 module_path: the path of module on the first line of 108 the block 109 110 Returns: 111 True if success 112 """ 113 # TODO(yuexima) check lib build 114 print "Checking module_lib is not supported now, " + \ 115 "assuming build success: " + self._path 116 return True 117 118 def IsBuildSuccessModulePrebuilt(self): 119 """Check whether a given prebuilt module in Android.mk file 120 is succesfully built 121 122 Args: 123 module_path: string, the path of module on the first 124 line of the block 125 126 Returns: 127 True if success 128 """ 129 return os.path.isfile(self._output_dir + self._path) 130 131 132class LtpModuleChecker(object): 133 """LTP module result check class. 134 Checks for success build of each module in LTP's Android.mk file 135 and rewrite it with only successfully built modules. 136 """ 137 _output_dir = "" 138 _file_path_android_ltp_mk = "" 139 _module_counts = {} 140 141 def __init__(self, android_build_top, ltp_dir, target_product): 142 self._output_dir = android_build_top + '/out/target/product/' + \ 143 target_product + '/data/nativetest/ltp/' 144 self._file_path_android_ltp_mk = ltp_dir + '/Android.ltp.mk' 145 146 def Read(self, file_path): 147 """Read a file and return its entire content 148 149 Args: 150 file_path: string, file path 151 152 Returns: 153 entire file content in string format 154 """ 155 with open(file_path, 'r') as file: 156 return file.read() 157 158 def LoadModules(self): 159 """Read the LTP Android.mk file and seperate modules into 160 a list of string 161 """ 162 return self.Read(self._file_path_android_ltp_mk).split("\n\n") 163 164 def CheckModules(self): 165 """Start the LTP module build result checking and counting.""" 166 modules = [Module(self._output_dir).parse(module) 167 for module in self.LoadModules()] 168 modules_succeed = \ 169 [module for module in modules 170 if module is not None and 171 module.IsBuildSuccess(self._module_counts) 172 ] 173 174 print "module type counts:" 175 print self._module_counts 176 177 print str(len(modules_succeed)) + \ 178 " of " + str(sum([self._module_counts[i] 179 for i in self._module_counts])) + \ 180 " modules were succesfully built." 181 print "--Check complete." 182 183 184def main(): 185 parser = argparse.ArgumentParser( 186 description='Generate Android.mk from parsed LTP make output') 187 parser.add_argument( 188 '--android_build_top', 189 dest='android_build_top', 190 required=True, 191 help='android build top directory') 192 parser.add_argument( 193 '--ltp_dir', 194 dest='ltp_dir', 195 required=True, 196 help='directory for the forked ltp project') 197 parser.add_argument( 198 '--target_product', 199 dest='target_product', 200 required=True, 201 help='target product name, \ 202 such as "bullhead", "angler", etc.') 203 args = parser.parse_args() 204 205 checker = LtpModuleChecker(args.android_build_top, args.ltp_dir, 206 args.target_product) 207 checker.CheckModules() 208 209 210if __name__ == '__main__': 211 main() 212