14514f5e3Sopenharmony_ci#!/usr/bin/env python3 24514f5e3Sopenharmony_ci# -*- coding: utf-8 -*- 34514f5e3Sopenharmony_ci 44514f5e3Sopenharmony_ci""" 54514f5e3Sopenharmony_ciCopyright (c) 2023-2024 Huawei Device Co., Ltd. 64514f5e3Sopenharmony_ciLicensed under the Apache License, Version 2.0 (the "License"); 74514f5e3Sopenharmony_ciyou may not use this file except in compliance with the License. 84514f5e3Sopenharmony_ciYou may obtain a copy of the License at 94514f5e3Sopenharmony_ci 104514f5e3Sopenharmony_ci http://www.apache.org/licenses/LICENSE-2.0 114514f5e3Sopenharmony_ci 124514f5e3Sopenharmony_ciUnless required by applicable law or agreed to in writing, software 134514f5e3Sopenharmony_cidistributed under the License is distributed on an "AS IS" BASIS, 144514f5e3Sopenharmony_ciWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 154514f5e3Sopenharmony_ciSee the License for the specific language governing permissions and 164514f5e3Sopenharmony_cilimitations under the License. 174514f5e3Sopenharmony_ci 184514f5e3Sopenharmony_ciDescription: run regress test case 194514f5e3Sopenharmony_ci""" 204514f5e3Sopenharmony_ciimport argparse 214514f5e3Sopenharmony_ciimport dataclasses 224514f5e3Sopenharmony_ciimport datetime 234514f5e3Sopenharmony_ciimport json 244514f5e3Sopenharmony_ciimport logging 254514f5e3Sopenharmony_ciimport multiprocessing 264514f5e3Sopenharmony_ciimport os 274514f5e3Sopenharmony_ciimport platform 284514f5e3Sopenharmony_ciimport re 294514f5e3Sopenharmony_ciimport shutil 304514f5e3Sopenharmony_ciimport stat 314514f5e3Sopenharmony_ciimport subprocess 324514f5e3Sopenharmony_ciimport sys 334514f5e3Sopenharmony_cifrom abc import ABC 344514f5e3Sopenharmony_cifrom typing import Optional, List, Type, Dict, Set, Tuple, Callable 354514f5e3Sopenharmony_cifrom os.path import dirname, join 364514f5e3Sopenharmony_cifrom pathlib import Path 374514f5e3Sopenharmony_ciimport xml.etree.cElementTree as XTree 384514f5e3Sopenharmony_cifrom enum import Enum, auto 394514f5e3Sopenharmony_ci 404514f5e3Sopenharmony_cifrom regress_test_config import RegressTestConfig 414514f5e3Sopenharmony_ci 424514f5e3Sopenharmony_ciENV_PATTERN = re.compile(r"//\s+Environment Variables:(.*)") 434514f5e3Sopenharmony_ci 444514f5e3Sopenharmony_ci 454514f5e3Sopenharmony_cidef init_log_file(args): 464514f5e3Sopenharmony_ci logging.basicConfig(filename=args.out_log, format=RegressTestConfig.DEFAULT_LOG_FORMAT, level=logging.INFO) 474514f5e3Sopenharmony_ci 484514f5e3Sopenharmony_ci 494514f5e3Sopenharmony_cidef parse_args(): 504514f5e3Sopenharmony_ci parser = argparse.ArgumentParser() 514514f5e3Sopenharmony_ci parser.add_argument('--test-dir', metavar='DIR', 524514f5e3Sopenharmony_ci help='Directory to test ') 534514f5e3Sopenharmony_ci parser.add_argument('--test-file', metavar='FILE', 544514f5e3Sopenharmony_ci help='File to test') 554514f5e3Sopenharmony_ci parser.add_argument('--test-list', metavar='FILE', dest="test_list", default=None, 564514f5e3Sopenharmony_ci help='File with list of tests to run') 574514f5e3Sopenharmony_ci parser.add_argument('--ignore-list', metavar='FILE', dest="ignore_list", default=None, 584514f5e3Sopenharmony_ci help='File with known failed tests list') 594514f5e3Sopenharmony_ci parser.add_argument('--timeout', default=RegressTestConfig.DEFAULT_TIMEOUT, type=int, 604514f5e3Sopenharmony_ci help='Set a custom test timeout in seconds !!!\n') 614514f5e3Sopenharmony_ci parser.add_argument('--processes', default=RegressTestConfig.DEFAULT_PROCESSES, type=int, 624514f5e3Sopenharmony_ci help='set number of processes to use. Default value: 1\n') 634514f5e3Sopenharmony_ci parser.add_argument('--merge-abc-binary', 644514f5e3Sopenharmony_ci help="merge-abc's binary tool") 654514f5e3Sopenharmony_ci parser.add_argument('--ark-tool', 664514f5e3Sopenharmony_ci help="ark's binary tool") 674514f5e3Sopenharmony_ci parser.add_argument('--ark-aot-tool', 684514f5e3Sopenharmony_ci help="ark_aot's binary tool") 694514f5e3Sopenharmony_ci parser.add_argument('--ark-aot', default=False, action='store_true', 704514f5e3Sopenharmony_ci help="runs in ark-aot mode") 714514f5e3Sopenharmony_ci parser.add_argument('--run-pgo', default=False, action='store_true', 724514f5e3Sopenharmony_ci help="runs in pgo mode") 734514f5e3Sopenharmony_ci parser.add_argument('--enable-litecg', default=False, action='store_true', 744514f5e3Sopenharmony_ci help="runs in litecg mode") 754514f5e3Sopenharmony_ci parser.add_argument('--ark-frontend-binary', 764514f5e3Sopenharmony_ci help="ark frontend conversion binary tool") 774514f5e3Sopenharmony_ci parser.add_argument('--stub-path', 784514f5e3Sopenharmony_ci help="stub file for run in AOT modes") 794514f5e3Sopenharmony_ci parser.add_argument('--LD_LIBRARY_PATH', '--libs-dir', 804514f5e3Sopenharmony_ci dest='ld_library_path', default=None, help='LD_LIBRARY_PATH') 814514f5e3Sopenharmony_ci parser.add_argument('--icu-path', 824514f5e3Sopenharmony_ci dest='icu_path', help='icu-data-path') 834514f5e3Sopenharmony_ci parser.add_argument('--out-dir', 844514f5e3Sopenharmony_ci default=None, help='target out dir') 854514f5e3Sopenharmony_ci parser.add_argument('--force-clone', action="store_true", 864514f5e3Sopenharmony_ci default=False, help='Force to clone tests folder') 874514f5e3Sopenharmony_ci parser.add_argument('--ark-arch', 884514f5e3Sopenharmony_ci default=RegressTestConfig.DEFAULT_ARK_ARCH, 894514f5e3Sopenharmony_ci required=False, 904514f5e3Sopenharmony_ci nargs='?', choices=RegressTestConfig.ARK_ARCH_LIST, type=str) 914514f5e3Sopenharmony_ci parser.add_argument('--ark-arch-root', 924514f5e3Sopenharmony_ci default=RegressTestConfig.DEFAULT_ARK_ARCH, 934514f5e3Sopenharmony_ci required=False, 944514f5e3Sopenharmony_ci help="the root path for qemu-aarch64 or qemu-arm") 954514f5e3Sopenharmony_ci parser.add_argument('--disable-force-gc', action='store_true', 964514f5e3Sopenharmony_ci help="Run regress tests with close force-gc") 974514f5e3Sopenharmony_ci return parser.parse_args() 984514f5e3Sopenharmony_ci 994514f5e3Sopenharmony_ci 1004514f5e3Sopenharmony_cidef check_ark_frontend_binary(args) -> bool: 1014514f5e3Sopenharmony_ci if args.ark_frontend_binary is None: 1024514f5e3Sopenharmony_ci output('ark_frontend_binary is required, please add this parameter') 1034514f5e3Sopenharmony_ci return False 1044514f5e3Sopenharmony_ci return True 1054514f5e3Sopenharmony_ci 1064514f5e3Sopenharmony_ci 1074514f5e3Sopenharmony_cidef check_frontend_library(args) -> bool: 1084514f5e3Sopenharmony_ci current_dir = str(os.getcwd()) 1094514f5e3Sopenharmony_ci current_frontend_binary = os.path.join(current_dir, str(args.ark_frontend_binary)) 1104514f5e3Sopenharmony_ci test_tool_frontend_binary = os.path.join(RegressTestConfig.TEST_TOOL_FILE_DIR, args.ark_frontend_binary) 1114514f5e3Sopenharmony_ci if not os.path.exists(current_frontend_binary) and not os.path.exists(test_tool_frontend_binary): 1124514f5e3Sopenharmony_ci output('entered ark_frontend_binary does not exist. please confirm') 1134514f5e3Sopenharmony_ci return False 1144514f5e3Sopenharmony_ci args.ark_frontend_binary = current_frontend_binary if os.path.exists( 1154514f5e3Sopenharmony_ci current_frontend_binary) else test_tool_frontend_binary 1164514f5e3Sopenharmony_ci args.ark_frontend_binary = os.path.abspath(args.ark_frontend_binary) 1174514f5e3Sopenharmony_ci return True 1184514f5e3Sopenharmony_ci 1194514f5e3Sopenharmony_ci 1204514f5e3Sopenharmony_cidef check_ark_tool(args) -> bool: 1214514f5e3Sopenharmony_ci current_dir = str(os.getcwd()) 1224514f5e3Sopenharmony_ci if args.ark_tool is None: 1234514f5e3Sopenharmony_ci output('ark_tool is required, please add this parameter') 1244514f5e3Sopenharmony_ci return False 1254514f5e3Sopenharmony_ci 1264514f5e3Sopenharmony_ci current_ark_tool = os.path.join(current_dir, str(args.ark_tool)) 1274514f5e3Sopenharmony_ci test_tool_ark_tool = os.path.join(RegressTestConfig.TEST_TOOL_FILE_DIR, args.ark_tool) 1284514f5e3Sopenharmony_ci if not os.path.exists(current_ark_tool) and not os.path.exists(test_tool_ark_tool): 1294514f5e3Sopenharmony_ci output('entered ark_tool does not exist. please confirm') 1304514f5e3Sopenharmony_ci return False 1314514f5e3Sopenharmony_ci 1324514f5e3Sopenharmony_ci args.ark_tool = current_ark_tool if os.path.exists(current_ark_tool) else test_tool_ark_tool 1334514f5e3Sopenharmony_ci args.ark_tool = os.path.abspath(args.ark_tool) 1344514f5e3Sopenharmony_ci return True 1354514f5e3Sopenharmony_ci 1364514f5e3Sopenharmony_ci 1374514f5e3Sopenharmony_cidef check_ark_aot(args) -> bool: 1384514f5e3Sopenharmony_ci if args.ark_aot: 1394514f5e3Sopenharmony_ci current_dir = str(os.getcwd()) 1404514f5e3Sopenharmony_ci current_ark_aot_tool = os.path.join(current_dir, str(args.ark_aot_tool)) 1414514f5e3Sopenharmony_ci test_tool_ark_aot_tool = os.path.join(RegressTestConfig.TEST_TOOL_FILE_DIR, args.ark_aot_tool) 1424514f5e3Sopenharmony_ci if not os.path.exists(current_ark_aot_tool) and not os.path.exists(test_tool_ark_aot_tool): 1434514f5e3Sopenharmony_ci output(f'entered ark_aot_tool "{args.ark_aot_tool}" does not exist. Please check') 1444514f5e3Sopenharmony_ci return False 1454514f5e3Sopenharmony_ci args.ark_aot_tool = current_ark_aot_tool if os.path.exists(current_ark_aot_tool) else test_tool_ark_aot_tool 1464514f5e3Sopenharmony_ci args.ark_aot_tool = os.path.abspath(args.ark_aot_tool) 1474514f5e3Sopenharmony_ci return True 1484514f5e3Sopenharmony_ci if args.run_pgo and not args.ark_aot: 1494514f5e3Sopenharmony_ci output('pgo mode cannot be used without aot') 1504514f5e3Sopenharmony_ci return False 1514514f5e3Sopenharmony_ci return True 1524514f5e3Sopenharmony_ci 1534514f5e3Sopenharmony_ci 1544514f5e3Sopenharmony_cidef check_stub_path(args) -> bool: 1554514f5e3Sopenharmony_ci if args.stub_path: 1564514f5e3Sopenharmony_ci current_dir = str(os.getcwd()) 1574514f5e3Sopenharmony_ci stub_path = os.path.join(current_dir, str(args.stub_path)) 1584514f5e3Sopenharmony_ci if not os.path.exists(stub_path): 1594514f5e3Sopenharmony_ci output(f'entered stub-file "{args.stub_path}" does not exist. Please check') 1604514f5e3Sopenharmony_ci return False 1614514f5e3Sopenharmony_ci args.stub_path = os.path.abspath(args.stub_path) 1624514f5e3Sopenharmony_ci return True 1634514f5e3Sopenharmony_ci 1644514f5e3Sopenharmony_ci 1654514f5e3Sopenharmony_cidef is_ignore_file_present(ignore_path: str) -> bool: 1664514f5e3Sopenharmony_ci if os.path.exists(ignore_path): 1674514f5e3Sopenharmony_ci return True 1684514f5e3Sopenharmony_ci output(f"Cannot find ignore list '{ignore_path}'") 1694514f5e3Sopenharmony_ci return False 1704514f5e3Sopenharmony_ci 1714514f5e3Sopenharmony_ci 1724514f5e3Sopenharmony_cidef check_ignore_list(args) -> bool: 1734514f5e3Sopenharmony_ci if args.ignore_list: 1744514f5e3Sopenharmony_ci if os.path.isabs(args.ignore_list): 1754514f5e3Sopenharmony_ci return is_ignore_file_present(args.ignore_list) 1764514f5e3Sopenharmony_ci args.ignore_list = str(os.path.join(RegressTestConfig.TEST_TOOL_FILE_DIR, args.ignore_list)) 1774514f5e3Sopenharmony_ci return is_ignore_file_present(args.ignore_list) 1784514f5e3Sopenharmony_ci return True 1794514f5e3Sopenharmony_ci 1804514f5e3Sopenharmony_ci 1814514f5e3Sopenharmony_cidef check_args(args): 1824514f5e3Sopenharmony_ci result = check_ark_frontend_binary(args) 1834514f5e3Sopenharmony_ci result = result and check_frontend_library(args) 1844514f5e3Sopenharmony_ci result = result and check_ark_tool(args) 1854514f5e3Sopenharmony_ci result = result and check_ark_aot(args) 1864514f5e3Sopenharmony_ci result = result and check_stub_path(args) 1874514f5e3Sopenharmony_ci result = result and check_ignore_list(args) 1884514f5e3Sopenharmony_ci 1894514f5e3Sopenharmony_ci if not result: 1904514f5e3Sopenharmony_ci return False 1914514f5e3Sopenharmony_ci 1924514f5e3Sopenharmony_ci if args.ld_library_path is not None: 1934514f5e3Sopenharmony_ci libs = args.ld_library_path.split(":") 1944514f5e3Sopenharmony_ci current_dir = str(os.getcwd()) 1954514f5e3Sopenharmony_ci libs = [os.path.abspath(os.path.join(current_dir, str(lib))) for lib in libs] 1964514f5e3Sopenharmony_ci args.ld_library_path = ":".join(libs) 1974514f5e3Sopenharmony_ci else: 1984514f5e3Sopenharmony_ci args.ld_library_path = RegressTestConfig.DEFAULT_LIBS_DIR 1994514f5e3Sopenharmony_ci if args.icu_path is None: 2004514f5e3Sopenharmony_ci args.icu_path = RegressTestConfig.ICU_PATH 2014514f5e3Sopenharmony_ci if args.out_dir is None: 2024514f5e3Sopenharmony_ci args.out_dir = RegressTestConfig.PROJECT_BASE_OUT_DIR 2034514f5e3Sopenharmony_ci else: 2044514f5e3Sopenharmony_ci args.out_dir = os.path.abspath(os.path.join(RegressTestConfig.CURRENT_PATH, args.out_dir)) 2054514f5e3Sopenharmony_ci if not args.out_dir.endswith("/"): 2064514f5e3Sopenharmony_ci args.out_dir = f"{args.out_dir}/" 2074514f5e3Sopenharmony_ci args.regress_out_dir = os.path.join(args.out_dir, "regresstest") 2084514f5e3Sopenharmony_ci args.out_result = os.path.join(args.regress_out_dir, 'result.txt') 2094514f5e3Sopenharmony_ci args.junit_report = os.path.join(args.regress_out_dir, 'report.xml') 2104514f5e3Sopenharmony_ci args.out_log = os.path.join(args.regress_out_dir, 'test.log') 2114514f5e3Sopenharmony_ci args.test_case_out_dir = os.path.join(args.regress_out_dir, RegressTestConfig.REGRESS_GIT_REPO) 2124514f5e3Sopenharmony_ci return True 2134514f5e3Sopenharmony_ci 2144514f5e3Sopenharmony_ci 2154514f5e3Sopenharmony_cidef remove_dir(path): 2164514f5e3Sopenharmony_ci if os.path.exists(path): 2174514f5e3Sopenharmony_ci shutil.rmtree(path) 2184514f5e3Sopenharmony_ci 2194514f5e3Sopenharmony_ci 2204514f5e3Sopenharmony_cidef output(msg): 2214514f5e3Sopenharmony_ci print(str(msg)) 2224514f5e3Sopenharmony_ci logging.info(str(msg)) 2234514f5e3Sopenharmony_ci 2244514f5e3Sopenharmony_ci 2254514f5e3Sopenharmony_cidef output_debug(msg): 2264514f5e3Sopenharmony_ci logging.debug(str(msg)) 2274514f5e3Sopenharmony_ci 2284514f5e3Sopenharmony_ci 2294514f5e3Sopenharmony_cidef get_extra_error_message(ret_code: int) -> str: 2304514f5e3Sopenharmony_ci error_messages = { 2314514f5e3Sopenharmony_ci 0: '', 2324514f5e3Sopenharmony_ci -6: 'Aborted (core dumped)', 2334514f5e3Sopenharmony_ci -4: 'Aborted (core dumped)', 2344514f5e3Sopenharmony_ci -11: 'Segmentation fault (core dumped)', 2354514f5e3Sopenharmony_ci 255: '(uncaught error)' 2364514f5e3Sopenharmony_ci } 2374514f5e3Sopenharmony_ci error_message = error_messages.get(ret_code, f'Unknown Error: {str(ret_code)}') 2384514f5e3Sopenharmony_ci return error_message 2394514f5e3Sopenharmony_ci 2404514f5e3Sopenharmony_ci 2414514f5e3Sopenharmony_ci@dataclasses.dataclass 2424514f5e3Sopenharmony_ciclass StepResult: 2434514f5e3Sopenharmony_ci step_name: str # a copy of the step name 2444514f5e3Sopenharmony_ci is_passed: bool = False # True if passed, any other state is False 2454514f5e3Sopenharmony_ci command: List[str] = dataclasses.field(default_factory=list) # command to run 2464514f5e3Sopenharmony_ci return_code: int = -1 2474514f5e3Sopenharmony_ci stdout: Optional[str] = None # present only if there is some output 2484514f5e3Sopenharmony_ci stderr: Optional[str] = None # can be present only if is_passed == False 2494514f5e3Sopenharmony_ci fileinfo: Optional[str] = None # content of fileinfo file if present 2504514f5e3Sopenharmony_ci 2514514f5e3Sopenharmony_ci def report(self) -> str: 2524514f5e3Sopenharmony_ci stdout = self.stdout if self.stdout else '' 2534514f5e3Sopenharmony_ci stderr = self.stderr if self.stderr else '' 2544514f5e3Sopenharmony_ci cmd = " ".join([str(cmd) for cmd in self.command]) 2554514f5e3Sopenharmony_ci result: List[str] = [ 2564514f5e3Sopenharmony_ci f"{self.step_name}:", 2574514f5e3Sopenharmony_ci f"\tCommand: {cmd}", 2584514f5e3Sopenharmony_ci f"\treturn code={self.return_code}", 2594514f5e3Sopenharmony_ci f"\toutput='{stdout}'", 2604514f5e3Sopenharmony_ci f"\terrors='{stderr}'"] 2614514f5e3Sopenharmony_ci if self.fileinfo: 2624514f5e3Sopenharmony_ci result.append(f"\tFileInfo:\n{self.fileinfo}") 2634514f5e3Sopenharmony_ci return "\n".join(result) 2644514f5e3Sopenharmony_ci 2654514f5e3Sopenharmony_ci 2664514f5e3Sopenharmony_ci@dataclasses.dataclass 2674514f5e3Sopenharmony_ciclass TestReport: 2684514f5e3Sopenharmony_ci src_path: str # full path to the source test 2694514f5e3Sopenharmony_ci test_id: str = "" # path starting from regresstest 2704514f5e3Sopenharmony_ci out_path: str = "" # full path to intermediate files up to folder 2714514f5e3Sopenharmony_ci passed: bool = False # False if the test has not started or failed 2724514f5e3Sopenharmony_ci is_skipped: bool = False # True if the test has found in the skipped (excluded) list 2734514f5e3Sopenharmony_ci is_ignored: bool = False # True if the test has found in the ignored list 2744514f5e3Sopenharmony_ci steps: List[StepResult] = dataclasses.field(default_factory=list) # list of results 2754514f5e3Sopenharmony_ci 2764514f5e3Sopenharmony_ci def report(self) -> str: 2774514f5e3Sopenharmony_ci result: List[str] = [f"{self.test_id}:"] 2784514f5e3Sopenharmony_ci if self.steps is None: 2794514f5e3Sopenharmony_ci return "" 2804514f5e3Sopenharmony_ci for step in self.steps: 2814514f5e3Sopenharmony_ci result.append(f"\t{step.report()}") 2824514f5e3Sopenharmony_ci return "\n".join(result) 2834514f5e3Sopenharmony_ci 2844514f5e3Sopenharmony_ci 2854514f5e3Sopenharmony_ciclass RegressTestStep(ABC): 2864514f5e3Sopenharmony_ci step_obj: Optional['RegressTestStep'] = None 2874514f5e3Sopenharmony_ci 2884514f5e3Sopenharmony_ci def __init__(self, args, name): 2894514f5e3Sopenharmony_ci output(f"--- Start step {name} ---") 2904514f5e3Sopenharmony_ci self.args = args 2914514f5e3Sopenharmony_ci self.__start: Optional[datetime.datetime] = None 2924514f5e3Sopenharmony_ci self.__end: Optional[datetime.datetime] = None 2934514f5e3Sopenharmony_ci self.__duration: Optional[datetime.timedelta] = None 2944514f5e3Sopenharmony_ci self.name: str = name 2954514f5e3Sopenharmony_ci 2964514f5e3Sopenharmony_ci @staticmethod 2974514f5e3Sopenharmony_ci def run(args, test_reports: Optional[List[TestReport]] = None) -> List[TestReport]: 2984514f5e3Sopenharmony_ci pass 2994514f5e3Sopenharmony_ci 3004514f5e3Sopenharmony_ci def get_duration(self) -> datetime.timedelta: 3014514f5e3Sopenharmony_ci if self.__duration is None: 3024514f5e3Sopenharmony_ci output(f"Step {self.name} not started or not completed") 3034514f5e3Sopenharmony_ci sys.exit(1) 3044514f5e3Sopenharmony_ci return self.__duration 3054514f5e3Sopenharmony_ci 3064514f5e3Sopenharmony_ci def _start(self): 3074514f5e3Sopenharmony_ci self.__start = datetime.datetime.now() 3084514f5e3Sopenharmony_ci 3094514f5e3Sopenharmony_ci def _end(self): 3104514f5e3Sopenharmony_ci self.__end = datetime.datetime.now() 3114514f5e3Sopenharmony_ci self.__duration = self.__end - self.__start 3124514f5e3Sopenharmony_ci 3134514f5e3Sopenharmony_ci 3144514f5e3Sopenharmony_ciclass RegressTestRepoPrepare(RegressTestStep): 3154514f5e3Sopenharmony_ci def __init__(self, args): 3164514f5e3Sopenharmony_ci RegressTestStep.__init__(self, args, "Repo preparation") 3174514f5e3Sopenharmony_ci self.test_list: List[str] = self.read_test_list(args.test_list) 3184514f5e3Sopenharmony_ci 3194514f5e3Sopenharmony_ci @staticmethod 3204514f5e3Sopenharmony_ci def read_test_list(test_list_name: Optional[str]) -> List[str]: 3214514f5e3Sopenharmony_ci if test_list_name is None: 3224514f5e3Sopenharmony_ci return [] 3234514f5e3Sopenharmony_ci filename = join(dirname(__file__), test_list_name) 3244514f5e3Sopenharmony_ci if not Path(filename).exists(): 3254514f5e3Sopenharmony_ci output(f"File {filename} set as --test-list value cannot be found") 3264514f5e3Sopenharmony_ci exit(1) 3274514f5e3Sopenharmony_ci with open(filename, 'r') as stream: 3284514f5e3Sopenharmony_ci return stream.read().split("\n") 3294514f5e3Sopenharmony_ci 3304514f5e3Sopenharmony_ci @staticmethod 3314514f5e3Sopenharmony_ci def run(args, test_reports: Optional[List[TestReport]] = None) -> List[TestReport]: 3324514f5e3Sopenharmony_ci repo = RegressTestRepoPrepare(args) 3334514f5e3Sopenharmony_ci RegressTestRepoPrepare.step_obj = repo 3344514f5e3Sopenharmony_ci repo._start() 3354514f5e3Sopenharmony_ci 3364514f5e3Sopenharmony_ci repo.run_regress_test_prepare() 3374514f5e3Sopenharmony_ci repo.prepare_clean_data() 3384514f5e3Sopenharmony_ci repo.get_test_case() 3394514f5e3Sopenharmony_ci test_list = repo.get_regress_test_files() 3404514f5e3Sopenharmony_ci skip_list = repo.get_skip_test_cases() 3414514f5e3Sopenharmony_ci if test_reports is None: 3424514f5e3Sopenharmony_ci test_reports = [] 3434514f5e3Sopenharmony_ci for test in test_list: 3444514f5e3Sopenharmony_ci shorten = Utils.get_inside_path(test) 3454514f5e3Sopenharmony_ci test_id = f"regresstest/ark-regress/{shorten}" 3464514f5e3Sopenharmony_ci if shorten not in skip_list: 3474514f5e3Sopenharmony_ci report = TestReport(src_path=test, test_id=test_id) 3484514f5e3Sopenharmony_ci test_reports.append(report) 3494514f5e3Sopenharmony_ci 3504514f5e3Sopenharmony_ci repo._end() 3514514f5e3Sopenharmony_ci return test_reports 3524514f5e3Sopenharmony_ci 3534514f5e3Sopenharmony_ci @staticmethod 3544514f5e3Sopenharmony_ci def git_checkout(checkout_options, check_out_dir=os.getcwd()): 3554514f5e3Sopenharmony_ci cmds = ['git', 'checkout', checkout_options] 3564514f5e3Sopenharmony_ci result = True 3574514f5e3Sopenharmony_ci with subprocess.Popen(cmds, cwd=check_out_dir) as proc: 3584514f5e3Sopenharmony_ci ret = proc.wait() 3594514f5e3Sopenharmony_ci if ret: 3604514f5e3Sopenharmony_ci output(f"\n error: git checkout '{checkout_options}' failed.") 3614514f5e3Sopenharmony_ci result = False 3624514f5e3Sopenharmony_ci return result 3634514f5e3Sopenharmony_ci 3644514f5e3Sopenharmony_ci @staticmethod 3654514f5e3Sopenharmony_ci def git_pull(check_out_dir=os.getcwd()): 3664514f5e3Sopenharmony_ci cmds = ['git', 'pull', '--rebase'] 3674514f5e3Sopenharmony_ci with subprocess.Popen(cmds, cwd=check_out_dir) as proc: 3684514f5e3Sopenharmony_ci proc.wait() 3694514f5e3Sopenharmony_ci 3704514f5e3Sopenharmony_ci @staticmethod 3714514f5e3Sopenharmony_ci def git_clean(clean_dir=os.getcwd()): 3724514f5e3Sopenharmony_ci cmds = ['git', 'checkout', '--', '.'] 3734514f5e3Sopenharmony_ci with subprocess.Popen(cmds, cwd=clean_dir) as proc: 3744514f5e3Sopenharmony_ci proc.wait() 3754514f5e3Sopenharmony_ci 3764514f5e3Sopenharmony_ci @staticmethod 3774514f5e3Sopenharmony_ci def git_clone(git_url, code_dir): 3784514f5e3Sopenharmony_ci cmds = ['git', 'clone', git_url, code_dir] 3794514f5e3Sopenharmony_ci retries = RegressTestConfig.DEFAULT_RETRIES 3804514f5e3Sopenharmony_ci while retries > 0: 3814514f5e3Sopenharmony_ci with subprocess.Popen(cmds) as proc: 3824514f5e3Sopenharmony_ci ret = proc.wait() 3834514f5e3Sopenharmony_ci if ret: 3844514f5e3Sopenharmony_ci output(f"\n Error: Cloning '{git_url}' failed. Retry remaining '{retries}' times") 3854514f5e3Sopenharmony_ci retries -= 1 3864514f5e3Sopenharmony_ci else: 3874514f5e3Sopenharmony_ci return True 3884514f5e3Sopenharmony_ci sys.exit(1) 3894514f5e3Sopenharmony_ci 3904514f5e3Sopenharmony_ci @staticmethod 3914514f5e3Sopenharmony_ci def get_skip_test_cases() -> List[str]: 3924514f5e3Sopenharmony_ci return Utils.read_skip_list(RegressTestConfig.SKIP_LIST_FILE) 3934514f5e3Sopenharmony_ci 3944514f5e3Sopenharmony_ci def get_test_case(self): 3954514f5e3Sopenharmony_ci if not os.path.isdir(os.path.join(RegressTestConfig.REGRESS_TEST_CASE_DIR, '.git')): 3964514f5e3Sopenharmony_ci self.git_clone(RegressTestConfig.REGRESS_GIT_URL, RegressTestConfig.REGRESS_TEST_CASE_DIR) 3974514f5e3Sopenharmony_ci return self.git_checkout(RegressTestConfig.REGRESS_GIT_HASH, RegressTestConfig.REGRESS_TEST_CASE_DIR) 3984514f5e3Sopenharmony_ci return True 3994514f5e3Sopenharmony_ci 4004514f5e3Sopenharmony_ci def prepare_clean_data(self): 4014514f5e3Sopenharmony_ci self.git_clean(RegressTestConfig.REGRESS_TEST_CASE_DIR) 4024514f5e3Sopenharmony_ci self.git_pull(RegressTestConfig.REGRESS_TEST_CASE_DIR) 4034514f5e3Sopenharmony_ci self.git_checkout(RegressTestConfig.REGRESS_GIT_HASH, RegressTestConfig.REGRESS_TEST_CASE_DIR) 4044514f5e3Sopenharmony_ci 4054514f5e3Sopenharmony_ci def run_regress_test_prepare(self): 4064514f5e3Sopenharmony_ci if self.args.force_clone: 4074514f5e3Sopenharmony_ci remove_dir(self.args.regress_out_dir) 4084514f5e3Sopenharmony_ci remove_dir(RegressTestConfig.REGRESS_TEST_CASE_DIR) 4094514f5e3Sopenharmony_ci os.makedirs(self.args.regress_out_dir, exist_ok=True) 4104514f5e3Sopenharmony_ci os.makedirs(RegressTestConfig.REGRESS_TEST_CASE_DIR, exist_ok=True) 4114514f5e3Sopenharmony_ci init_log_file(self.args) 4124514f5e3Sopenharmony_ci 4134514f5e3Sopenharmony_ci def get_regress_test_files(self) -> List[str]: 4144514f5e3Sopenharmony_ci result: List[str] = [] 4154514f5e3Sopenharmony_ci if self.args.test_file is not None and len(self.args.test_file) > 0: 4164514f5e3Sopenharmony_ci test_file_list = os.path.join(RegressTestConfig.REGRESS_TEST_CASE_DIR, self.args.test_file) 4174514f5e3Sopenharmony_ci result.append(str(test_file_list)) 4184514f5e3Sopenharmony_ci return result 4194514f5e3Sopenharmony_ci elif self.args.test_dir is not None and len(self.args.test_dir) > 0: 4204514f5e3Sopenharmony_ci test_file_list = os.path.join(RegressTestConfig.REGRESS_TEST_CASE_DIR, self.args.test_dir) 4214514f5e3Sopenharmony_ci else: 4224514f5e3Sopenharmony_ci test_file_list = RegressTestConfig.REGRESS_TEST_CASE_DIR 4234514f5e3Sopenharmony_ci for dir_path, path, filenames in os.walk(test_file_list): 4244514f5e3Sopenharmony_ci if dir_path.find(".git") != -1: 4254514f5e3Sopenharmony_ci continue 4264514f5e3Sopenharmony_ci for filename in filenames: 4274514f5e3Sopenharmony_ci if filename.endswith(".js") or filename.endswith(".mjs"): 4284514f5e3Sopenharmony_ci result.append(str(os.path.join(dir_path, filename))) 4294514f5e3Sopenharmony_ci return result 4304514f5e3Sopenharmony_ci 4314514f5e3Sopenharmony_ci 4324514f5e3Sopenharmony_ciclass RegressTestCompile(RegressTestStep): 4334514f5e3Sopenharmony_ci def __init__(self, args, test_reports: List[TestReport]): 4344514f5e3Sopenharmony_ci RegressTestStep.__init__(self, args, "Regress test compilation") 4354514f5e3Sopenharmony_ci self.out_dir = args.out_dir 4364514f5e3Sopenharmony_ci self.test_reports = test_reports 4374514f5e3Sopenharmony_ci for test in self.test_reports: 4384514f5e3Sopenharmony_ci test.out_path = os.path.dirname(os.path.join(self.out_dir, test.test_id)) 4394514f5e3Sopenharmony_ci 4404514f5e3Sopenharmony_ci @staticmethod 4414514f5e3Sopenharmony_ci def run(args, test_reports: Optional[List[TestReport]] = None) -> List[TestReport]: 4424514f5e3Sopenharmony_ci if test_reports is None: 4434514f5e3Sopenharmony_ci output("No tests loaded") 4444514f5e3Sopenharmony_ci exit(-1) 4454514f5e3Sopenharmony_ci test_prepare = RegressTestCompile(args, test_reports) 4464514f5e3Sopenharmony_ci RegressTestCompile.step_obj = test_prepare 4474514f5e3Sopenharmony_ci test_prepare._start() 4484514f5e3Sopenharmony_ci test_reports = test_prepare.gen_abc_files() 4494514f5e3Sopenharmony_ci test_prepare._end() 4504514f5e3Sopenharmony_ci return test_reports 4514514f5e3Sopenharmony_ci 4524514f5e3Sopenharmony_ci @staticmethod 4534514f5e3Sopenharmony_ci def create_files_info(test_report: TestReport) -> Tuple[str, str]: 4544514f5e3Sopenharmony_ci src_files_info = [ 4554514f5e3Sopenharmony_ci RegressTestConfig.REGRESS_TEST_TOOL_DIR, 4564514f5e3Sopenharmony_ci test_report.src_path 4574514f5e3Sopenharmony_ci ] 4584514f5e3Sopenharmony_ci file_info_content: List[str] = [] 4594514f5e3Sopenharmony_ci file_info_path = str(os.path.join( 4604514f5e3Sopenharmony_ci test_report.out_path, 4614514f5e3Sopenharmony_ci f"{Utils.get_file_only_name(test_report.src_path)}-filesInfo.txt")) 4624514f5e3Sopenharmony_ci os.makedirs(test_report.out_path, exist_ok=True) 4634514f5e3Sopenharmony_ci with os.fdopen( 4644514f5e3Sopenharmony_ci os.open(file_info_path, flags=os.O_RDWR | os.O_CREAT, mode=stat.S_IRUSR | stat.S_IWUSR), 4654514f5e3Sopenharmony_ci mode="w+", encoding="utf-8" 4664514f5e3Sopenharmony_ci ) as fp: 4674514f5e3Sopenharmony_ci for src_file_info in src_files_info: 4684514f5e3Sopenharmony_ci line = f"{src_file_info};{Utils.get_file_only_name(src_file_info)};esm;xxx;yyy\n" 4694514f5e3Sopenharmony_ci file_info_content.append(line) 4704514f5e3Sopenharmony_ci fp.write(line) 4714514f5e3Sopenharmony_ci return file_info_path, "\n".join(file_info_content) 4724514f5e3Sopenharmony_ci 4734514f5e3Sopenharmony_ci def gen_abc_files(self) -> List[TestReport]: 4744514f5e3Sopenharmony_ci with multiprocessing.Pool(processes=self.args.processes) as pool: 4754514f5e3Sopenharmony_ci results = pool.imap_unordered(self.gen_abc_file, self.test_reports) 4764514f5e3Sopenharmony_ci results = list(results) 4774514f5e3Sopenharmony_ci pool.close() 4784514f5e3Sopenharmony_ci pool.join() 4794514f5e3Sopenharmony_ci 4804514f5e3Sopenharmony_ci return results 4814514f5e3Sopenharmony_ci 4824514f5e3Sopenharmony_ci def gen_abc_file(self, test_report: TestReport) -> Optional[TestReport]: 4834514f5e3Sopenharmony_ci if test_report.src_path == RegressTestConfig.REGRESS_TEST_TOOL_DIR: 4844514f5e3Sopenharmony_ci return None 4854514f5e3Sopenharmony_ci file_info_path, file_info_content = self.create_files_info(test_report) 4864514f5e3Sopenharmony_ci out_file = change_extension(test_report.src_path, '.out') 4874514f5e3Sopenharmony_ci expect_file_exists = os.path.exists(out_file) 4884514f5e3Sopenharmony_ci output_file = change_extension( 4894514f5e3Sopenharmony_ci os.path.join(test_report.out_path, Utils.get_file_name(test_report.test_id)), 4904514f5e3Sopenharmony_ci ".abc") 4914514f5e3Sopenharmony_ci command = [ 4924514f5e3Sopenharmony_ci self.args.ark_frontend_binary, 4934514f5e3Sopenharmony_ci f"@{file_info_path}", 4944514f5e3Sopenharmony_ci "--merge-abc", 4954514f5e3Sopenharmony_ci "--module", 4964514f5e3Sopenharmony_ci f'--output={output_file}' 4974514f5e3Sopenharmony_ci ] 4984514f5e3Sopenharmony_ci step_result = StepResult(self.name, command=command, fileinfo=file_info_content) 4994514f5e3Sopenharmony_ci Utils.exec_command(command, test_report.test_id, step_result, self.args.timeout, 5004514f5e3Sopenharmony_ci lambda rt, _, _2: get_extra_error_message(rt)) 5014514f5e3Sopenharmony_ci test_report.steps.append(step_result) 5024514f5e3Sopenharmony_ci test_report.passed = step_result.is_passed 5034514f5e3Sopenharmony_ci if expect_file_exists: 5044514f5e3Sopenharmony_ci out_file_path = os.path.join(test_report.out_path, change_extension(test_report.test_id, '.out')) 5054514f5e3Sopenharmony_ci shutil.copy(str(out_file), str(out_file_path)) 5064514f5e3Sopenharmony_ci return test_report 5074514f5e3Sopenharmony_ci 5084514f5e3Sopenharmony_ci 5094514f5e3Sopenharmony_ciclass RegressTestPgo(RegressTestStep): 5104514f5e3Sopenharmony_ci def __init__(self, args): 5114514f5e3Sopenharmony_ci RegressTestStep.__init__(self, args, "Regress Test PGO ") 5124514f5e3Sopenharmony_ci 5134514f5e3Sopenharmony_ci @staticmethod 5144514f5e3Sopenharmony_ci def run(args, test_reports: Optional[List[TestReport]] = None) -> List[TestReport]: 5154514f5e3Sopenharmony_ci pgo = RegressTestPgo(args) 5164514f5e3Sopenharmony_ci RegressTestPgo.step_obj = pgo 5174514f5e3Sopenharmony_ci pgo._start() 5184514f5e3Sopenharmony_ci test_reports = pgo.generate_aps(test_reports) 5194514f5e3Sopenharmony_ci pgo._end() 5204514f5e3Sopenharmony_ci return test_reports 5214514f5e3Sopenharmony_ci 5224514f5e3Sopenharmony_ci def get_test_ap_cmd(self, test_report: TestReport) -> List[str]: 5234514f5e3Sopenharmony_ci abc_file = change_extension( 5244514f5e3Sopenharmony_ci os.path.join(test_report.out_path, Utils.get_file_name(test_report.test_id)), 5254514f5e3Sopenharmony_ci ".abc") 5264514f5e3Sopenharmony_ci ap_file = change_extension(abc_file, ".ap") 5274514f5e3Sopenharmony_ci entry_point = Utils.get_file_only_name(RegressTestConfig.TEST_TOOL_FILE_JS_NAME) 5284514f5e3Sopenharmony_ci os.environ["LD_LIBRARY_PATH"] = self.args.ld_library_path 5294514f5e3Sopenharmony_ci gen_ap_cmd = [] 5304514f5e3Sopenharmony_ci if self.args.ark_arch == RegressTestConfig.ARK_ARCH_LIST[1]: 5314514f5e3Sopenharmony_ci qemu_tool = "qemu-aarch64" 5324514f5e3Sopenharmony_ci gen_ap_cmd = [ 5334514f5e3Sopenharmony_ci qemu_tool, 5344514f5e3Sopenharmony_ci "-L", 5354514f5e3Sopenharmony_ci self.args.ark_arch_root 5364514f5e3Sopenharmony_ci ] 5374514f5e3Sopenharmony_ci gen_ap_cmd.append(self.args.ark_tool) 5384514f5e3Sopenharmony_ci gen_ap_cmd.append("--log-level=info") 5394514f5e3Sopenharmony_ci gen_ap_cmd.append(f"--icu-data-path={self.args.icu_path}") 5404514f5e3Sopenharmony_ci gen_ap_cmd.append("--compiler-target-triple=aarch64-unknown-linux-gn") 5414514f5e3Sopenharmony_ci gen_ap_cmd.append("--enable-pgo-profiler=true") 5424514f5e3Sopenharmony_ci gen_ap_cmd.append("--compiler-opt-inlining=true") 5434514f5e3Sopenharmony_ci gen_ap_cmd.append(f"--compiler-pgo-profiler-path={ap_file}") 5444514f5e3Sopenharmony_ci gen_ap_cmd.append("--asm-interpreter=true") 5454514f5e3Sopenharmony_ci gen_ap_cmd.append(f"--entry-point={entry_point}") 5464514f5e3Sopenharmony_ci gen_ap_cmd.append(f"{abc_file}") 5474514f5e3Sopenharmony_ci return gen_ap_cmd 5484514f5e3Sopenharmony_ci 5494514f5e3Sopenharmony_ci def generate_ap(self, test_report: Optional[TestReport]) -> Optional[TestReport]: 5504514f5e3Sopenharmony_ci if test_report is None or not test_report.passed: 5514514f5e3Sopenharmony_ci return test_report 5524514f5e3Sopenharmony_ci command = self.get_test_ap_cmd(test_report) 5534514f5e3Sopenharmony_ci step = StepResult(self.name, command=command) 5544514f5e3Sopenharmony_ci Utils.exec_command(command, test_report.test_id, step, self.args.timeout, 5554514f5e3Sopenharmony_ci lambda rt, _, _2: get_extra_error_message(rt)) 5564514f5e3Sopenharmony_ci test_report.steps.append(step) 5574514f5e3Sopenharmony_ci test_report.passed = step.is_passed 5584514f5e3Sopenharmony_ci return test_report 5594514f5e3Sopenharmony_ci 5604514f5e3Sopenharmony_ci def generate_aps(self, test_reports: List[TestReport]) -> List[TestReport]: 5614514f5e3Sopenharmony_ci with multiprocessing.Pool(processes=self.args.processes) as pool: 5624514f5e3Sopenharmony_ci results = pool.imap_unordered(self.generate_ap, test_reports) 5634514f5e3Sopenharmony_ci results = list(results) 5644514f5e3Sopenharmony_ci pool.close() 5654514f5e3Sopenharmony_ci pool.join() 5664514f5e3Sopenharmony_ci 5674514f5e3Sopenharmony_ci return results 5684514f5e3Sopenharmony_ci 5694514f5e3Sopenharmony_ci 5704514f5e3Sopenharmony_ciclass Utils: 5714514f5e3Sopenharmony_ci ark_regress = "ark-regress" 5724514f5e3Sopenharmony_ci 5734514f5e3Sopenharmony_ci @staticmethod 5744514f5e3Sopenharmony_ci def get_file_only_name(full_file_name: str) -> str: 5754514f5e3Sopenharmony_ci _, file_name = os.path.split(full_file_name) 5764514f5e3Sopenharmony_ci only_name, _ = os.path.splitext(file_name) 5774514f5e3Sopenharmony_ci return only_name 5784514f5e3Sopenharmony_ci 5794514f5e3Sopenharmony_ci @staticmethod 5804514f5e3Sopenharmony_ci def get_file_name(full_file_name: str) -> str: 5814514f5e3Sopenharmony_ci _, file_name = os.path.split(full_file_name) 5824514f5e3Sopenharmony_ci return file_name 5834514f5e3Sopenharmony_ci 5844514f5e3Sopenharmony_ci @staticmethod 5854514f5e3Sopenharmony_ci def mk_dst_dir(file, src_dir, dist_dir): 5864514f5e3Sopenharmony_ci idx = file.rfind(src_dir) 5874514f5e3Sopenharmony_ci fpath, _ = os.path.split(file[idx:]) 5884514f5e3Sopenharmony_ci fpath = fpath.replace(src_dir, dist_dir) 5894514f5e3Sopenharmony_ci os.makedirs(fpath, exist_ok=True) 5904514f5e3Sopenharmony_ci 5914514f5e3Sopenharmony_ci @staticmethod 5924514f5e3Sopenharmony_ci def get_inside_path(file_path: str, marker: Optional[str] = None) -> str: 5934514f5e3Sopenharmony_ci if marker is None: 5944514f5e3Sopenharmony_ci marker = Utils.ark_regress 5954514f5e3Sopenharmony_ci index = file_path.find(marker) 5964514f5e3Sopenharmony_ci if index > -1: 5974514f5e3Sopenharmony_ci return file_path[index + len(marker) + 1:] 5984514f5e3Sopenharmony_ci return file_path 5994514f5e3Sopenharmony_ci 6004514f5e3Sopenharmony_ci @staticmethod 6014514f5e3Sopenharmony_ci def exec_command(cmd_args, test_id: str, step_result: StepResult, timeout=RegressTestConfig.DEFAULT_TIMEOUT, 6024514f5e3Sopenharmony_ci get_extra_error_msg: Optional[Callable[[int, str, str], str]] = None) -> None: 6034514f5e3Sopenharmony_ci code_format = 'utf-8' 6044514f5e3Sopenharmony_ci if platform.system() == "Windows": 6054514f5e3Sopenharmony_ci code_format = 'gbk' 6064514f5e3Sopenharmony_ci cmd_string = "\n\t".join([str(arg).strip() for arg in cmd_args if arg is not None]) 6074514f5e3Sopenharmony_ci msg_cmd = "\n".join([ 6084514f5e3Sopenharmony_ci f"Run command:\n{cmd_string}", 6094514f5e3Sopenharmony_ci f"Env: {os.environ.get('LD_LIBRARY_PATH')}" 6104514f5e3Sopenharmony_ci ]) 6114514f5e3Sopenharmony_ci msg_result = f"TEST ({step_result.step_name.strip()}): {test_id}" 6124514f5e3Sopenharmony_ci try: 6134514f5e3Sopenharmony_ci with subprocess.Popen(cmd_args, stderr=subprocess.PIPE, stdout=subprocess.PIPE, close_fds=True, 6144514f5e3Sopenharmony_ci start_new_session=True) as process: 6154514f5e3Sopenharmony_ci output_res, errs = process.communicate(timeout=timeout) 6164514f5e3Sopenharmony_ci ret_code = process.poll() 6174514f5e3Sopenharmony_ci step_result.return_code = ret_code 6184514f5e3Sopenharmony_ci stderr = str(errs.decode(code_format, 'ignore').strip()) 6194514f5e3Sopenharmony_ci stdout = str(output_res.decode(code_format, 'ignore').strip()) 6204514f5e3Sopenharmony_ci extra_message = get_extra_error_msg(ret_code, stdout, stderr) if get_extra_error_msg is not None else "" 6214514f5e3Sopenharmony_ci step_result.stderr = f"{extra_message + '. ' if extra_message else '' }{stderr if stderr else ''}" 6224514f5e3Sopenharmony_ci step_result.stdout = stdout 6234514f5e3Sopenharmony_ci if ret_code == 0: 6244514f5e3Sopenharmony_ci msg_result = f"{msg_result} PASSED" 6254514f5e3Sopenharmony_ci step_result.is_passed = True 6264514f5e3Sopenharmony_ci else: 6274514f5e3Sopenharmony_ci msg_result = f"{msg_result} FAILED" 6284514f5e3Sopenharmony_ci except subprocess.TimeoutExpired: 6294514f5e3Sopenharmony_ci process.kill() 6304514f5e3Sopenharmony_ci process.terminate() 6314514f5e3Sopenharmony_ci step_result.return_code = -1 6324514f5e3Sopenharmony_ci step_result.stderr = f"Timeout: timed out after {timeout} seconds" 6334514f5e3Sopenharmony_ci msg_result = f"{msg_result} FAILED" 6344514f5e3Sopenharmony_ci except Exception as exc: 6354514f5e3Sopenharmony_ci step_result.return_code = -1 6364514f5e3Sopenharmony_ci step_result.stderr = f"Unknown error: {exc}" 6374514f5e3Sopenharmony_ci msg_result = f"{msg_result} FAILED" 6384514f5e3Sopenharmony_ci if step_result.is_passed: 6394514f5e3Sopenharmony_ci output(msg_result) 6404514f5e3Sopenharmony_ci output_debug(msg_cmd) 6414514f5e3Sopenharmony_ci else: 6424514f5e3Sopenharmony_ci output(f"{msg_result}\n{step_result.stderr}\n{msg_cmd}") 6434514f5e3Sopenharmony_ci 6444514f5e3Sopenharmony_ci @staticmethod 6454514f5e3Sopenharmony_ci def read_skip_list(skip_list_path: str) -> List[str]: 6464514f5e3Sopenharmony_ci skip_tests_list = [] 6474514f5e3Sopenharmony_ci with os.fdopen(os.open(skip_list_path, os.O_RDONLY, stat.S_IRUSR), "r") as file_object: 6484514f5e3Sopenharmony_ci json_data = json.load(file_object) 6494514f5e3Sopenharmony_ci for key in json_data: 6504514f5e3Sopenharmony_ci skip_tests_list.extend(key["files"]) 6514514f5e3Sopenharmony_ci return skip_tests_list 6524514f5e3Sopenharmony_ci 6534514f5e3Sopenharmony_ci @staticmethod 6544514f5e3Sopenharmony_ci def read_file_as_str(file_name: str) -> str: 6554514f5e3Sopenharmony_ci with os.fdopen(os.open(file_name, os.O_RDONLY, stat.S_IRUSR), "r") as file_object: 6564514f5e3Sopenharmony_ci content = [line.strip() for line in file_object.readlines()] 6574514f5e3Sopenharmony_ci return "\n".join(content) 6584514f5e3Sopenharmony_ci 6594514f5e3Sopenharmony_ci 6604514f5e3Sopenharmony_ciclass RegressTestAot(RegressTestStep): 6614514f5e3Sopenharmony_ci def __init__(self, args): 6624514f5e3Sopenharmony_ci RegressTestStep.__init__(self, args, "Regress Test AOT mode") 6634514f5e3Sopenharmony_ci 6644514f5e3Sopenharmony_ci @staticmethod 6654514f5e3Sopenharmony_ci def run(args, test_reports: Optional[List[TestReport]] = None) -> List[TestReport]: 6664514f5e3Sopenharmony_ci aot = RegressTestAot(args) 6674514f5e3Sopenharmony_ci RegressTestAot.step_obj = aot 6684514f5e3Sopenharmony_ci aot._start() 6694514f5e3Sopenharmony_ci test_reports = aot.compile_aots(test_reports) 6704514f5e3Sopenharmony_ci aot._end() 6714514f5e3Sopenharmony_ci return test_reports 6724514f5e3Sopenharmony_ci 6734514f5e3Sopenharmony_ci def get_test_aot_cmd(self, test_report: TestReport) -> List[str]: 6744514f5e3Sopenharmony_ci abc_file = change_extension( 6754514f5e3Sopenharmony_ci os.path.join(test_report.out_path, Utils.get_file_name(test_report.test_id)), 6764514f5e3Sopenharmony_ci ".abc") 6774514f5e3Sopenharmony_ci ap_file = change_extension(abc_file, ".ap") 6784514f5e3Sopenharmony_ci aot_file = change_extension(abc_file, "") 6794514f5e3Sopenharmony_ci os.environ["LD_LIBRARY_PATH"] = self.args.ld_library_path 6804514f5e3Sopenharmony_ci if self.args.ark_arch == RegressTestConfig.ARK_ARCH_LIST[1]: 6814514f5e3Sopenharmony_ci aot_cmd = [ 6824514f5e3Sopenharmony_ci "qemu-aarch64", 6834514f5e3Sopenharmony_ci "-L", 6844514f5e3Sopenharmony_ci self.args.ark_arch_root, 6854514f5e3Sopenharmony_ci self.args.ark_aot_tool, 6864514f5e3Sopenharmony_ci "--compiler-target-triple=aarch64-unknown-linux-gnu", 6874514f5e3Sopenharmony_ci f"--aot-file={aot_file}" 6884514f5e3Sopenharmony_ci ] 6894514f5e3Sopenharmony_ci else: 6904514f5e3Sopenharmony_ci aot_cmd = [ 6914514f5e3Sopenharmony_ci self.args.ark_aot_tool, 6924514f5e3Sopenharmony_ci f"--aot-file={aot_file}", 6934514f5e3Sopenharmony_ci ] 6944514f5e3Sopenharmony_ci 6954514f5e3Sopenharmony_ci pgo = [ 6964514f5e3Sopenharmony_ci "--compiler-opt-loop-peeling=true", 6974514f5e3Sopenharmony_ci "--compiler-fast-compile=false", 6984514f5e3Sopenharmony_ci "--compiler-opt-track-field=true", 6994514f5e3Sopenharmony_ci "--compiler-opt-inlining=true", 7004514f5e3Sopenharmony_ci "--compiler-max-inline-bytecodes=45", 7014514f5e3Sopenharmony_ci "--compiler-opt-level=2", 7024514f5e3Sopenharmony_ci f"--compiler-pgo-profiler-path={ap_file}", 7034514f5e3Sopenharmony_ci ] 7044514f5e3Sopenharmony_ci litecg = [ 7054514f5e3Sopenharmony_ci "--compiler-enable-litecg=true", 7064514f5e3Sopenharmony_ci ] 7074514f5e3Sopenharmony_ci aot_cmd_tail = [ 7084514f5e3Sopenharmony_ci f"{abc_file}", 7094514f5e3Sopenharmony_ci ] 7104514f5e3Sopenharmony_ci 7114514f5e3Sopenharmony_ci if self.args.run_pgo: 7124514f5e3Sopenharmony_ci aot_cmd.extend(pgo) 7134514f5e3Sopenharmony_ci if self.args.enable_litecg: 7144514f5e3Sopenharmony_ci aot_cmd.extend(litecg) 7154514f5e3Sopenharmony_ci aot_cmd.extend(aot_cmd_tail) 7164514f5e3Sopenharmony_ci return aot_cmd 7174514f5e3Sopenharmony_ci 7184514f5e3Sopenharmony_ci def compile_aot(self, test_report: Optional[TestReport]) -> Optional[TestReport]: 7194514f5e3Sopenharmony_ci if test_report is None or not test_report.passed: 7204514f5e3Sopenharmony_ci return test_report 7214514f5e3Sopenharmony_ci command = self.get_test_aot_cmd(test_report) 7224514f5e3Sopenharmony_ci step = StepResult(self.name, command=command) 7234514f5e3Sopenharmony_ci Utils.exec_command(command, test_report.test_id, step, self.args.timeout, 7244514f5e3Sopenharmony_ci lambda rt, _, _2: get_extra_error_message(rt)) 7254514f5e3Sopenharmony_ci test_report.steps.append(step) 7264514f5e3Sopenharmony_ci test_report.passed = step.is_passed 7274514f5e3Sopenharmony_ci return test_report 7284514f5e3Sopenharmony_ci 7294514f5e3Sopenharmony_ci def compile_aots(self, test_reports: List[TestReport]) -> List[TestReport]: 7304514f5e3Sopenharmony_ci with multiprocessing.Pool(processes=self.args.processes) as pool: 7314514f5e3Sopenharmony_ci results = pool.imap_unordered(self.compile_aot, test_reports) 7324514f5e3Sopenharmony_ci results = list(results) 7334514f5e3Sopenharmony_ci pool.close() 7344514f5e3Sopenharmony_ci pool.join() 7354514f5e3Sopenharmony_ci 7364514f5e3Sopenharmony_ci return results 7374514f5e3Sopenharmony_ci 7384514f5e3Sopenharmony_ci 7394514f5e3Sopenharmony_ciclass RegressOption(Enum): 7404514f5e3Sopenharmony_ci NO_FORCE_GC = auto() 7414514f5e3Sopenharmony_ci ELEMENTS_KIND = auto() 7424514f5e3Sopenharmony_ci 7434514f5e3Sopenharmony_ci 7444514f5e3Sopenharmony_cidef get_regress_groups() -> Dict[RegressOption, List[str]]: 7454514f5e3Sopenharmony_ci groups = {} 7464514f5e3Sopenharmony_ci with os.fdopen(os.open(RegressTestConfig.REGRESS_TEST_OPTIONS, os.O_RDONLY, stat.S_IRUSR), "r") as file: 7474514f5e3Sopenharmony_ci for group in json.load(file): 7484514f5e3Sopenharmony_ci groups[RegressOption[group["name"]]] = group["files"] 7494514f5e3Sopenharmony_ci return groups 7504514f5e3Sopenharmony_ci 7514514f5e3Sopenharmony_ci 7524514f5e3Sopenharmony_cidef get_test_options(test: str, test_groups: Dict[RegressOption, List[str]], regress_option: RegressOption) -> List[str]: 7534514f5e3Sopenharmony_ci opt_values: Dict[RegressOption, str] = { 7544514f5e3Sopenharmony_ci RegressOption.NO_FORCE_GC: "--enable-force-gc=", 7554514f5e3Sopenharmony_ci RegressOption.ELEMENTS_KIND: "--enable-elements-kind=" 7564514f5e3Sopenharmony_ci } 7574514f5e3Sopenharmony_ci 7584514f5e3Sopenharmony_ci def match(opt: RegressOption) -> bool: 7594514f5e3Sopenharmony_ci return test in test_groups.get(opt, []) 7604514f5e3Sopenharmony_ci 7614514f5e3Sopenharmony_ci def to_flag(b: bool) -> str: 7624514f5e3Sopenharmony_ci return str(b).lower() 7634514f5e3Sopenharmony_ci 7644514f5e3Sopenharmony_ci try: 7654514f5e3Sopenharmony_ci return [opt_values.get(regress_option) + to_flag(not match(regress_option))] 7664514f5e3Sopenharmony_ci except KeyError: 7674514f5e3Sopenharmony_ci return [] 7684514f5e3Sopenharmony_ci 7694514f5e3Sopenharmony_ci 7704514f5e3Sopenharmony_ciclass RegressTestRun(RegressTestStep): 7714514f5e3Sopenharmony_ci def __init__(self, args): 7724514f5e3Sopenharmony_ci RegressTestStep.__init__(self, args, "Regress Test Run ") 7734514f5e3Sopenharmony_ci self.test_groups: Dict[RegressOption, List[str]] = get_regress_groups() 7744514f5e3Sopenharmony_ci 7754514f5e3Sopenharmony_ci @staticmethod 7764514f5e3Sopenharmony_ci def run(args, test_reports: Optional[List[TestReport]] = None) -> List[TestReport]: 7774514f5e3Sopenharmony_ci runner = RegressTestRun(args) 7784514f5e3Sopenharmony_ci RegressTestRun.step_obj = runner 7794514f5e3Sopenharmony_ci runner._start() 7804514f5e3Sopenharmony_ci test_reports = runner.run_test_case_dir(test_reports) 7814514f5e3Sopenharmony_ci runner._end() 7824514f5e3Sopenharmony_ci return test_reports 7834514f5e3Sopenharmony_ci 7844514f5e3Sopenharmony_ci @staticmethod 7854514f5e3Sopenharmony_ci def extra_check_with_expect(ret_code: int, test_report: TestReport, expect_file, stdout: str, stderr: str) -> str: 7864514f5e3Sopenharmony_ci expect_output_str = read_expect_file(expect_file, test_report.src_path) 7874514f5e3Sopenharmony_ci test_case_file = Utils.read_file_as_str(test_report.src_path) 7884514f5e3Sopenharmony_ci if stdout == expect_output_str.strip() or stderr == expect_output_str.strip(): 7894514f5e3Sopenharmony_ci if ret_code == 0 or (ret_code == 255 and "/fail/" in test_case_file): 7904514f5e3Sopenharmony_ci return "" 7914514f5e3Sopenharmony_ci else: 7924514f5e3Sopenharmony_ci return get_extra_error_message(ret_code) 7934514f5e3Sopenharmony_ci msg = f'expect: [{expect_output_str}]\nbut got: [{stderr}]' 7944514f5e3Sopenharmony_ci return msg 7954514f5e3Sopenharmony_ci 7964514f5e3Sopenharmony_ci @staticmethod 7974514f5e3Sopenharmony_ci def extra_check_with_assert(ret_code: int, stderr: Optional[str]) -> str: 7984514f5e3Sopenharmony_ci if ret_code == 0 and stderr and "[ecmascript] Stack overflow" not in stderr: 7994514f5e3Sopenharmony_ci return str(stderr) 8004514f5e3Sopenharmony_ci return get_extra_error_message(ret_code) 8014514f5e3Sopenharmony_ci 8024514f5e3Sopenharmony_ci def run_test_case_dir(self, test_reports: List[TestReport]) -> List[TestReport]: 8034514f5e3Sopenharmony_ci with multiprocessing.Pool(processes=self.args.processes, initializer=init_worker, 8044514f5e3Sopenharmony_ci initargs=(self.args,)) as pool: 8054514f5e3Sopenharmony_ci results = pool.imap_unordered(self.run_test_case, test_reports) 8064514f5e3Sopenharmony_ci results = list(results) 8074514f5e3Sopenharmony_ci pool.close() 8084514f5e3Sopenharmony_ci pool.join() 8094514f5e3Sopenharmony_ci 8104514f5e3Sopenharmony_ci return results 8114514f5e3Sopenharmony_ci 8124514f5e3Sopenharmony_ci def run_test_case(self, test_report: TestReport) -> Optional[TestReport]: 8134514f5e3Sopenharmony_ci self.args = worker_wrapper_args 8144514f5e3Sopenharmony_ci if self.args is None or test_report is None or not test_report.passed: 8154514f5e3Sopenharmony_ci return test_report 8164514f5e3Sopenharmony_ci if test_report.src_path.endswith(RegressTestConfig.TEST_TOOL_FILE_JS_NAME): 8174514f5e3Sopenharmony_ci return None 8184514f5e3Sopenharmony_ci 8194514f5e3Sopenharmony_ci abc_file = change_extension( 8204514f5e3Sopenharmony_ci os.path.join(test_report.out_path, Utils.get_file_name(test_report.test_id)), 8214514f5e3Sopenharmony_ci ".abc") 8224514f5e3Sopenharmony_ci aot_file = change_extension(abc_file, "") 8234514f5e3Sopenharmony_ci expect_file = change_extension(abc_file, ".out") 8244514f5e3Sopenharmony_ci entry_point = Utils.get_file_only_name(RegressTestConfig.TEST_TOOL_FILE_JS_NAME) 8254514f5e3Sopenharmony_ci 8264514f5e3Sopenharmony_ci os.environ["LD_LIBRARY_PATH"] = self.args.ld_library_path 8274514f5e3Sopenharmony_ci 8284514f5e3Sopenharmony_ci # test environ LC_ALL/TZ 8294514f5e3Sopenharmony_ci test_name = test_report.test_id.replace('regresstest/ark-regress/', '') 8304514f5e3Sopenharmony_ci set_test_environ(test_report.src_path) 8314514f5e3Sopenharmony_ci command = [] 8324514f5e3Sopenharmony_ci if self.args.ark_arch == RegressTestConfig.ARK_ARCH_LIST[1]: 8334514f5e3Sopenharmony_ci qemu_tool = "qemu-aarch64" 8344514f5e3Sopenharmony_ci qemu_arg1 = "-L" 8354514f5e3Sopenharmony_ci qemu_arg2 = self.args.ark_arch_root 8364514f5e3Sopenharmony_ci command = [qemu_tool, qemu_arg1, qemu_arg2] 8374514f5e3Sopenharmony_ci command.append(self.args.ark_tool) 8384514f5e3Sopenharmony_ci command.append(f"--icu-data-path={self.args.icu_path}") 8394514f5e3Sopenharmony_ci command.append(f"--entry-point={entry_point}") 8404514f5e3Sopenharmony_ci if self.args.ark_aot: 8414514f5e3Sopenharmony_ci command.append(f"--stub-file={self.args.stub_path}") 8424514f5e3Sopenharmony_ci command.append(f"--aot-file={aot_file}") 8434514f5e3Sopenharmony_ci if self.args.disable_force_gc: 8444514f5e3Sopenharmony_ci command.append("--enable-force-gc=false") 8454514f5e3Sopenharmony_ci else: 8464514f5e3Sopenharmony_ci command.extend(get_test_options(test_name, self.test_groups, RegressOption.NO_FORCE_GC)) 8474514f5e3Sopenharmony_ci command.extend(get_test_options(test_name, self.test_groups, RegressOption.ELEMENTS_KIND)) 8484514f5e3Sopenharmony_ci command.append(abc_file) 8494514f5e3Sopenharmony_ci 8504514f5e3Sopenharmony_ci return self.run_test_case_file(command, test_report, expect_file) 8514514f5e3Sopenharmony_ci 8524514f5e3Sopenharmony_ci def run_test_case_file(self, command, test_report: TestReport, expect_file) -> TestReport: 8534514f5e3Sopenharmony_ci expect_file_exits = os.path.exists(expect_file) 8544514f5e3Sopenharmony_ci step = StepResult(self.name, command=command) 8554514f5e3Sopenharmony_ci if expect_file_exits: 8564514f5e3Sopenharmony_ci self.run_test_case_with_expect(command, step, test_report, expect_file) 8574514f5e3Sopenharmony_ci else: 8584514f5e3Sopenharmony_ci self.run_test_case_with_assert(command, step, test_report) 8594514f5e3Sopenharmony_ci test_report.steps.append(step) 8604514f5e3Sopenharmony_ci test_report.passed = step.is_passed 8614514f5e3Sopenharmony_ci return test_report 8624514f5e3Sopenharmony_ci 8634514f5e3Sopenharmony_ci def run_test_case_with_expect(self, command, step: StepResult, test_report: TestReport, expect_file) -> None: 8644514f5e3Sopenharmony_ci Utils.exec_command(command, test_report.test_id, step, self.args.timeout, 8654514f5e3Sopenharmony_ci lambda rt, out, err: self.extra_check_with_expect(rt, test_report, expect_file, out, err)) 8664514f5e3Sopenharmony_ci 8674514f5e3Sopenharmony_ci def run_test_case_with_assert(self, command, step: StepResult, test_report: TestReport) -> None: 8684514f5e3Sopenharmony_ci Utils.exec_command(command, test_report.test_id, step, self.args.timeout, 8694514f5e3Sopenharmony_ci lambda rt, _, err: self.extra_check_with_assert(rt, err)) 8704514f5e3Sopenharmony_ci 8714514f5e3Sopenharmony_ci 8724514f5e3Sopenharmony_ciclass Stats: 8734514f5e3Sopenharmony_ci def __init__(self, args, test_reports: List[TestReport]): 8744514f5e3Sopenharmony_ci self.args = args 8754514f5e3Sopenharmony_ci self.pass_count = 0 8764514f5e3Sopenharmony_ci self.fail_count = 0 8774514f5e3Sopenharmony_ci self.test_reports = test_reports 8784514f5e3Sopenharmony_ci self.errors: Dict[str, List[TestReport]] = {} 8794514f5e3Sopenharmony_ci 8804514f5e3Sopenharmony_ci def read_ignore_list(self) -> Optional[Set[str]]: 8814514f5e3Sopenharmony_ci if self.args.ignore_list is None: 8824514f5e3Sopenharmony_ci return None 8834514f5e3Sopenharmony_ci with os.fdopen(os.open(self.args.ignore_list, os.O_RDWR, stat.S_IRUSR), "r+") as file_object: 8844514f5e3Sopenharmony_ci lines = file_object.readlines() 8854514f5e3Sopenharmony_ci lines = [line.strip() for line in lines if not line.strip().startswith('#')] 8864514f5e3Sopenharmony_ci return set(lines) 8874514f5e3Sopenharmony_ci 8884514f5e3Sopenharmony_ci def get_new_failures(self) -> Optional[List[TestReport]]: 8894514f5e3Sopenharmony_ci ignore_list = self.read_ignore_list() 8904514f5e3Sopenharmony_ci if ignore_list is None: 8914514f5e3Sopenharmony_ci return None 8924514f5e3Sopenharmony_ci new_failures: List[TestReport] = [] 8934514f5e3Sopenharmony_ci for test_report in self.test_reports: 8944514f5e3Sopenharmony_ci if test_report and not test_report.passed and test_report.steps: 8954514f5e3Sopenharmony_ci if test_report.test_id not in ignore_list: 8964514f5e3Sopenharmony_ci new_failures.append(test_report) 8974514f5e3Sopenharmony_ci return new_failures 8984514f5e3Sopenharmony_ci 8994514f5e3Sopenharmony_ci def statistics(self): 9004514f5e3Sopenharmony_ci root = XTree.Element("testsuite") 9014514f5e3Sopenharmony_ci root.set("name", "Regression") 9024514f5e3Sopenharmony_ci 9034514f5e3Sopenharmony_ci result_file = open_write_file(self.args.out_result, False) 9044514f5e3Sopenharmony_ci for test_report in self.test_reports: 9054514f5e3Sopenharmony_ci if test_report is None: 9064514f5e3Sopenharmony_ci continue 9074514f5e3Sopenharmony_ci testcase = XTree.SubElement(root, "testcase") 9084514f5e3Sopenharmony_ci testcase.set("name", f"{test_report.test_id}") 9094514f5e3Sopenharmony_ci if test_report.passed: 9104514f5e3Sopenharmony_ci write_result_file(f"PASS: {test_report.test_id}", result_file) 9114514f5e3Sopenharmony_ci self.pass_count += 1 9124514f5e3Sopenharmony_ci else: 9134514f5e3Sopenharmony_ci self.fail_count += 1 9144514f5e3Sopenharmony_ci write_result_file(f"FAIL: {test_report.test_id}", result_file) 9154514f5e3Sopenharmony_ci failed_step = test_report.steps[-1] 9164514f5e3Sopenharmony_ci if failed_step.step_name not in self.errors: 9174514f5e3Sopenharmony_ci self.errors[failed_step.step_name] = [] 9184514f5e3Sopenharmony_ci self.errors[failed_step.step_name].append(test_report) 9194514f5e3Sopenharmony_ci XTree.SubElement(testcase, "failure").text = f"<![CDATA[{test_report.report()}]]>" 9204514f5e3Sopenharmony_ci 9214514f5e3Sopenharmony_ci root.set("tests", f"{self.pass_count + self.fail_count}") 9224514f5e3Sopenharmony_ci root.set("failures", f"{self.fail_count}") 9234514f5e3Sopenharmony_ci 9244514f5e3Sopenharmony_ci tree = XTree.ElementTree(root) 9254514f5e3Sopenharmony_ci tree.write(self.args.junit_report, xml_declaration=True, encoding="UTF-8") 9264514f5e3Sopenharmony_ci result_file.close() 9274514f5e3Sopenharmony_ci 9284514f5e3Sopenharmony_ci def print_result(self, args, steps): 9294514f5e3Sopenharmony_ci result_file = open_write_file(args.out_result, True) 9304514f5e3Sopenharmony_ci summary_duration = datetime.timedelta() 9314514f5e3Sopenharmony_ci for step in steps: 9324514f5e3Sopenharmony_ci output(f"Step {step.step_obj.name} - duration {step.step_obj.get_duration()}") 9334514f5e3Sopenharmony_ci summary_duration += step.step_obj.get_duration() 9344514f5e3Sopenharmony_ci msg = f'\npass count: {self.pass_count}' 9354514f5e3Sopenharmony_ci write_result_file(msg, result_file) 9364514f5e3Sopenharmony_ci output(msg) 9374514f5e3Sopenharmony_ci msg = f'fail count: {self.fail_count}' 9384514f5e3Sopenharmony_ci write_result_file(msg, result_file) 9394514f5e3Sopenharmony_ci output(msg) 9404514f5e3Sopenharmony_ci msg = f'total count: {self.fail_count + self.pass_count}' 9414514f5e3Sopenharmony_ci write_result_file(msg, result_file) 9424514f5e3Sopenharmony_ci output(msg) 9434514f5e3Sopenharmony_ci msg = f'total used time is: {str(summary_duration)}' 9444514f5e3Sopenharmony_ci write_result_file(msg, result_file) 9454514f5e3Sopenharmony_ci output(msg) 9464514f5e3Sopenharmony_ci result_file.close() 9474514f5e3Sopenharmony_ci 9484514f5e3Sopenharmony_ci def print_failed_tests(self): 9494514f5e3Sopenharmony_ci output("=== Failed tests ===") 9504514f5e3Sopenharmony_ci for key, values in self.errors.items(): 9514514f5e3Sopenharmony_ci output(f"{key}: {len(values)} tests") 9524514f5e3Sopenharmony_ci 9534514f5e3Sopenharmony_ci 9544514f5e3Sopenharmony_cidef change_extension(path, new_ext: str): 9554514f5e3Sopenharmony_ci base_path, ext = os.path.splitext(path) 9564514f5e3Sopenharmony_ci if ext: 9574514f5e3Sopenharmony_ci new_path = base_path + new_ext 9584514f5e3Sopenharmony_ci else: 9594514f5e3Sopenharmony_ci new_path = path + new_ext 9604514f5e3Sopenharmony_ci return new_path 9614514f5e3Sopenharmony_ci 9624514f5e3Sopenharmony_ci 9634514f5e3Sopenharmony_cidef get_files_by_ext(start_dir, suffix): 9644514f5e3Sopenharmony_ci result = [] 9654514f5e3Sopenharmony_ci for dir_path, dir_names, filenames in os.walk(start_dir): 9664514f5e3Sopenharmony_ci for filename in filenames: 9674514f5e3Sopenharmony_ci if filename.endswith(suffix): 9684514f5e3Sopenharmony_ci result.append(os.path.join(dir_path, filename)) 9694514f5e3Sopenharmony_ci return result 9704514f5e3Sopenharmony_ci 9714514f5e3Sopenharmony_ci 9724514f5e3Sopenharmony_cidef read_expect_file(expect_file, test_case_file): 9734514f5e3Sopenharmony_ci with os.fdopen(os.open(expect_file, os.O_RDWR, stat.S_IRUSR), "r+") as file_object: 9744514f5e3Sopenharmony_ci lines = file_object.readlines() 9754514f5e3Sopenharmony_ci lines = [line for line in lines if not line.strip().startswith('#')] 9764514f5e3Sopenharmony_ci expect_output = ''.join(lines) 9774514f5e3Sopenharmony_ci if test_case_file.startswith("/"): 9784514f5e3Sopenharmony_ci test_case_file = test_case_file.lstrip("/") 9794514f5e3Sopenharmony_ci expect_file = test_case_file.replace('regresstest/', '') 9804514f5e3Sopenharmony_ci test_file_path = os.path.join(RegressTestConfig.REGRESS_BASE_TEST_DIR, expect_file) 9814514f5e3Sopenharmony_ci expect_output_str = expect_output.replace('*%(basename)s', test_file_path) 9824514f5e3Sopenharmony_ci return expect_output_str 9834514f5e3Sopenharmony_ci 9844514f5e3Sopenharmony_ci 9854514f5e3Sopenharmony_cidef open_write_file(file_path, append): 9864514f5e3Sopenharmony_ci if append: 9874514f5e3Sopenharmony_ci args = os.O_RDWR | os.O_CREAT | os.O_APPEND 9884514f5e3Sopenharmony_ci else: 9894514f5e3Sopenharmony_ci args = os.O_RDWR | os.O_CREAT 9904514f5e3Sopenharmony_ci file_descriptor = os.open(file_path, args, stat.S_IRUSR | stat.S_IWUSR) 9914514f5e3Sopenharmony_ci file_object = os.fdopen(file_descriptor, "w+") 9924514f5e3Sopenharmony_ci return file_object 9934514f5e3Sopenharmony_ci 9944514f5e3Sopenharmony_ci 9954514f5e3Sopenharmony_cidef open_result_excel(file_path): 9964514f5e3Sopenharmony_ci file_descriptor = os.open(file_path, os.O_RDWR | os.O_CREAT | os.O_APPEND, stat.S_IRUSR | stat.S_IWUSR) 9974514f5e3Sopenharmony_ci file_object = os.fdopen(file_descriptor, "w+") 9984514f5e3Sopenharmony_ci return file_object 9994514f5e3Sopenharmony_ci 10004514f5e3Sopenharmony_ci 10014514f5e3Sopenharmony_cidef get_file_source(file): 10024514f5e3Sopenharmony_ci with open(file, encoding='ISO-8859-1') as f: 10034514f5e3Sopenharmony_ci return f.read() 10044514f5e3Sopenharmony_ci 10054514f5e3Sopenharmony_ci 10064514f5e3Sopenharmony_cidef set_test_environ(case): 10074514f5e3Sopenharmony_ci # intl environ LC_ALL 10084514f5e3Sopenharmony_ci if 'LC_ALL' in os.environ: 10094514f5e3Sopenharmony_ci del os.environ['LC_ALL'] 10104514f5e3Sopenharmony_ci if 'TZ' in os.environ: 10114514f5e3Sopenharmony_ci del os.environ['TZ'] 10124514f5e3Sopenharmony_ci if not os.path.exists(case): 10134514f5e3Sopenharmony_ci return 10144514f5e3Sopenharmony_ci source = get_file_source(case) 10154514f5e3Sopenharmony_ci env_match = ENV_PATTERN.search(source) 10164514f5e3Sopenharmony_ci if env_match: 10174514f5e3Sopenharmony_ci for env_pair in env_match.group(1).strip().split(): 10184514f5e3Sopenharmony_ci var, value = env_pair.split('=') 10194514f5e3Sopenharmony_ci if var.find('TZ') >= 0: 10204514f5e3Sopenharmony_ci os.environ['TZ'] = value 10214514f5e3Sopenharmony_ci if var.find('LC_ALL') >= 0: 10224514f5e3Sopenharmony_ci os.environ['LC_ALL'] = value 10234514f5e3Sopenharmony_ci break 10244514f5e3Sopenharmony_ci 10254514f5e3Sopenharmony_ci 10264514f5e3Sopenharmony_ci# pylint: disable=invalid-name,global-statement 10274514f5e3Sopenharmony_ciworker_wrapper_args = None 10284514f5e3Sopenharmony_ci 10294514f5e3Sopenharmony_ci 10304514f5e3Sopenharmony_cidef init_worker(args): 10314514f5e3Sopenharmony_ci global worker_wrapper_args 10324514f5e3Sopenharmony_ci worker_wrapper_args = args 10334514f5e3Sopenharmony_ci 10344514f5e3Sopenharmony_ci 10354514f5e3Sopenharmony_cidef write_result_file(msg: str, result_file): 10364514f5e3Sopenharmony_ci result_file.write(f'{msg}\n') 10374514f5e3Sopenharmony_ci 10384514f5e3Sopenharmony_ci 10394514f5e3Sopenharmony_cidef main(args): 10404514f5e3Sopenharmony_ci if not check_args(args): 10414514f5e3Sopenharmony_ci return 1 10424514f5e3Sopenharmony_ci output("\nStart regresstest........") 10434514f5e3Sopenharmony_ci steps: List[Type[RegressTestStep]] = [ 10444514f5e3Sopenharmony_ci RegressTestRepoPrepare, 10454514f5e3Sopenharmony_ci RegressTestCompile, 10464514f5e3Sopenharmony_ci ] 10474514f5e3Sopenharmony_ci if args.ark_aot: 10484514f5e3Sopenharmony_ci if args.run_pgo: 10494514f5e3Sopenharmony_ci steps.append(RegressTestPgo) 10504514f5e3Sopenharmony_ci steps.append(RegressTestAot) 10514514f5e3Sopenharmony_ci steps.append(RegressTestRun) 10524514f5e3Sopenharmony_ci 10534514f5e3Sopenharmony_ci test_reports: List[TestReport] = [] 10544514f5e3Sopenharmony_ci for step in steps: 10554514f5e3Sopenharmony_ci test_reports = step.run(args, test_reports) 10564514f5e3Sopenharmony_ci 10574514f5e3Sopenharmony_ci stats = Stats(args, test_reports) 10584514f5e3Sopenharmony_ci stats.statistics() 10594514f5e3Sopenharmony_ci stats.print_result(args, steps) 10604514f5e3Sopenharmony_ci stats.print_failed_tests() 10614514f5e3Sopenharmony_ci new_failures = stats.get_new_failures() 10624514f5e3Sopenharmony_ci if new_failures is None: 10634514f5e3Sopenharmony_ci return 0 10644514f5e3Sopenharmony_ci if len(new_failures) > 0: 10654514f5e3Sopenharmony_ci msg = [f"Found {len(new_failures)} new failures:"] 10664514f5e3Sopenharmony_ci for failure in new_failures: 10674514f5e3Sopenharmony_ci msg.append(f"\t{failure.test_id}") 10684514f5e3Sopenharmony_ci output("\n".join(msg)) 10694514f5e3Sopenharmony_ci else: 10704514f5e3Sopenharmony_ci output("No new failures have been found") 10714514f5e3Sopenharmony_ci return len(new_failures) 10724514f5e3Sopenharmony_ci 10734514f5e3Sopenharmony_ci 10744514f5e3Sopenharmony_ciif __name__ == "__main__": 10754514f5e3Sopenharmony_ci sys.exit(main(parse_args())) 1076