diff --git a/config/framework_config.xml b/config/framework_config.xml
index 98b6c3e42bf6b06c5ed805338410a58ae4759edc..5aff53684d7af5fb9a871ead71e9993bc98b03a2 100644
--- a/config/framework_config.xml
+++ b/config/framework_config.xml
@@ -57,6 +57,9 @@
+
@@ -71,5 +74,6 @@
+
\ No newline at end of file
diff --git a/src/core/arkts_tdd/arkts_tdd_execute/arkts_tdd_build.py b/src/core/arkts_tdd/arkts_tdd_execute/arkts_tdd_build.py
new file mode 100644
index 0000000000000000000000000000000000000000..50045cd5c7d00c9b8688198cb237e20e30c7d263
--- /dev/null
+++ b/src/core/arkts_tdd/arkts_tdd_execute/arkts_tdd_build.py
@@ -0,0 +1,240 @@
+#!/usr/bin/env python3
+# coding=utf-8
+
+#
+# Copyright (c) 2025 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+import os
+import subprocess
+import threading
+from datetime import timezone
+from datetime import timedelta
+from datetime import datetime
+
+from core.arkts_tdd.artts_tdd_report.arkts_tdd_report_generator import ResultConstruction
+from core.driver.drivers import _create_empty_result_file
+from xdevice import ResultReporter
+from xdevice import platform_logger, ExecInfo
+
+ARKPATH = "arkcompiler/runtime_core/static_core/out/bin/ark"
+ETSSTDLIBPATH = "arkcompiler/runtime_core/static_core/out/plugins/ets/etsstdlib.abc"
+
+LOG = platform_logger("arkts_tdd_build")
+
+
+def get_path_code_directory(after_dir):
+ """
+ 拼接绝对路径工具类
+ """
+ current_path = os.path.abspath(__file__)
+ current_dir = os.path.dirname(current_path)
+
+ root_path = current_dir.split("/test/testfwk/developer_test")[0]
+
+ # 拼接用户传入路径
+ full_path = os.path.join(root_path, after_dir)
+
+ return full_path
+
+
+def run_test(options):
+ report_folder_path = options.result_rootpath
+ log_path = options.log_path
+
+ result_path = os.path.join(report_folder_path, "result")
+ if not os.path.exists(result_path):
+ os.makedirs(result_path)
+
+ test_file_dict = options.testdict
+ suite_file_list = test_file_dict['ABC']
+
+ testcases_path = options.testcases_path
+
+ os.getcwd()
+ result_construction = ResultConstruction()
+ test_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+
+ for index, suite_file in enumerate(suite_file_list):
+ run_abc_files(suite_file, log_path, testcases_path, result_path, index, suite_file_list, result_construction)
+
+ exec_info = ExecInfo()
+ exec_info.test_type = "ARKTS TDD"
+ exec_info.device_name = "ALL"
+ exec_info.host_info = ""
+ exec_info.test_time = test_time
+ exec_info.log_path = log_path
+ exec_info.platform = ""
+ exec_info.execute_time = ""
+
+ result_report = ResultReporter()
+ result_report.__generate_reports__(report_path=report_folder_path,
+ task_info=exec_info)
+
+
+def write_output_to_log(result, log_file, testsuite_summary):
+ class_name = ''
+ case_name = ''
+ testcase_result = ''
+ testcase_map = {}
+ testcase_list = []
+ case_index = 0
+ testsuite_case_num = 0
+ while True:
+ # 读取一行输出
+ output = result.stdout.readline()
+ if result.poll() is not None:
+ # 子进程结束,退出循环
+ break
+ if not output:
+ continue
+ line = output.rstrip().replace("\n", "").replace("\r", "").replace("\t", " ")
+
+ if line.startswith('[Hypium][suite start]'):
+ class_name = line.replace('[Hypium][suite start]', '')
+ testsuite_summary[class_name] = {}
+ testcase_map = {}
+ testcase_list = []
+ testsuite_summary[class_name]['case_detail'] = []
+ case_index = 0
+
+ if line.startswith('OHOS_REPORT_SUM:'):
+ testsuite_case_num = line.replace('OHOS_REPORT_SUM:', '').strip()
+ testsuite_summary[class_name]['testsuiteCaseNum'] = testsuite_case_num
+
+ if line.startswith('OHOS_REPORT_STATUS: test='):
+ testcase_map = {}
+ testsuite_summary[class_name]['case_detail'].append(testcase_map)
+ testcase_list.append(testcase_map)
+ case_name = line.replace('OHOS_REPORT_STATUS: test=', '')
+ testcase_map['case_name'] = case_name
+ case_index += 1
+
+ if case_name + ' ; consuming ' in line:
+ testcase_result = get_testcase_result(case_index, case_name, class_name, line, testcase_map, testsuite_case_num)
+
+ if testcase_result == 'fail' and line.startswith('[Hypium][failDetail]'):
+ testcase_faildetail = line.replace('[Hypium][failDetail]', '')
+ testcase_map['testcaseFailDetail'] = testcase_faildetail
+
+ if line.startswith('OHOS_REPORT_STATUS: suiteconsuming='):
+ testsuite_consuming = line.replace('OHOS_REPORT_STATUS: suiteconsuming=', '')
+ testsuite_summary[class_name]['testsuite_consuming'] = testsuite_consuming
+
+ if line.startswith('OHOS_REPORT_RESULT:'):
+ testsuites_result = line.replace("OHOS_REPORT_RESULT: stream=", "")
+ testsuites_detail = testsuites_result.split(",")
+ for detail in testsuites_detail:
+ detail_temp = detail.split(":")
+ testsuite_summary[detail_temp[0].strip()] = detail_temp[1].strip()
+
+ if line.startswith('OHOS_REPORT_STATUS: taskconsuming='):
+ taskconsuming = line.replace("OHOS_REPORT_STATUS: taskconsuming=", "")
+ testsuite_summary["taskconsuming"] = taskconsuming
+ # 将输出写入文件
+ log_file.write(output)
+ log_file.flush() # 确保内容立即写入文件
+
+
+def get_testcase_result(case_index, case_name, class_name, line, testcase_map, testsuite_case_num):
+ testcase_result = line[9:13]
+ consuming_list = line.split(case_name + ' ; consuming ')
+ testcase_consuming = '0'
+ if len(consuming_list) > 1:
+ testcase_consuming = consuming_list[1].replace('ms', '')
+ testcase_map['testcaseResult'] = testcase_result
+ testcase_map['testcaseConsuming'] = testcase_consuming
+ LOG.info(f'[{case_index}/{testsuite_case_num.strip()}] {class_name}#{case_name} {testcase_result}')
+ return testcase_result
+
+
+def run_abc_files(suite_file, log_path, testcases_path, result_path, index, suite_file_list, result_construction):
+ file_name = os.path.basename(suite_file)
+ prefix_name, suffix_name = os.path.splitext(file_name)
+ suite_name = prefix_name
+ suite_log_path = os.path.join(log_path, prefix_name)
+ if not os.path.exists(suite_log_path):
+ os.makedirs(suite_log_path)
+
+ suite_file_path = os.path.dirname(suite_file)
+ module_output_path = suite_file_path.replace(testcases_path, "")
+ suite_result_path = os.path.join(result_path, module_output_path.lstrip("/").lstrip("\\"))
+ if not os.path.exists(suite_result_path):
+ os.makedirs(suite_result_path)
+
+ suite_result_file = os.path.join(suite_result_path, prefix_name + '.xml')
+ os.chdir(suite_file_path)
+ """
+ 执行生成的abc文件并生成报告日志
+ """
+ abs_ark_path = get_path_code_directory(ARKPATH)
+ abs_etsstdlib_path = get_path_code_directory(ETSSTDLIBPATH)
+ log_file = os.path.join(suite_log_path, f"{suite_name}.log")
+ command = [
+ abs_ark_path, f"--boot-panda-files={abs_etsstdlib_path}", f"--load-runtimes=ets", f"{file_name}",
+ f"OpenHarmonyTestRunner/ETSGLOBAL::main"]
+ LOG.info(f"执行命令 {command}")
+
+ start_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+
+ LOG.info(f'[{index + 1} / {len(suite_file_list)}] Executing: {suite_file}')
+ testsuite_summary = {}
+ return_message = ""
+ try:
+ result = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
+
+ with open(log_file, "a") as log_file:
+ # 启动线程,实时读取输出并写入文件
+ thread = threading.Thread(target=write_output_to_log, args=(result, log_file, testsuite_summary))
+ thread.start()
+
+ # 等待子进程完成
+ result.wait()
+ thread.join() # 等待线程完成
+ stdout, stderr = result.communicate()
+ if stderr:
+ return_message = stderr
+ except Exception as error:
+ return_message = str(error)
+
+ end_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
+ if len(testsuite_summary) != 0:
+ result_construction.testsuite_summary = testsuite_summary
+ result_construction.start_time = start_time
+ result_construction.end_time = end_time
+ result_construction.suite_file_name = suite_name
+ result_construction.node_construction(suite_result_file)
+
+ if return_message != "":
+ error_message = str(return_message)
+ error_message = error_message.replace("\"", "")
+ error_message = error_message.replace("<", "")
+ error_message = error_message.replace(">", "")
+ error_message = error_message.replace("&", "")
+ _create_empty_result_file(suite_result_file, prefix_name, error_message)
+
+
+def get_cst_time():
+ sh_tz = timezone(
+ timedelta(hours=8),
+ name='Asia/Shanghai',
+ )
+ return datetime.now(tz=sh_tz)
+
+
+def main():
+ run_test("Functions")
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/src/core/arkts_tdd/artts_tdd_report/arkts_tdd_report_generator.py b/src/core/arkts_tdd/artts_tdd_report/arkts_tdd_report_generator.py
new file mode 100644
index 0000000000000000000000000000000000000000..b198fa1ee2d461f6552588f8ac1a6fc26d6f5484
--- /dev/null
+++ b/src/core/arkts_tdd/artts_tdd_report/arkts_tdd_report_generator.py
@@ -0,0 +1,109 @@
+#!/usr/bin/env python3
+# coding=utf-8
+
+#
+# Copyright (c) 2025 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+import datetime
+import xml.etree.ElementTree as ET
+from xdevice import platform_logger
+
+LOG = platform_logger("arkts_tdd_report_generator")
+
+
+class ResultConstruction(object):
+ def __init__(self):
+ self.testsuite_summary = {}
+ self.start_time = None
+ self.end_time = None
+ self.suite_file_name = None
+
+ def format_xml(self, elem_node, level=0):
+ if len(elem_node):
+ if not elem_node.text or not elem_node.text.strip():
+ elem_node.text = "\n" + level * " "
+ if not elem_node.tail or not elem_node.tail.strip():
+ elem_node.tail = "\n" + level * " "
+ for elem in elem_node:
+ self.format_xml(elem, level + 1)
+ if not elem_node.tail or not elem_node.tail.strip():
+ elem_node.tail = "\n" + level * " "
+ else:
+ if level and (not elem_node.tail or not elem_node.tail.strip()):
+ elem_node.tail = "\n" + level * " "
+
+ def set_testsuites_element(self, testsuites):
+ testsuites.set("name", self.suite_file_name)
+ testsuites.set("timestamp", datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
+ testsuites.set("time", str(float(self.testsuite_summary['taskconsuming']) / 1000))
+ testsuites.set("errors", self.testsuite_summary['Error'])
+ testsuites.set("disabled", '0') # ?
+ testsuites.set("failures", self.testsuite_summary['Failure'])
+ testsuites.set("tests", self.testsuite_summary['Tests run'])
+ testsuites.set("ignored", self.testsuite_summary['Ignore'])
+ testsuites.set("unavailable", "0") # ?
+ testsuites.set("starttime", self.start_time)
+ testsuites.set("endtime", self.end_time)
+ testsuites.set("repeat", "1") # ?
+ testsuites.set("round", "1") # ?
+ testsuites.set("test_type", "OHJSUnitTest")
+
+ def node_construction(self, suite_result_file):
+ # 创建根元素
+ testsuites = ET.Element("testsuites")
+ self.set_testsuites_element(testsuites)
+
+ for key, value in self.testsuite_summary.items():
+ if not isinstance(value, dict):
+ continue
+ testsuite = ET.SubElement(testsuites, "testsuite")
+ case_detail = value['case_detail']
+ fail_count = 0
+ for detail in case_detail:
+ if detail['testcaseResult'] == 'fail':
+ fail_count += 1
+
+ testsuite.set("name", key)
+ testsuite.set("time", str(float(value['testsuite_consuming']) / 1000))
+ testsuite.set("errors", "0")
+ testsuite.set("disabled", "0")
+ testsuite.set("failures", str(fail_count))
+ testsuite.set("ignored", "0")
+ testsuite.set("tests", value['testsuiteCaseNum'])
+ testsuite.set("report", "")
+
+ case_detail = value['case_detail']
+ for detail in case_detail:
+ testcase = ET.SubElement(testsuite, "testcase")
+ testcase.set("name", detail['case_name'])
+ testcase.set("status", "run")
+ testcase.set("time", str(float(detail['testcaseConsuming']) / 1000))
+ testcase.set("classname", key)
+
+ if detail['testcaseResult'] is not None:
+ testcase.set("result", "completed")
+
+ testcase.set("level", "1")
+
+ if detail['testcaseResult'] == 'fail':
+ failure = ET.SubElement(testcase, "failure")
+ failure.set("message", detail['testcaseFailDetail'])
+ failure.set("type", "")
+ failure.text = detail['testcaseFailDetail']
+ self.format_xml(testsuites)
+
+ # 将 ElementTree 写入 XML 文件
+ tree = ET.ElementTree(testsuites)
+ tree.write(suite_result_file, encoding="UTF-8", xml_declaration=True, short_empty_elements=True)
+ LOG.info(f"XML 文件已生成: {suite_result_file}")
\ No newline at end of file
diff --git a/src/core/arkts_tdd/toolchain_hypium_build.py b/src/core/arkts_tdd/toolchain_hypium_build.py
new file mode 100644
index 0000000000000000000000000000000000000000..38e8d8f6991f33ef7adee9a1e0890065695ae99b
--- /dev/null
+++ b/src/core/arkts_tdd/toolchain_hypium_build.py
@@ -0,0 +1,333 @@
+#!/usr/bin/env python3
+# coding=utf-8
+#
+# Copyright (c) 2025 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+import os
+import subprocess
+import shutil
+import json
+
+STATICCOREPATH = "arkcompiler/runtime_core/static_core/"
+ES2PANDAPATH = "arkcompiler/runtime_core/static_core/out/bin/es2panda"
+CONFIGPATH = "arkcompiler/runtime_core/static_core/out/bin/arktsconfig.json"
+HYPIUMPATH = "test/testfwk/arkxtest/jsunit/src_static/"
+TOOLSPATH = "test/testfwk/developer_test/libs/arkts1.2"
+ARKLINKPATH = "arkcompiler/runtime_core/static_core/out/bin/ark_link"
+
+
+def get_path_code_directory(after_dir):
+ """
+ 拼接绝对路径工具类
+ """
+ current_path = os.path.abspath(__file__)
+ current_dir = os.path.dirname(current_path)
+
+ root_path = current_dir.split("/test/testfwk/developer_test")[0]
+
+ # 拼接用户传入路径
+ full_path = os.path.join(root_path, after_dir)
+
+ return full_path
+
+
+def run_command(command):
+ try:
+ print(f'{"*" * 35}开始执行命令:{command}{"*" * 35}')
+ command_list = command.split(" ")
+ result = subprocess.run(command_list,
+ capture_output=True, text=True, check=True)
+ if result.returncode == 0:
+ print("命令执行成功")
+ print("输出:", result.stdout)
+ else:
+ print("命令执行失败")
+ print("错误:", result.stderr)
+ print(f'{"*" * 35}命令:{command}执行结束{"*" * 35}')
+ except FileNotFoundError:
+ print("错误:未找到 sudo 命令。请确保已安装 sudo。")
+ except Exception as e:
+ print(f"发生错误: {e}")
+
+
+def create_soft_link(target_path, link_path):
+ try:
+ print(f'{"*" * 35}开始创建软连接{"*" * 35}')
+ os.symlink(target_path, link_path)
+ print(f'{"*" * 35}成功创建软链接:{link_path} -> {target_path}{"*" * 35}')
+ except OSError as e:
+ print(f'创建软连接失败:{e}')
+
+
+def run_toolchain_build():
+ static_core_path = get_path_code_directory(STATICCOREPATH)
+ os.path.join(static_core_path, "tools")
+ current_dir = os.path.join(static_core_path, "tools")
+ os.chdir(current_dir)
+ target_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(current_dir))), 'ets_frontend/ets2panda')
+ link_path = os.path.join(current_dir, 'es2panda')
+ if os.path.exists(link_path):
+ try:
+ os.remove(link_path)
+ print(f"文件 {link_path} 已成功删除。")
+ except OSError as e:
+ print(f"删除文件时出错: {e}")
+
+ relative_path = os.path.relpath(target_path, os.path.dirname(link_path))
+ # 创建软链接ln -s ../../../ets_frontend/ets2panda es2panda
+ create_soft_link(relative_path, link_path)
+
+ os.chdir(static_core_path)
+
+ command_1 = "sudo -S ./scripts/install-deps-ubuntu -i=dev -i=test"
+ command_2 = "sudo apt install gdb"
+ command_3 = "pip3 install tqdm"
+ command_4 = "pip3 install python-dotenv"
+ command_5 = "./scripts/install-third-party --force-clone"
+ command_6 = "cmake -B out -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=./cmake/toolchain/host_clang_default.cmake -GNinja ."
+ command_7 = "cmake --build out"
+ command_list = [command_1, command_2, command_3, command_4, command_5, command_6, command_7]
+
+ for command in command_list:
+ run_command(command)
+
+
+# 删除目录下的特定文件
+def delete_specific_files(directory, target_extension):
+ for root_path, _, file_names in os.walk(directory):
+ for file_name in file_names:
+ if file_name != target_extension:
+ continue
+ file_path = os.path.join(root_path, file_name)
+ try:
+ os.remove(file_path)
+ print(f"已删除文件:{file_path}")
+ except Exception as e:
+ print(f"删除文件 {file_path} 时出错:{str(e)}")
+
+
+# 删除某个目录下所有的文件和文件夹
+def remove_directory_contents(dir_path):
+ print(f'dir_path:{dir_path}')
+ if dir_path is not None:
+ for root_path, dir_paths, file_names in os.walk(dir_path, topdown=False):
+ # 第一步:删除文件
+ for file_name in file_names:
+ os.remove(os.path.join(root_path, file_name))
+ # 第二步:删除空文件夹
+ for name in dir_paths:
+ os.rmdir(os.path.join(root_path, name))
+
+ if os.path.exists(dir_path):
+ print(f'删除路径:{dir_path}')
+ os.rmdir(dir_path)
+
+
+#*************hypium build***************
+def write_arktsconfig_file():
+ """
+ 将当前目录下的 .ets文件生成 file_map, 并追加写入 arktsconfig.json
+ """
+ tools_path = get_path_code_directory(TOOLSPATH)
+
+ # 1. 获取当前目录下的所有.ets文件
+ ets_files = [f for f in os.listdir(tools_path) if f.endswith('.ets')]
+
+ # 2. 构建file_map:{文件名:[文件绝对路径]}
+ file_map = {}
+ for ets_file in ets_files:
+ module_name = os.path.splitext(ets_file)[0]
+ relative_path = os.path.join(tools_path, ets_file)
+ print(f'relative_path:{relative_path}')
+ file_map[module_name] = [relative_path]
+
+ # 3. 定位要写入的 arktsconfig.json文件
+ abs_config_path = get_path_code_directory(CONFIGPATH)
+
+ # 4. 读取并更新配置
+ try:
+ with open(abs_config_path, 'r', encoding='utf-8') as f:
+ config = json.load(f)
+ except FileNotFoundError:
+ config = {"compilerOptions": {"baseUrl": "/code/arkcompiler/runtime_core/static_core", "paths": {}}}
+
+ # 5. 更新配置中的paths(保留之前的配置项)
+ config.setdefault("compilerOptions", {})
+ config["compilerOptions"].setdefault("paths", {})
+ config["compilerOptions"]["paths"].update(file_map)
+
+ with open(abs_config_path, 'w', encoding='utf-8') as f:
+ json.dump(config, f, indent=4, ensure_ascii=False)
+
+ print(f"已成功更新 {abs_config_path}")
+
+
+def build_tools(compile_filelist, hypium_output_dir):
+ """
+ 编译工具类
+ """
+ abs_es2panda_path = get_path_code_directory(ES2PANDAPATH)
+
+ # 1. 创建输出目录
+ output_dir = os.path.join(hypium_output_dir, "out")
+ os.makedirs(output_dir, exist_ok=True)
+
+ # 逐个执行编译命令
+ for ets_file in compile_filelist:
+ try:
+ # 获取文件名(不带路径)
+ file_name = os.path.basename(ets_file)
+ base_name = os.path.splitext(file_name)[0]
+ output_filepath = os.path.join(output_dir, f"{base_name}.abc")
+
+ # 构造编译命令
+ command = [abs_es2panda_path, ets_file, f"--output={output_filepath}"]
+ print(f"执行命令: {' '.join(command)}")
+
+ # 执行命令并获取输出
+ result = subprocess.run(
+ command,
+ check=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ text=True
+ )
+
+ # 成功编译
+ print(f"成功编译'{ets_file}', 输出路径: {output_filepath}")
+
+ except Exception as e:
+ print(f"'{ets_file}'编译失败:{e}")
+ break
+
+ count = 0
+ for root, _, filenames in os.walk(output_dir):
+ for filename in filenames:
+ if filename.endswith(".abc"):
+ count += 1
+
+ # 如果hypium和tools所有的文件都编译成功,则把所有abc文件link成一个abc文件
+ if count == len(compile_filelist):
+ link_abc_files(output_dir)
+
+
+def collect_abc_files(output_dir):
+ abc_files = []
+
+ # 1. 收集out目录下的.abc文件
+ if os.path.exists(output_dir):
+ out_files = [
+ os.path.join(output_dir, f)
+ for f in os.listdir(output_dir)
+ if f.endswith('.abc')
+ ]
+ abc_files.extend(out_files)
+
+ return abc_files
+
+
+def build_ets_files(hypium_output_dir):
+ # 将当前目录下的 .ets文件生成 file_map, 并追加写入 arktsconfig.json
+ write_arktsconfig_file()
+ """
+ 编译hypium、tools文件
+ """
+ if os.path.exists(hypium_output_dir):
+ try:
+ shutil.rmtree(hypium_output_dir)
+ print(f'已成功清除文件夹:{hypium_output_dir}')
+ except OSError as e:
+ print(f'清空文件夹失败:{e}')
+ else:
+ print(f'文件夹不存在:{hypium_output_dir}')
+
+ abs_hypium_path = get_path_code_directory(HYPIUMPATH)
+
+ files_to_compile = []
+ for root, dirs, files in os.walk(abs_hypium_path):
+ if "testAbility" in dirs:
+ dirs.remove("testAbility")
+ if "testrunner" in dirs:
+ dirs.remove("testrunner")
+
+ for f in files:
+ if f.endswith(".ets"):
+ file_path = os.path.join(root, f)
+ files_to_compile.append(file_path)
+
+ abs_tools_path = get_path_code_directory(TOOLSPATH)
+ ets_files = [os.path.join(abs_tools_path, f) for f in os.listdir(abs_tools_path) if f.endswith('.ets')]
+ files_to_compile.extend(ets_files)
+
+ if not files_to_compile:
+ print("未找到可编译的 .ets 文件,跳过编译。")
+ return
+ build_tools(files_to_compile, hypium_output_dir)
+
+
+def link_abc_files(output_dir):
+ """
+ 链接所有abc文件生成最终的test.abc
+ """
+ abs_arklink_path = get_path_code_directory(ARKLINKPATH)
+ abc_files = collect_abc_files(output_dir)
+
+ if not abc_files:
+ print("终止: 没有找到可连接的.abc文件")
+ return
+
+ out_path = os.path.join(os.path.dirname(output_dir), "hypium_tools.abc")
+
+ command = [
+ abs_arklink_path,
+ f"--output={out_path}",
+ "--",
+ *abc_files
+ ]
+
+ print(f"执行命令: {' '.join(command)}")
+
+ try:
+ result = subprocess.run(
+ command,
+ check=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ text=True
+ )
+ print("状态: 链接成功\n输出:", result.stdout.strip())
+
+ except subprocess.CalledProcessError as e:
+ print("错误: 链接失败")
+ print("错误详情:", e.stderr.strip())
+ raise # 可以选择抛出异常或处理错误
+
+
+def main():
+ # 工具链编译
+ static_core_path = get_path_code_directory(STATICCOREPATH)
+ #清空上次编译结果
+ remove_directory_contents(os.path.join(static_core_path, "out"))
+ run_toolchain_build()
+ third_party_path = os.path.join(static_core_path, "third_party")
+ #删除third_party路径下的bundle.json防止编译出错
+ delete_specific_files(third_party_path, 'bundle.json')
+ # hypium编译
+ arktstest_output_path = 'out/generic_generic_arm_64only/general_all_phone_standard/tests/arktstdd/hypium'
+ hypium_output_dir = get_path_code_directory(arktstest_output_path)
+ build_ets_files(hypium_output_dir)
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/src/core/command/run.py b/src/core/command/run.py
index 1e09767029abb50e4c00fa81b0d6c39cfcf32ed9..7125395065379bf28601304455991a3b6ee6e175 100644
--- a/src/core/command/run.py
+++ b/src/core/command/run.py
@@ -42,6 +42,7 @@ from core.testcase.testcase_manager import TestCaseManager
from core.config.config_manager import UserConfigManager
from core.config.parse_parts_config import ParsePartsConfig
from core.config.resource_manager import ResourceManager
+from core.arkts_tdd.arkts_tdd_execute.arkts_tdd_build import run_test
LOG = platform_logger("Run")
@@ -362,25 +363,46 @@ class Run(object):
options.testdict = test_dict
options.target_outpath = self.get_target_out_path(
options.productform)
- setattr(options, "scheduler", "Scheduler")
- scheduler = get_plugin(plugin_type=Plugin.SCHEDULER,
- plugin_id=SchedulerType.SCHEDULER)[0]
- if scheduler is None:
- LOG.error("Can not find the scheduler plugin.")
+ if "arktstdd" in options.testtype:
+ local_time = time.localtime()
+ create_time = time.strftime('%Y-%m-%d-%H-%M-%S', local_time)
+ result_rootpath = os.path.join(sys.framework_root_dir, "reports", create_time)
+ log_path = os.path.join(result_rootpath, "log")
+ os.makedirs(log_path, exist_ok=True)
+
+ options.result_rootpath = result_rootpath
+ options.log_path = log_path
+
+ 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
+
+ Binder.get_runtime_log().start_task_log(log_path)
+
+ options.testcases_path = os.path.join(test_case_path, options.testtype[0])
+ run_test(options)
+ Binder.get_runtime_log().stop_task_logcat()
else:
- options.testcases_path = self.get_tests_out_path(options.productform)
- options.resource_path = os.path.abspath(os.path.join(
- sys.framework_root_dir, "..", "resource"))
- if is_lite_product(options.productform,
- sys.source_code_root_path):
- if options.productform.find("wifiiot") != -1:
- Binder.get_tdd_config().update_test_type_in_source(
- ".bin", DeviceTestType.ctest_lite)
- Binder.get_tdd_config().update_ext_type_in_source(
- "BIN", DeviceTestType.ctest_lite)
- else:
- print("productform is not wifiiot")
- scheduler.exec_command(command, options)
+ setattr(options, "scheduler", "Scheduler")
+ scheduler = get_plugin(plugin_type=Plugin.SCHEDULER,
+ plugin_id=SchedulerType.SCHEDULER)[0]
+ if scheduler is None:
+ LOG.error("Can not find the scheduler plugin.")
+ else:
+ options.testcases_path = self.get_tests_out_path(options.productform)
+ options.resource_path = os.path.abspath(os.path.join(
+ sys.framework_root_dir, "..", "resource"))
+ if is_lite_product(options.productform,
+ sys.source_code_root_path):
+ if options.productform.find("wifiiot") != -1:
+ Binder.get_tdd_config().update_test_type_in_source(
+ ".bin", DeviceTestType.ctest_lite)
+ Binder.get_tdd_config().update_ext_type_in_source(
+ "BIN", DeviceTestType.ctest_lite)
+ else:
+ print("productform is not wifiiot")
+ scheduler.exec_command(command, options)
if need_record_history:
#读文件获取运行结果
from xdevice import Variables
diff --git a/src/core/testcase/testcase_manager.py b/src/core/testcase/testcase_manager.py
index bb0a7b1ac0bf280265bba5764f0b863047d94e87..115adee6f0bfeff497b3976c67147fbaae1a4dae 100644
--- a/src/core/testcase/testcase_manager.py
+++ b/src/core/testcase/testcase_manager.py
@@ -41,7 +41,8 @@ TESTFILE_TYPE_DATA_DIC = {
"OHJST": [],
"JST": [],
"LTPPosix": [],
- "OHRust": []
+ "OHRust": [],
+ "ABC": []
}
FILTER_SUFFIX_NAME_LIST = [".TOC", ".info", ".pyc"]
@@ -291,6 +292,9 @@ class TestCaseManager(object):
suite_file_dictionary.get("CXX").append(suite_file)
elif suffix_name == ".bin":
suite_file_dictionary.get("BIN").append(suite_file)
+ elif (suffix_name == ".abc" and not os.path.dirname(suite_file).endswith("out")
+ and not os.path.dirname(suite_file).endswith("hypium")):
+ suite_file_dictionary.get("ABC").append(suite_file)
return suite_file_dictionary