1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3""" 4Copyright (c) 2021 Huawei Device Co., Ltd. 5Licensed under the Apache License, Version 2.0 (the "License"); 6you may not use this file except in compliance with the License. 7You may obtain a copy of the License at 8 9 http://www.apache.org/licenses/LICENSE-2.0 10 11Unless required by applicable law or agreed to in writing, software 12distributed under the License is distributed on an "AS IS" BASIS, 13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14See the License for the specific language governing permissions and 15limitations under the License. 16""" 17 18 19import os 20import sys 21import argparse 22import re 23import subprocess 24import xml.dom.minidom 25from xml.parsers.expat import ExpatError 26from string import Template 27import utils 28import json 29import shutil 30import platform 31 32 33class SuiteModuleBuilder: 34 """ 35 To Build Suite Module 36 @arguments(build_target_name, target_file...) 37 """ 38 39 def __init__(self, arguments): 40 self.arguments = arguments 41 self.args = None 42 43 def build_module(self): 44 """ 45 build_target_name='wifiaware_test', 46 javalib_file=None, 47 project_path='xxx/communication_lite/wifiaware', 48 project_type='hctest', 49 source_path='xxx/x.c,xxx/x.c 50 subsystem_name='communication', 51 suite_filename='libwifiaware_test.a', 52 suite_out_paths='out/x/suites/acts/testcases/communication,' 53 target_file='xxxx/libs/libmodule_wifiaware_test.a', 54 test_xml='xxx/Test.json' 55 :return: 56 """ 57 58 parser = argparse.ArgumentParser() 59 parser.add_argument('--build_target_name', help='', required=False) 60 parser.add_argument('--target_file', help='', required=False) 61 parser.add_argument('--hap_name', help='', required=False) 62 parser.add_argument('--project_path', help='', required=True) 63 parser.add_argument('--test_xml', help='', required=False) 64 parser.add_argument('--project_type', help='', required=True) 65 parser.add_argument('--suite_out_paths', help='', required=True) 66 parser.add_argument('--suite_filename', help='', required=True) 67 parser.add_argument('--subsystem_name', help='', required=False) 68 parser.add_argument('--build_root_path', help='', required=False) 69 parser.add_argument('--hap_sign', help='', required=False) 70 self.args = parser.parse_args(self.arguments) 71 72 73 for _suite_out_file in self.args.suite_out_paths.split(","): 74 if not _suite_out_file: 75 continue 76 if self.args.project_type == "pythontest": 77 _out_file = _suite_out_file 78 else: 79 _out_file = os.path.join(_suite_out_file, 80 self.args.suite_filename) 81 if self.args.project_type == "pythontest": 82 utils.copy_file(output=_out_file, 83 source_dirs=self.args.target_file, 84 to_dir=True) 85 elif self.args.project_type == "open_source_test": 86 utils.copy_file(output=_out_file, 87 sources=self.args.target_file, 88 to_dir=True) 89 elif self.args.project_type == "hjsunit": 90 utils.build_js_hap(self.args.project_path, self.args. 91 suite_out_paths, self.args.hap_name) 92 elif self.args.project_type != "hctest": 93 utils.copy_file(output=_out_file, 94 sources=self.args.target_file, 95 to_dir=False) 96 97 _testsuite_name = self.args.suite_filename 98 _matcher = re.match(r"(lib|libmodule_)?(\S+)\.\S+", 99 _testsuite_name) 100 if _matcher: 101 _testsuite_name = _matcher.group(2) 102 if self.args.project_type != "open_source_test": 103 _config_file = os.path.join(_suite_out_file, 104 _testsuite_name + ".json") 105 else: 106 _config_file = os.path.join(_out_file, 107 _testsuite_name + ".json") 108 utils.record_testmodule_info(self.args.build_target_name, 109 _testsuite_name, 110 self.args.subsystem_name, 111 _suite_out_file) 112 _test_xml = self.args.test_xml 113 if _test_xml and os.path.exists(_test_xml): 114 utils.copy_file(output=_config_file, sources=_test_xml, 115 to_dir=False) 116 else: 117 self._generate_xml_by_template(_test_xml, _testsuite_name, 118 _config_file) 119 120 @staticmethod 121 def _record_testmodule_info(build_target_name, module_name, 122 subsystem_name, suite_out_dir): 123 if not build_target_name or not subsystem_name: 124 print( 125 'build_target_name or subsystem_name of testmodule "%s" ' 126 'is invalid!' % module_name) 127 return 128 module_info_dir = os.path.dirname(suite_out_dir) 129 module_info_list_file = os.path.join(module_info_dir, 130 'module_info.json') 131 module_info_data = {} 132 if os.path.exists(module_info_list_file): 133 try: 134 with open(module_info_list_file, 'r') as module_file: 135 module_info_data = json.load(module_file) 136 except ValueError: 137 print("NO json object could be decoded but continue") 138 module_info = {'subsystem': subsystem_name, 139 'build_target_name': build_target_name} 140 module_info_data[module_name] = module_info 141 with open(module_info_list_file, 'w') as out_file: 142 json.dump(module_info_data, out_file) 143 144 def _generate_xml_by_template(self, test_xml, module_name, 145 config_file): 146 index = test_xml.rfind(".json") 147 tmpl_file = test_xml[:index] + ".tmpl" 148 if not os.path.exists(tmpl_file): 149 raise Exception( 150 "Can't find the Test.json or Test.tmpl in the " 151 "path %s " % os.path.dirname( 152 test_xml)) 153 tmpl_content = utils.read_file(tmpl_file) 154 values = {"module": module_name, "subsystem": self.args.subsystem_name} 155 xml_content = Template(tmpl_content).substitute(values) 156 utils.write_file(config_file, xml_content, False) 157 158 @staticmethod 159 def _check_file_exist(file_path): 160 if not os.path.exists(file_path): 161 raise Exception("File [%s] does not exist!" % file_path) 162 163 164class XDeviceBuilder: 165 """ 166 To build XTS as a egg package 167 @arguments(project_dir, output_dirs) 168 """ 169 170 def __init__(self, arguments): 171 parser = argparse.ArgumentParser() 172 parser.add_argument('--project_dir', help='', required=True) 173 parser.add_argument('--output_dirs', help='', required=True) 174 self.args = parser.parse_args(arguments) 175 176 def build_xdevice(self): 177 """ 178 build xdevice package 179 :return: 180 """ 181 command = [utils.get_python_cmd(), "setup.py", "install", "--user"] 182 factory_script = os.path.join(self.args.project_dir, "factory.sh") 183 if os.path.exists(factory_script): 184 os.chmod(factory_script, 0o775) 185 command = factory_script 186 try: 187 subprocess.check_call(command, cwd=self.args.project_dir) 188 except subprocess.CalledProcessError as exc: 189 print('returncode: {} cmd: {} output: {}'.format( 190 exc.returncode, exc.cmd, exc.output)) 191 192 dist_dir = os.path.join(self.args.project_dir, 'dist') 193 run_scripts = ",".join( 194 [os.path.join(self.args.project_dir, "run.bat"), 195 os.path.join(self.args.project_dir, "run.sh")]) 196 config_dir = os.path.join(self.args.project_dir, "config") 197 res_dir = os.path.join(self.args.project_dir, "resource") 198 for tool_dir in self.args.output_dirs.split(","): 199 if tool_dir: 200 utils.copy_file(output=tool_dir, source_dirs=dist_dir, 201 to_dir=True) 202 root_dir = os.path.dirname(tool_dir) 203 utils.copy_file(output=root_dir, sources=run_scripts, 204 to_dir=True) 205 to_dir = os.path.join(root_dir, "config") 206 utils.copy_file(output=to_dir, source_dirs=config_dir, 207 to_dir=True) 208 utils.copy_file(os.path.join(root_dir, "resource"), 209 source_dirs=res_dir) 210 if not os.path.exists(os.path.join( 211 root_dir, "resource", "tools")): 212 os.mkdir(os.path.join(root_dir, "resource", "tools")) 213 return 0 214 215 216class SuiteArchiveBuilder: 217 def __init__(self, arguments): 218 self.module_info_dir = None 219 self.arguments = arguments 220 221 def archive_suite(self): 222 parser = argparse.ArgumentParser() 223 parser.add_argument('--suite_path', help='', required=True) 224 parser.add_argument('--build_enabled', help='', required=True) 225 args = parser.parse_args(self.arguments) 226 if not args.build_enabled.lower() == 'true': 227 print('build hit not enabled, skip making archive') 228 return 0 229 230 suite_path = args.suite_path 231 if not os.path.isdir(suite_path): 232 raise Exception("[%s] does not exist" % suite_path) 233 234 archive_name = os.path.basename(suite_path) 235 suite_root_path = os.path.dirname(suite_path) 236 shutil.make_archive(suite_path, "zip", suite_root_path, archive_name) 237 return 0 238 239 240ACTION_MAP = {"build_module": "SuiteModuleBuilder", 241 "build_xdevice": "XDeviceBuilder", 242 "archive_suite": "SuiteArchiveBuilder", 243 } 244 245 246def _find_action(action, arguments): 247 class_name = ACTION_MAP[action] 248 if not class_name: 249 raise ValueError('Unsupported operation: %s' % action) 250 251 this_module = sys.modules[__name__] 252 class_def = getattr(this_module, class_name, None) 253 if not class_def: 254 raise ValueError( 255 'Unsupported operation(No Implementation Class): %s' % action) 256 class_obj = class_def(arguments) 257 func = getattr(class_obj, action, None) 258 if not func: 259 raise ValueError( 260 'Unsupported operation(No Implementation Method): %s' % action) 261 return func 262 263 264def main(arguments): 265 action = arguments[0] 266 args = arguments[1:] 267 func = _find_action(action, args) 268 func() 269 return 0 270 271 272if __name__ == '__main__': 273 sys.exit(main(sys.argv[1:])) 274