From 682e4f32be288b9cf837b370946ed537e0e2d2d8 Mon Sep 17 00:00:00 2001 From: leiwen Date: Fri, 24 Jun 2022 15:15:00 +0800 Subject: [PATCH 01/22] development of compiling function Signed-off-by: leiwen --- src/core/build/build_manager.py | 40 ++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/src/core/build/build_manager.py b/src/core/build/build_manager.py index 0f95c6d..5627e3a 100755 --- a/src/core/build/build_manager.py +++ b/src/core/build/build_manager.py @@ -48,6 +48,10 @@ class BuildManager(object): gn_file.write(" ]\n") gn_file.write("}\n") + # 根据目标编译测试用例 + # project_root_path 工程根目录 + # product_form 产品形态,指令第一步选择的产品 + # build_target 编译目标 @classmethod def _compile_test_cases_by_target(cls, project_root_path, product_form, build_target): @@ -60,6 +64,19 @@ class BuildManager(object): build_result = False return build_result + # 根据目标编译acts测试用例 + # project_root_path 工程根目录 + # para 指令参数 + @classmethod + def _compile_acts_test_cases(cls, project_root_path, para): + if BuildTestcases(project_root_path).build_acts_testcases(para): + LOG.info("Acts test case compilation successed.") + build_result = True + else: + LOG.info("Acts test compilation failed, please modify.") + build_result = False + return build_result + @classmethod def _compile_fuzz_test_case(cls, project_root_path, para): build_result = BuildTestcases( @@ -70,19 +87,23 @@ class BuildManager(object): LOG.info("Test case compilation failed, please modify.") return build_result + # 编译入口 def _compile_testcases(self, project_root_path, para): + # 获取所有支持的产品,3.1Release版本为["DAYU","Hi3516DV300","ohos-arm64","ohos-sdk","rk3568"] all_product_list = scan_support_product() if para.productform not in all_product_list: from core.build.build_lite_manager import BuildLiteManager build_lite_manager = BuildLiteManager(project_root_path) return build_lite_manager.build_testcases(para) + # 如果测试集不为空,build_target为测试集 if para.testsuit != "": return self._compile_test_cases_by_target( project_root_path, para.productform, para.testsuit) + # 如果测试集为空,部件列表为空,模块列表为空,测试类型中含有“ALL”,build_target为"make_test" if (len(para.partname_list) == 0 and para.testmodule == "" and "ALL" in para.testtype): return self._compile_test_cases_by_target( @@ -90,16 +111,18 @@ class BuildManager(object): para.productform, "make_test") + # 如果测试集为空,三个条件(部件列表为空,模块列表为空,测试类型中含有“ALL”)不同时成立 target_list = SelectTargets( project_root_path).filter_build_targets(para) if len(target_list) == 0: LOG.warning("No build target found.") return False + # build_cfg_filepath = OpenHarmony/test/developertest/BUILD.gn build_cfg_filepath = os.path.join(project_root_path, - "test", - "developertest", - "BUILD.gn") + "test", + "developertest", + "BUILD.gn") self._make_gn_file(build_cfg_filepath, target_list) if "fuzztest" in para.testtype: @@ -155,7 +178,14 @@ class BuildManager(object): LOG.info("**************************************************") LOG.info("") - build_result = self._compile_testcases(project_root_path, param) + build_acts_result = True + build_result = True + if "actstest" in param.testtype: + LOG.info("**********************Start build acts testcases****************************") + build_acts_result = self._compile_acts_test_cases(project_root_path, param) + else: + LOG.info("**********************Start build subsystem testcases****************************") + build_result = self._compile_testcases(project_root_path, param) LOG.info("") LOG.info("**************************************************") @@ -163,7 +193,7 @@ class BuildManager(object): LOG.info("**************************************************") LOG.info("") - return build_result + return build_result and build_acts_result ############################################################################## -- Gitee From 3e0a408c65f6623b48782675aa08f2bda2e71c85 Mon Sep 17 00:00:00 2001 From: zhanghaili Date: Fri, 24 Jun 2022 15:18:16 +0800 Subject: [PATCH 02/22] compile and execute command parameter development Signed-off-by: zhanghaili --- src/core/build/build_testcases.py | 55 ++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/src/core/build/build_testcases.py b/src/core/build/build_testcases.py index 3d07569..0000efd 100755 --- a/src/core/build/build_testcases.py +++ b/src/core/build/build_testcases.py @@ -31,6 +31,8 @@ from core.config.config_manager import UserConfigManager BUILD_FILEPATH = "./build.sh" BUILD_LITE = "build/lite/build.py" BUILD_TARGET_PLATFORM = "build_platform=\"%s\"" +BUILD_PRODUCT_NAME = "product_name=%s" +BUILD_TARGET_SUBSYSTEM = "target_subsystem=%s" LOG = platform_logger("BuildTestcases") @@ -40,7 +42,10 @@ LOG = platform_logger("BuildTestcases") class BuildTestcases(object): def __init__(self, project_rootpath): self.project_rootpath = project_rootpath - + self.xts_project_rootpath = os.path.join(sys.source_code_root_path, + "test", + "xts", + "acts") user_manager = UserConfigManager() self.is_build_example = user_manager.get_user_config_flag( "build", "example") @@ -67,6 +72,8 @@ class BuildTestcases(object): return "" testcase_outpath = "" + + # get_build_output_path = OpenHarmony/out/rk3568/build_configs/platforms_info/toolchain_to_variant.json toolchain_filepath = os.path.join( get_build_output_path(productform), "build_configs", @@ -86,6 +93,18 @@ class BuildTestcases(object): testcase_outpath = testcase_outpath[pos:len(testcase_outpath)] return testcase_outpath + @classmethod + def _delete_acts_testcase_dir(cls, productform): + acts_testcase_out_dir = os.path.join( + get_build_output_path(productform), + "suites", + "acts", + "testcases") + LOG.info("acts_testcase_out_dir=%s" % acts_testcase_out_dir) + # 删除~/OpenHarmony/out/rk3568/suites/acts/testcases目录内容 + if os.path.exists(acts_testcase_out_dir): + shutil.rmtree(acts_testcase_out_dir) + def _delete_testcase_dir(self, productform): if is_open_source_product(productform): package_out_dir = os.path.join( @@ -101,12 +120,14 @@ class BuildTestcases(object): "tests") LOG.info("package_out_dir=%s" % package_out_dir) + # 删除~/OpenHarmony/out/rk3568/packages/phone/tests目录内容 if os.path.exists(package_out_dir): shutil.rmtree(package_out_dir) phone_out_dir = os.path.join( self.project_rootpath, "out", "release", "tests") LOG.info("phone_out_dir=%s" % phone_out_dir) + # 删除~/OpenHarmony/out/release/tests目录内容 if os.path.exists(phone_out_dir): shutil.rmtree(phone_out_dir) @@ -177,6 +198,31 @@ class BuildTestcases(object): os.chdir(current_path) return build_result + def _execute_build_acts_command(self, para): + build_result = False + acts_build_command = [] + current_path = os.getcwd() + # acts_rootpath = ~/OpenHarmony/test/xts/acts + os.chdir(self.xts_project_rootpath) + acts_build_command.append(BUILD_PRODUCT_NAME % para.productform) + acts_build_command.append("system_size=standard") + if len(para.subsystem) > 0: + acts_build_command.append(BUILD_TARGET_SUBSYSTEM % para.subsystem[0]) + + if os.path.exists(BUILD_FILEPATH): + build_command = [BUILD_FILEPATH] + build_command.extend(acts_build_command) + LOG.info("build_acts_command: %s" % str(build_command)) + if subprocess.call(build_command) == 0: + build_result = True + else: + build_result = False + else: + LOG.warning("Build Acts Testcase Error: The %s is not exist" % BUILD_FILEPATH) + + os.chdir(current_path) + return build_result + def build_fuzz_testcases(self, para): self._delete_testcase_dir(para.productform) helper_path = os.path.join("..", "libs", "fuzzlib", "fuzzer_helper.py") @@ -189,6 +235,7 @@ class BuildTestcases(object): self._merge_testcase_dir(para.productform) return build_result + # 编译测试用例(编译命令拼接) def build_testcases(self, productform, target): command = [] if self.is_build_example: @@ -203,6 +250,12 @@ class BuildTestcases(object): self._merge_testcase_dir(productform) return build_result + # 编译ACTS测试用例 + def build_acts_testcases(self, para): + self._delete_acts_testcase_dir(para.productform) + build_result = self._execute_build_acts_command(para) + return build_result + def build_gn_file(self, productform): command = [] if self.is_build_example: -- Gitee From 474c79e74d6dc8ebbcf0154f9b4b661f42326b02 Mon Sep 17 00:00:00 2001 From: leiqian Date: Fri, 24 Jun 2022 15:21:26 +0800 Subject: [PATCH 03/22] add logic to execute a command Signed-off-by: leiqian --- src/core/command/console.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/core/command/console.py b/src/core/command/console.py index a8b3822..749b0be 100755 --- a/src/core/command/console.py +++ b/src/core/command/console.py @@ -85,6 +85,7 @@ class Console(object): else: self.command_parser(" ".join(args[1:])) + # 命令执行总入口 def _console(self): if platform.system() != 'Windows': signal.signal(signal.SIGTSTP, self.handler_ctrl_z) # ctrl+x linux @@ -92,9 +93,11 @@ class Console(object): while True: try: + # 获取用户命令输入 usr_input = input(">>> ") if usr_input == "": continue + # 用户输入命令解析 self.command_parser(usr_input) except SystemExit: LOG.info("Program exit normally!") @@ -102,6 +105,7 @@ class Console(object): except (IOError, EOFError, KeyboardInterrupt) as error: LOG.exception("Input Error: %s" % error) + # 参数解析方法 @classmethod def argument_parser(cls, para_list): """ @@ -113,6 +117,8 @@ class Console(object): parser = None try: + # argparse是一个Python模块:命令行选项、参数和子命令解析器 + # 使用argparse的第一步:创建一个ArgumentParser对象,ArgumentParser对象包含将命令行解析成Python数据类型所需的全部信息 parser = argparse.ArgumentParser(description="Specify test para.") parser.add_argument("action", type=str.lower, help="Specify action") @@ -208,6 +214,7 @@ class Console(object): default="", help="Specify fuzzer name" ) + # 解析部分命令行参数,会返回一个由两个条目构成的元组,其中包含带成员的命名空间(options)和剩余参数字符串的列表(unparsed) (options, unparsed) = parser.parse_known_args(para_list) # Set default value @@ -228,12 +235,14 @@ class Console(object): def command_parser(self, args): try: + # 将用户输入的指令按空格拆分成字符串数组 para_list = args.split() options, _, valid_param = self.argument_parser(para_list) if options is None or not valid_param: LOG.warning("options is None.") return + # 根据命令行的命令选择不同的方法执行 command = options.action if command == "": LOG.warning("action is empty.") @@ -288,6 +297,7 @@ class Console(object): LOG.error("Wrong gen command.") return + # run命令执行入口 @classmethod def _process_command_run(cls, command, options): if command == ToolCommandType.TOOLCMD_KEY_RUN: -- Gitee From fd028128e2362c255f4f4e57ddafc9064bf4a54b Mon Sep 17 00:00:00 2001 From: mankangmin Date: Fri, 24 Jun 2022 15:25:13 +0800 Subject: [PATCH 04/22] compile and execute command parameter development Signed-off-by: mankangmin --- src/core/build/select_targets.py | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/core/build/select_targets.py b/src/core/build/select_targets.py index 912a6d9..ce6c88c 100755 --- a/src/core/build/select_targets.py +++ b/src/core/build/select_targets.py @@ -48,7 +48,7 @@ class SelectTargets(object): def _get_part_path_data(cls, productform): part_path_dic = {} parser = ParsePartsConfig(productform) - + # 获取infos_for_testfwk.json配置文件中“phone”节点下“part_infos”节点数据 part_infos = parser.get_part_infos() if part_infos is None: LOG.error("part_infos is None.") @@ -63,13 +63,14 @@ class SelectTargets(object): build_out_dir = part_info.get("build_out_dir") part_path_list = [] + # default_part_path:~/OpenHarmony/out/rk3568/module_list_files/部件名(以rk3568举例) default_part_path = os.path.join( get_build_output_path(productform), "module_list_files", origin_part_name) if os.path.exists(default_part_path): part_path_list.append(default_part_path) - + # 如果build_out_dir不是当前目录,将新目录加到part_path_list中 if build_out_dir != ".": product_part_path = os.path.join( get_build_output_path(productform), @@ -84,12 +85,18 @@ class SelectTargets(object): def _get_target_list_from_path(self, typelist, check_path): target_list = [] if os.path.exists(check_path): + # 获取部件编译输出目录(~/OpenHarmony/out/rk3568/module_list_files/部件名1)中.mlf文件列表 mlf_file_list = get_file_list_by_postfix( check_path, ".mlf") + # 遍历mlf_file_list中所有目录下面mlf文件中的label列表 for filepath in mlf_file_list: + # 获取mlf文件中的JSON数据信息列表 mlf_info_list = self._get_mlf_data_from_file(filepath) for data in mlf_info_list: + # 举例:"test_type": "moduletest" test_type = data.get("test_type") + # 举例:"label": "//base/accessibility/services/test:aams_accessibility_keyevent_filter_test + # (//build/toolchain/ohos:ohos_clang_arm)" target_path = data.get("label") if "ALL" in typelist: target_list.append(target_path) @@ -100,6 +107,8 @@ class SelectTargets(object): def _get_target_list_by_type(self, productform, typelist): target_list = [] + # 获取所有部件编译输出信息列表:[{“部件名1”:[~/OpenHarmony/out/rk3568/module_list_files/部件名1]}] + # 或者{“部件名1”:[~/OpenHarmony/out/rk3568/module_list_files/部件名1,~/OpenHarmony/out/rk3568/编译目录build_out_dir/module_list_files/部件名1]} part_path_dic = self._get_part_path_data(productform) for item in part_path_dic: part_path_list = part_path_dic.get(item) @@ -147,16 +156,19 @@ class SelectTargets(object): LOG.warning( "The part cannot be empty When the module is not empty.") return [] - + # productform不为空,typelist(test type[UT,MST,ST,PERF,ALL])不为空 + # partlist和testmodule为空,通过testtype获取部件列表 if len(partlist) == 0 and testmodule == "": target_list = self._get_target_list_by_type(productform, typelist) return target_list - + # productform不为空,typelist(test type[UT,MST,ST,PERF,ALL])不为空 + # partlist不为空,testmodule为空,通过testtype、partlist一起获取部件列表 if len(partlist) != 0 and testmodule == "": target_list = self._get_target_list_by_part(productform, typelist, partlist) return target_list - + # productform不为空,typelist(test type[UT,MST,ST,PERF,ALL])不为空 + # partlist不为空,testmodule不为空,通过testtype、partlist、testmodule一起获取部件列表 if len(partlist) != 0 and testmodule != "": target_list = self._get_target_list_by_module(productform, typelist, @@ -165,6 +177,11 @@ class SelectTargets(object): return target_list + # 通过infos_for_testfwk.json文件获取所有子部件信息编译目录信息: + # [{“部件名1”:[~/OpenHarmony/out/rk3568/module_list_files/部件名1]}] + # 然后遍历这些目录中的mlf文件,获取其中定义的label,返回label集合 + # 遍历时通过testmodule控制遍历的部件指定模块目录,如果不定义,则遍历子部件下面所有模块目录 + # 遍历时通过partlist控制遍历指定部件目录,如果不定义,则遍历infos_for_testfwk.json文件中定义的所有子部件目录 def filter_build_targets(self, para): productform = para.productform typelist = para.testtype -- Gitee From b29469f9bfb9617e4649af093029796b5bed7c55 Mon Sep 17 00:00:00 2001 From: chenhui Date: Fri, 24 Jun 2022 15:49:05 +0800 Subject: [PATCH 05/22] compile and execute command parameter development Signed-off-by: chenhui --- src/core/command/run.py | 43 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/src/core/command/run.py b/src/core/command/run.py index d89d657..640fa31 100755 --- a/src/core/command/run.py +++ b/src/core/command/run.py @@ -41,17 +41,21 @@ LOG = platform_logger("Run") class Run(object): def process_command_run(self, command, options): para = Parameter() + # 过滤options中的test type参数,确保都是合法的,最终的数据结构为: + # [{unittest:300,moduletest:300}] test_type_list = para.get_testtype_list(options.testtype) if len(test_type_list) == 0: LOG.error("The testtype parameter is incorrect.") return options.testtype = test_type_list - + # 初始化ParsePartsConfig,根据productform获取对应的所有子系统名称列表、子系统下的部件名列表 parser = ParsePartsConfig(options.productform) + # 获取部件名列表 partname_list = parser.get_part_list( options.subsystem, options.testpart) options.partname_list = partname_list + # 获取编译结果输出目录 options.coverage_outpath = self.get_coverage_outpath(options) LOG.info("") @@ -68,21 +72,25 @@ class Run(object): LOG.info("partname_list = %s" % str(options.partname_list)) LOG.info("------------------------------------") LOG.info("") - + # options参数校验 if not para.check_run_parameter(options): LOG.error("Input parameter is incorrect.") return - + # 编译测试用例 if not self._build_test_cases(options): LOG.error("Build test cases failed.") return + test_case_path = self.get_tests_out_path(options.productform) if not os.path.exists(test_case_path): LOG.error("%s is not exist." % test_case_path) return - test_dict = TestCaseManager().get_test_files(test_case_path, options) + if "actstest" in options.testtype: + test_dict = self.get_acts_test_dict(options) + else: + test_dict = TestCaseManager().get_test_files(test_case_path, options) if not self._check_test_dictionary(test_dict): LOG.error("The test file list is empty.") return @@ -170,13 +178,14 @@ class Run(object): if options.coverage: LOG.info("Coverage testing, no need to compile testcases") return True - + # 从user_config.xml文件获取的配置,判断是否编译测试用例 is_build_testcase = UserConfigManager().get_user_config_flag( "build", "testcase") project_root_path = sys.source_code_root_path if is_build_testcase and project_root_path != "": from core.build.build_manager import BuildManager build_manager = BuildManager() + # 实际编译调用逻辑 return build_manager.build_testcases(project_root_path, options) else: return True @@ -216,6 +225,16 @@ class Run(object): LOG.info("testcase_path=%s" % testcase_path) return testcase_path + @classmethod + def get_acts_tests_out_path(cls, product_form): + acts_testcase_path = os.path.abspath(os.path.join( + get_build_output_path(product_form), + "suites", + "acts", + "testcases")) + LOG.info("acts_testcase_path=%s" % acts_testcase_path) + return acts_testcase_path + @classmethod def get_coverage_outpath(cls, options): coverage_out_path = "" @@ -228,4 +247,18 @@ class Run(object): LOG.error("Coverage test: coverage_outpath is empty.") return coverage_out_path + def get_acts_test_dict(self, options): + # 获取测试用例编译结果路径 + acts_test_case_path = self.get_acts_tests_out_path(options.productform) + acts_test_dict = TestCaseManager().get_acts_test_files(acts_test_case_path, options) + return acts_test_dict + def get_test_dict(self, options): + # 获取测试用例编译结果路径 + test_case_path = self.get_tests_out_path(options.productform) + if not os.path.exists(test_case_path): + LOG.error("%s is not exist." % test_case_path) + return + # 根据测试用例目录文件的后缀名,将测试文件按照DEX、JST、PYT、CXX、BIN进行分类,存放到字典中 + test_dict = TestCaseManager().get_test_files(test_case_path, options) + return test_dict -- Gitee From dbf1eaa1bfd2dce4e89df13b3e797fbd8424c7ef Mon Sep 17 00:00:00 2001 From: lvgang Date: Fri, 24 Jun 2022 15:51:20 +0800 Subject: [PATCH 06/22] analysis of function Signed-off-by: lvgang --- src/core/config/parse_parts_config.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/core/config/parse_parts_config.py b/src/core/config/parse_parts_config.py index 3e51417..5a271b7 100755 --- a/src/core/config/parse_parts_config.py +++ b/src/core/config/parse_parts_config.py @@ -32,10 +32,13 @@ class ParsePartsConfig(object): self.productform = productform self.subsystem_infos, self.part_infos = self.get_infos_data() + # 获取配置文件地址:~/OpenHarmony/out/rk3568/build_configs/infos_for_testfwk.json(以rk3568举例) def get_config_file_path(self): manager = UserConfigManager() + # 获取user_config.xml文件中的配置的(编译好的测试用例地址) testcase_dir = manager.get_test_cases_dir() + # 如果没有在developtertest/config/user_config里配置test_cases路径,就到OpenHarmony/out/rk3568/build_configs/infos_for_testfwk.json里查找 if testcase_dir == "": if sys.source_code_root_path != "": config_filepath = os.path.join( @@ -44,6 +47,8 @@ class ParsePartsConfig(object): "infos_for_testfwk.json") else: config_filepath = "" + + # 如果在developtertest/config/user_config里配置了test_cases路径,就在这个路径下的infos_for_testfwk.json里查找 else: config_filepath = os.path.join( testcase_dir, @@ -52,6 +57,8 @@ class ParsePartsConfig(object): def get_infos_data(self): config_filepath = self.get_config_file_path() + + # 检验给出的路径是否真地存在 if not os.path.exists(config_filepath): print("Error: %s is not exist." % config_filepath) return None, None @@ -68,11 +75,13 @@ class ParsePartsConfig(object): product_data_dic = data_dic.get("phone", None) else: product_data_dic = data_dic.get(self.productform, None) + # product_data_dic:infos_for_testfwk.json配置文件中“phone”节点数据 if product_data_dic is None: print("Error: product_data_dic is None.") return None, None - + # subsystem_infos(系统中定义的子系统列表):infos_for_testfwk.json配置文件中“phone”节点下“subsystem_infos”节点数据 subsystem_infos = product_data_dic.get("subsystem_infos", None) + # subsystem_infos(系统中定义的部件信息列表):infos_for_testfwk.json配置文件中“phone”节点下“part_infos”节点数据 part_infos = product_data_dic.get("part_infos", None) return subsystem_infos, part_infos @@ -89,14 +98,17 @@ class ParsePartsConfig(object): subsystem_name_list.append(item) return subsystem_name_list + # 获取部件列表 def get_part_list(self, subsystemlist, partlist): + # 如果options参数中的partlist不为空,直接返回partlist if len(partlist) != 0: return partlist - + # 如果infos_for_testfwk.json配置文件的subsystem_infos为None,返回options参数中的subsystemlist if self.subsystem_infos is None: return subsystemlist part_name_list = [] + # 遍历options参数中的子系统列表,并且将infos_for_testfwk.json配置文件的subsystem_infos中的对应子系统的部件列表加入到part_name_list中 if len(subsystemlist) != 0: for item in subsystemlist: parts = self.subsystem_infos.get(item, []) -- Gitee From c1cb2058d3a5f873de39c4dfe94c43ce5d151505 Mon Sep 17 00:00:00 2001 From: huningning Date: Fri, 24 Jun 2022 15:54:06 +0800 Subject: [PATCH 07/22] analysis of function Signed-off-by: huningning --- src/core/utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/utils.py b/src/core/utils.py index fc0a589..21ad7d2 100755 --- a/src/core/utils.py +++ b/src/core/utils.py @@ -49,7 +49,7 @@ def get_file_list(find_path, postfix=""): file_list.append(file_name) return file_list - +# 获取目录下每一个文件,并放到一个列表里 def get_file_list_by_postfix(path, postfix=""): file_list = [] for dirs in os.walk(path): @@ -96,11 +96,13 @@ def get_build_output_path(product_form): build_output_path = os.path.join(sys.source_code_root_path, "out", build_output_name) + # 返回编译结果输出目录:~/OpenHarmony/out/rk3568(以rk3568举例) return build_output_path def scan_support_product(): # scan standard and large system info + # product_form_dir = OpenHarmony/productdefine/common/products/ product_form_dir = os.path.join(sys.source_code_root_path, "productdefine", "common", -- Gitee From a60f7d47d808b75652888baa77405cf249c210ea Mon Sep 17 00:00:00 2001 From: dingpeng Date: Fri, 24 Jun 2022 15:56:08 +0800 Subject: [PATCH 08/22] analysis of function Signed-off-by: dingpeng --- src/core/command/display.py | 55 ++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/src/core/command/display.py b/src/core/command/display.py index 1a69bbf..a6f9cd3 100755 --- a/src/core/command/display.py +++ b/src/core/command/display.py @@ -16,6 +16,11 @@ # limitations under the License. # +# 执行如下命令 获取到的信息 +# show subsystemlist 通过show subsystemlist得到子系统名称列表 +# show partlist 通过show partlist得到对应子系统下的部件名 +# show modulelist 通过show modulelist得到对应部件名下的模块列表 + import sys import os @@ -28,10 +33,37 @@ from core.config.config_manager import UserConfigManager from core.config.config_manager import FrameworkConfigManager from core.config.parse_parts_config import ParsePartsConfig +# 支持的设备名称 +# 1. ohos-sdk +# 2. rk3568 +# 3. Hi3516DV300 +# 4. DAYU +# 5. ohos-arm64 +# 6. ipcamera_hispark_aries +# 7. ipcamera_hispark_taurus +# 8. wifiiot_hispark_pegasus CMD_KEY_PRODUCTLIST = "productlist" + +# 测试用例类型 +# 1. UT +# 2. MST +# 3. ST +# 4. PERF +# 5. SEC +# 6. FUZZ +# 7. RELI +# 8. DST +# 9. BENCHMARK +# 10. ALL CMD_KEY_TYPELIST = "typelist" + +# 子系统名称列表 CMD_KEY_SUBSYSTEMLIST = "subsystemlist" + +# 子系统下的部件名 CMD_KEY_PARTLIST = "partlist" + +# 部件下的模块 CMD_KEY_MODULELIST = "modulelist" @@ -157,12 +189,20 @@ def select_user_input(data_list): sys.exit(0) return select_item_value, select_item_index - +# 选择productform def select_productform(): select_value = "phone" + + # scan_support_product() = [DAYU,Hi3516,ohos_arm64,ohos_sdk,rk3568] scan_product_list = scan_support_product() + + # 从framework_config.xml里取productform节点的value:ipcamera_hispark_aries、ipcamera_hispark_taurus、wifiiot_hispark_pegasus config_product_list = \ FrameworkConfigManager().get_framework_config("productform") + + # productform_list = [DAYU,Hi3516,ohos_arm64,ohos_sdk,rk3568, + # ipcamera_hispark_aries、ipcamera_hispark_taurus、wifiiot_hispark_pegasus] + productform_list = scan_product_list + config_product_list if len(productform_list) != 0: print("Please select the current tested product form:") @@ -217,10 +257,14 @@ def display_show_info(para_list, productform): ############################################################################# ############################################################################# +# 获取模块列表 从 OpenHarmony/out/rk3568/module_list_files或者 OpenHarmony/out/rk3568/test_info/module_list_files里获取 def get_module_list_from_output_dir(product_form): module_path_list = [] all_product_list = scan_support_product() if product_form in all_product_list: + # get_build_output_path = Openharmony/out/product_form/ + # module_list_file_path = Openharmony/out/product_form/module_list_files/ + # product_form choosed according to the input,such as rk3568 module_list_file_path = os.path.join( get_build_output_path(product_form), "module_list_files") @@ -231,6 +275,8 @@ def get_module_list_from_output_dir(product_form): "module_list_files") print(module_list_file_path) if os.path.exists(module_list_file_path): + + # 遍历查找目录路径下存在后缀为.mlf文件的文件 file_list = get_file_list_by_postfix(module_list_file_path, ".mlf") for file in file_list: module_path = \ @@ -300,7 +346,7 @@ def show_testtype_list(): else: print("No category specified.") - +# 从OpenHarmony/out/rk3568/build_configs/infos_for_testfwk.json里的subsystem_infos中subsystem_infos下获取subsystemlist def show_subsystem_list(product_form): print("List of currently supported subsystem names:") parser = ParsePartsConfig(product_form) @@ -312,7 +358,7 @@ def show_subsystem_list(product_form): for index, element in enumerate(subsystem_name_list): print(" %d. %s" % (index + 1, element)) - +# 从OpenHarmony/out/rk3568/build_configs/infos_for_testfwk.json里的subsystem_infos中subsystem_infos下获取partlist def show_partname_list(product_form): print("List of currently supported part names:") parser = ParsePartsConfig(product_form) @@ -329,7 +375,8 @@ def show_partname_list(product_form): for index, element in enumerate(part_name_list): print(" %d. %s" % (index + 1, element)) - +# 从 OpenHarmony/out/rk3568/module_list_files或者 OpenHarmony/out/rk3568/test_info/module_list_files里获取modulelist,就是里面的文件 +# 这里有点奇怪 跟前面的子系统 部件 不对应 def show_module_list(product_form): print("List of currently supported module names:") subsystem_name_list = [] -- Gitee From 03b4ff01a2f43e8b928862a5d35d11e33a86a8f4 Mon Sep 17 00:00:00 2001 From: fengkai Date: Fri, 24 Jun 2022 15:58:33 +0800 Subject: [PATCH 09/22] analysis of function Signed-off-by: fengkai --- src/core/config/config_manager.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/core/config/config_manager.py b/src/core/config/config_manager.py index 3b463f6..44a5898 100755 --- a/src/core/config/config_manager.py +++ b/src/core/config/config_manager.py @@ -24,24 +24,38 @@ from xdevice import platform_logger from core.constants import ConfigFileConst LOG = platform_logger("config_manager") -CONFIG_PATH = os.path.join(sys.framework_res_dir, "config") +# framework_res_dir = OpenHarmony/test/developertest +# CONFIG_PATH = OpenHarmony/test/developertest/config +CONFIG_PATH = os.path.join(sys.framework_res_dir, "config") +# framework_config.xml class FrameworkConfigManager(object): def __init__(self, filepath=""): if filepath == "": + + # filepath = OpenHarmony/test/developertest/config/framework_config.xml self.filepath = os.path.abspath(os.path.join( CONFIG_PATH, ConfigFileConst.FRAMECONFIG_FILEPATH)) else: self.filepath = filepath + # 获取framework_config.xml中所有name的value,返回列表 def get_framework_config(self, target_name): data_list = [] try: if os.path.exists(self.filepath): + + # 读取xml文件 tree = ET.parse(self.filepath) + + # 获取根节点 root = tree.getroot() + + # 获取节点的名字 node = root.find(target_name) + + # 遍历 name 节点 获取value 添加到data_list中 for sub in node: value = sub.attrib.get("name") if value and value != "": @@ -50,6 +64,7 @@ class FrameworkConfigManager(object): LOG.error(("Parse %s fail!" % self.filepath) + xml_exception.args) return data_list + # 获取framework_config.xml中test_category标签里name、desc、timeout的value,返回字典 def get_test_category_info(self, target_name="test_category"): test_type_timeout_dic = {} try: @@ -69,13 +84,17 @@ class FrameworkConfigManager(object): LOG.error(("Parse %s fail!" % self.filepath) + xml_exception.args) return test_type_timeout_dic + # 获取framework_config.xml中all_category标签里name的value,返回列表 如:unittest、moduletest、systemtest、performance def get_all_category_info(self, target_name="all_category"): return self.get_framework_config(target_name) +# filter_config.xml class FilterConfigManager(object): def __init__(self, filepath=""): if filepath == "": + + # filepath = OpenHarmony/test/developertest/config/filter_config.xml self.filepath = os.path.abspath( os.path.join(CONFIG_PATH, ConfigFileConst.FILTERCONFIG_FILEPATH)) @@ -106,7 +125,7 @@ class FilterConfigManager(object): def get_filter_config_path(self): return self.filepath - +# 这里的filepath不存在 class ResourceConfigManager(object): def __init__(self, filepath=""): if filepath == "": @@ -142,6 +161,8 @@ class ResourceConfigManager(object): class UserConfigManager(object): def __init__(self, config_file=""): if config_file == "": + + # filepath = OpenHarmony/test/developertest/config/user_config.xml self.filepath = os.path.abspath(os.path.join( CONFIG_PATH, ConfigFileConst.USERCONFIG_FILEPATH)) else: @@ -261,6 +282,8 @@ class UserConfigManager(object): class BuildConfigManager(object): def __init__(self, filepath=""): if filepath == "": + + # filepath = OpenHarmony/test/developertest/config/build_config.xml self.filepath = os.path.abspath(os.path.join( CONFIG_PATH, ConfigFileConst.BUILDCONFIG_FILEPATH)) else: @@ -287,6 +310,8 @@ class BuildConfigManager(object): class FuzzerConfigManager(object): def __init__(self, config_path=""): if config_path == "": + + # filepath = OpenHarmony/test/developertest/config/fuzz_config.xml self.filepath = self.filepath = os.path.abspath(os.path.join( CONFIG_PATH, ConfigFileConst.FUZZCONFIG_FILEPATH)) else: -- Gitee From a6b0a14ce3fe10f2957486d285c166dcf5131ae9 Mon Sep 17 00:00:00 2001 From: cuishuangxi Date: Fri, 24 Jun 2022 16:00:10 +0800 Subject: [PATCH 10/22] scheduling logic analysis Signed-off-by: cuishuangxi --- src/main/_init_global_config.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/_init_global_config.py b/src/main/_init_global_config.py index f01dced..4e51316 100755 --- a/src/main/_init_global_config.py +++ b/src/main/_init_global_config.py @@ -22,12 +22,20 @@ def _init_global_config(): import os # insert src path for loading xdevice modules + # 当前脚本运行的绝对路径 去掉最后两个路径 + # framework_src_dir = OpenHarmony/test/developertest sys.framework_src_dir = os.path.abspath(os.path.dirname( os.path.dirname(__file__))) + + # 将目录存放到sys.path模块中,新添加的目录会优先于其他目录被import检查 0代表最高优先级 sys.path.insert(0, sys.framework_src_dir) + + # 当前脚本运行的绝对路径 去掉最后两个路径 + # framework_root_dir = OpenHarmony/test/developertest sys.framework_root_dir = os.path.abspath(os.path.dirname( os.path.dirname(os.path.dirname(__file__)))) + # sys.xdevice_dir = OpenHarmony/test/xdevice/src sys.xdevice_dir = os.path.abspath(os.path.join( sys.framework_root_dir, "..", @@ -35,6 +43,7 @@ def _init_global_config(): "src")) sys.path.insert(0, sys.xdevice_dir) + # sys.xdevice_extension_dir = OpenHarmony/xdevice/extension/src sys.xdevice_extension_dir = os.path.abspath(os.path.join( sys.framework_root_dir, "..", @@ -43,12 +52,14 @@ def _init_global_config(): "src")) sys.path.insert(1, sys.xdevice_extension_dir) + # pytest_dir = OpenHarmony/test/developertest/aw/python sys.pytest_dir = os.path.abspath(os.path.join( sys.framework_root_dir, "aw", "python")) sys.path.insert(2, sys.pytest_dir) + # adapter_dir = OpenHarmony/test/developertest/adapter/aw/python sys.adapter_dir = os.path.abspath(os.path.join( sys.framework_root_dir, "adapter" @@ -56,18 +67,23 @@ def _init_global_config(): "python")) sys.path.insert(3, sys.adapter_dir) + # hmh_script = OpenHarmony/test/developertest/libs sys.hmh_script = os.path.abspath(os.path.join( sys.framework_root_dir, "libs")) sys.path.insert(4, sys.hmh_script) + # framework_res_dir = OpenHarmony/test/developertest sys.framework_res_dir = sys.framework_root_dir + + # exec_dir = OpenHarmony/test/developertest sys.exec_dir = sys.framework_root_dir from core.common import get_source_code_root_path sys.source_code_root_path = get_source_code_root_path( sys.framework_root_dir) + # python的参数配置 设置脚本路径 调度python的xdevice from xdevice import Variables Variables.exec_dir = sys.framework_root_dir @@ -76,6 +92,8 @@ def _iter_module_plugins(packages): import importlib import pkgutil for package in packages: + + # 获取__path__对象属性的值,若不存在,默认为“” pkg_path = getattr(package, "__path__", "") pkg_name = getattr(package, "__name__", "") if not pkg_name or not pkg_path: -- Gitee From af06c9038afd8a900cf8bf438bd0f5ffa8fe8a57 Mon Sep 17 00:00:00 2001 From: liangzhigao Date: Fri, 24 Jun 2022 16:01:35 +0800 Subject: [PATCH 11/22] add ACTS testtype Signed-off-by: liangzhigao --- config/framework_config.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/framework_config.xml b/config/framework_config.xml index 4bad38c..c76070f 100755 --- a/config/framework_config.xml +++ b/config/framework_config.xml @@ -23,6 +23,9 @@