diff --git a/src/core/build/build_manager.py b/src/core/build/build_manager.py index 04f0a2fda8770b521f6a0eee3636adf70fd84115..b7ca0e22b5e91e57e9a100aee24dbf9bef919ce7 100644 --- a/src/core/build/build_manager.py +++ b/src/core/build/build_manager.py @@ -24,6 +24,7 @@ from core.build.select_targets import SelectTargets from core.build.pretreat_targets import PretreatTargets from core.build.build_testcases import BuildTestcases from core.command.gen import Gen +from core.command.run import Run LOG = platform_logger("BuildManager") @@ -64,6 +65,31 @@ class BuildManager(object): build_result = False return build_result + # 根据json生成部件间依赖关系 + # para 指令参数 + # 编译代码生成中间文件,只执行gn阶段,并打开check_deps属性 + + @classmethod + def _compile_deps_files(cls, project_root_path, para): + build_deps_files_result = False + if BuildTestcases(project_root_path).build_deps_files(para.productform): + LOG.info("Deps files compilation successed.") + build_deps_files_result = True + else: + LOG.info("Deps files compilation failed, please modify.") + return build_deps_files_result + + # 运行脚本,生成part_deps_info.json部件间依赖关系文件 + @classmethod + def _compile_part_deps(cls, project_root_path, para): + build_part_deps_result = False + if BuildTestcases(project_root_path).build_part_deps(para): + LOG.info("Part deps info compilation successed.") + build_part_deps_result = True + else: + LOG.info("Part deps info compilation failed, please modify.") + return build_part_deps_result + # 根据目标编译xts测试用例 # project_root_path 工程根目录 # para 指令参数 @@ -99,12 +125,28 @@ class BuildManager(object): build_lite_manager = BuildLiteManager(project_root_path) return build_lite_manager.build_testcases(para) + # 如果测试集不为空或测试部件不为空,build_target为测试集或测试部件 # 如果测试集不为空,build_target为测试集 if para.testsuit != "": return self._compile_test_cases_by_target( project_root_path, para.productform, para.testsuit) + if para.partname_list != "": + if "partdeps" == para.partdeps: + LOG.info("External deps part build.") + external_deps_part_list = Run.get_part_deps_list(para.productform, para.testpart) + external_deps_part_list.append(para.testpart[0]) + return self._compile_test_cases_by_target( + project_root_path, + para.productform, + external_deps_part_list) + else: + LOG.info("Multi testpart build.") + return self._compile_test_cases_by_target( + project_root_path, + para.productform, + para.partname_list) # 如果测试集为空,部件列表为空,模块列表为空,测试类型中含有“ALL”,build_target为"make_test" if (len(para.partname_list) == 0 and para.testmodule == "" and @@ -185,6 +227,12 @@ class BuildManager(object): build_xts_result = True build_result = True + if "partdeps" == param.partdeps: + LOG.info("**********************Start prebuild testcases****************************") + build_deps_files_result = self._compile_deps_files(project_root_path, param) + if build_deps_files_result: + self._compile_part_deps(project_root_path, param) + if "acts" in param.testtype or "hats" in param.testtype or "hits" in param.testtype: LOG.info("**********************Start build xts testcases****************************") build_xts_result = self._compile_xts_test_cases(project_root_path, param) diff --git a/src/core/build/build_testcases.py b/src/core/build/build_testcases.py index cdbb57f299fca94f980e800ef09de1aa9eb0b6cd..6572097df9e88bb9639166b357dce4ce25deb327 100644 --- a/src/core/build/build_testcases.py +++ b/src/core/build/build_testcases.py @@ -45,6 +45,11 @@ class BuildTestcases(object): def __init__(self, project_rootpath): self.project_rootpath = project_rootpath user_manager = UserConfigManager() + self.part_deps_path = os.path.join(sys.source_code_root_path, + "build", + "tools", + "module_dependence", + "part_deps.py") self.is_build_example = user_manager.get_user_config_flag( "build", "example") self.build_parameter_dic = user_manager.get_user_config( @@ -196,6 +201,54 @@ class BuildTestcases(object): os.chdir(current_path) return build_result + def _execute_build_deps_files_command(self, productform, command): + build_deps_files_result = False + current_path = os.getcwd() + os.chdir(self.project_rootpath) + + command.append("--product-name") + command.append(productform) + + if os.path.exists(BUILD_FILEPATH): + build_deps_files_command = [BUILD_FILEPATH] + build_deps_files_command.extend(command) + LOG.info("build_deps_files_command: %s" % str(build_deps_files_command)) + if subprocess.call(build_deps_files_command) == 0: + build_deps_files_result = True + else: + build_deps_files_result = False + else: + LOG.warning("Build Deps Files Error: The %s is not exist" % BUILD_FILEPATH) + + os.chdir(current_path) + return build_deps_files_result + + def _execute_build_part_deps_command(self, para): + build_part_deps_result = False + build_part_deps_command = [] + current_path = os.getcwd() + #路径 deps_files_path = ~/OpenHarmony/out/baltimore/deps_files + os.chdir(self.project_rootpath) + deps_files_path = os.path.abspath(os.path.join( + get_build_output_path(para.productform), + "deps_files")) + LOG.info("deps_files_path: %s" % deps_files_path) + build_part_deps_command.append(self.part_deps_path) + build_part_deps_command.append("--deps-files-path") + + if os.path.exists(deps_files_path): + build_part_deps_command.append(deps_files_path) + LOG.info("build_part_deps_command: %s" % str(build_part_deps_command)) + if subprocess.call(build_part_deps_command) == 0: + build_part_deps_result = True + else: + build_part_deps_result = False + else: + LOG.warning("Build Part Deps Info Error: The %s is not exist" % deps_files_path) + + os.chdir(current_path) + return build_part_deps_result + def _execute_build_xts_command(self, para): build_result = False xts_build_command = [] @@ -250,8 +303,14 @@ class BuildTestcases(object): if self.is_build_example: command.append("--gn-args") command.append("build_example=true") - command.append("--build-target") - command.append(target) + if isinstance(target, list): + for test in target: + command.append("--build-target") + command.append(test + "_test") + elif isinstance(target, str): + for test in target.split(','): + command.append("--build-target") + command.append(test) target_cpu = self.build_parameter_dic.get("target_cpu") if target_cpu == "arm64": if productform == "m40": @@ -275,6 +334,26 @@ class BuildTestcases(object): build_result = self._execute_build_xts_command(para) return build_result + def build_deps_files(self, productform): + command = [] + command.append("--ccache") + command.append("--gn-args") + command.append("pycache_enable=true") + command.append("--gn-args") + command.append("check_deps=true") + command.append("--build-only-gn") + target_cpu = self.build_parameter_dic.get("target_cpu") + if target_cpu == "arm64": + if productform == "m40": + command.append("--target-cpu") + command.append(target_cpu) + return self._execute_build_deps_files_command(productform, command) + + #部件间依赖关系预处理,生成part_deps_info.json + def build_part_deps(self, para): + build_part_deps_result = self._execute_build_part_deps_command(para) + return build_part_deps_result + def build_gn_file(self, productform): command = [] if self.is_build_example: diff --git a/src/core/command/console.py b/src/core/command/console.py index 16453180d19ff15312f5e2db66ef38a23c93b66e..d35ef17a513280687c9dd5a23575cb178f335f88 100755 --- a/src/core/command/console.py +++ b/src/core/command/console.py @@ -281,6 +281,14 @@ class Console(object): help="Specify random name", choices=["random"] ) + parser.add_argument("-pd", "--partdeps", + action="store", + type=str, + dest="partdeps", + default="", + help="Specify part deps", + choices=["partdeps"] + ) # 解析部分命令行参数,会返回一个由两个条目构成的元组,其中包含带成员的命名空间(options)和剩余参数字符串的列表(unparsed) cls._params_pre_processing(para_list) diff --git a/src/core/command/run.py b/src/core/command/run.py index d47b2b279a3d46cf283d0fa419e6459e8d058856..c159190fdacd824ca00e3a5582ef6dcb87a74dfd 100644 --- a/src/core/command/run.py +++ b/src/core/command/run.py @@ -84,6 +84,7 @@ class Run(object): LOG.info("historylist = %s" % options.historylist) LOG.info("runhistory = %s" % options.runhistory) LOG.info("partname_list = %s" % str(options.partname_list)) + LOG.info("partdeps = %s" % options.partdeps) LOG.info("------------------------------------") LOG.info("") @@ -165,6 +166,11 @@ class Run(object): LOG.error("Build test cases failed.") return + if "partdeps" == options.partdeps: + self.get_part_deps_list(options.productform, options.testpart) + options.testcases_path = self.get_external_deps_out_path(options.productform) + LOG.info("partdeps = %s" % options.partdeps) + if "acts" in options.testtype or "hats" in options.testtype or "hits" in options.testtype: test_dict = self.get_xts_test_dict(options) options.testcases_path = self.get_xts_tests_out_path(options.productform, options.testtype) @@ -338,6 +344,15 @@ class Run(object): LOG.info("xts_testcase_path=%s" % xts_testcase_path) return xts_testcase_path + @classmethod + def get_external_deps_out_path(cls, product_form): + external_deps_path = os.path.abspath(os.path.join( + get_build_output_path(product_form), + "part_deps_info", + "part_deps_info.json")) + LOG.info("external_deps_path=%s" % external_deps_path) + return external_deps_path + @classmethod def get_coverage_outpath(cls, options): coverage_out_path = "" @@ -350,6 +365,13 @@ class Run(object): LOG.error("Coverage test: coverage_outpath is empty.") return coverage_out_path + @classmethod + def get_part_deps_list(cls, productform, testpart): + #获取预处理部件间依赖的编译结果路径 + external_deps_path = cls.get_external_deps_out_path(productform) + external_deps_path_list = TestCaseManager().get_part_deps_files(external_deps_path, testpart) + return external_deps_path_list + def get_xts_test_dict(self, options): # 获取XTS测试用例编译结果路径 xts_test_case_path = self.get_xts_tests_out_path(options.productform, options.testtype) diff --git a/src/core/testcase/testcase_manager.py b/src/core/testcase/testcase_manager.py index e1f7fe109e02410044e61eb72540c095223efa8b..25c1b537fa1d5711685b4c0d53ae10676cbf1fc5 100644 --- a/src/core/testcase/testcase_manager.py +++ b/src/core/testcase/testcase_manager.py @@ -156,6 +156,25 @@ class TestCaseManager(object): return suite_file_dictionary + def get_part_deps_files(self, external_deps_path, testpart): + LOG.info("external_deps_path:" + external_deps_path) + if os.path.exists(external_deps_path): + with open(external_deps_path, 'r') as json_file: + data_dic = json.load(json_file) + if not data_dic: + LOG.error("data_dic is empty.") + return [] + test_part = testpart[0] + if test_part in data_dic.keys(): + external_deps_part_list = data_dic.get(test_part) + LOG.info("external_deps_part_list = %s" % external_deps_part_list) + return external_deps_part_list + else: + LOG.error("%s is not in part deps info json." % test_part) + else: + LOG.error("Part deps info %s is not exist." % external_deps_path) + return [] + def check_xts_config_match(self, options, prefix_name, xts_suite_file): # 如果xts测试指定了-tp,只有部件名与moduleInfo中part一致的文件才会加入最终执行的队列 if options.testpart != [] and options.testpart[0] != self.get_part_name_test_file(xts_suite_file): @@ -205,8 +224,12 @@ class TestCaseManager(object): if testsuit != "": short_name, _ = os.path.splitext(os.path.basename(suite_file)) - return short_name.startswith(testsuit) or \ - testsuit.startswith(short_name) + testsuit_list = testsuit.split(',') + for test in testsuit_list: + if short_name.startswith(test) or \ + testsuit.startswith(short_name): + return True + return False is_valid_status = False suitfile_subpath = suite_file.replace(test_case_out_path, "")