#!/usr/bin/env python # # Copyright 2016 - 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 os import argparse import math class Module(object): """class used to represent a ltp module Attribute: _lines: list of string, lines of module text _header: list of string, first line of module splited by := _type: string, type of module _path: string, path of module _output_dir: string, output directory of module """ _lines = None _header = None _type = None _path = None _output_dir = None def __init__(self, output_dir): self._output_dir = output_dir def parse(self, module_text): """parse a module text Args: module_text: string, one block of ltp module build rule. output_dir: string, ltp compile output directory Return: None if the input text is not a ltp module Self if parsed succesfully """ self._lines = module_text.splitlines() if len(self._lines) < 2: self._type = None return None self._header = self._lines[0].split(' := ') if len(self._header) < 2: self._type = None return None self._type = self._header[0] self._path = self._header[1] return self def IsBuildSuccess(self, counts): """Check whether a given module specified in Android.mk file is succesfully built Returns: True if success """ if self._type is None: return False counts[self._type] = counts.get(self._type, 0) + 1 success = {"module_testname": self.IsBuildSuccessModuleTestname, "module_libname": self.IsBuildSuccessModuleLibname, "module_prebuilt": self.IsBuildSuccessModulePrebuilt, }[self._type]() if not success: print " Module build failed: " + os.path.basename(self._path) return success def IsBuildSuccessModuleTestname(self): """Check whether a given ltp test module in Android.mk file is succesfully built Args: module_path: string, the path of module on the first line of the block Returns: True if success """ return os.path.isfile(self._output_dir + \ "testcases/bin/" + \ os.path.basename(self._path)) def IsBuildSuccessModuleLibname(self): """Check whether a given ltp lib module in Android.mk file is succesfully built Args: module_path: the path of module on the first line of the block Returns: True if success """ # TODO(yuexima) check lib build print "Checking module_lib is not supported now, " + \ "assuming build success: " + self._path return True def IsBuildSuccessModulePrebuilt(self): """Check whether a given prebuilt module in Android.mk file is succesfully built Args: module_path: string, the path of module on the first line of the block Returns: True if success """ return os.path.isfile(self._output_dir + self._path) class LtpModuleChecker(object): """LTP module result check class. Checks for success build of each module in LTP's Android.mk file and rewrite it with only successfully built modules. """ _output_dir = "" _file_path_android_ltp_mk = "" _module_counts = {} def __init__(self, android_build_top, ltp_dir, target_product): self._output_dir = android_build_top + '/out/target/product/' + \ target_product + '/data/nativetest/ltp/' self._file_path_android_ltp_mk = ltp_dir + '/Android.ltp.mk' def Read(self, file_path): """Read a file and return its entire content Args: file_path: string, file path Returns: entire file content in string format """ with open(file_path, 'r') as file: return file.read() def LoadModules(self): """Read the LTP Android.mk file and seperate modules into a list of string """ return self.Read(self._file_path_android_ltp_mk).split("\n\n") def CheckModules(self): """Start the LTP module build result checking and counting.""" modules = [Module(self._output_dir).parse(module) for module in self.LoadModules()] modules_succeed = \ [module for module in modules if module is not None and module.IsBuildSuccess(self._module_counts) ] print "module type counts:" print self._module_counts print str(len(modules_succeed)) + \ " of " + str(sum([self._module_counts[i] for i in self._module_counts])) + \ " modules were succesfully built." print "--Check complete." def main(): parser = argparse.ArgumentParser( description='Generate Android.mk from parsed LTP make output') parser.add_argument( '--android_build_top', dest='android_build_top', required=True, help='android build top directory') parser.add_argument( '--ltp_dir', dest='ltp_dir', required=True, help='directory for the forked ltp project') parser.add_argument( '--target_product', dest='target_product', required=True, help='target product name, \ such as "bullhead", "angler", etc.') args = parser.parse_args() checker = LtpModuleChecker(args.android_build_top, args.ltp_dir, args.target_product) checker.CheckModules() if __name__ == '__main__': main()