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 ohos_dir = os.path.join(self.args.project_dir, 'plugins', 'ohos') 182 command = [utils.get_python_cmd(), "setup.py", "install", "--user"] 183 factory_script = os.path.join(self.args.project_dir, "factory.sh") 184 if os.path.exists(factory_script): 185 os.chmod(factory_script, 0o775) 186 command = factory_script 187 try: 188 subprocess.check_call(command, cwd=self.args.project_dir) 189 subprocess.check_call(command, cwd=ohos_dir) 190 except subprocess.CalledProcessError as exc: 191 print('returncode: {} cmd: {} output: {}'.format( 192 exc.returncode, exc.cmd, exc.output)) 193 194 dist_dir = os.path.join(self.args.project_dir, 'dist') 195 ohos_dist_dir = os.path.join(ohos_dir, 'dist') 196 run_scripts = ",".join( 197 [os.path.join(self.args.project_dir, "run.bat"), 198 os.path.join(self.args.project_dir, "run.sh")]) 199 config_dir = os.path.join(self.args.project_dir, "config") 200 res_dir = os.path.join(self.args.project_dir, "resource") 201 for tool_dir in self.args.output_dirs.split(","): 202 if tool_dir: 203 utils.copy_file(output=tool_dir, source_dirs=dist_dir, 204 to_dir=True) 205 utils.copy_file(output=tool_dir, source_dirs=ohos_dist_dir, 206 to_dir=True) 207 root_dir = os.path.dirname(tool_dir) 208 utils.copy_file(output=root_dir, sources=run_scripts, 209 to_dir=True) 210 to_dir = os.path.join(root_dir, "config") 211 utils.copy_file(output=to_dir, source_dirs=config_dir, 212 to_dir=True) 213 utils.copy_file(os.path.join(root_dir, "resource"), 214 source_dirs=res_dir) 215 if not os.path.exists(os.path.join( 216 root_dir, "resource", "tools")): 217 os.mkdir(os.path.join(root_dir, "resource", "tools")) 218 return 0 219 220 221class SuiteArchiveBuilder: 222 def __init__(self, arguments): 223 self.module_info_dir = None 224 self.arguments = arguments 225 226 def archive_suite(self): 227 parser = argparse.ArgumentParser() 228 parser.add_argument('--suite_path', help='', required=True) 229 parser.add_argument('--build_enabled', help='', required=True) 230 args = parser.parse_args(self.arguments) 231 if not args.build_enabled.lower() == 'true': 232 print('build hit not enabled, skip making archive') 233 return 0 234 235 suite_path = args.suite_path 236 if not os.path.isdir(suite_path): 237 raise Exception("[%s] does not exist" % suite_path) 238 239 archive_name = os.path.basename(suite_path) 240 suite_root_path = os.path.dirname(suite_path) 241 shutil.make_archive(suite_path, "zip", suite_root_path, archive_name) 242 return 0 243 244 245ACTION_MAP = {"build_module": "SuiteModuleBuilder", 246 "build_xdevice": "XDeviceBuilder", 247 "archive_suite": "SuiteArchiveBuilder", 248 } 249 250 251def _find_action(action, arguments): 252 class_name = ACTION_MAP[action] 253 if not class_name: 254 raise ValueError('Unsupported operation: %s' % action) 255 256 this_module = sys.modules[__name__] 257 class_def = getattr(this_module, class_name, None) 258 if not class_def: 259 raise ValueError( 260 'Unsupported operation(No Implementation Class): %s' % action) 261 class_obj = class_def(arguments) 262 func = getattr(class_obj, action, None) 263 if not func: 264 raise ValueError( 265 'Unsupported operation(No Implementation Method): %s' % action) 266 return func 267 268 269def main(arguments): 270 action = arguments[0] 271 args = arguments[1:] 272 func = _find_action(action, args) 273 func() 274 return 0 275 276 277if __name__ == '__main__': 278 sys.exit(main(sys.argv[1:])) 279