• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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