Home | History | Annotate | Download | only in tools
      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 
     18 import os
     19 import argparse
     20 import math
     21 
     22 
     23 class 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 
    132 class 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 
    184 def 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 
    210 if __name__ == '__main__':
    211     main()
    212