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