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