1#!/usr/bin/env python3 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 18import os 19import fnmatch 20import sys 21import argparse 22import json 23import platform 24import subprocess 25 26import distutils.dir_util as dir_util 27import distutils.file_util as file_util 28from distutils.errors import DistutilsError 29 30 31# all sub system list, must be lowercase. 32_SUB_SYSTEM_LIST = [ 33 "kernel", 34 "hiviewdfx", 35 "communication", 36 "security", 37 "update", 38 "sstsutils", 39 "utils", 40 "multimedia", 41 "hdf", 42 "aafwk", 43 "appexecfwk", 44 "distributed_schedule", 45 "startup", 46 "sensors", 47 "sample", 48 "iot_hardware", 49 "open_posix_testsuite", 50 "graphic", 51 "ace", 52 "applications", 53 "ai", 54 "global", 55 "telephony", 56 "dcts" 57] 58 59_NO_FILTE_SUB_SYSTEM_LIST = [ 60 "applications", 61 "kernel", 62 "open_posix_testsuite", 63 "sample", 64 "telephony", 65 "dcts", 66 "hiviewdfx", 67 "security", 68 "update", 69 "sstsutils", 70 "hdf", 71 "distributed_schedule" 72] 73 74 75def main(): 76 parser = argparse.ArgumentParser() 77 parser.add_argument('--method_name', help='', required=True) 78 parser.add_argument('--arguments', help='', 79 required=True) # format key=value#key=value 80 args = parser.parse_args() 81 this_module = sys.modules[__name__] 82 method = getattr(this_module, args.method_name) 83 arguments = {} 84 for argument in args.arguments.split("#"): 85 key_value = argument.strip().split("=") 86 if len(key_value) != 2: 87 raise ValueError( 88 "The arguments' format is 'key=value#key=value'. Wrong format:" 89 " " + argument) 90 arguments.setdefault(key_value[0].strip(), key_value[1].strip()) 91 method(**arguments) 92 return 0 93 94 95def read_file(input_file): 96 if not os.path.exists(input_file): 97 return "" 98 99 with open(input_file, 'r') as input_f: 100 content = input_f.read().strip() 101 return content 102 103 104def write_file(output_file, content, append): 105 file_dir = os.path.dirname(os.path.abspath(output_file)) 106 if not os.path.exists(file_dir): 107 os.makedirs(file_dir) 108 mode = 'a+' if append else 'w' 109 with open(output_file, mode) as output_f: 110 output_f.write("%s\n" % content) 111 112 113def copy_file(output, sources="", source_dirs="", to_dir=True): 114 """ 115 copy source files or source dir to output. 116 if sources is not empty, the output can be file(will be created 117 automatically) 118 or directory(must be exist). 119 :param output: If source_dirs is not empty, output must be directory. 120 :param sources: source files is separated by dot 121 :param source_dirs: source directory is separated by dot 122 :param to_dir: output is directory or not 123 :return: 124 """ 125 if not sources and not source_dirs: 126 raise Exception( 127 "sources or source_dirs parameter must be specified one") 128 _output = output.strip() 129 _sources = sources.strip() 130 _source_dirs = source_dirs.strip() 131 _parent_output = os.path.dirname(_output) 132 try: 133 if to_dir and not os.path.exists(_output): 134 os.makedirs(_output) 135 if not to_dir and not os.path.exists(_parent_output): 136 os.makedirs(_parent_output) 137 except OSError: 138 if not os.path.isdir(_output): 139 raise 140 try: 141 if _sources: 142 _copy_files(_sources.split(","), _output) 143 144 if _source_dirs: 145 _copy_dir(_source_dirs.split(","), _output) 146 except DistutilsError: 147 print("ignore file exist error") 148 return 0 149 150 151def _copy_files(sources, output): 152 copy_set = set() 153 for source_file in sources: 154 source_file = source_file.strip() 155 if os.path.isfile(source_file) and os.path.exists(source_file): 156 # if same file name exist, add dir path 157 if os.path.basename(source_file) in copy_set: 158 new_output = os.path.join(output, os.path.dirname(source_file). 159 split(os.sep)[-1]) 160 if not os.path.exists(new_output): 161 os.makedirs(new_output) 162 file_util.copy_file(source_file, new_output) 163 else: 164 file_util.copy_file(source_file, output) 165 copy_set.add(os.path.basename(source_file)) 166 167 168def _copy_dir(sources, output): 169 for source_file in sources: 170 source_file = source_file.strip() 171 if os.path.isdir(source_file): 172 dir_util.copy_tree(source_file, output) 173 174 175def gen_suite_out(suite_output_prefix, suite_names, out_suffix): 176 outputs = [] 177 _suite_output_prefix = suite_output_prefix.strip() 178 _dirname_suffix = out_suffix.strip().rstrip(os.sep) 179 for suite in suite_names.split(","): 180 path = "%s%s/%s" % ( 181 _suite_output_prefix, suite.strip(), _dirname_suffix) 182 outputs.append(path) 183 print(path) 184 return outputs 185 186 187def get_subsystem_name(path): 188 subsystem_name = "" 189 for subsystem in _SUB_SYSTEM_LIST: 190 subsystem_path = "/" + subsystem + "/" 191 _path = path.lower() 192 if subsystem_path in _path: 193 subsystem_name = subsystem 194 break 195 subsystem_path = "/" + subsystem + "_lite/" 196 if subsystem_path in _path: 197 subsystem_name = subsystem 198 break 199 sys.stdout.write(subsystem_name) 200 return subsystem_name 201 202 203def get_modulename_by_buildtarget(module_list_file, build_target): 204 if not os.path.exists(module_list_file): 205 return "" 206 with open(module_list_file, "r") as module_file: 207 module_info_data = json.load(module_file) 208 for module in module_info_data: 209 if module_info_data[module]["build_target_name"] == build_target: 210 sys.stdout.write(module) 211 return module 212 return "" 213 214 215def glob(path, filename_pattern): 216 files = [] 217 for dir_path, _, files in os.walk(path): 218 for filename in fnmatch.filter(files, filename_pattern): 219 files.append(os.path.join(dir_path, filename)) 220 return files 221 222 223def filter_by_subsystem(testsuites, product_json): 224 product_info = {} 225 filtered_features = [] 226 subs_comps = {} 227 # parses product json to obtain all the subsystem name 228 if os.path.exists(product_json): 229 try: 230 with open(product_json, 'r') as product_info: 231 product_info = json.load(product_info) 232 except ValueError: 233 print("NO json object could be decoded.") 234 subsystem_info = product_info.get("subsystems") 235 for subsystem in subsystem_info: 236 subs_comps[subsystem.get("subsystem")] = \ 237 subsystem.get("components", []) 238 239 feature_list = testsuites.split(",") 240 for feature in feature_list: 241 # if subsytem name match 242 subsystem = get_subsystem_name_no_output(feature) 243 if subsystem in _NO_FILTE_SUB_SYSTEM_LIST: 244 filtered_features.append(feature) 245 print(feature) 246 elif subsystem in subs_comps: 247 components = subs_comps.get(subsystem, []) 248 if check_component(feature, components): 249 filtered_features.append(feature) 250 print(feature) 251 return filtered_features 252 253 254def get_subsystem_name_no_output(path): 255 subsystem_name = "" 256 for subsystem in _SUB_SYSTEM_LIST: 257 subsystem_path = "/" + subsystem 258 _path = path.lower() 259 if subsystem_path in _path: 260 subsystem_name = subsystem 261 break 262 subsystem_path = "/" + subsystem + "_lite" 263 if subsystem_path in _path: 264 subsystem_name = subsystem 265 break 266 return subsystem_name 267 268 269def check_component(path, components): 270 for component in components: 271 component_name = component.get("component", "") 272 component_name = component_name.replace("_lite", "") 273 if component_name in path or "{}_hal".format(component_name) in path \ 274 or "{}_posix".format(component_name) in path: 275 return True 276 return False 277 278 279def get_python_cmd(): 280 major, _, _ = platform.python_version_tuple() 281 if major == "3": 282 return "python" 283 else: 284 return "python3" 285 286 287def record_testmodule_info(build_target_name, module_name, 288 subsystem_name, suite_out_dir, same_file=False): 289 if not build_target_name or not subsystem_name: 290 print( 291 'build_target_name or subsystem_name of testmodule "%s" ' 292 'is invalid!' % module_name) 293 return 294 if same_file: 295 module_info_list_file = os.path.join(suite_out_dir, 'module_info.json') 296 else: 297 module_info_list_file = os.path.join(suite_out_dir, 298 '{}_module_info.json'.format 299 (build_target_name)) 300 module_info_data = {} 301 if os.path.exists(module_info_list_file): 302 try: 303 with open(module_info_list_file, 'r') as module_file: 304 module_info_data = json.load(module_file) 305 except ValueError: 306 print("NO json object could be decoded but continue") 307 module_info = {'subsystem': subsystem_name, 308 'build_target_name': build_target_name} 309 module_info_data[module_name] = module_info 310 with open(module_info_list_file, 'w') as out_file: 311 json.dump(module_info_data, out_file) 312 313 314def record_test_component_info(out_dir, version): 315 if not os.path.exists(out_dir): 316 os.makedirs(out_dir) 317 all_module_file = os.path.join(out_dir, 'module_info.json') 318 all_module_data = {} 319 for root, dirs, files in os.walk(out_dir): 320 for file in files: 321 if file.endswith("module_info.json"): 322 with open(os.path.join(root, file), 'r') as json_data: 323 module_data = json.load(json_data) 324 all_module_data.update(module_data) 325 os.remove(os.path.join(root, file)) 326 with open(all_module_file, 'w') as out_file: 327 json.dump(all_module_data, out_file) 328 329 test_component_file = os.path.join(out_dir, 'test_component.json') 330 test_component_data = {'version': version, } 331 with open(test_component_file, 'w') as out_file: 332 json.dump(test_component_data, out_file) 333 334 335def get_target_modules(all_features): 336 feature_list = [] 337 if all_features: 338 for feature in all_features.split(","): 339 if feature: 340 feature_list.append(feature) 341 print(feature) 342 return feature_list 343 344 345def cmd_popen(cmd): 346 proc = subprocess.Popen(cmd) 347 proc.wait() 348 ret_code = proc.returncode 349 if ret_code != 0: 350 raise Exception("{} failed, return code is {}".format(cmd, ret_code)) 351 352 353def build_js_hap(project_path, out_put_dir, hap_name): 354 if not check_env(): 355 return 356 gradle_dir = os.path.join(project_path, "gradle") 357 os.chdir(gradle_dir) 358 build_clean = ["gradle", "clean"] 359 cmd_popen(build_clean) 360 build_cmd = ["gradle", "entry:packageDebugHap"] 361 cmd_popen(build_cmd) 362 gralde_output_dir = os.path.join(gradle_dir, "entry", "build", "outputs") 363 if os.path.exists(gralde_output_dir): 364 for root, _, files in os.walk(gralde_output_dir): 365 for file in files: 366 if file.endswith(".hap"): 367 file_util.copy_file(os.path.join(root, file), 368 os.path.join(out_put_dir.rstrip(','), 369 hap_name)) 370 return 371 372 373 374def check_env(): 375 """ 376 check all the env for js hap build 377 return: return true if all env ready, otherwise return false 378 """ 379 env_list = ['OHOS_SDK_HOME', 'NODE_HOME', 'GRADLE_HOME'] 380 for env in env_list: 381 if not os.environ.get(env): 382 print("the env {} not set, skip build!".format(env)) 383 return False 384 else: 385 return True 386if __name__ == '__main__': 387 sys.exit(main()) 388