13af6ab5fSopenharmony_ci#!/usr/bin/env python3
23af6ab5fSopenharmony_ci# -*- coding: utf-8 -*-
33af6ab5fSopenharmony_ci#
43af6ab5fSopenharmony_ci# Copyright (c) 2021-2022 Huawei Device Co., Ltd.
53af6ab5fSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
63af6ab5fSopenharmony_ci# you may not use this file except in compliance with the License.
73af6ab5fSopenharmony_ci# You may obtain a copy of the License at
83af6ab5fSopenharmony_ci#
93af6ab5fSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0
103af6ab5fSopenharmony_ci#
113af6ab5fSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
123af6ab5fSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
133af6ab5fSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
143af6ab5fSopenharmony_ci# See the License for the specific language governing permissions and
153af6ab5fSopenharmony_ci# limitations under the License.
163af6ab5fSopenharmony_ci
173af6ab5fSopenharmony_cifrom glob import glob
183af6ab5fSopenharmony_cifrom os import path
193af6ab5fSopenharmony_cifrom enum import Enum
203af6ab5fSopenharmony_ciimport argparse
213af6ab5fSopenharmony_ciimport fnmatch
223af6ab5fSopenharmony_ciimport multiprocessing
233af6ab5fSopenharmony_ciimport os
243af6ab5fSopenharmony_ciimport re
253af6ab5fSopenharmony_ciimport shutil
263af6ab5fSopenharmony_ciimport subprocess
273af6ab5fSopenharmony_ciimport sys
283af6ab5fSopenharmony_cifrom config import API_VERSION_MAP, MIN_SUPPORT_BC_VERSION, MIX_COMPILE_ENTRY_POINT
293af6ab5fSopenharmony_ci
303af6ab5fSopenharmony_ci
313af6ab5fSopenharmony_cidef is_directory(parser, arg):
323af6ab5fSopenharmony_ci    if not path.isdir(arg):
333af6ab5fSopenharmony_ci        parser.error("The directory '%s' does not exist" % arg)
343af6ab5fSopenharmony_ci
353af6ab5fSopenharmony_ci    return path.abspath(arg)
363af6ab5fSopenharmony_ci
373af6ab5fSopenharmony_ci
383af6ab5fSopenharmony_cidef is_file(parser, arg):
393af6ab5fSopenharmony_ci    if not path.isfile(arg):
403af6ab5fSopenharmony_ci        parser.error("The file '%s' does not exist" % arg)
413af6ab5fSopenharmony_ci
423af6ab5fSopenharmony_ci    return path.abspath(arg)
433af6ab5fSopenharmony_ci
443af6ab5fSopenharmony_cidef prepare_tsc_testcases(test_root):
453af6ab5fSopenharmony_ci    third_party_tsc = path.join(test_root, "TypeScript")
463af6ab5fSopenharmony_ci    ohos_third_party_tsc = path.join(test_root, "../../../../third_party/typescript")
473af6ab5fSopenharmony_ci
483af6ab5fSopenharmony_ci    if not path.isdir(third_party_tsc):
493af6ab5fSopenharmony_ci        if (path.isdir(ohos_third_party_tsc)):
503af6ab5fSopenharmony_ci            return path.abspath(ohos_third_party_tsc)
513af6ab5fSopenharmony_ci        subprocess.run(
523af6ab5fSopenharmony_ci            f"git clone https://gitee.com/openharmony/third_party_typescript.git {third_party_tsc}",
533af6ab5fSopenharmony_ci            shell=True,
543af6ab5fSopenharmony_ci            stdout=subprocess.DEVNULL,
553af6ab5fSopenharmony_ci        )
563af6ab5fSopenharmony_ci    else:
573af6ab5fSopenharmony_ci        subprocess.run(
583af6ab5fSopenharmony_ci            f"cd {third_party_tsc} && git clean -f > /dev/null 2>&1",
593af6ab5fSopenharmony_ci            shell=True,
603af6ab5fSopenharmony_ci            stdout=subprocess.DEVNULL,
613af6ab5fSopenharmony_ci        )
623af6ab5fSopenharmony_ci    return third_party_tsc
633af6ab5fSopenharmony_ci
643af6ab5fSopenharmony_cidef check_timeout(value):
653af6ab5fSopenharmony_ci    ivalue = int(value)
663af6ab5fSopenharmony_ci    if ivalue <= 0:
673af6ab5fSopenharmony_ci        raise argparse.ArgumentTypeError(
683af6ab5fSopenharmony_ci            "%s is an invalid timeout value" % value)
693af6ab5fSopenharmony_ci    return ivalue
703af6ab5fSopenharmony_ci
713af6ab5fSopenharmony_ci
723af6ab5fSopenharmony_cidef get_args():
733af6ab5fSopenharmony_ci    parser = argparse.ArgumentParser(description="Regression test runner")
743af6ab5fSopenharmony_ci    parser.add_argument(
753af6ab5fSopenharmony_ci        'build_dir', type=lambda arg: is_directory(parser, arg),
763af6ab5fSopenharmony_ci        help='panda build directory')
773af6ab5fSopenharmony_ci    parser.add_argument(
783af6ab5fSopenharmony_ci        '--error', action='store_true', dest='error', default=False,
793af6ab5fSopenharmony_ci        help='capture stderr')
803af6ab5fSopenharmony_ci    parser.add_argument(
813af6ab5fSopenharmony_ci        '--abc-to-asm', action='store_true', dest='abc_to_asm',
823af6ab5fSopenharmony_ci        default=False, help='run abc2asm tests')
833af6ab5fSopenharmony_ci    parser.add_argument(
843af6ab5fSopenharmony_ci        '--regression', '-r', action='store_true', dest='regression',
853af6ab5fSopenharmony_ci        default=False, help='run regression tests')
863af6ab5fSopenharmony_ci    parser.add_argument(
873af6ab5fSopenharmony_ci        '--compiler', '-c', action='store_true', dest='compiler',
883af6ab5fSopenharmony_ci        default=False, help='run compiler tests')
893af6ab5fSopenharmony_ci    parser.add_argument(
903af6ab5fSopenharmony_ci        '--tsc', action='store_true', dest='tsc',
913af6ab5fSopenharmony_ci        default=False, help='run tsc tests')
923af6ab5fSopenharmony_ci    parser.add_argument(
933af6ab5fSopenharmony_ci        '--no-progress', action='store_false', dest='progress', default=True,
943af6ab5fSopenharmony_ci        help='don\'t show progress bar')
953af6ab5fSopenharmony_ci    parser.add_argument(
963af6ab5fSopenharmony_ci        '--no-skip', action='store_false', dest='skip', default=True,
973af6ab5fSopenharmony_ci        help='don\'t use skiplists')
983af6ab5fSopenharmony_ci    parser.add_argument(
993af6ab5fSopenharmony_ci        '--update', action='store_true', dest='update', default=False,
1003af6ab5fSopenharmony_ci        help='update skiplist')
1013af6ab5fSopenharmony_ci    parser.add_argument(
1023af6ab5fSopenharmony_ci        '--no-run-gc-in-place', action='store_true', dest='no_gip', default=False,
1033af6ab5fSopenharmony_ci        help='enable --run-gc-in-place mode')
1043af6ab5fSopenharmony_ci    parser.add_argument(
1053af6ab5fSopenharmony_ci        '--filter', '-f', action='store', dest='filter',
1063af6ab5fSopenharmony_ci        default="*", help='test filter regexp')
1073af6ab5fSopenharmony_ci    parser.add_argument(
1083af6ab5fSopenharmony_ci        '--es2panda-timeout', type=check_timeout,
1093af6ab5fSopenharmony_ci        dest='es2panda_timeout', default=60, help='es2panda translator timeout')
1103af6ab5fSopenharmony_ci    parser.add_argument(
1113af6ab5fSopenharmony_ci        '--paoc-timeout', type=check_timeout,
1123af6ab5fSopenharmony_ci        dest='paoc_timeout', default=600, help='paoc compiler timeout')
1133af6ab5fSopenharmony_ci    parser.add_argument(
1143af6ab5fSopenharmony_ci        '--timeout', type=check_timeout,
1153af6ab5fSopenharmony_ci        dest='timeout', default=10, help='JS runtime timeout')
1163af6ab5fSopenharmony_ci    parser.add_argument(
1173af6ab5fSopenharmony_ci        '--gc-type', dest='gc_type', default="g1-gc", help='Type of garbage collector')
1183af6ab5fSopenharmony_ci    parser.add_argument(
1193af6ab5fSopenharmony_ci        '--aot', action='store_true', dest='aot', default=False,
1203af6ab5fSopenharmony_ci        help='use AOT compilation')
1213af6ab5fSopenharmony_ci    parser.add_argument(
1223af6ab5fSopenharmony_ci        '--no-bco', action='store_false', dest='bco', default=True,
1233af6ab5fSopenharmony_ci        help='disable bytecodeopt')
1243af6ab5fSopenharmony_ci    parser.add_argument(
1253af6ab5fSopenharmony_ci        '--jit', action='store_true', dest='jit', default=False,
1263af6ab5fSopenharmony_ci        help='use JIT in interpreter')
1273af6ab5fSopenharmony_ci    parser.add_argument(
1283af6ab5fSopenharmony_ci        '--arm64-compiler-skip', action='store_true', dest='arm64_compiler_skip', default=False,
1293af6ab5fSopenharmony_ci        help='use skiplist for tests failing on aarch64 in AOT or JIT mode')
1303af6ab5fSopenharmony_ci    parser.add_argument(
1313af6ab5fSopenharmony_ci        '--arm64-qemu', action='store_true', dest='arm64_qemu', default=False,
1323af6ab5fSopenharmony_ci        help='launch all binaries in qemu aarch64')
1333af6ab5fSopenharmony_ci    parser.add_argument(
1343af6ab5fSopenharmony_ci        '--arm32-qemu', action='store_true', dest='arm32_qemu', default=False,
1353af6ab5fSopenharmony_ci        help='launch all binaries in qemu arm')
1363af6ab5fSopenharmony_ci    parser.add_argument(
1373af6ab5fSopenharmony_ci        '--test-list', dest='test_list', default=None, type=lambda arg: is_file(parser, arg),
1383af6ab5fSopenharmony_ci        help='run tests listed in file')
1393af6ab5fSopenharmony_ci    parser.add_argument(
1403af6ab5fSopenharmony_ci        '--aot-args', action='append', dest='aot_args', default=[],
1413af6ab5fSopenharmony_ci        help='Additional arguments that will passed to ark_aot')
1423af6ab5fSopenharmony_ci    parser.add_argument(
1433af6ab5fSopenharmony_ci        '--verbose', '-v', action='store_true', dest='verbose', default=False,
1443af6ab5fSopenharmony_ci        help='Enable verbose output')
1453af6ab5fSopenharmony_ci    parser.add_argument(
1463af6ab5fSopenharmony_ci        '--js-runtime', dest='js_runtime_path', default=None, type=lambda arg: is_directory(parser, arg),
1473af6ab5fSopenharmony_ci        help='the path of js vm runtime')
1483af6ab5fSopenharmony_ci    parser.add_argument(
1493af6ab5fSopenharmony_ci        '--LD_LIBRARY_PATH', dest='ld_library_path', default=None, help='LD_LIBRARY_PATH')
1503af6ab5fSopenharmony_ci    parser.add_argument(
1513af6ab5fSopenharmony_ci        '--tsc-path', dest='tsc_path', default=None, type=lambda arg: is_directory(parser, arg),
1523af6ab5fSopenharmony_ci        help='the path of tsc')
1533af6ab5fSopenharmony_ci    parser.add_argument('--hotfix', dest='hotfix', action='store_true', default=False,
1543af6ab5fSopenharmony_ci        help='run hotfix tests')
1553af6ab5fSopenharmony_ci    parser.add_argument('--hotreload', dest='hotreload', action='store_true', default=False,
1563af6ab5fSopenharmony_ci        help='run hotreload tests')
1573af6ab5fSopenharmony_ci    parser.add_argument('--coldfix', dest='coldfix', action='store_true', default=False,
1583af6ab5fSopenharmony_ci        help='run coldfix tests')
1593af6ab5fSopenharmony_ci    parser.add_argument('--coldreload', dest='coldreload', action='store_true', default=False,
1603af6ab5fSopenharmony_ci        help='run coldreload tests')
1613af6ab5fSopenharmony_ci    parser.add_argument('--base64', dest='base64', action='store_true', default=False,
1623af6ab5fSopenharmony_ci        help='run base64 tests')
1633af6ab5fSopenharmony_ci    parser.add_argument('--bytecode', dest='bytecode', action='store_true', default=False,
1643af6ab5fSopenharmony_ci        help='run bytecode tests')
1653af6ab5fSopenharmony_ci    parser.add_argument('--debugger', dest='debugger', action='store_true', default=False,
1663af6ab5fSopenharmony_ci        help='run debugger tests')
1673af6ab5fSopenharmony_ci    parser.add_argument('--debug', dest='debug', action='store_true', default=False,
1683af6ab5fSopenharmony_ci        help='run debug tests')
1693af6ab5fSopenharmony_ci    parser.add_argument('--enable-arkguard', action='store_true', dest='enable_arkguard', default=False,
1703af6ab5fSopenharmony_ci        help='enable arkguard for compiler tests')
1713af6ab5fSopenharmony_ci    parser.add_argument('--aop-transform', dest='aop_transform', action='store_true', default=False,
1723af6ab5fSopenharmony_ci        help='run debug tests')
1733af6ab5fSopenharmony_ci    parser.add_argument('--version-control', action='store_true', dest='version_control', default=False,
1743af6ab5fSopenharmony_ci        help='run api version control tests')
1753af6ab5fSopenharmony_ci
1763af6ab5fSopenharmony_ci    return parser.parse_args()
1773af6ab5fSopenharmony_ci
1783af6ab5fSopenharmony_ci
1793af6ab5fSopenharmony_cidef run_subprocess_with_beta3(test_obj, cmd):
1803af6ab5fSopenharmony_ci    has_target_api = False
1813af6ab5fSopenharmony_ci    has_version_12 = False
1823af6ab5fSopenharmony_ci    has_sub_version = False
1833af6ab5fSopenharmony_ci    is_es2abc_cmd = False
1843af6ab5fSopenharmony_ci
1853af6ab5fSopenharmony_ci    for param in cmd:
1863af6ab5fSopenharmony_ci        if "es2abc" in param:
1873af6ab5fSopenharmony_ci            is_es2abc_cmd = True
1883af6ab5fSopenharmony_ci        if "--target-api-sub-version" in param:
1893af6ab5fSopenharmony_ci            has_sub_version = True
1903af6ab5fSopenharmony_ci        if "--target-api-version" in param:
1913af6ab5fSopenharmony_ci            has_target_api = True
1923af6ab5fSopenharmony_ci        if "12" in param:
1933af6ab5fSopenharmony_ci            has_version_12 = True
1943af6ab5fSopenharmony_ci    if is_es2abc_cmd and (not has_target_api or (has_version_12 and not has_sub_version)):
1953af6ab5fSopenharmony_ci        cmd.append("--target-api-sub-version=beta3")
1963af6ab5fSopenharmony_ci    if test_obj:
1973af6ab5fSopenharmony_ci        test_obj.log_cmd(cmd)
1983af6ab5fSopenharmony_ci    return subprocess.Popen(
1993af6ab5fSopenharmony_ci        cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
2003af6ab5fSopenharmony_ci
2013af6ab5fSopenharmony_ci
2023af6ab5fSopenharmony_ciclass Test:
2033af6ab5fSopenharmony_ci    def __init__(self, test_path, flags):
2043af6ab5fSopenharmony_ci        self.path = test_path
2053af6ab5fSopenharmony_ci        self.flags = flags
2063af6ab5fSopenharmony_ci        self.output = None
2073af6ab5fSopenharmony_ci        self.error = None
2083af6ab5fSopenharmony_ci        self.passed = None
2093af6ab5fSopenharmony_ci        self.skipped = None
2103af6ab5fSopenharmony_ci        self.reproduce = ""
2113af6ab5fSopenharmony_ci
2123af6ab5fSopenharmony_ci    def log_cmd(self, cmd):
2133af6ab5fSopenharmony_ci        self.reproduce += "\n" + ' '.join(cmd)
2143af6ab5fSopenharmony_ci
2153af6ab5fSopenharmony_ci    def get_path_to_expected(self):
2163af6ab5fSopenharmony_ci        if self.path.find(".d.ts") == -1:
2173af6ab5fSopenharmony_ci            return "%s-expected.txt" % (path.splitext(self.path)[0])
2183af6ab5fSopenharmony_ci        return "%s-expected.txt" % (self.path[:self.path.find(".d.ts")])
2193af6ab5fSopenharmony_ci
2203af6ab5fSopenharmony_ci    def run(self, runner):
2213af6ab5fSopenharmony_ci        test_abc_name = ("%s.abc" % (path.splitext(self.path)[0])).replace("/", "_")
2223af6ab5fSopenharmony_ci        test_abc_path = path.join(runner.build_dir, test_abc_name)
2233af6ab5fSopenharmony_ci        cmd = runner.cmd_prefix + [runner.es2panda]
2243af6ab5fSopenharmony_ci        cmd.extend(self.flags)
2253af6ab5fSopenharmony_ci        cmd.extend(["--output=" + test_abc_path])
2263af6ab5fSopenharmony_ci        cmd.append(self.path)
2273af6ab5fSopenharmony_ci        process = run_subprocess_with_beta3(self, cmd)
2283af6ab5fSopenharmony_ci        out, err = process.communicate()
2293af6ab5fSopenharmony_ci        self.output = out.decode("utf-8", errors="ignore") + err.decode("utf-8", errors="ignore")
2303af6ab5fSopenharmony_ci
2313af6ab5fSopenharmony_ci        expected_path = self.get_path_to_expected()
2323af6ab5fSopenharmony_ci        try:
2333af6ab5fSopenharmony_ci            with open(expected_path, 'r') as fp:
2343af6ab5fSopenharmony_ci                expected = fp.read()
2353af6ab5fSopenharmony_ci            self.passed = expected == self.output and process.returncode in [
2363af6ab5fSopenharmony_ci                0, 1]
2373af6ab5fSopenharmony_ci        except Exception:
2383af6ab5fSopenharmony_ci            self.passed = False
2393af6ab5fSopenharmony_ci
2403af6ab5fSopenharmony_ci        if not self.passed:
2413af6ab5fSopenharmony_ci            self.error = err.decode("utf-8", errors="ignore")
2423af6ab5fSopenharmony_ci
2433af6ab5fSopenharmony_ci        if os.path.exists(test_abc_path):
2443af6ab5fSopenharmony_ci            os.remove(test_abc_path)
2453af6ab5fSopenharmony_ci
2463af6ab5fSopenharmony_ci        return self
2473af6ab5fSopenharmony_ci
2483af6ab5fSopenharmony_ci
2493af6ab5fSopenharmony_ciclass TSCTest(Test):
2503af6ab5fSopenharmony_ci    def __init__(self, test_path, flags):
2513af6ab5fSopenharmony_ci        Test.__init__(self, test_path, flags)
2523af6ab5fSopenharmony_ci        self.options = self.parse_options()
2533af6ab5fSopenharmony_ci
2543af6ab5fSopenharmony_ci    def parse_options(self):
2553af6ab5fSopenharmony_ci        test_options = {}
2563af6ab5fSopenharmony_ci
2573af6ab5fSopenharmony_ci        with open(self.path, "r", encoding="latin1") as f:
2583af6ab5fSopenharmony_ci            lines = f.read()
2593af6ab5fSopenharmony_ci            options = re.findall(r"//\s?@\w+:.*\n", lines)
2603af6ab5fSopenharmony_ci
2613af6ab5fSopenharmony_ci            for option in options:
2623af6ab5fSopenharmony_ci                separated = option.split(":")
2633af6ab5fSopenharmony_ci                opt = re.findall(r"\w+", separated[0])[0].lower()
2643af6ab5fSopenharmony_ci                value = separated[1].strip().lower()
2653af6ab5fSopenharmony_ci
2663af6ab5fSopenharmony_ci                if opt == "filename":
2673af6ab5fSopenharmony_ci                    if opt in options:
2683af6ab5fSopenharmony_ci                        test_options[opt].append(value)
2693af6ab5fSopenharmony_ci                    else:
2703af6ab5fSopenharmony_ci                        test_options[opt] = [value]
2713af6ab5fSopenharmony_ci
2723af6ab5fSopenharmony_ci                elif opt == "lib" or opt == "module":
2733af6ab5fSopenharmony_ci                    test_options[opt] = [each.strip()
2743af6ab5fSopenharmony_ci                                         for each in value.split(",")]
2753af6ab5fSopenharmony_ci                elif value == "true" or value == "false":
2763af6ab5fSopenharmony_ci                    test_options[opt] = value.lower() == "true"
2773af6ab5fSopenharmony_ci                else:
2783af6ab5fSopenharmony_ci                    test_options[opt] = value
2793af6ab5fSopenharmony_ci
2803af6ab5fSopenharmony_ci            # TODO: Possibility of error: all exports will be catched, even the commented ones
2813af6ab5fSopenharmony_ci            if 'module' not in test_options and re.search(r"export ", lines):
2823af6ab5fSopenharmony_ci                test_options['module'] = []
2833af6ab5fSopenharmony_ci
2843af6ab5fSopenharmony_ci        return test_options
2853af6ab5fSopenharmony_ci
2863af6ab5fSopenharmony_ci    def run(self, runner):
2873af6ab5fSopenharmony_ci        cmd = runner.cmd_prefix + [runner.es2panda, '--parse-only']
2883af6ab5fSopenharmony_ci        cmd.extend(self.flags)
2893af6ab5fSopenharmony_ci        if "module" in self.options:
2903af6ab5fSopenharmony_ci            cmd.append('--module')
2913af6ab5fSopenharmony_ci        cmd.append(self.path)
2923af6ab5fSopenharmony_ci        process = run_subprocess_with_beta3(self, cmd)
2933af6ab5fSopenharmony_ci        out, err = process.communicate()
2943af6ab5fSopenharmony_ci        self.output = out.decode("utf-8", errors="ignore")
2953af6ab5fSopenharmony_ci
2963af6ab5fSopenharmony_ci        self.passed = True if process.returncode == 0 else False
2973af6ab5fSopenharmony_ci
2983af6ab5fSopenharmony_ci        if not self.passed:
2993af6ab5fSopenharmony_ci            self.error = err.decode("utf-8", errors="ignore")
3003af6ab5fSopenharmony_ci
3013af6ab5fSopenharmony_ci        return self
3023af6ab5fSopenharmony_ci
3033af6ab5fSopenharmony_ci
3043af6ab5fSopenharmony_ciclass TestAop:
3053af6ab5fSopenharmony_ci    def __init__(self, cmd, compare_str, compare_abc_str, remove_file):
3063af6ab5fSopenharmony_ci        self.cmd = cmd
3073af6ab5fSopenharmony_ci        self.compare_str = compare_str
3083af6ab5fSopenharmony_ci        self.compare_abc_str = compare_abc_str
3093af6ab5fSopenharmony_ci        self.remove_file = remove_file
3103af6ab5fSopenharmony_ci        self.path = ''
3113af6ab5fSopenharmony_ci        self.output = None
3123af6ab5fSopenharmony_ci        self.error = None
3133af6ab5fSopenharmony_ci        self.passed = None
3143af6ab5fSopenharmony_ci        self.skipped = None
3153af6ab5fSopenharmony_ci        self.reproduce = ""
3163af6ab5fSopenharmony_ci
3173af6ab5fSopenharmony_ci    def log_cmd(self, cmd):
3183af6ab5fSopenharmony_ci        self.reproduce += ''.join(["\n", ' '.join(cmd)])
3193af6ab5fSopenharmony_ci
3203af6ab5fSopenharmony_ci    def run(self, runner):
3213af6ab5fSopenharmony_ci        cmd = self.cmd
3223af6ab5fSopenharmony_ci        process = run_subprocess_with_beta3(self, cmd)
3233af6ab5fSopenharmony_ci        out, err = process.communicate()
3243af6ab5fSopenharmony_ci        self.output = out.decode("utf-8", errors="ignore") + err.decode("utf-8", errors="ignore")
3253af6ab5fSopenharmony_ci
3263af6ab5fSopenharmony_ci        if self.compare_str == '':
3273af6ab5fSopenharmony_ci            self.passed = True
3283af6ab5fSopenharmony_ci        else :
3293af6ab5fSopenharmony_ci            self.passed = self.output.startswith(self.compare_str) and process.returncode in [0, 1]
3303af6ab5fSopenharmony_ci            if self.remove_file != '' and os.path.exists(self.remove_file):
3313af6ab5fSopenharmony_ci                os.remove(self.remove_file)
3323af6ab5fSopenharmony_ci
3333af6ab5fSopenharmony_ci        if not self.passed:
3343af6ab5fSopenharmony_ci            self.error = err.decode("utf-8", errors="ignore")
3353af6ab5fSopenharmony_ci
3363af6ab5fSopenharmony_ci        abc_path = path.join(os.getcwd(), 'test_aop.abc')
3373af6ab5fSopenharmony_ci        if os.path.exists(abc_path):
3383af6ab5fSopenharmony_ci            if self.compare_abc_str != '':
3393af6ab5fSopenharmony_ci                with open(abc_path, "r") as abc_file:
3403af6ab5fSopenharmony_ci                    self.passed = self.passed and abc_file.read() == self.compare_abc_str
3413af6ab5fSopenharmony_ci            os.remove(abc_path)
3423af6ab5fSopenharmony_ci
3433af6ab5fSopenharmony_ci        return self
3443af6ab5fSopenharmony_ci
3453af6ab5fSopenharmony_ci
3463af6ab5fSopenharmony_ciclass Runner:
3473af6ab5fSopenharmony_ci    def __init__(self, args, name):
3483af6ab5fSopenharmony_ci        self.test_root = path.dirname(path.abspath(__file__))
3493af6ab5fSopenharmony_ci        self.args = args
3503af6ab5fSopenharmony_ci        self.name = name
3513af6ab5fSopenharmony_ci        self.tests = []
3523af6ab5fSopenharmony_ci        self.failed = 0
3533af6ab5fSopenharmony_ci        self.passed = 0
3543af6ab5fSopenharmony_ci        self.es2panda = path.join(args.build_dir, 'es2abc')
3553af6ab5fSopenharmony_ci        self.build_dir = args.build_dir
3563af6ab5fSopenharmony_ci        self.cmd_prefix = []
3573af6ab5fSopenharmony_ci        self.ark_js_vm = ""
3583af6ab5fSopenharmony_ci        self.ark_aot_compiler = ""
3593af6ab5fSopenharmony_ci        self.ld_library_path = ""
3603af6ab5fSopenharmony_ci
3613af6ab5fSopenharmony_ci        if args.js_runtime_path:
3623af6ab5fSopenharmony_ci            self.ark_js_vm = path.join(args.js_runtime_path, 'ark_js_vm')
3633af6ab5fSopenharmony_ci            self.ark_aot_compiler = path.join(args.js_runtime_path, 'ark_aot_compiler')
3643af6ab5fSopenharmony_ci
3653af6ab5fSopenharmony_ci        if args.ld_library_path:
3663af6ab5fSopenharmony_ci            self.ld_library_path = args.ld_library_path
3673af6ab5fSopenharmony_ci
3683af6ab5fSopenharmony_ci        if args.arm64_qemu:
3693af6ab5fSopenharmony_ci            self.cmd_prefix = ["qemu-aarch64", "-L", "/usr/aarch64-linux-gnu/"]
3703af6ab5fSopenharmony_ci
3713af6ab5fSopenharmony_ci        if args.arm32_qemu:
3723af6ab5fSopenharmony_ci            self.cmd_prefix = ["qemu-arm", "-L", "/usr/arm-linux-gnueabi"]
3733af6ab5fSopenharmony_ci
3743af6ab5fSopenharmony_ci        if not path.isfile(self.es2panda):
3753af6ab5fSopenharmony_ci            raise Exception("Cannot find es2panda binary: %s" % self.es2panda)
3763af6ab5fSopenharmony_ci
3773af6ab5fSopenharmony_ci    def add_directory(self, directory, extension, flags):
3783af6ab5fSopenharmony_ci        pass
3793af6ab5fSopenharmony_ci
3803af6ab5fSopenharmony_ci    def test_path(self, src):
3813af6ab5fSopenharmony_ci        pass
3823af6ab5fSopenharmony_ci
3833af6ab5fSopenharmony_ci    def run_test(self, test):
3843af6ab5fSopenharmony_ci        return test.run(self)
3853af6ab5fSopenharmony_ci
3863af6ab5fSopenharmony_ci    def run(self):
3873af6ab5fSopenharmony_ci        pool = multiprocessing.Pool()
3883af6ab5fSopenharmony_ci        result_iter = pool.imap_unordered(
3893af6ab5fSopenharmony_ci            self.run_test, self.tests, chunksize=32)
3903af6ab5fSopenharmony_ci        pool.close()
3913af6ab5fSopenharmony_ci
3923af6ab5fSopenharmony_ci        if self.args.progress:
3933af6ab5fSopenharmony_ci            from tqdm import tqdm
3943af6ab5fSopenharmony_ci            result_iter = tqdm(result_iter, total=len(self.tests))
3953af6ab5fSopenharmony_ci
3963af6ab5fSopenharmony_ci        results = []
3973af6ab5fSopenharmony_ci        for res in result_iter:
3983af6ab5fSopenharmony_ci            results.append(res)
3993af6ab5fSopenharmony_ci
4003af6ab5fSopenharmony_ci        self.tests = results
4013af6ab5fSopenharmony_ci        pool.join()
4023af6ab5fSopenharmony_ci
4033af6ab5fSopenharmony_ci    def deal_error(self, test):
4043af6ab5fSopenharmony_ci        path_str = test.path
4053af6ab5fSopenharmony_ci        err_col = {}
4063af6ab5fSopenharmony_ci        if test.error:
4073af6ab5fSopenharmony_ci            err_str = test.error.split('[')[0] if "patchfix" not in test.path else " patchfix throw error failed"
4083af6ab5fSopenharmony_ci            err_col = {"path" : [path_str], "status": ["fail"], "error" : [test.error], "type" : [err_str]}
4093af6ab5fSopenharmony_ci        else:
4103af6ab5fSopenharmony_ci            err_col = {"path" : [path_str], "status": ["fail"], "error" : ["Segmentation fault"],
4113af6ab5fSopenharmony_ci                        "type" : ["Segmentation fault"]}
4123af6ab5fSopenharmony_ci        return err_col
4133af6ab5fSopenharmony_ci
4143af6ab5fSopenharmony_ci    def summarize(self):
4153af6ab5fSopenharmony_ci        print("")
4163af6ab5fSopenharmony_ci        fail_list = []
4173af6ab5fSopenharmony_ci        success_list = []
4183af6ab5fSopenharmony_ci
4193af6ab5fSopenharmony_ci        for test in self.tests:
4203af6ab5fSopenharmony_ci            assert(test.passed is not None)
4213af6ab5fSopenharmony_ci            if not test.passed:
4223af6ab5fSopenharmony_ci                fail_list.append(test)
4233af6ab5fSopenharmony_ci            else:
4243af6ab5fSopenharmony_ci                success_list.append(test)
4253af6ab5fSopenharmony_ci
4263af6ab5fSopenharmony_ci        if len(fail_list):
4273af6ab5fSopenharmony_ci            if self.args.error:
4283af6ab5fSopenharmony_ci                import pandas as pd
4293af6ab5fSopenharmony_ci                test_list = pd.DataFrame(columns=["path", "status", "error", "type"])
4303af6ab5fSopenharmony_ci            for test in success_list:
4313af6ab5fSopenharmony_ci                suc_col = {"path" : [test.path], "status": ["success"], "error" : ["success"], "type" : ["success"]}
4323af6ab5fSopenharmony_ci                if self.args.error:
4333af6ab5fSopenharmony_ci                    test_list = pd.concat([test_list, pd.DataFrame(suc_col)])
4343af6ab5fSopenharmony_ci            print("Failed tests:")
4353af6ab5fSopenharmony_ci            for test in fail_list:
4363af6ab5fSopenharmony_ci                print(self.test_path(test.path))
4373af6ab5fSopenharmony_ci
4383af6ab5fSopenharmony_ci                if self.args.error:
4393af6ab5fSopenharmony_ci                    print("steps:", test.reproduce)
4403af6ab5fSopenharmony_ci                    print("error:")
4413af6ab5fSopenharmony_ci                    print(test.error)
4423af6ab5fSopenharmony_ci                    print("\n")
4433af6ab5fSopenharmony_ci                    err_col = self.deal_error(test)
4443af6ab5fSopenharmony_ci                    test_list = pd.concat([test_list, pd.DataFrame(err_col)])
4453af6ab5fSopenharmony_ci
4463af6ab5fSopenharmony_ci            if self.args.error:
4473af6ab5fSopenharmony_ci                test_list.to_csv('test_statistics.csv', index=False)
4483af6ab5fSopenharmony_ci                test_list["type"].value_counts().to_csv('type_statistics.csv', index_label="error")
4493af6ab5fSopenharmony_ci                print("Type statistics:\n", test_list["type"].value_counts())
4503af6ab5fSopenharmony_ci            print("")
4513af6ab5fSopenharmony_ci
4523af6ab5fSopenharmony_ci        print("Summary(%s):" % self.name)
4533af6ab5fSopenharmony_ci        print("\033[37mTotal:   %5d" % (len(self.tests)))
4543af6ab5fSopenharmony_ci        print("\033[92mPassed:  %5d" % (len(self.tests) - len(fail_list)))
4553af6ab5fSopenharmony_ci        print("\033[91mFailed:  %5d" % (len(fail_list)))
4563af6ab5fSopenharmony_ci        print("\033[0m")
4573af6ab5fSopenharmony_ci
4583af6ab5fSopenharmony_ci        return len(fail_list)
4593af6ab5fSopenharmony_ci
4603af6ab5fSopenharmony_ci
4613af6ab5fSopenharmony_ciclass RegressionRunner(Runner):
4623af6ab5fSopenharmony_ci    def __init__(self, args):
4633af6ab5fSopenharmony_ci        Runner.__init__(self, args, "Regression")
4643af6ab5fSopenharmony_ci
4653af6ab5fSopenharmony_ci    def add_directory(self, directory, extension, flags, func=Test):
4663af6ab5fSopenharmony_ci        glob_expression = path.join(
4673af6ab5fSopenharmony_ci            self.test_root, directory, "*.%s" % (extension))
4683af6ab5fSopenharmony_ci        files = glob(glob_expression)
4693af6ab5fSopenharmony_ci        files = fnmatch.filter(files, self.test_root + '**' + self.args.filter)
4703af6ab5fSopenharmony_ci
4713af6ab5fSopenharmony_ci        self.tests += list(map(lambda f: func(f, flags), files))
4723af6ab5fSopenharmony_ci
4733af6ab5fSopenharmony_ci    def test_path(self, src):
4743af6ab5fSopenharmony_ci        return src
4753af6ab5fSopenharmony_ci
4763af6ab5fSopenharmony_ci
4773af6ab5fSopenharmony_ciclass AbcToAsmRunner(Runner):
4783af6ab5fSopenharmony_ci    def __init__(self, args, is_debug):
4793af6ab5fSopenharmony_ci        Runner.__init__(self, args, "Abc2asm" if not is_debug else "Abc2asmDebug")
4803af6ab5fSopenharmony_ci        self.is_debug = is_debug
4813af6ab5fSopenharmony_ci
4823af6ab5fSopenharmony_ci    def add_directory(self, directory, extension, flags, func=Test):
4833af6ab5fSopenharmony_ci        glob_expression = path.join(
4843af6ab5fSopenharmony_ci            self.test_root, directory, "*.%s" % (extension))
4853af6ab5fSopenharmony_ci        files = glob(glob_expression)
4863af6ab5fSopenharmony_ci        files = fnmatch.filter(files, self.test_root + '**' + self.args.filter)
4873af6ab5fSopenharmony_ci
4883af6ab5fSopenharmony_ci        self.tests += list(map(lambda f: AbcToAsmTest(f, flags, self.is_debug), files))
4893af6ab5fSopenharmony_ci
4903af6ab5fSopenharmony_ci    def test_path(self, src):
4913af6ab5fSopenharmony_ci        return os.path.basename(src)
4923af6ab5fSopenharmony_ci
4933af6ab5fSopenharmony_ci
4943af6ab5fSopenharmony_ciclass AbcToAsmTest(Test):
4953af6ab5fSopenharmony_ci    def __init__(self, test_path, flags, is_debug):
4963af6ab5fSopenharmony_ci        Test.__init__(self, test_path, flags)
4973af6ab5fSopenharmony_ci        self.is_debug = is_debug
4983af6ab5fSopenharmony_ci
4993af6ab5fSopenharmony_ci    def run(self, runner):
5003af6ab5fSopenharmony_ci        output_abc_file = ("%s.abc" % (path.splitext(self.path)[0])).replace("/", "_")
5013af6ab5fSopenharmony_ci        # source code compilation, generate an abc file
5023af6ab5fSopenharmony_ci        gen_abc_cmd = runner.cmd_prefix + [runner.es2panda]
5033af6ab5fSopenharmony_ci        if (self.is_debug):
5043af6ab5fSopenharmony_ci            gen_abc_cmd.extend(["--debug-info"])
5053af6ab5fSopenharmony_ci        gen_abc_cmd.extend(["--module", "--dump-normalized-asm-program", "--output=" + output_abc_file])
5063af6ab5fSopenharmony_ci        gen_abc_cmd.append(self.path)
5073af6ab5fSopenharmony_ci        process_gen_abc = run_subprocess_with_beta3(self, gen_abc_cmd)
5083af6ab5fSopenharmony_ci        gen_abc_out, gen_abc_err = process_gen_abc.communicate()
5093af6ab5fSopenharmony_ci        gen_abc_output = gen_abc_out.decode("utf-8", errors="ignore")
5103af6ab5fSopenharmony_ci
5113af6ab5fSopenharmony_ci        # If no abc file is generated, an error occurs during parser, but abc2asm function is normal.
5123af6ab5fSopenharmony_ci        if not os.path.exists(output_abc_file):
5133af6ab5fSopenharmony_ci            self.passed = True
5143af6ab5fSopenharmony_ci            return self
5153af6ab5fSopenharmony_ci
5163af6ab5fSopenharmony_ci        # abc file compilation
5173af6ab5fSopenharmony_ci        abc_to_asm_cmd = runner.cmd_prefix + [runner.es2panda]
5183af6ab5fSopenharmony_ci        if (self.is_debug):
5193af6ab5fSopenharmony_ci            abc_to_asm_cmd.extend(["--debug-info"])
5203af6ab5fSopenharmony_ci        abc_to_asm_cmd.extend(["--module", "--dump-normalized-asm-program", "--enable-abc-input"])
5213af6ab5fSopenharmony_ci        abc_to_asm_cmd.append(output_abc_file)
5223af6ab5fSopenharmony_ci        process_abc_to_asm = run_subprocess_with_beta3(self, abc_to_asm_cmd)
5233af6ab5fSopenharmony_ci        abc_to_asm_out, abc_to_asm_err = process_abc_to_asm.communicate()
5243af6ab5fSopenharmony_ci        abc_to_asm_output = abc_to_asm_out.decode("utf-8", errors="ignore")
5253af6ab5fSopenharmony_ci
5263af6ab5fSopenharmony_ci        self.passed = gen_abc_output == abc_to_asm_output and process_abc_to_asm.returncode in [0, 1]
5273af6ab5fSopenharmony_ci        if not self.passed:
5283af6ab5fSopenharmony_ci            self.error = "Comparison of dump results between source code compilation and abc file compilation failed."
5293af6ab5fSopenharmony_ci            if gen_abc_err:
5303af6ab5fSopenharmony_ci                self.error += "\n" + gen_abc_err.decode("utf-8", errors="ignore")
5313af6ab5fSopenharmony_ci            if abc_to_asm_err:
5323af6ab5fSopenharmony_ci                self.error += "\n" + abc_to_asm_err.decode("utf-8", errors="ignore")
5333af6ab5fSopenharmony_ci
5343af6ab5fSopenharmony_ci        os.remove(output_abc_file)
5353af6ab5fSopenharmony_ci        return self
5363af6ab5fSopenharmony_ci
5373af6ab5fSopenharmony_ci
5383af6ab5fSopenharmony_ciclass TSCRunner(Runner):
5393af6ab5fSopenharmony_ci    def __init__(self, args):
5403af6ab5fSopenharmony_ci        Runner.__init__(self, args, "TSC")
5413af6ab5fSopenharmony_ci
5423af6ab5fSopenharmony_ci        if self.args.tsc_path:
5433af6ab5fSopenharmony_ci            self.tsc_path = self.args.tsc_path
5443af6ab5fSopenharmony_ci        else :
5453af6ab5fSopenharmony_ci            self.tsc_path = prepare_tsc_testcases(self.test_root)
5463af6ab5fSopenharmony_ci
5473af6ab5fSopenharmony_ci        self.add_directory("conformance", [])
5483af6ab5fSopenharmony_ci        self.add_directory("compiler", [])
5493af6ab5fSopenharmony_ci
5503af6ab5fSopenharmony_ci    def add_directory(self, directory, flags):
5513af6ab5fSopenharmony_ci        ts_suite_dir = path.join(self.tsc_path, 'tests/cases')
5523af6ab5fSopenharmony_ci
5533af6ab5fSopenharmony_ci        glob_expression = path.join(
5543af6ab5fSopenharmony_ci            ts_suite_dir, directory, "**/*.ts")
5553af6ab5fSopenharmony_ci        files = glob(glob_expression, recursive=True)
5563af6ab5fSopenharmony_ci        files = fnmatch.filter(files, ts_suite_dir + '**' + self.args.filter)
5573af6ab5fSopenharmony_ci
5583af6ab5fSopenharmony_ci        for f in files:
5593af6ab5fSopenharmony_ci            test_name = path.basename(f.split(".ts")[0])
5603af6ab5fSopenharmony_ci            negative_references = path.join(
5613af6ab5fSopenharmony_ci                self.tsc_path, 'tests/baselines/reference')
5623af6ab5fSopenharmony_ci            is_negative = path.isfile(path.join(negative_references,
5633af6ab5fSopenharmony_ci                                                test_name + ".errors.txt"))
5643af6ab5fSopenharmony_ci            test = TSCTest(f, flags)
5653af6ab5fSopenharmony_ci
5663af6ab5fSopenharmony_ci            if 'target' in test.options:
5673af6ab5fSopenharmony_ci                targets = test.options['target'].replace(" ", "").split(',')
5683af6ab5fSopenharmony_ci                for target in targets:
5693af6ab5fSopenharmony_ci                    if path.isfile(path.join(negative_references,
5703af6ab5fSopenharmony_ci                                             test_name + "(target=%s).errors.txt" % (target))):
5713af6ab5fSopenharmony_ci                        is_negative = True
5723af6ab5fSopenharmony_ci                        break
5733af6ab5fSopenharmony_ci
5743af6ab5fSopenharmony_ci            if is_negative or "filename" in test.options:
5753af6ab5fSopenharmony_ci                continue
5763af6ab5fSopenharmony_ci
5773af6ab5fSopenharmony_ci            with open(path.join(self.test_root, 'test_tsc_ignore_list.txt'), 'r') as failed_references:
5783af6ab5fSopenharmony_ci                if self.args.skip:
5793af6ab5fSopenharmony_ci                    if path.relpath(f, self.tsc_path) in failed_references.read():
5803af6ab5fSopenharmony_ci                        continue
5813af6ab5fSopenharmony_ci
5823af6ab5fSopenharmony_ci            self.tests.append(test)
5833af6ab5fSopenharmony_ci
5843af6ab5fSopenharmony_ci    def test_path(self, src):
5853af6ab5fSopenharmony_ci        return src
5863af6ab5fSopenharmony_ci
5873af6ab5fSopenharmony_ci
5883af6ab5fSopenharmony_ciclass CompilerRunner(Runner):
5893af6ab5fSopenharmony_ci    def __init__(self, args):
5903af6ab5fSopenharmony_ci        Runner.__init__(self, args, "Compiler")
5913af6ab5fSopenharmony_ci
5923af6ab5fSopenharmony_ci    def add_directory(self, directory, extension, flags):
5933af6ab5fSopenharmony_ci        if directory.endswith("projects"):
5943af6ab5fSopenharmony_ci            projects_path = path.join(self.test_root, directory)
5953af6ab5fSopenharmony_ci            for project in os.listdir(projects_path):
5963af6ab5fSopenharmony_ci                glob_expression = path.join(projects_path, project, "**/*.%s" % (extension))
5973af6ab5fSopenharmony_ci                files = glob(glob_expression, recursive=True)
5983af6ab5fSopenharmony_ci                files = fnmatch.filter(files, self.test_root + '**' + self.args.filter)
5993af6ab5fSopenharmony_ci                self.tests.append(CompilerProjectTest(projects_path, project, files, flags))
6003af6ab5fSopenharmony_ci        else:
6013af6ab5fSopenharmony_ci            glob_expression = path.join(
6023af6ab5fSopenharmony_ci                self.test_root, directory, "**/*.%s" % (extension))
6033af6ab5fSopenharmony_ci            files = glob(glob_expression, recursive=True)
6043af6ab5fSopenharmony_ci            files = fnmatch.filter(files, self.test_root + '**' + self.args.filter)
6053af6ab5fSopenharmony_ci            self.tests += list(map(lambda f: CompilerTest(f, flags), files))
6063af6ab5fSopenharmony_ci
6073af6ab5fSopenharmony_ci    def test_path(self, src):
6083af6ab5fSopenharmony_ci        return src
6093af6ab5fSopenharmony_ci
6103af6ab5fSopenharmony_ci
6113af6ab5fSopenharmony_ciclass CompilerTest(Test):
6123af6ab5fSopenharmony_ci    def __init__(self, test_path, flags):
6133af6ab5fSopenharmony_ci        Test.__init__(self, test_path, flags)
6143af6ab5fSopenharmony_ci
6153af6ab5fSopenharmony_ci    def execute_arkguard(self, runner):
6163af6ab5fSopenharmony_ci        input_file_path = self.path
6173af6ab5fSopenharmony_ci        arkguard_root_dir = os.path.join(runner.test_root, "../../arkguard")
6183af6ab5fSopenharmony_ci        arkgurad_entry_path = os.path.join(arkguard_root_dir, "lib/cli/SecHarmony.js")
6193af6ab5fSopenharmony_ci        config_path = os.path.join(arkguard_root_dir, "test/compilerTestConfig.json")
6203af6ab5fSopenharmony_ci        arkguard_cmd = [
6213af6ab5fSopenharmony_ci            'node',
6223af6ab5fSopenharmony_ci            '--no-warnings',
6233af6ab5fSopenharmony_ci            arkgurad_entry_path,
6243af6ab5fSopenharmony_ci            input_file_path,
6253af6ab5fSopenharmony_ci            '--config-path',
6263af6ab5fSopenharmony_ci            config_path,
6273af6ab5fSopenharmony_ci            '--inplace'
6283af6ab5fSopenharmony_ci        ]
6293af6ab5fSopenharmony_ci        self.log_cmd(arkguard_cmd)
6303af6ab5fSopenharmony_ci        process = subprocess.Popen(arkguard_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
6313af6ab5fSopenharmony_ci        out, err = process.communicate()
6323af6ab5fSopenharmony_ci        process.wait()
6333af6ab5fSopenharmony_ci        success = True
6343af6ab5fSopenharmony_ci        if err or process.returncode != 0:
6353af6ab5fSopenharmony_ci            success = False
6363af6ab5fSopenharmony_ci            self.passed = False
6373af6ab5fSopenharmony_ci            self.error = err.decode("utf-8", errors="ignore")
6383af6ab5fSopenharmony_ci        return success
6393af6ab5fSopenharmony_ci
6403af6ab5fSopenharmony_ci    def run(self, runner):
6413af6ab5fSopenharmony_ci        test_abc_name = ("%s.abc" % (path.splitext(self.path)[0])).replace("/", "_")
6423af6ab5fSopenharmony_ci        test_abc_path = path.join(runner.build_dir, test_abc_name)
6433af6ab5fSopenharmony_ci        es2abc_cmd = runner.cmd_prefix + [runner.es2panda]
6443af6ab5fSopenharmony_ci        es2abc_cmd.extend(self.flags)
6453af6ab5fSopenharmony_ci        es2abc_cmd.extend(["--output=" + test_abc_path])
6463af6ab5fSopenharmony_ci        es2abc_cmd.append(self.path)
6473af6ab5fSopenharmony_ci        enable_arkguard = runner.args.enable_arkguard
6483af6ab5fSopenharmony_ci        if enable_arkguard:
6493af6ab5fSopenharmony_ci            success = self.execute_arkguard(runner)
6503af6ab5fSopenharmony_ci            if not success:
6513af6ab5fSopenharmony_ci                return self
6523af6ab5fSopenharmony_ci
6533af6ab5fSopenharmony_ci        process = run_subprocess_with_beta3(self, es2abc_cmd)
6543af6ab5fSopenharmony_ci        out, err = process.communicate()
6553af6ab5fSopenharmony_ci        if "--dump-assembly" in self.flags:
6563af6ab5fSopenharmony_ci            pa_expected_path = "".join([self.get_path_to_expected()[:self.get_path_to_expected().rfind(".txt")],
6573af6ab5fSopenharmony_ci                                       ".pa.txt"])
6583af6ab5fSopenharmony_ci            self.output = out.decode("utf-8", errors="ignore") + err.decode("utf-8", errors="ignore")
6593af6ab5fSopenharmony_ci            try:
6603af6ab5fSopenharmony_ci                with open(pa_expected_path, 'r') as fp:
6613af6ab5fSopenharmony_ci                    expected = fp.read()
6623af6ab5fSopenharmony_ci                self.passed = expected == self.output and process.returncode in [0, 1]
6633af6ab5fSopenharmony_ci            except Exception:
6643af6ab5fSopenharmony_ci                self.passed = False
6653af6ab5fSopenharmony_ci            if not self.passed:
6663af6ab5fSopenharmony_ci                self.error = err.decode("utf-8", errors="ignore")
6673af6ab5fSopenharmony_ci                if os.path.exists(test_abc_path):
6683af6ab5fSopenharmony_ci                    os.remove(test_abc_path)
6693af6ab5fSopenharmony_ci                return self
6703af6ab5fSopenharmony_ci        if "--dump-debug-info" in self.flags:
6713af6ab5fSopenharmony_ci            self.output = out.decode("utf-8", errors="ignore") + err.decode("utf-8", errors="ignore")
6723af6ab5fSopenharmony_ci            try:
6733af6ab5fSopenharmony_ci                with open(self.get_path_to_expected(), 'r') as fp:
6743af6ab5fSopenharmony_ci                    expected = fp.read()
6753af6ab5fSopenharmony_ci                self.passed = expected == self.output and process.returncode in [0, 1]
6763af6ab5fSopenharmony_ci                if os.path.exists(test_abc_path):
6773af6ab5fSopenharmony_ci                    os.remove(test_abc_path)
6783af6ab5fSopenharmony_ci                return self
6793af6ab5fSopenharmony_ci            except Exception:
6803af6ab5fSopenharmony_ci                self.passed = False
6813af6ab5fSopenharmony_ci            if not self.passed:
6823af6ab5fSopenharmony_ci                self.error = err.decode("utf-8", errors="ignore")
6833af6ab5fSopenharmony_ci                if os.path.exists(test_abc_path):
6843af6ab5fSopenharmony_ci                    os.remove(test_abc_path)
6853af6ab5fSopenharmony_ci                return self
6863af6ab5fSopenharmony_ci        if err:
6873af6ab5fSopenharmony_ci            self.passed = False
6883af6ab5fSopenharmony_ci            self.error = err.decode("utf-8", errors="ignore")
6893af6ab5fSopenharmony_ci            return self
6903af6ab5fSopenharmony_ci
6913af6ab5fSopenharmony_ci        ld_library_path = runner.ld_library_path
6923af6ab5fSopenharmony_ci        os.environ.setdefault("LD_LIBRARY_PATH", ld_library_path)
6933af6ab5fSopenharmony_ci        run_abc_cmd = [runner.ark_js_vm, '--enable-force-gc=false', test_abc_path]
6943af6ab5fSopenharmony_ci        self.log_cmd(run_abc_cmd)
6953af6ab5fSopenharmony_ci
6963af6ab5fSopenharmony_ci        process = subprocess.Popen(run_abc_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
6973af6ab5fSopenharmony_ci        out, err = process.communicate()
6983af6ab5fSopenharmony_ci        self.output = out.decode("utf-8", errors="ignore") + err.decode("utf-8", errors="ignore")
6993af6ab5fSopenharmony_ci        expected_path = self.get_path_to_expected()
7003af6ab5fSopenharmony_ci        try:
7013af6ab5fSopenharmony_ci            with open(expected_path, 'r') as fp:
7023af6ab5fSopenharmony_ci                expected = fp.read()
7033af6ab5fSopenharmony_ci            self.passed = expected == self.output and process.returncode in [0, 1]
7043af6ab5fSopenharmony_ci        except Exception:
7053af6ab5fSopenharmony_ci            self.passed = False
7063af6ab5fSopenharmony_ci
7073af6ab5fSopenharmony_ci        if not self.passed:
7083af6ab5fSopenharmony_ci            self.error = err.decode("utf-8", errors="ignore")
7093af6ab5fSopenharmony_ci
7103af6ab5fSopenharmony_ci        os.remove(test_abc_path)
7113af6ab5fSopenharmony_ci
7123af6ab5fSopenharmony_ci        return self
7133af6ab5fSopenharmony_ci
7143af6ab5fSopenharmony_ci
7153af6ab5fSopenharmony_ciclass CompilerProjectTest(Test):
7163af6ab5fSopenharmony_ci    def __init__(self, projects_path, project, test_paths, flags):
7173af6ab5fSopenharmony_ci        Test.__init__(self, "", flags)
7183af6ab5fSopenharmony_ci        self.projects_path = projects_path
7193af6ab5fSopenharmony_ci        self.project = project
7203af6ab5fSopenharmony_ci        self.test_paths = test_paths
7213af6ab5fSopenharmony_ci        self.files_info_path = os.path.join(os.path.join(self.projects_path, self.project), 'filesInfo.txt')
7223af6ab5fSopenharmony_ci        # Skip execution if --dump-assembly exists in flags
7233af6ab5fSopenharmony_ci        self.requires_execution = "--dump-assembly" not in self.flags
7243af6ab5fSopenharmony_ci        self.file_record_mapping = None
7253af6ab5fSopenharmony_ci        self.generated_abc_inputs_path = os.path.join(os.path.join(self.projects_path, self.project), "abcinputs_gen")
7263af6ab5fSopenharmony_ci        self.abc_input_filenames = None
7273af6ab5fSopenharmony_ci        self.record_names_path = os.path.join(os.path.join(self.projects_path, self.project), 'recordnames.txt')
7283af6ab5fSopenharmony_ci        self.abc_inputs_path = os.path.join(os.path.join(self.projects_path, self.project), 'abcinputs')
7293af6ab5fSopenharmony_ci
7303af6ab5fSopenharmony_ci    def remove_project(self, runner):
7313af6ab5fSopenharmony_ci        project_path = runner.build_dir + "/" + self.project
7323af6ab5fSopenharmony_ci        if path.exists(project_path):
7333af6ab5fSopenharmony_ci            shutil.rmtree(project_path)
7343af6ab5fSopenharmony_ci        if path.exists(self.files_info_path):
7353af6ab5fSopenharmony_ci            os.remove(self.files_info_path)
7363af6ab5fSopenharmony_ci        if path.exists(self.generated_abc_inputs_path):
7373af6ab5fSopenharmony_ci            shutil.rmtree(self.generated_abc_inputs_path)
7383af6ab5fSopenharmony_ci
7393af6ab5fSopenharmony_ci    def get_file_absolute_path_and_name(self, runner):
7403af6ab5fSopenharmony_ci        sub_path = self.path[len(self.projects_path):]
7413af6ab5fSopenharmony_ci        file_relative_path = path.split(sub_path)[0]
7423af6ab5fSopenharmony_ci        file_name = path.split(sub_path)[1]
7433af6ab5fSopenharmony_ci        file_absolute_path = runner.build_dir + "/" + file_relative_path
7443af6ab5fSopenharmony_ci        return [file_absolute_path, file_name]
7453af6ab5fSopenharmony_ci
7463af6ab5fSopenharmony_ci    def gen_single_abc(self, runner):
7473af6ab5fSopenharmony_ci        for test_path in self.test_paths:
7483af6ab5fSopenharmony_ci            self.path = test_path
7493af6ab5fSopenharmony_ci            [file_absolute_path, file_name] = self.get_file_absolute_path_and_name(runner)
7503af6ab5fSopenharmony_ci            if not path.exists(file_absolute_path):
7513af6ab5fSopenharmony_ci                os.makedirs(file_absolute_path)
7523af6ab5fSopenharmony_ci
7533af6ab5fSopenharmony_ci            test_abc_name = ("%s.abc" % (path.splitext(file_name)[0]))
7543af6ab5fSopenharmony_ci            test_abc_path = path.join(file_absolute_path, test_abc_name)
7553af6ab5fSopenharmony_ci            es2abc_cmd = runner.cmd_prefix + [runner.es2panda]
7563af6ab5fSopenharmony_ci            es2abc_cmd.extend(self.flags)
7573af6ab5fSopenharmony_ci            es2abc_cmd.extend(['%s%s' % ("--output=", test_abc_path)])
7583af6ab5fSopenharmony_ci            es2abc_cmd.append(self.path)
7593af6ab5fSopenharmony_ci            process = run_subprocess_with_beta3(self, es2abc_cmd)
7603af6ab5fSopenharmony_ci            out, err = process.communicate()
7613af6ab5fSopenharmony_ci            if err:
7623af6ab5fSopenharmony_ci                self.passed = False
7633af6ab5fSopenharmony_ci                self.error = err.decode("utf-8", errors="ignore")
7643af6ab5fSopenharmony_ci                self.remove_project(runner)
7653af6ab5fSopenharmony_ci                return self
7663af6ab5fSopenharmony_ci
7673af6ab5fSopenharmony_ci    def collect_record_mapping(self):
7683af6ab5fSopenharmony_ci        # Collect record mappings from recordnames.txt, file format:
7693af6ab5fSopenharmony_ci        # 'source_file_name:record_name\n' * n
7703af6ab5fSopenharmony_ci        if path.exists(self.record_names_path):
7713af6ab5fSopenharmony_ci            with open(self.record_names_path) as mapping_fp:
7723af6ab5fSopenharmony_ci                mapping_lines = mapping_fp.readlines()
7733af6ab5fSopenharmony_ci                self.file_record_mapping = {}
7743af6ab5fSopenharmony_ci                for mapping_line in mapping_lines:
7753af6ab5fSopenharmony_ci                    cur_mapping = mapping_line[:-1].split(":")
7763af6ab5fSopenharmony_ci                    self.file_record_mapping[cur_mapping[0]] = cur_mapping[1]
7773af6ab5fSopenharmony_ci
7783af6ab5fSopenharmony_ci    def get_record_name(self, test_path):
7793af6ab5fSopenharmony_ci        record_name = os.path.relpath(test_path, os.path.dirname(self.files_info_path)).split('.')[0]
7803af6ab5fSopenharmony_ci        if (self.file_record_mapping is not None and record_name in self.file_record_mapping):
7813af6ab5fSopenharmony_ci            record_name = self.file_record_mapping[record_name]
7823af6ab5fSopenharmony_ci        return record_name
7833af6ab5fSopenharmony_ci
7843af6ab5fSopenharmony_ci    def collect_abc_inputs(self, runner):
7853af6ab5fSopenharmony_ci        # Collect abc input information from the 'abcinputs' directory. Each txt file in the directory
7863af6ab5fSopenharmony_ci        # will generate a merged abc file with the same filename and serve as the final abc input.
7873af6ab5fSopenharmony_ci        # file format: 'source_file_name.ts\n' * n
7883af6ab5fSopenharmony_ci        if not path.exists(self.abc_inputs_path):
7893af6ab5fSopenharmony_ci            return
7903af6ab5fSopenharmony_ci        if not path.exists(self.generated_abc_inputs_path):
7913af6ab5fSopenharmony_ci            os.makedirs(self.generated_abc_inputs_path)
7923af6ab5fSopenharmony_ci        self.abc_input_filenames = {}
7933af6ab5fSopenharmony_ci        filenames = os.listdir(self.abc_inputs_path)
7943af6ab5fSopenharmony_ci        for filename in filenames:
7953af6ab5fSopenharmony_ci            if not filename.endswith('.txt'):
7963af6ab5fSopenharmony_ci                self.remove_project(runner)
7973af6ab5fSopenharmony_ci                raise Exception("Invalid abc input file: %s, only txt files are allowed in abcinputs directory: %s"
7983af6ab5fSopenharmony_ci                                % (filename, self.abc_inputs_path))
7993af6ab5fSopenharmony_ci            with open(path.join(self.abc_inputs_path, filename)) as abc_inputs_fp:
8003af6ab5fSopenharmony_ci                abc_inputs_lines = abc_inputs_fp.readlines()
8013af6ab5fSopenharmony_ci                for abc_input_line in abc_inputs_lines:
8023af6ab5fSopenharmony_ci                    # filename is 'xxx.txt', remove '.txt' here
8033af6ab5fSopenharmony_ci                    self.abc_input_filenames[abc_input_line[:-1]] = filename[:-len('.txt')]
8043af6ab5fSopenharmony_ci
8053af6ab5fSopenharmony_ci    def get_belonging_abc_input(self, test_path):
8063af6ab5fSopenharmony_ci        filename = os.path.relpath(test_path, os.path.dirname(self.files_info_path))
8073af6ab5fSopenharmony_ci        if (self.abc_input_filenames is not None and filename in self.abc_input_filenames):
8083af6ab5fSopenharmony_ci            return self.abc_input_filenames[filename]
8093af6ab5fSopenharmony_ci        return None
8103af6ab5fSopenharmony_ci
8113af6ab5fSopenharmony_ci    def gen_abc_input_files_infos(self, runner, abc_files_infos, final_file_info_f):
8123af6ab5fSopenharmony_ci        for abc_files_info_name in abc_files_infos:
8133af6ab5fSopenharmony_ci            abc_files_info = abc_files_infos[abc_files_info_name]
8143af6ab5fSopenharmony_ci            if len(abc_files_info) != 0:
8153af6ab5fSopenharmony_ci                abc_input_path = path.join(self.generated_abc_inputs_path, abc_files_info_name)
8163af6ab5fSopenharmony_ci                abc_files_info_path = ("%s-filesInfo.txt" % (abc_input_path))
8173af6ab5fSopenharmony_ci                abc_files_info_fd = os.open(abc_files_info_path, os.O_RDWR | os.O_CREAT | os.O_TRUNC)
8183af6ab5fSopenharmony_ci                abc_files_info_f = os.fdopen(abc_files_info_fd, 'w')
8193af6ab5fSopenharmony_ci                abc_files_info_f.writelines(abc_files_info)
8203af6ab5fSopenharmony_ci                final_file_info_f.writelines('%s-abcinput.abc;;;;%s;\n' % (abc_input_path, abc_files_info_name))
8213af6ab5fSopenharmony_ci
8223af6ab5fSopenharmony_ci    def gen_files_info(self, runner):
8233af6ab5fSopenharmony_ci        # After collect_record_mapping, self.file_record_mapping stores {'source file name' : 'source file record name'}
8243af6ab5fSopenharmony_ci        self.collect_record_mapping()
8253af6ab5fSopenharmony_ci        # After collect_abc_inputs, self.abc_input_filenames stores {'source file name' : 'belonging abc input name'}
8263af6ab5fSopenharmony_ci        self.collect_abc_inputs(runner)
8273af6ab5fSopenharmony_ci
8283af6ab5fSopenharmony_ci        fd = os.open(self.files_info_path, os.O_RDWR | os.O_CREAT | os.O_TRUNC)
8293af6ab5fSopenharmony_ci        f = os.fdopen(fd, 'w')
8303af6ab5fSopenharmony_ci        abc_files_infos = {}
8313af6ab5fSopenharmony_ci        for test_path in self.test_paths:
8323af6ab5fSopenharmony_ci            record_name = self.get_record_name(test_path)
8333af6ab5fSopenharmony_ci            module_kind = 'esm'
8343af6ab5fSopenharmony_ci            if (os.path.basename(test_path).startswith("commonjs")):
8353af6ab5fSopenharmony_ci                module_kind = 'commonjs'
8363af6ab5fSopenharmony_ci            is_shared_module = 'false'
8373af6ab5fSopenharmony_ci            if (os.path.basename(test_path).startswith("sharedmodule")):
8383af6ab5fSopenharmony_ci                is_shared_module = 'true'
8393af6ab5fSopenharmony_ci            file_info = ('%s;%s;%s;%s;%s;%s\n' % (test_path, record_name, module_kind,
8403af6ab5fSopenharmony_ci                                               os.path.relpath(test_path, self.projects_path), record_name,
8413af6ab5fSopenharmony_ci                                               is_shared_module))
8423af6ab5fSopenharmony_ci            belonging_abc_input = self.get_belonging_abc_input(test_path)
8433af6ab5fSopenharmony_ci            if belonging_abc_input is not None:
8443af6ab5fSopenharmony_ci                if not belonging_abc_input in abc_files_infos:
8453af6ab5fSopenharmony_ci                    abc_files_infos[belonging_abc_input] = []
8463af6ab5fSopenharmony_ci                abc_files_infos[belonging_abc_input].append(file_info)
8473af6ab5fSopenharmony_ci            else:
8483af6ab5fSopenharmony_ci                f.writelines(file_info)
8493af6ab5fSopenharmony_ci        self.gen_abc_input_files_infos(runner, abc_files_infos, f)
8503af6ab5fSopenharmony_ci        f.close()
8513af6ab5fSopenharmony_ci
8523af6ab5fSopenharmony_ci    def gen_es2abc_cmd(self, runner, input_file, output_file):
8533af6ab5fSopenharmony_ci        es2abc_cmd = runner.cmd_prefix + [runner.es2panda]
8543af6ab5fSopenharmony_ci        es2abc_cmd.extend(self.flags)
8553af6ab5fSopenharmony_ci        es2abc_cmd.extend(['%s%s' % ("--output=", output_file)])
8563af6ab5fSopenharmony_ci        es2abc_cmd.append(input_file)
8573af6ab5fSopenharmony_ci        return es2abc_cmd
8583af6ab5fSopenharmony_ci
8593af6ab5fSopenharmony_ci    def gen_merged_abc_for_abc_input(self, runner, files_info_name):
8603af6ab5fSopenharmony_ci        self.passed = True
8613af6ab5fSopenharmony_ci        if not files_info_name.endswith(".txt"):
8623af6ab5fSopenharmony_ci            return
8633af6ab5fSopenharmony_ci        abc_input_files_info_path = path.join(self.generated_abc_inputs_path, files_info_name)
8643af6ab5fSopenharmony_ci        abc_input_merged_abc_path = path.join(self.generated_abc_inputs_path,
8653af6ab5fSopenharmony_ci                                              '%s-abcinput.abc' % (files_info_name[:-len('-filesInfo.txt')]))
8663af6ab5fSopenharmony_ci
8673af6ab5fSopenharmony_ci        abc_input_file_path = '@' + abc_input_files_info_path
8683af6ab5fSopenharmony_ci        if "unmerged_abc_input" in self.generated_abc_inputs_path:
8693af6ab5fSopenharmony_ci            self.flags.remove("--merge-abc")
8703af6ab5fSopenharmony_ci            with open(abc_input_files_info_path, 'r') as fp:
8713af6ab5fSopenharmony_ci                abc_input_file_path = fp.read().split(';')[0]
8723af6ab5fSopenharmony_ci
8733af6ab5fSopenharmony_ci        es2abc_cmd = self.gen_es2abc_cmd(runner, abc_input_file_path, abc_input_merged_abc_path)
8743af6ab5fSopenharmony_ci        process = run_subprocess_with_beta3(self, es2abc_cmd)
8753af6ab5fSopenharmony_ci        out, err = process.communicate()
8763af6ab5fSopenharmony_ci        if err:
8773af6ab5fSopenharmony_ci            self.passed = False
8783af6ab5fSopenharmony_ci            self.error = err.decode("utf-8", errors="ignore")
8793af6ab5fSopenharmony_ci
8803af6ab5fSopenharmony_ci    def gen_merged_abc(self, runner):
8813af6ab5fSopenharmony_ci        # Generate abc inputs
8823af6ab5fSopenharmony_ci        if (os.path.exists(self.generated_abc_inputs_path)):
8833af6ab5fSopenharmony_ci            files_info_names = os.listdir(self.generated_abc_inputs_path)
8843af6ab5fSopenharmony_ci            for filename in files_info_names:
8853af6ab5fSopenharmony_ci                self.gen_merged_abc_for_abc_input(runner, filename)
8863af6ab5fSopenharmony_ci                if (not self.passed):
8873af6ab5fSopenharmony_ci                    self.remove_project(runner)
8883af6ab5fSopenharmony_ci                    return self
8893af6ab5fSopenharmony_ci        # Generate the abc to be tested
8903af6ab5fSopenharmony_ci        for test_path in self.test_paths:
8913af6ab5fSopenharmony_ci            self.path = test_path
8923af6ab5fSopenharmony_ci            if (self.path.endswith("-exec.ts")) or (self.path.endswith("-exec.js")):
8933af6ab5fSopenharmony_ci                exec_file_path = self.path
8943af6ab5fSopenharmony_ci                [file_absolute_path, file_name] = self.get_file_absolute_path_and_name(runner)
8953af6ab5fSopenharmony_ci                if not path.exists(file_absolute_path):
8963af6ab5fSopenharmony_ci                    os.makedirs(file_absolute_path)
8973af6ab5fSopenharmony_ci                test_abc_name = ("%s.abc" % (path.splitext(file_name)[0]))
8983af6ab5fSopenharmony_ci                output_abc_name = path.join(file_absolute_path, test_abc_name)
8993af6ab5fSopenharmony_ci
9003af6ab5fSopenharmony_ci        # reverse merge-abc flag
9013af6ab5fSopenharmony_ci        if "merge_abc_consistence_check" in self.path:
9023af6ab5fSopenharmony_ci            if "--merge-abc" in self.flags:
9033af6ab5fSopenharmony_ci                self.flags.remove("--merge-abc")
9043af6ab5fSopenharmony_ci            else:
9053af6ab5fSopenharmony_ci                self.flags.append("--merge-abc")
9063af6ab5fSopenharmony_ci
9073af6ab5fSopenharmony_ci        es2abc_cmd = self.gen_es2abc_cmd(runner, '@' + self.files_info_path, output_abc_name)
9083af6ab5fSopenharmony_ci        compile_context_info_path = path.join(path.join(self.projects_path, self.project), "compileContextInfo.json")
9093af6ab5fSopenharmony_ci        if path.exists(compile_context_info_path):
9103af6ab5fSopenharmony_ci            es2abc_cmd.append("%s%s" % ("--compile-context-info=", compile_context_info_path))
9113af6ab5fSopenharmony_ci        process = run_subprocess_with_beta3(self, es2abc_cmd)
9123af6ab5fSopenharmony_ci        self.path = exec_file_path
9133af6ab5fSopenharmony_ci        out, err = process.communicate()
9143af6ab5fSopenharmony_ci
9153af6ab5fSopenharmony_ci        # restore merge-abc flag
9163af6ab5fSopenharmony_ci        if "merge_abc_consistence_check" in self.path and "--merge-abc" not in self.flags:
9173af6ab5fSopenharmony_ci            self.flags.append("--merge-abc")
9183af6ab5fSopenharmony_ci
9193af6ab5fSopenharmony_ci        # Check dump-assembly outputs when required
9203af6ab5fSopenharmony_ci        if "--dump-assembly" in self.flags:
9213af6ab5fSopenharmony_ci            pa_expected_path = "".join([self.get_path_to_expected()[:self.get_path_to_expected().rfind(".txt")],
9223af6ab5fSopenharmony_ci                                        ".pa.txt"])
9233af6ab5fSopenharmony_ci            self.output = out.decode("utf-8", errors="ignore") + err.decode("utf-8", errors="ignore")
9243af6ab5fSopenharmony_ci            if "merge_abc_consistence_check" in self.path:
9253af6ab5fSopenharmony_ci                self.output = self.output.split('.')[0]
9263af6ab5fSopenharmony_ci            try:
9273af6ab5fSopenharmony_ci                with open(pa_expected_path, 'r') as fp:
9283af6ab5fSopenharmony_ci                    expected = fp.read()
9293af6ab5fSopenharmony_ci                self.passed = expected == self.output and process.returncode in [0, 1]
9303af6ab5fSopenharmony_ci            except Exception:
9313af6ab5fSopenharmony_ci                self.passed = False
9323af6ab5fSopenharmony_ci            if not self.passed:
9333af6ab5fSopenharmony_ci                self.error = err.decode("utf-8", errors="ignore")
9343af6ab5fSopenharmony_ci                self.remove_project(runner)
9353af6ab5fSopenharmony_ci                return self
9363af6ab5fSopenharmony_ci            else:
9373af6ab5fSopenharmony_ci                return self
9383af6ab5fSopenharmony_ci
9393af6ab5fSopenharmony_ci        if err:
9403af6ab5fSopenharmony_ci            self.passed = False
9413af6ab5fSopenharmony_ci            self.error = err.decode("utf-8", errors="ignore")
9423af6ab5fSopenharmony_ci            self.remove_project(runner)
9433af6ab5fSopenharmony_ci            return self
9443af6ab5fSopenharmony_ci
9453af6ab5fSopenharmony_ci    def run(self, runner):
9463af6ab5fSopenharmony_ci        # Compile all ts source files in the project to abc files.
9473af6ab5fSopenharmony_ci        if ("--merge-abc" in self.flags):
9483af6ab5fSopenharmony_ci            self.gen_files_info(runner)
9493af6ab5fSopenharmony_ci            self.gen_merged_abc(runner)
9503af6ab5fSopenharmony_ci        else:
9513af6ab5fSopenharmony_ci            self.gen_single_abc(runner)
9523af6ab5fSopenharmony_ci
9533af6ab5fSopenharmony_ci        if (not self.requires_execution):
9543af6ab5fSopenharmony_ci            self.remove_project(runner)
9553af6ab5fSopenharmony_ci            return self
9563af6ab5fSopenharmony_ci
9573af6ab5fSopenharmony_ci        # Run test files that need to be executed in the project.
9583af6ab5fSopenharmony_ci        for test_path in self.test_paths:
9593af6ab5fSopenharmony_ci            self.path = test_path
9603af6ab5fSopenharmony_ci            if self.path.endswith("-exec.ts"):
9613af6ab5fSopenharmony_ci                [file_absolute_path, file_name] = self.get_file_absolute_path_and_name(runner)
9623af6ab5fSopenharmony_ci
9633af6ab5fSopenharmony_ci                entry_point_name = path.splitext(file_name)[0]
9643af6ab5fSopenharmony_ci                test_abc_name = ("%s.abc" % entry_point_name)
9653af6ab5fSopenharmony_ci                test_abc_path = path.join(file_absolute_path, test_abc_name)
9663af6ab5fSopenharmony_ci
9673af6ab5fSopenharmony_ci                ld_library_path = runner.ld_library_path
9683af6ab5fSopenharmony_ci                os.environ.setdefault("LD_LIBRARY_PATH", ld_library_path)
9693af6ab5fSopenharmony_ci                run_abc_cmd = [runner.ark_js_vm]
9703af6ab5fSopenharmony_ci                if ("--merge-abc" in self.flags):
9713af6ab5fSopenharmony_ci                    run_abc_cmd.extend(["--entry-point", entry_point_name])
9723af6ab5fSopenharmony_ci                run_abc_cmd.extend([test_abc_path])
9733af6ab5fSopenharmony_ci                self.log_cmd(run_abc_cmd)
9743af6ab5fSopenharmony_ci
9753af6ab5fSopenharmony_ci                process = subprocess.Popen(run_abc_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
9763af6ab5fSopenharmony_ci                out, err = process.communicate()
9773af6ab5fSopenharmony_ci                self.output = out.decode("utf-8", errors="ignore") + err.decode("utf-8", errors="ignore")
9783af6ab5fSopenharmony_ci                expected_path = self.get_path_to_expected()
9793af6ab5fSopenharmony_ci                try:
9803af6ab5fSopenharmony_ci                    with open(expected_path, 'r') as fp:
9813af6ab5fSopenharmony_ci                        expected = fp.read()
9823af6ab5fSopenharmony_ci                    self.passed = expected == self.output and process.returncode in [0, 1]
9833af6ab5fSopenharmony_ci                except Exception:
9843af6ab5fSopenharmony_ci                    self.passed = False
9853af6ab5fSopenharmony_ci
9863af6ab5fSopenharmony_ci                if not self.passed:
9873af6ab5fSopenharmony_ci                    self.error = err.decode("utf-8", errors="ignore")
9883af6ab5fSopenharmony_ci                    self.remove_project(runner)
9893af6ab5fSopenharmony_ci                    return self
9903af6ab5fSopenharmony_ci
9913af6ab5fSopenharmony_ci            self.passed = True
9923af6ab5fSopenharmony_ci
9933af6ab5fSopenharmony_ci        self.remove_project(runner)
9943af6ab5fSopenharmony_ci        return self
9953af6ab5fSopenharmony_ci
9963af6ab5fSopenharmony_ci
9973af6ab5fSopenharmony_ciclass TSDeclarationTest(Test):
9983af6ab5fSopenharmony_ci    def get_path_to_expected(self):
9993af6ab5fSopenharmony_ci        file_name = self.path[:self.path.find(".d.ts")]
10003af6ab5fSopenharmony_ci        return "%s-expected.txt" % file_name
10013af6ab5fSopenharmony_ci
10023af6ab5fSopenharmony_ci
10033af6ab5fSopenharmony_ciclass BcVersionRunner(Runner):
10043af6ab5fSopenharmony_ci    def __init__(self, args):
10053af6ab5fSopenharmony_ci        Runner.__init__(self, args, "Target bc version")
10063af6ab5fSopenharmony_ci        self.ts2abc = path.join(self.test_root, '..', 'scripts', 'ts2abc.js')
10073af6ab5fSopenharmony_ci
10083af6ab5fSopenharmony_ci    def add_cmd(self):
10093af6ab5fSopenharmony_ci        api_sub_version_list = ["beta1", "beta2", "beta3"]
10103af6ab5fSopenharmony_ci        for api_version in range(8, 17):
10113af6ab5fSopenharmony_ci            cmd = self.cmd_prefix + [self.es2panda]
10123af6ab5fSopenharmony_ci            cmd += ["--target-bc-version"]
10133af6ab5fSopenharmony_ci            cmd += ["--target-api-version"]
10143af6ab5fSopenharmony_ci            cmd += [str(api_version)]
10153af6ab5fSopenharmony_ci            self.tests += [BcVersionTest(cmd, api_version)]
10163af6ab5fSopenharmony_ci            node_cmd = ["node"] + [self.ts2abc]
10173af6ab5fSopenharmony_ci            node_cmd += ["".join(["es2abc=", self.es2panda])]
10183af6ab5fSopenharmony_ci            node_cmd += ["--target-api-version"]
10193af6ab5fSopenharmony_ci            node_cmd += [str(api_version)]
10203af6ab5fSopenharmony_ci            self.tests += [BcVersionTest(node_cmd, api_version)]
10213af6ab5fSopenharmony_ci
10223af6ab5fSopenharmony_ci            # Add tests for "--target-api-sub-version" option
10233af6ab5fSopenharmony_ci            if api_version == 12:
10243af6ab5fSopenharmony_ci                for api_sub_version in api_sub_version_list:
10253af6ab5fSopenharmony_ci                    new_cmd = cmd.copy()
10263af6ab5fSopenharmony_ci                    new_cmd += ["--target-api-sub-version", api_sub_version]
10273af6ab5fSopenharmony_ci                    self.tests += [BcVersionTest(new_cmd, str(api_version) + '_' + api_sub_version)]
10283af6ab5fSopenharmony_ci                    new_node_cmd = node_cmd.copy()
10293af6ab5fSopenharmony_ci                    new_node_cmd += ["--target-api-sub-version", api_sub_version]
10303af6ab5fSopenharmony_ci                    self.tests += [BcVersionTest(new_node_cmd, str(api_version) + '_' + api_sub_version)]
10313af6ab5fSopenharmony_ci
10323af6ab5fSopenharmony_ci    def run(self):
10333af6ab5fSopenharmony_ci        for test in self.tests:
10343af6ab5fSopenharmony_ci            test.run()
10353af6ab5fSopenharmony_ci
10363af6ab5fSopenharmony_ci
10373af6ab5fSopenharmony_ciclass BcVersionTest(Test):
10383af6ab5fSopenharmony_ci    def __init__(self, cmd, api_version):
10393af6ab5fSopenharmony_ci        Test.__init__(self, "", 0)
10403af6ab5fSopenharmony_ci        self.cmd = cmd
10413af6ab5fSopenharmony_ci        self.api_version = api_version
10423af6ab5fSopenharmony_ci        # To avoid problems when api version is upgraded abruptly,
10433af6ab5fSopenharmony_ci        # the corresponding bytecode version of the api version not written in isa.yaml is alaways the newest version.
10443af6ab5fSopenharmony_ci        self.bc_version_expect = {
10453af6ab5fSopenharmony_ci            8: "13.0.0.0",
10463af6ab5fSopenharmony_ci            9: "9.0.0.0",
10473af6ab5fSopenharmony_ci            10: "9.0.0.0",
10483af6ab5fSopenharmony_ci            11: "11.0.2.0",
10493af6ab5fSopenharmony_ci            12: "12.0.2.0",
10503af6ab5fSopenharmony_ci            "12_beta1": "12.0.2.0",
10513af6ab5fSopenharmony_ci            "12_beta2": "12.0.2.0",
10523af6ab5fSopenharmony_ci            "12_beta3": "12.0.6.0",
10533af6ab5fSopenharmony_ci            13: "12.0.6.0",
10543af6ab5fSopenharmony_ci            14: "12.0.6.0",
10553af6ab5fSopenharmony_ci            15: "13.0.0.0",
10563af6ab5fSopenharmony_ci            16: "13.0.0.0"
10573af6ab5fSopenharmony_ci        }
10583af6ab5fSopenharmony_ci        self.es2abc_script_expect = {
10593af6ab5fSopenharmony_ci            8: "0.0.0.2",
10603af6ab5fSopenharmony_ci            9: "9.0.0.0",
10613af6ab5fSopenharmony_ci            10: "9.0.0.0",
10623af6ab5fSopenharmony_ci            11: "11.0.2.0",
10633af6ab5fSopenharmony_ci            12: "12.0.2.0",
10643af6ab5fSopenharmony_ci            "12_beta1": "12.0.2.0",
10653af6ab5fSopenharmony_ci            "12_beta2": "12.0.2.0",
10663af6ab5fSopenharmony_ci            "12_beta3": "12.0.6.0",
10673af6ab5fSopenharmony_ci            13: "12.0.6.0",
10683af6ab5fSopenharmony_ci            14: "12.0.6.0",
10693af6ab5fSopenharmony_ci            15: "13.0.0.0",
10703af6ab5fSopenharmony_ci            16: "13.0.0.0"
10713af6ab5fSopenharmony_ci        }
10723af6ab5fSopenharmony_ci
10733af6ab5fSopenharmony_ci    def run(self):
10743af6ab5fSopenharmony_ci        process = subprocess.Popen(self.cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
10753af6ab5fSopenharmony_ci        out, err = process.communicate()
10763af6ab5fSopenharmony_ci        self.output = out.decode("utf-8", errors="ignore") + err.decode("utf-8", errors="ignore")
10773af6ab5fSopenharmony_ci        if self.cmd[0] == "node":
10783af6ab5fSopenharmony_ci            self.passed = self.es2abc_script_expect.get(self.api_version) == self.output and process.returncode in [0, 1]
10793af6ab5fSopenharmony_ci        else:
10803af6ab5fSopenharmony_ci            self.passed = self.bc_version_expect.get(self.api_version) == self.output and process.returncode in [0, 1]
10813af6ab5fSopenharmony_ci        if not self.passed:
10823af6ab5fSopenharmony_ci            self.error = err.decode("utf-8", errors="ignore")
10833af6ab5fSopenharmony_ci        return self
10843af6ab5fSopenharmony_ci
10853af6ab5fSopenharmony_ci
10863af6ab5fSopenharmony_ciclass TransformerRunner(Runner):
10873af6ab5fSopenharmony_ci    def __init__(self, args):
10883af6ab5fSopenharmony_ci        Runner.__init__(self, args, "Transformer")
10893af6ab5fSopenharmony_ci
10903af6ab5fSopenharmony_ci    def add_directory(self, directory, extension, flags):
10913af6ab5fSopenharmony_ci        glob_expression = path.join(
10923af6ab5fSopenharmony_ci            self.test_root, directory, "**/*.%s" % (extension))
10933af6ab5fSopenharmony_ci        files = glob(glob_expression, recursive=True)
10943af6ab5fSopenharmony_ci        files = fnmatch.filter(files, self.test_root + '**' + self.args.filter)
10953af6ab5fSopenharmony_ci
10963af6ab5fSopenharmony_ci        self.tests += list(map(lambda f: TransformerTest(f, flags), files))
10973af6ab5fSopenharmony_ci
10983af6ab5fSopenharmony_ci    def test_path(self, src):
10993af6ab5fSopenharmony_ci        return src
11003af6ab5fSopenharmony_ci
11013af6ab5fSopenharmony_ci
11023af6ab5fSopenharmony_ciclass TransformerInTargetApiVersion10Runner(Runner):
11033af6ab5fSopenharmony_ci    def __init__(self, args):
11043af6ab5fSopenharmony_ci        Runner.__init__(self, args, "TransformerInTargetApiVersion10")
11053af6ab5fSopenharmony_ci
11063af6ab5fSopenharmony_ci    def add_directory(self, directory, extension, flags):
11073af6ab5fSopenharmony_ci        glob_expression = path.join(
11083af6ab5fSopenharmony_ci            self.test_root, directory, "**/*.%s" % (extension))
11093af6ab5fSopenharmony_ci        files = glob(glob_expression, recursive=True)
11103af6ab5fSopenharmony_ci        files = fnmatch.filter(files, self.test_root + '**' + self.args.filter)
11113af6ab5fSopenharmony_ci
11123af6ab5fSopenharmony_ci        self.tests += list(map(lambda f: TransformerTest(f, flags), files))
11133af6ab5fSopenharmony_ci
11143af6ab5fSopenharmony_ci    def test_path(self, src):
11153af6ab5fSopenharmony_ci        return src
11163af6ab5fSopenharmony_ci
11173af6ab5fSopenharmony_ci
11183af6ab5fSopenharmony_ciclass TransformerTest(Test):
11193af6ab5fSopenharmony_ci    def __init__(self, test_path, flags):
11203af6ab5fSopenharmony_ci        Test.__init__(self, test_path, flags)
11213af6ab5fSopenharmony_ci
11223af6ab5fSopenharmony_ci    def get_path_to_expected(self):
11233af6ab5fSopenharmony_ci        return "%s-transformed-expected.txt" % (path.splitext(self.path)[0])
11243af6ab5fSopenharmony_ci
11253af6ab5fSopenharmony_ci    def run(self, runner):
11263af6ab5fSopenharmony_ci        cmd = runner.cmd_prefix + [runner.es2panda]
11273af6ab5fSopenharmony_ci        cmd.extend(self.flags)
11283af6ab5fSopenharmony_ci        cmd.append(self.path)
11293af6ab5fSopenharmony_ci        process = run_subprocess_with_beta3(self, cmd)
11303af6ab5fSopenharmony_ci        out, err = process.communicate()
11313af6ab5fSopenharmony_ci        self.output = out.decode("utf-8", errors="ignore") + err.decode("utf-8", errors="ignore")
11323af6ab5fSopenharmony_ci
11333af6ab5fSopenharmony_ci        expected_path = self.get_path_to_expected()
11343af6ab5fSopenharmony_ci        try:
11353af6ab5fSopenharmony_ci            with open(expected_path, 'r') as fp:
11363af6ab5fSopenharmony_ci                expected = fp.read()
11373af6ab5fSopenharmony_ci            self.passed = expected == self.output and process.returncode in [0, 1]
11383af6ab5fSopenharmony_ci        except Exception:
11393af6ab5fSopenharmony_ci            self.passed = False
11403af6ab5fSopenharmony_ci
11413af6ab5fSopenharmony_ci        if not self.passed:
11423af6ab5fSopenharmony_ci            self.error = err.decode("utf-8", errors="ignore")
11433af6ab5fSopenharmony_ci
11443af6ab5fSopenharmony_ci        return self
11453af6ab5fSopenharmony_ci
11463af6ab5fSopenharmony_ci
11473af6ab5fSopenharmony_ciclass PatchTest(Test):
11483af6ab5fSopenharmony_ci    def __init__(self, test_path, mode_arg, target_version, preserve_files):
11493af6ab5fSopenharmony_ci        Test.__init__(self, test_path, "")
11503af6ab5fSopenharmony_ci        self.mode = mode_arg
11513af6ab5fSopenharmony_ci        self.target_version = target_version
11523af6ab5fSopenharmony_ci        self.preserve_files = preserve_files
11533af6ab5fSopenharmony_ci
11543af6ab5fSopenharmony_ci    def gen_cmd(self, runner):
11553af6ab5fSopenharmony_ci        symbol_table_file = os.path.join(self.path, 'base.map')
11563af6ab5fSopenharmony_ci        origin_input_file = 'base.js'
11573af6ab5fSopenharmony_ci        origin_output_abc = os.path.join(self.path, 'base.abc')
11583af6ab5fSopenharmony_ci        modified_input_file = 'base_mod.js'
11593af6ab5fSopenharmony_ci        modified_output_abc = os.path.join(self.path, 'patch.abc')
11603af6ab5fSopenharmony_ci        target_version_cmd = ""
11613af6ab5fSopenharmony_ci        if self.target_version > 0:
11623af6ab5fSopenharmony_ci            target_version_cmd = "--target-api-version=" + str(self.target_version)
11633af6ab5fSopenharmony_ci
11643af6ab5fSopenharmony_ci        gen_base_cmd = runner.cmd_prefix + [runner.es2panda, '--module', target_version_cmd]
11653af6ab5fSopenharmony_ci        if 'record-name-with-dots' in os.path.basename(self.path):
11663af6ab5fSopenharmony_ci            gen_base_cmd.extend(['--merge-abc', '--record-name=record.name.with.dots'])
11673af6ab5fSopenharmony_ci        gen_base_cmd.extend(['--dump-symbol-table', symbol_table_file])
11683af6ab5fSopenharmony_ci        gen_base_cmd.extend(['--output', origin_output_abc])
11693af6ab5fSopenharmony_ci        gen_base_cmd.extend([os.path.join(self.path, origin_input_file)])
11703af6ab5fSopenharmony_ci        self.log_cmd(gen_base_cmd)
11713af6ab5fSopenharmony_ci
11723af6ab5fSopenharmony_ci        if self.mode == 'hotfix':
11733af6ab5fSopenharmony_ci            mode_arg = ["--generate-patch"]
11743af6ab5fSopenharmony_ci        elif self.mode == 'hotreload':
11753af6ab5fSopenharmony_ci            mode_arg = ["--hot-reload"]
11763af6ab5fSopenharmony_ci        elif self.mode == 'coldfix':
11773af6ab5fSopenharmony_ci            mode_arg = ["--generate-patch", "--cold-fix"]
11783af6ab5fSopenharmony_ci        elif self.mode == 'coldreload':
11793af6ab5fSopenharmony_ci            mode_arg = ["--cold-reload"]
11803af6ab5fSopenharmony_ci
11813af6ab5fSopenharmony_ci        patch_test_cmd = runner.cmd_prefix + [runner.es2panda, '--module', target_version_cmd]
11823af6ab5fSopenharmony_ci        patch_test_cmd.extend(mode_arg)
11833af6ab5fSopenharmony_ci        patch_test_cmd.extend(['--input-symbol-table', symbol_table_file])
11843af6ab5fSopenharmony_ci        patch_test_cmd.extend(['--output', modified_output_abc])
11853af6ab5fSopenharmony_ci        patch_test_cmd.extend([os.path.join(self.path, modified_input_file)])
11863af6ab5fSopenharmony_ci        if 'record-name-with-dots' in os.path.basename(self.path):
11873af6ab5fSopenharmony_ci            patch_test_cmd.extend(['--merge-abc', '--record-name=record.name.with.dots'])
11883af6ab5fSopenharmony_ci        dump_assembly_testname = [
11893af6ab5fSopenharmony_ci            'modify-anon-content-keep-origin-name',
11903af6ab5fSopenharmony_ci            'modify-class-memeber-function',
11913af6ab5fSopenharmony_ci            'exist-lexenv-3',
11923af6ab5fSopenharmony_ci            'lexenv-reduce',
11933af6ab5fSopenharmony_ci            'lexenv-increase']
11943af6ab5fSopenharmony_ci        for name in dump_assembly_testname:
11953af6ab5fSopenharmony_ci            if name in os.path.basename(self.path):
11963af6ab5fSopenharmony_ci                patch_test_cmd.extend(['--dump-assembly'])
11973af6ab5fSopenharmony_ci        self.log_cmd(patch_test_cmd)
11983af6ab5fSopenharmony_ci
11993af6ab5fSopenharmony_ci        return gen_base_cmd, patch_test_cmd, symbol_table_file, origin_output_abc, modified_output_abc
12003af6ab5fSopenharmony_ci
12013af6ab5fSopenharmony_ci    def run(self, runner):
12023af6ab5fSopenharmony_ci        gen_base_cmd, patch_test_cmd, symbol_table_file, origin_output_abc, modified_output_abc = self.gen_cmd(runner)
12033af6ab5fSopenharmony_ci
12043af6ab5fSopenharmony_ci        process_base = run_subprocess_with_beta3(None, gen_base_cmd)
12053af6ab5fSopenharmony_ci        stdout_base, stderr_base = process_base.communicate(timeout=runner.args.es2panda_timeout)
12063af6ab5fSopenharmony_ci        if stderr_base:
12073af6ab5fSopenharmony_ci            self.passed = False
12083af6ab5fSopenharmony_ci            self.error = stderr_base.decode("utf-8", errors="ignore")
12093af6ab5fSopenharmony_ci            self.output = stdout_base.decode("utf-8", errors="ignore") + stderr_base.decode("utf-8", errors="ignore")
12103af6ab5fSopenharmony_ci        else:
12113af6ab5fSopenharmony_ci            process_patch = run_subprocess_with_beta3(None, patch_test_cmd)
12123af6ab5fSopenharmony_ci            process_patch = subprocess.Popen(patch_test_cmd, stdout=subprocess.PIPE,
12133af6ab5fSopenharmony_ci                stderr=subprocess.PIPE)
12143af6ab5fSopenharmony_ci            stdout_patch, stderr_patch = process_patch.communicate(timeout=runner.args.es2panda_timeout)
12153af6ab5fSopenharmony_ci            if stderr_patch:
12163af6ab5fSopenharmony_ci                self.passed = False
12173af6ab5fSopenharmony_ci                self.error = stderr_patch.decode("utf-8", errors="ignore")
12183af6ab5fSopenharmony_ci            self.output = stdout_patch.decode("utf-8", errors="ignore") + stderr_patch.decode("utf-8", errors="ignore")
12193af6ab5fSopenharmony_ci
12203af6ab5fSopenharmony_ci        expected_path = os.path.join(self.path, 'expected.txt')
12213af6ab5fSopenharmony_ci        try:
12223af6ab5fSopenharmony_ci            with open(expected_path, 'r') as fp:
12233af6ab5fSopenharmony_ci                # ignore license description lines and skip leading blank lines
12243af6ab5fSopenharmony_ci                expected = (''.join((fp.readlines()[12:]))).lstrip()
12253af6ab5fSopenharmony_ci            self.passed = expected == self.output
12263af6ab5fSopenharmony_ci        except Exception:
12273af6ab5fSopenharmony_ci            self.passed = False
12283af6ab5fSopenharmony_ci
12293af6ab5fSopenharmony_ci        if not self.passed:
12303af6ab5fSopenharmony_ci            self.error = "expected output:" + os.linesep + expected + os.linesep + "actual output:" + os.linesep +\
12313af6ab5fSopenharmony_ci                self.output
12323af6ab5fSopenharmony_ci        if not self.preserve_files:
12333af6ab5fSopenharmony_ci            os.remove(symbol_table_file)
12343af6ab5fSopenharmony_ci            os.remove(origin_output_abc)
12353af6ab5fSopenharmony_ci            if (os.path.exists(modified_output_abc)):
12363af6ab5fSopenharmony_ci                os.remove(modified_output_abc)
12373af6ab5fSopenharmony_ci        return self
12383af6ab5fSopenharmony_ci
12393af6ab5fSopenharmony_ci
12403af6ab5fSopenharmony_ciclass PatchRunner(Runner):
12413af6ab5fSopenharmony_ci    def __init__(self, args, name):
12423af6ab5fSopenharmony_ci        Runner.__init__(self, args, name)
12433af6ab5fSopenharmony_ci        self.preserve_files = args.error
12443af6ab5fSopenharmony_ci        self.tests_in_dirs = []
12453af6ab5fSopenharmony_ci        dirs = os.listdir(path.join(self.test_root, "patch"))
12463af6ab5fSopenharmony_ci        for target_version_path in dirs:
12473af6ab5fSopenharmony_ci            self.add_tests(target_version_path, name)
12483af6ab5fSopenharmony_ci
12493af6ab5fSopenharmony_ci    def add_tests(self, target_version_path, name):
12503af6ab5fSopenharmony_ci        name_dir = os.path.join(self.test_root, "patch", target_version_path, name)
12513af6ab5fSopenharmony_ci        if not os.path.exists(name_dir):
12523af6ab5fSopenharmony_ci            return
12533af6ab5fSopenharmony_ci        target_version = 0
12543af6ab5fSopenharmony_ci        if target_version_path.isdigit():
12553af6ab5fSopenharmony_ci            target_version = int(target_version_path)
12563af6ab5fSopenharmony_ci        for sub_path in os.listdir(name_dir):
12573af6ab5fSopenharmony_ci            test_base_path = os.path.join(name_dir, sub_path)
12583af6ab5fSopenharmony_ci            if name != "coldreload":
12593af6ab5fSopenharmony_ci                for test_dir in os.listdir(test_base_path):
12603af6ab5fSopenharmony_ci                    test_path = os.path.join(test_base_path, test_dir)
12613af6ab5fSopenharmony_ci                    self.tests_in_dirs.append(test_path)
12623af6ab5fSopenharmony_ci                    self.tests.append(PatchTest(test_path, name, target_version, self.preserve_files))
12633af6ab5fSopenharmony_ci            else:
12643af6ab5fSopenharmony_ci                self.tests_in_dirs.append(test_base_path)
12653af6ab5fSopenharmony_ci                self.tests.append(PatchTest(test_base_path, name, target_version, self.preserve_files))
12663af6ab5fSopenharmony_ci
12673af6ab5fSopenharmony_ci    def test_path(self, src):
12683af6ab5fSopenharmony_ci        return os.path.basename(src)
12693af6ab5fSopenharmony_ci
12703af6ab5fSopenharmony_ci
12713af6ab5fSopenharmony_ciclass HotfixRunner(PatchRunner):
12723af6ab5fSopenharmony_ci    def __init__(self, args):
12733af6ab5fSopenharmony_ci        PatchRunner.__init__(self, args, "hotfix")
12743af6ab5fSopenharmony_ci
12753af6ab5fSopenharmony_ci
12763af6ab5fSopenharmony_ciclass HotreloadRunner(PatchRunner):
12773af6ab5fSopenharmony_ci    def __init__(self, args):
12783af6ab5fSopenharmony_ci        PatchRunner.__init__(self, args, "hotreload")
12793af6ab5fSopenharmony_ci
12803af6ab5fSopenharmony_ci
12813af6ab5fSopenharmony_ciclass ColdfixRunner(PatchRunner):
12823af6ab5fSopenharmony_ci    def __init__(self, args):
12833af6ab5fSopenharmony_ci        PatchRunner.__init__(self, args, "coldfix")
12843af6ab5fSopenharmony_ci
12853af6ab5fSopenharmony_ci
12863af6ab5fSopenharmony_ciclass ColdreloadRunner(PatchRunner):
12873af6ab5fSopenharmony_ci    def __init__(self, args):
12883af6ab5fSopenharmony_ci        PatchRunner.__init__(self, args, "coldreload")
12893af6ab5fSopenharmony_ci
12903af6ab5fSopenharmony_ci
12913af6ab5fSopenharmony_ciclass DebuggerTest(Test):
12923af6ab5fSopenharmony_ci    def __init__(self, test_path, mode):
12933af6ab5fSopenharmony_ci        Test.__init__(self, test_path, "")
12943af6ab5fSopenharmony_ci        self.mode = mode
12953af6ab5fSopenharmony_ci
12963af6ab5fSopenharmony_ci    def run(self, runner):
12973af6ab5fSopenharmony_ci        cmd = runner.cmd_prefix + [runner.es2panda, "--module"]
12983af6ab5fSopenharmony_ci        input_file_name = 'base.js'
12993af6ab5fSopenharmony_ci        if self.mode == "debug-mode":
13003af6ab5fSopenharmony_ci            cmd.extend(['--debug-info'])
13013af6ab5fSopenharmony_ci        cmd.extend([os.path.join(self.path, input_file_name)])
13023af6ab5fSopenharmony_ci        cmd.extend(['--dump-assembly'])
13033af6ab5fSopenharmony_ci        process = run_subprocess_with_beta3(self, cmd)
13043af6ab5fSopenharmony_ci        stdout, stderr = process.communicate(timeout=runner.args.es2panda_timeout)
13053af6ab5fSopenharmony_ci        if stderr:
13063af6ab5fSopenharmony_ci            self.passed = False
13073af6ab5fSopenharmony_ci            self.error = stderr.decode("utf-8", errors="ignore")
13083af6ab5fSopenharmony_ci            return self
13093af6ab5fSopenharmony_ci
13103af6ab5fSopenharmony_ci        self.output = stdout.decode("utf-8", errors="ignore")
13113af6ab5fSopenharmony_ci
13123af6ab5fSopenharmony_ci        expected_path = os.path.join(self.path, 'expected.txt')
13133af6ab5fSopenharmony_ci        try:
13143af6ab5fSopenharmony_ci            with open(expected_path, 'r') as fp:
13153af6ab5fSopenharmony_ci                expected = (''.join((fp.readlines()[12:]))).lstrip()
13163af6ab5fSopenharmony_ci            self.passed = expected == self.output
13173af6ab5fSopenharmony_ci        except Exception:
13183af6ab5fSopenharmony_ci            self.passed = False
13193af6ab5fSopenharmony_ci
13203af6ab5fSopenharmony_ci        if not self.passed:
13213af6ab5fSopenharmony_ci            self.error = "expected output:" + os.linesep + expected + os.linesep + "actual output:" + os.linesep +\
13223af6ab5fSopenharmony_ci                self.output
13233af6ab5fSopenharmony_ci
13243af6ab5fSopenharmony_ci        if os.path.exists("base.abc"):
13253af6ab5fSopenharmony_ci            os.remove("base.abc")
13263af6ab5fSopenharmony_ci
13273af6ab5fSopenharmony_ci        return self
13283af6ab5fSopenharmony_ci
13293af6ab5fSopenharmony_ci
13303af6ab5fSopenharmony_ciclass DebuggerRunner(Runner):
13313af6ab5fSopenharmony_ci    def __init__(self, args):
13323af6ab5fSopenharmony_ci        Runner.__init__(self, args, "debugger")
13333af6ab5fSopenharmony_ci        self.test_directory = path.join(self.test_root, "debugger")
13343af6ab5fSopenharmony_ci        self.add_test()
13353af6ab5fSopenharmony_ci
13363af6ab5fSopenharmony_ci    def add_test(self):
13373af6ab5fSopenharmony_ci        self.tests = []
13383af6ab5fSopenharmony_ci        self.tests.append(DebuggerTest(os.path.join(self.test_directory, "debugger-in-debug"), "debug-mode"))
13393af6ab5fSopenharmony_ci        self.tests.append(DebuggerTest(os.path.join(self.test_directory, "debugger-in-release"), "release-mode"))
13403af6ab5fSopenharmony_ci
13413af6ab5fSopenharmony_ci
13423af6ab5fSopenharmony_ciclass Base64Test(Test):
13433af6ab5fSopenharmony_ci    def __init__(self, test_path, input_type):
13443af6ab5fSopenharmony_ci        Test.__init__(self, test_path, "")
13453af6ab5fSopenharmony_ci        self.input_type = input_type
13463af6ab5fSopenharmony_ci
13473af6ab5fSopenharmony_ci    def run(self, runner):
13483af6ab5fSopenharmony_ci        cmd = runner.cmd_prefix + [runner.es2panda, "--base64Output"]
13493af6ab5fSopenharmony_ci        if self.input_type == "file":
13503af6ab5fSopenharmony_ci            input_file_name = 'input.js'
13513af6ab5fSopenharmony_ci            cmd.extend(['--source-file', input_file_name])
13523af6ab5fSopenharmony_ci            cmd.extend([os.path.join(self.path, input_file_name)])
13533af6ab5fSopenharmony_ci        elif self.input_type == "string":
13543af6ab5fSopenharmony_ci            input_file = os.path.join(self.path, "input.txt")
13553af6ab5fSopenharmony_ci            try:
13563af6ab5fSopenharmony_ci                with open(input_file, 'r') as fp:
13573af6ab5fSopenharmony_ci                    base64_input = (''.join((fp.readlines()[12:]))).lstrip()  # ignore license description lines
13583af6ab5fSopenharmony_ci                    cmd.extend(["--base64Input", base64_input])
13593af6ab5fSopenharmony_ci            except Exception:
13603af6ab5fSopenharmony_ci                self.passed = False
13613af6ab5fSopenharmony_ci        elif self.input_type == "targetApiVersion":
13623af6ab5fSopenharmony_ci            # base64 test for all available target api version.
13633af6ab5fSopenharmony_ci            version = os.path.basename(self.path)
13643af6ab5fSopenharmony_ci            cmd.extend(['--target-api-version', version])
13653af6ab5fSopenharmony_ci            if version == "12":
13663af6ab5fSopenharmony_ci                cmd.append("--target-api-sub-version=beta3")
13673af6ab5fSopenharmony_ci            input_file = os.path.join(self.path, "input.txt")
13683af6ab5fSopenharmony_ci            try:
13693af6ab5fSopenharmony_ci                with open(input_file, 'r') as fp:
13703af6ab5fSopenharmony_ci                    base64_input = (''.join((fp.readlines()[12:]))).lstrip()  # ignore license description lines
13713af6ab5fSopenharmony_ci                    cmd.extend(["--base64Input", base64_input])
13723af6ab5fSopenharmony_ci            except Exception:
13733af6ab5fSopenharmony_ci                self.passed = False
13743af6ab5fSopenharmony_ci        else:
13753af6ab5fSopenharmony_ci            self.error = "Unsupported base64 input type"
13763af6ab5fSopenharmony_ci            self.passed = False
13773af6ab5fSopenharmony_ci            return self
13783af6ab5fSopenharmony_ci
13793af6ab5fSopenharmony_ci        version = os.path.basename(self.path)
13803af6ab5fSopenharmony_ci        if not self.input_type == "targetApiVersion":
13813af6ab5fSopenharmony_ci            cmd.append("--target-api-sub-version=beta3")
13823af6ab5fSopenharmony_ci
13833af6ab5fSopenharmony_ci        self.log_cmd(cmd)
13843af6ab5fSopenharmony_ci
13853af6ab5fSopenharmony_ci        process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
13863af6ab5fSopenharmony_ci        stdout, stderr = process.communicate(timeout=runner.args.es2panda_timeout)
13873af6ab5fSopenharmony_ci        if stderr:
13883af6ab5fSopenharmony_ci            self.passed = False
13893af6ab5fSopenharmony_ci            self.error = stderr.decode("utf-8", errors="ignore")
13903af6ab5fSopenharmony_ci            return self
13913af6ab5fSopenharmony_ci
13923af6ab5fSopenharmony_ci        self.output = stdout.decode("utf-8", errors="ignore")
13933af6ab5fSopenharmony_ci
13943af6ab5fSopenharmony_ci        expected_path = os.path.join(self.path, 'expected.txt')
13953af6ab5fSopenharmony_ci        try:
13963af6ab5fSopenharmony_ci            with open(expected_path, 'r') as fp:
13973af6ab5fSopenharmony_ci                expected = (''.join((fp.readlines()[12:]))).lstrip()
13983af6ab5fSopenharmony_ci            self.passed = expected == self.output
13993af6ab5fSopenharmony_ci        except Exception:
14003af6ab5fSopenharmony_ci            self.passed = False
14013af6ab5fSopenharmony_ci
14023af6ab5fSopenharmony_ci        if not self.passed:
14033af6ab5fSopenharmony_ci            self.error = "expected output:" + os.linesep + expected + os.linesep + "actual output:" + os.linesep +\
14043af6ab5fSopenharmony_ci                self.output
14053af6ab5fSopenharmony_ci
14063af6ab5fSopenharmony_ci        return self
14073af6ab5fSopenharmony_ci
14083af6ab5fSopenharmony_ci
14093af6ab5fSopenharmony_ciclass Base64Runner(Runner):
14103af6ab5fSopenharmony_ci    def __init__(self, args):
14113af6ab5fSopenharmony_ci        Runner.__init__(self, args, "Base64")
14123af6ab5fSopenharmony_ci        self.test_directory = path.join(self.test_root, "base64")
14133af6ab5fSopenharmony_ci        self.add_test()
14143af6ab5fSopenharmony_ci
14153af6ab5fSopenharmony_ci    def add_test(self):
14163af6ab5fSopenharmony_ci        self.tests = []
14173af6ab5fSopenharmony_ci        self.tests.append(Base64Test(os.path.join(self.test_directory, "inputFile"), "file"))
14183af6ab5fSopenharmony_ci        self.tests.append(Base64Test(os.path.join(self.test_directory, "inputString"), "string"))
14193af6ab5fSopenharmony_ci        # current target api version is 12, once a new version is addded, a new testcase should be added here.
14203af6ab5fSopenharmony_ci        current_version = 12
14213af6ab5fSopenharmony_ci        available_target_api_versions = [9, 10, 11, current_version]
14223af6ab5fSopenharmony_ci        for version in available_target_api_versions:
14233af6ab5fSopenharmony_ci            self.tests.append(Base64Test(os.path.join(self.test_directory, "availableTargetApiVersion", str(version)),
14243af6ab5fSopenharmony_ci                "targetApiVersion"))
14253af6ab5fSopenharmony_ci
14263af6ab5fSopenharmony_ci    def test_path(self, src):
14273af6ab5fSopenharmony_ci        return os.path.basename(src)
14283af6ab5fSopenharmony_ci
14293af6ab5fSopenharmony_ci
14303af6ab5fSopenharmony_ciclass BytecodeRunner(Runner):
14313af6ab5fSopenharmony_ci    def __init__(self, args):
14323af6ab5fSopenharmony_ci        Runner.__init__(self, args, "Bytecode")
14333af6ab5fSopenharmony_ci
14343af6ab5fSopenharmony_ci    def add_directory(self, directory, extension, flags, func=Test):
14353af6ab5fSopenharmony_ci        glob_expression = path.join(
14363af6ab5fSopenharmony_ci            self.test_root, directory, "**/*.%s" % (extension))
14373af6ab5fSopenharmony_ci        files = glob(glob_expression, recursive=True)
14383af6ab5fSopenharmony_ci        files = fnmatch.filter(files, self.test_root + '**' + self.args.filter)
14393af6ab5fSopenharmony_ci        self.tests += list(map(lambda f: func(f, flags), files))
14403af6ab5fSopenharmony_ci
14413af6ab5fSopenharmony_ci    def test_path(self, src):
14423af6ab5fSopenharmony_ci        return src
14433af6ab5fSopenharmony_ci
14443af6ab5fSopenharmony_ci
14453af6ab5fSopenharmony_ciclass ArkJsVmDownload:  # Obtain different versions of ark_js_vm and their dependent libraries
14463af6ab5fSopenharmony_ci    def __init__(self, args):
14473af6ab5fSopenharmony_ci        self.build_dir = args.build_dir
14483af6ab5fSopenharmony_ci        self.url = "https://gitee.com/zhongmingwei123123/ark_js_vm_version.git"
14493af6ab5fSopenharmony_ci        self.local_path = path.join(self.build_dir, "ark_js_vm_version")
14503af6ab5fSopenharmony_ci        self.max_retries = 3
14513af6ab5fSopenharmony_ci
14523af6ab5fSopenharmony_ci    def run_cmd_cwd(self, cmd):
14533af6ab5fSopenharmony_ci        try:
14543af6ab5fSopenharmony_ci            proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
14553af6ab5fSopenharmony_ci            _, _ = proc.communicate()
14563af6ab5fSopenharmony_ci            return proc.wait()
14573af6ab5fSopenharmony_ci        except Exception as e:
14583af6ab5fSopenharmony_ci            print(f"Error executing command: {e}")
14593af6ab5fSopenharmony_ci            return -1
14603af6ab5fSopenharmony_ci
14613af6ab5fSopenharmony_ci    def git_clone(self, git_url, code_dir):
14623af6ab5fSopenharmony_ci        cmd = ["git", "clone", git_url, code_dir]
14633af6ab5fSopenharmony_ci        retries = 1
14643af6ab5fSopenharmony_ci        while retries <= self.max_retries:
14653af6ab5fSopenharmony_ci            ret = self.run_cmd_cwd(cmd)
14663af6ab5fSopenharmony_ci            if ret == 0:
14673af6ab5fSopenharmony_ci                break
14683af6ab5fSopenharmony_ci            else:
14693af6ab5fSopenharmony_ci                print(f"\n warning: Atempt: #{retries} to clone '{git_url}' failed. Try cloining again")
14703af6ab5fSopenharmony_ci                retries += 1
14713af6ab5fSopenharmony_ci        assert not ret, f"\n error: Cloning '{git_url}' failed."
14723af6ab5fSopenharmony_ci
14733af6ab5fSopenharmony_ci    def run(self):
14743af6ab5fSopenharmony_ci        if not os.path.exists(self.local_path):
14753af6ab5fSopenharmony_ci            print("\nstart downLoad ark_js_vm_version ...\n")
14763af6ab5fSopenharmony_ci            self.git_clone(self.url, self.local_path)
14773af6ab5fSopenharmony_ci            print("\ndownload finish.\n")
14783af6ab5fSopenharmony_ci
14793af6ab5fSopenharmony_ci
14803af6ab5fSopenharmony_ciclass AbcTestCasesPrepare:
14813af6ab5fSopenharmony_ci    def __init__(self, args):
14823af6ab5fSopenharmony_ci        self.test_root = path.dirname(path.abspath(__file__))
14833af6ab5fSopenharmony_ci        self.es2panda = path.join(args.build_dir, "es2abc")
14843af6ab5fSopenharmony_ci        self.args = args
14853af6ab5fSopenharmony_ci        self.valid_mode_list = ["non_merge_mode", "merge_mode"]
14863af6ab5fSopenharmony_ci        self.test_abc_path_list = set()
14873af6ab5fSopenharmony_ci
14883af6ab5fSopenharmony_ci    @staticmethod
14893af6ab5fSopenharmony_ci    def split_api_version(version_str):
14903af6ab5fSopenharmony_ci        parts = version_str.split("API")[1].split("beta")
14913af6ab5fSopenharmony_ci        main_part = parts[0]
14923af6ab5fSopenharmony_ci        beta_part = "beta%s" % parts[1] if len(parts) > 1 else ""
14933af6ab5fSopenharmony_ci        return (main_part, beta_part)
14943af6ab5fSopenharmony_ci
14953af6ab5fSopenharmony_ci    def add_abc_directory(self, directory, extension):
14963af6ab5fSopenharmony_ci        test_directory = path.join(self.test_root, directory)
14973af6ab5fSopenharmony_ci        glob_expression = path.join(test_directory, "*.%s" % (extension))
14983af6ab5fSopenharmony_ci        files = glob(glob_expression)
14993af6ab5fSopenharmony_ci        files = fnmatch.filter(files, self.test_root + "**" + self.args.filter)
15003af6ab5fSopenharmony_ci        return files
15013af6ab5fSopenharmony_ci
15023af6ab5fSopenharmony_ci    def gen_abc_versions(self, flags, source_path):
15033af6ab5fSopenharmony_ci        for api_version in API_VERSION_MAP:
15043af6ab5fSopenharmony_ci            main_version, beta_version = AbcTestCasesPrepare.split_api_version(api_version)
15053af6ab5fSopenharmony_ci            output_path = "%s_version_API%s%s.abc" % (
15063af6ab5fSopenharmony_ci                path.splitext(source_path)[0],
15073af6ab5fSopenharmony_ci                main_version,
15083af6ab5fSopenharmony_ci                beta_version,
15093af6ab5fSopenharmony_ci            )
15103af6ab5fSopenharmony_ci            self.test_abc_path_list.add(output_path)
15113af6ab5fSopenharmony_ci            _, stderr = self.compile_for_target_version(flags, source_path, output_path, main_version, beta_version)
15123af6ab5fSopenharmony_ci            if stderr:
15133af6ab5fSopenharmony_ci                raise RuntimeError(f"abc generate error: " % (stderr.decode("utf-8", errors="ignore")))
15143af6ab5fSopenharmony_ci
15153af6ab5fSopenharmony_ci    def gen_abc_tests(self, directory, extension, flags, abc_mode):
15163af6ab5fSopenharmony_ci        if abc_mode not in self.valid_mode_list:
15173af6ab5fSopenharmony_ci            raise ValueError(f"Invalid abc_mode value: {abc_mode}")
15183af6ab5fSopenharmony_ci        test_source_list = self.add_abc_directory(directory, extension)
15193af6ab5fSopenharmony_ci        for input_path in test_source_list:
15203af6ab5fSopenharmony_ci            self.gen_abc_versions(flags, input_path)
15213af6ab5fSopenharmony_ci
15223af6ab5fSopenharmony_ci    def compile_for_target_version(self, flags, input_path, output_path, target_api_version, target_api_sub_version=""):
15233af6ab5fSopenharmony_ci        cmd = []
15243af6ab5fSopenharmony_ci        cmd.append(self.es2panda)
15253af6ab5fSopenharmony_ci        cmd.append(input_path)
15263af6ab5fSopenharmony_ci        cmd.extend(flags)
15273af6ab5fSopenharmony_ci        cmd.append("--target-api-version=%s" % (target_api_version))
15283af6ab5fSopenharmony_ci        cmd.extend(["--output=%s" % (output_path)])
15293af6ab5fSopenharmony_ci        if target_api_version != "":
15303af6ab5fSopenharmony_ci            cmd.append("--target-api-sub-version=%s" % (target_api_sub_version))
15313af6ab5fSopenharmony_ci        process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
15323af6ab5fSopenharmony_ci        stdout, stderr = process.communicate(timeout=10)
15333af6ab5fSopenharmony_ci        if stderr:
15343af6ab5fSopenharmony_ci            stderr = "Error executing command: %s\n%s" % (cmd, stderr)
15353af6ab5fSopenharmony_ci        return stdout, stderr
15363af6ab5fSopenharmony_ci
15373af6ab5fSopenharmony_ci    def remove_abc_tests(self):
15383af6ab5fSopenharmony_ci        for abc_path in self.test_abc_path_list:
15393af6ab5fSopenharmony_ci            if path.exists(abc_path):
15403af6ab5fSopenharmony_ci                os.remove(abc_path)
15413af6ab5fSopenharmony_ci
15423af6ab5fSopenharmony_ci
15433af6ab5fSopenharmony_ciclass AbcVersionControlRunner(Runner):
15443af6ab5fSopenharmony_ci    def __init__(self, args):
15453af6ab5fSopenharmony_ci        super().__init__(args, "AbcVersionControl")
15463af6ab5fSopenharmony_ci        self.valid_mode_list = ["non_merge_mode", "merge_mode", "mix_compile_mode"]
15473af6ab5fSopenharmony_ci
15483af6ab5fSopenharmony_ci    def add_directory(self, directory, extension, flags, abc_mode, is_discard=False):
15493af6ab5fSopenharmony_ci        if abc_mode not in self.valid_mode_list:
15503af6ab5fSopenharmony_ci            raise ValueError(f"Invalid abc_mode value: {abc_mode}")
15513af6ab5fSopenharmony_ci        glob_expression = path.join(self.test_root, directory, "*.%s" % (extension))
15523af6ab5fSopenharmony_ci        files = glob(glob_expression)
15533af6ab5fSopenharmony_ci        files = fnmatch.filter(files, self.test_root + "**" + self.args.filter)
15543af6ab5fSopenharmony_ci        if abc_mode == "mix_compile_mode":
15553af6ab5fSopenharmony_ci            files = [f for f in files if not f.endswith("-expected.txt")]
15563af6ab5fSopenharmony_ci        self.tests += list(map(lambda f: TestAbcVersionControl(f, flags, abc_mode, is_discard), files))
15573af6ab5fSopenharmony_ci
15583af6ab5fSopenharmony_ci    def test_path(self, src):
15593af6ab5fSopenharmony_ci        return src
15603af6ab5fSopenharmony_ci
15613af6ab5fSopenharmony_ci    def run(self):
15623af6ab5fSopenharmony_ci        for test in self.tests:
15633af6ab5fSopenharmony_ci            test.run(self)
15643af6ab5fSopenharmony_ci        self.args.abc_tests_prepare.remove_abc_tests()
15653af6ab5fSopenharmony_ci
15663af6ab5fSopenharmony_ci
15673af6ab5fSopenharmony_ciclass VersionControlRunner(Runner):
15683af6ab5fSopenharmony_ci    def __init__(self, args):
15693af6ab5fSopenharmony_ci        Runner.__init__(self, args, "VersionControl")
15703af6ab5fSopenharmony_ci
15713af6ab5fSopenharmony_ci    def add_directory(self, directory, extension, flags, test_version, feature_type, module_dir=None, func=Test):
15723af6ab5fSopenharmony_ci        glob_expression = path.join(self.test_root, directory, "*.%s" % (extension))
15733af6ab5fSopenharmony_ci        files = glob(glob_expression)
15743af6ab5fSopenharmony_ci        files = fnmatch.filter(files, self.test_root + "**" + self.args.filter)
15753af6ab5fSopenharmony_ci        module_path_list = []
15763af6ab5fSopenharmony_ci        if module_dir is not None:
15773af6ab5fSopenharmony_ci            module_path_list = self.add_module_path(module_dir)
15783af6ab5fSopenharmony_ci        self.tests += list(
15793af6ab5fSopenharmony_ci            map(lambda f: TestVersionControl(f, flags, test_version, feature_type, module_path_list), files)
15803af6ab5fSopenharmony_ci        )
15813af6ab5fSopenharmony_ci
15823af6ab5fSopenharmony_ci    def add_module_path(self, module_dir):
15833af6ab5fSopenharmony_ci        module_path_list = []
15843af6ab5fSopenharmony_ci        glob_expression_ts = path.join(self.test_root, module_dir, "*.%s" % ("ts"))
15853af6ab5fSopenharmony_ci        glob_expression_js = path.join(self.test_root, module_dir, "*.%s" % ("js"))
15863af6ab5fSopenharmony_ci        module_path_list = glob(glob_expression_ts)
15873af6ab5fSopenharmony_ci        module_path_list.extend(glob(glob_expression_js))
15883af6ab5fSopenharmony_ci        module_path_list = fnmatch.filter(module_path_list, self.test_root + "**" + self.args.filter)
15893af6ab5fSopenharmony_ci        return module_path_list
15903af6ab5fSopenharmony_ci
15913af6ab5fSopenharmony_ci    def test_path(self, src):
15923af6ab5fSopenharmony_ci        return src
15933af6ab5fSopenharmony_ci
15943af6ab5fSopenharmony_ci    def run(self):
15953af6ab5fSopenharmony_ci        for test in self.tests:
15963af6ab5fSopenharmony_ci            test.run(self)
15973af6ab5fSopenharmony_ci
15983af6ab5fSopenharmony_ci
15993af6ab5fSopenharmony_ciclass TestAbcVersionControl(Test):
16003af6ab5fSopenharmony_ci    def __init__(self, test_path, flags, abc_mode, is_discard):
16013af6ab5fSopenharmony_ci        super().__init__(test_path, flags)
16023af6ab5fSopenharmony_ci        self.min_support_version_number = API_VERSION_MAP.get(MIN_SUPPORT_BC_VERSION)
16033af6ab5fSopenharmony_ci        self.abc_mode = abc_mode
16043af6ab5fSopenharmony_ci        self.is_discard = is_discard
16053af6ab5fSopenharmony_ci        self.output = None
16063af6ab5fSopenharmony_ci        self.process = None
16073af6ab5fSopenharmony_ci        self.is_support = False
16083af6ab5fSopenharmony_ci        self.test_abc_list = list()
16093af6ab5fSopenharmony_ci        self.test_input = None
16103af6ab5fSopenharmony_ci        self.target_abc_path = None
16113af6ab5fSopenharmony_ci        self.entry_point = self.get_entry_point()
16123af6ab5fSopenharmony_ci
16133af6ab5fSopenharmony_ci    @staticmethod
16143af6ab5fSopenharmony_ci    def compare_version_number(version1, version2):
16153af6ab5fSopenharmony_ci        v1 = TestAbcVersionControl.version_number_to_tuple(version1)
16163af6ab5fSopenharmony_ci        v2 = TestAbcVersionControl.version_number_to_tuple(version2)
16173af6ab5fSopenharmony_ci        for num1, num2 in zip(v1, v2):
16183af6ab5fSopenharmony_ci            if num1 > num2:
16193af6ab5fSopenharmony_ci                return 1
16203af6ab5fSopenharmony_ci            elif num1 < num2:
16213af6ab5fSopenharmony_ci                return -1
16223af6ab5fSopenharmony_ci        return 0
16233af6ab5fSopenharmony_ci
16243af6ab5fSopenharmony_ci    @staticmethod
16253af6ab5fSopenharmony_ci    def version_number_to_tuple(version):
16263af6ab5fSopenharmony_ci        return tuple(int(part) for part in version.split("."))
16273af6ab5fSopenharmony_ci
16283af6ab5fSopenharmony_ci    def get_entry_point(self):
16293af6ab5fSopenharmony_ci        if self.abc_mode == "merge_mode":
16303af6ab5fSopenharmony_ci            base_name = os.path.basename(self.path)
16313af6ab5fSopenharmony_ci            return os.path.splitext(base_name)[0]
16323af6ab5fSopenharmony_ci        elif self.abc_mode == "mix_compile_mode":
16333af6ab5fSopenharmony_ci            return MIX_COMPILE_ENTRY_POINT
16343af6ab5fSopenharmony_ci        return ""
16353af6ab5fSopenharmony_ci
16363af6ab5fSopenharmony_ci    def get_path_to_expected(self, is_support=False, test_stage=""):
16373af6ab5fSopenharmony_ci        support_name = "supported_" if is_support else "unsupported_"
16383af6ab5fSopenharmony_ci        if self.abc_mode == "mix_compile_mode" and test_stage != "runtime":
16393af6ab5fSopenharmony_ci            support_name = ""
16403af6ab5fSopenharmony_ci        expected_name = path.splitext(self.path)[0].split("_version_API")[0]
16413af6ab5fSopenharmony_ci        expected_path = "%s_%s%s-expected.txt" % (expected_name, support_name, test_stage)
16423af6ab5fSopenharmony_ci        return expected_path
16433af6ab5fSopenharmony_ci
16443af6ab5fSopenharmony_ci    def run_process(self, cmd):
16453af6ab5fSopenharmony_ci        self.process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
16463af6ab5fSopenharmony_ci        stdout, stderr = self.process.communicate(timeout=10)
16473af6ab5fSopenharmony_ci        self.output = stdout.decode("utf-8", errors="ignore") + stderr.decode("utf-8", errors="ignore").split("\n")[0]
16483af6ab5fSopenharmony_ci        if stderr:
16493af6ab5fSopenharmony_ci            stderr = "Error executing command: %s\n%s" % (cmd, stderr)
16503af6ab5fSopenharmony_ci        return stdout, stderr
16513af6ab5fSopenharmony_ci
16523af6ab5fSopenharmony_ci    def compile_for_target_version(
16533af6ab5fSopenharmony_ci        self, runner, input_path, output_path, target_api_version, target_api_sub_version=""
16543af6ab5fSopenharmony_ci    ):
16553af6ab5fSopenharmony_ci        cmd = []
16563af6ab5fSopenharmony_ci        cmd.append(runner.es2panda)
16573af6ab5fSopenharmony_ci        if self.abc_mode == "mix_compile_mode":
16583af6ab5fSopenharmony_ci            input_path = "@%s" % (input_path)
16593af6ab5fSopenharmony_ci        cmd.append(input_path)
16603af6ab5fSopenharmony_ci        cmd.extend(self.flags)
16613af6ab5fSopenharmony_ci        cmd.append("--target-api-version=%s" % (target_api_version))
16623af6ab5fSopenharmony_ci        cmd.extend(["--output=%s" % (output_path)])
16633af6ab5fSopenharmony_ci        if target_api_version != "":
16643af6ab5fSopenharmony_ci            cmd.append("--target-api-sub-version=%s" % (target_api_sub_version))
16653af6ab5fSopenharmony_ci        stdout, stderr = self.run_process(cmd)
16663af6ab5fSopenharmony_ci        return stdout, stderr
16673af6ab5fSopenharmony_ci
16683af6ab5fSopenharmony_ci    def generate_abc(self, runner, target_api_version, target_api_sub_version=""):
16693af6ab5fSopenharmony_ci        compile_expected_path = None
16703af6ab5fSopenharmony_ci        target_abc_name = (
16713af6ab5fSopenharmony_ci            "%s_target_%s%s.abc" % (path.splitext(self.path)[0], target_api_version, target_api_sub_version)
16723af6ab5fSopenharmony_ci        ).replace("/", "_")
16733af6ab5fSopenharmony_ci        self.target_abc_path = path.join(runner.build_dir, target_abc_name)
16743af6ab5fSopenharmony_ci        _, stderr = self.compile_for_target_version(
16753af6ab5fSopenharmony_ci            runner, self.path, self.target_abc_path, target_api_version, target_api_sub_version
16763af6ab5fSopenharmony_ci        )
16773af6ab5fSopenharmony_ci        format_content = ""
16783af6ab5fSopenharmony_ci        self.is_support = False
16793af6ab5fSopenharmony_ci
16803af6ab5fSopenharmony_ci        # Extract the API versions of the input abc files from the file name of the test case.
16813af6ab5fSopenharmony_ci        input_api_versions = self.extract_api_versions(path.split(self.path)[1])
16823af6ab5fSopenharmony_ci        input_version_numbers = [API_VERSION_MAP.get(api) for api in input_api_versions]
16833af6ab5fSopenharmony_ci        sorted(input_version_numbers, key=TestAbcVersionControl.version_number_to_tuple)
16843af6ab5fSopenharmony_ci        min_input_version_number = input_version_numbers[0]
16853af6ab5fSopenharmony_ci        max_input_version_number = input_version_numbers[-1]
16863af6ab5fSopenharmony_ci        target_version = "API" + target_api_version + target_api_sub_version
16873af6ab5fSopenharmony_ci        target_version_number = API_VERSION_MAP.get(target_version)
16883af6ab5fSopenharmony_ci
16893af6ab5fSopenharmony_ci        if TestAbcVersionControl.compare_version_number(target_version_number, self.min_support_version_number) < 0:
16903af6ab5fSopenharmony_ci            compile_expected_path = self.get_path_to_expected(
16913af6ab5fSopenharmony_ci                self.is_support, "compile_target_version_below_min_support"
16923af6ab5fSopenharmony_ci            )
16933af6ab5fSopenharmony_ci            format_content = target_api_version
16943af6ab5fSopenharmony_ci        elif (
16953af6ab5fSopenharmony_ci            TestAbcVersionControl.compare_version_number(min_input_version_number, self.min_support_version_number) < 0
16963af6ab5fSopenharmony_ci        ):
16973af6ab5fSopenharmony_ci            compile_expected_path = self.get_path_to_expected(self.is_support, "compile_cur_version_below_min_support")
16983af6ab5fSopenharmony_ci            format_content = self.path
16993af6ab5fSopenharmony_ci        elif TestAbcVersionControl.compare_version_number(target_version_number, max_input_version_number) < 0:
17003af6ab5fSopenharmony_ci            compile_expected_path = self.get_path_to_expected(self.is_support, "compile_target_version_below_cur")
17013af6ab5fSopenharmony_ci            format_content = self.path
17023af6ab5fSopenharmony_ci        elif self.is_discard:
17033af6ab5fSopenharmony_ci            compile_expected_path = self.get_path_to_expected(self.is_support, "compile_discard")
17043af6ab5fSopenharmony_ci        else:
17053af6ab5fSopenharmony_ci            self.is_support = True
17063af6ab5fSopenharmony_ci            if stderr:
17073af6ab5fSopenharmony_ci                self.passed = False
17083af6ab5fSopenharmony_ci            return stderr
17093af6ab5fSopenharmony_ci
17103af6ab5fSopenharmony_ci        try:
17113af6ab5fSopenharmony_ci            with open(compile_expected_path, "r") as fp:
17123af6ab5fSopenharmony_ci                expected = fp.read()
17133af6ab5fSopenharmony_ci                self.passed = expected.format(format_content) in self.output and self.process.returncode in [0, 1]
17143af6ab5fSopenharmony_ci        except Exception:
17153af6ab5fSopenharmony_ci            self.passed = False
17163af6ab5fSopenharmony_ci        return stderr
17173af6ab5fSopenharmony_ci
17183af6ab5fSopenharmony_ci    def execute_abc(self, runner, vm_api_version, vm_api_sub_version="", entry_point=""):
17193af6ab5fSopenharmony_ci        cmd = []
17203af6ab5fSopenharmony_ci        if vm_api_version != "12":
17213af6ab5fSopenharmony_ci            vm_api_sub_version = ""
17223af6ab5fSopenharmony_ci        # there is no virtual machine with version api12beta2 available.
17233af6ab5fSopenharmony_ci        # chosen api12beta1 as a replacement.
17243af6ab5fSopenharmony_ci        elif vm_api_version == "12" and vm_api_sub_version == "beta2":
17253af6ab5fSopenharmony_ci            vm_api_sub_version = "beta1"
17263af6ab5fSopenharmony_ci        ark_js_vm_dir = os.path.join(
17273af6ab5fSopenharmony_ci            runner.build_dir,
17283af6ab5fSopenharmony_ci            "ark_js_vm_version",
17293af6ab5fSopenharmony_ci            "API%s%s" % (vm_api_version, vm_api_sub_version),
17303af6ab5fSopenharmony_ci        )
17313af6ab5fSopenharmony_ci        ld_library_path = os.path.join(ark_js_vm_dir, "lib")
17323af6ab5fSopenharmony_ci        os.environ["LD_LIBRARY_PATH"] = ld_library_path
17333af6ab5fSopenharmony_ci        ark_js_vm_path = os.path.join(ark_js_vm_dir, "ark_js_vm")
17343af6ab5fSopenharmony_ci        cmd.append(ark_js_vm_path)
17353af6ab5fSopenharmony_ci        if entry_point != "":
17363af6ab5fSopenharmony_ci            cmd.append("--entry-point=%s" % entry_point)
17373af6ab5fSopenharmony_ci        cmd.append(self.target_abc_path)
17383af6ab5fSopenharmony_ci        stdout, stderr = self.run_process(cmd)
17393af6ab5fSopenharmony_ci        return stdout, stderr
17403af6ab5fSopenharmony_ci
17413af6ab5fSopenharmony_ci    def test_abc_execution(self, runner, target_api_version, target_api_sub_version=""):
17423af6ab5fSopenharmony_ci        stderr = None
17433af6ab5fSopenharmony_ci        target_version = "API" + target_api_version + target_api_sub_version
17443af6ab5fSopenharmony_ci        target_version_number = API_VERSION_MAP.get(target_version)
17453af6ab5fSopenharmony_ci        for api_version in API_VERSION_MAP:
17463af6ab5fSopenharmony_ci            vm_api_version, vm_api_sub_version = AbcTestCasesPrepare.split_api_version(api_version)
17473af6ab5fSopenharmony_ci            vm_version = "API" + vm_api_version + vm_api_sub_version
17483af6ab5fSopenharmony_ci            vm_version_number = API_VERSION_MAP.get(vm_version)
17493af6ab5fSopenharmony_ci            _, stderr = self.execute_abc(runner, vm_api_version, vm_api_sub_version, self.entry_point)
17503af6ab5fSopenharmony_ci            self.is_support = (
17513af6ab5fSopenharmony_ci                TestAbcVersionControl.compare_version_number(vm_version_number, target_version_number) >= 0
17523af6ab5fSopenharmony_ci            )
17533af6ab5fSopenharmony_ci            runtime_expect_path = self.get_path_to_expected(self.is_support, "runtime")
17543af6ab5fSopenharmony_ci            try:
17553af6ab5fSopenharmony_ci                with open(runtime_expect_path, "r") as fp:
17563af6ab5fSopenharmony_ci                    expected = fp.read()
17573af6ab5fSopenharmony_ci                    if self.is_support and self.abc_mode != "merge_mode":
17583af6ab5fSopenharmony_ci                        self.passed = expected == self.output and self.process.returncode in [0, 1, 255]
17593af6ab5fSopenharmony_ci                    else:
17603af6ab5fSopenharmony_ci                        self.passed = expected in self.output
17613af6ab5fSopenharmony_ci                    pass
17623af6ab5fSopenharmony_ci            except Exception:
17633af6ab5fSopenharmony_ci                self.passed = False
17643af6ab5fSopenharmony_ci            if not self.passed:
17653af6ab5fSopenharmony_ci                return stderr
17663af6ab5fSopenharmony_ci        return stderr
17673af6ab5fSopenharmony_ci
17683af6ab5fSopenharmony_ci    def extract_api_versions(self, file_name):
17693af6ab5fSopenharmony_ci        pattern = r"(API\d+)(beta\d+)?"
17703af6ab5fSopenharmony_ci        matches = re.findall(pattern, file_name)
17713af6ab5fSopenharmony_ci        api_versions = [f"{api}{f'{beta}' if beta else ''}" for api, beta in matches]
17723af6ab5fSopenharmony_ci        return api_versions
17733af6ab5fSopenharmony_ci
17743af6ab5fSopenharmony_ci    def remove_abc(self, abc_path):
17753af6ab5fSopenharmony_ci        if path.exists(abc_path):
17763af6ab5fSopenharmony_ci            os.remove(abc_path)
17773af6ab5fSopenharmony_ci
17783af6ab5fSopenharmony_ci    def run(self, runner):
17793af6ab5fSopenharmony_ci        for api_version in API_VERSION_MAP:
17803af6ab5fSopenharmony_ci            target_api_version, target_api_sub_version = AbcTestCasesPrepare.split_api_version(api_version)
17813af6ab5fSopenharmony_ci            stderr = self.generate_abc(runner, target_api_version, target_api_sub_version)
17823af6ab5fSopenharmony_ci            if not self.passed:
17833af6ab5fSopenharmony_ci                self.error = stderr.decode("utf-8", errors="ignore")
17843af6ab5fSopenharmony_ci                return self
17853af6ab5fSopenharmony_ci            if stderr:
17863af6ab5fSopenharmony_ci                continue
17873af6ab5fSopenharmony_ci            stderr = self.test_abc_execution(runner, target_api_version, target_api_sub_version)
17883af6ab5fSopenharmony_ci            self.remove_abc(self.target_abc_path)
17893af6ab5fSopenharmony_ci            if not self.passed:
17903af6ab5fSopenharmony_ci                self.error = stderr.decode("utf-8", errors="ignore")
17913af6ab5fSopenharmony_ci                return self
17923af6ab5fSopenharmony_ci        return self
17933af6ab5fSopenharmony_ci
17943af6ab5fSopenharmony_ci
17953af6ab5fSopenharmony_ciclass TestVersionControl(Test):
17963af6ab5fSopenharmony_ci    def __init__(self, test_path, flags, test_version, feature_type, module_path_list):
17973af6ab5fSopenharmony_ci        Test.__init__(self, test_path, flags)
17983af6ab5fSopenharmony_ci        self.beta_version_default = 3
17993af6ab5fSopenharmony_ci        self.version_with_sub_version_list = [12]
18003af6ab5fSopenharmony_ci        self.target_api_version_list = ["9", "10", "11", "12"]
18013af6ab5fSopenharmony_ci        self.target_api_sub_version_list = ["beta1", "beta2", "beta3"]
18023af6ab5fSopenharmony_ci        self.specific_api_version_list = ["API11", "API12beta3"]
18033af6ab5fSopenharmony_ci        self.output = None
18043af6ab5fSopenharmony_ci        self.process = None
18053af6ab5fSopenharmony_ci        self.test_version = test_version
18063af6ab5fSopenharmony_ci        self.test_abc_path = None
18073af6ab5fSopenharmony_ci        self.feature_type = feature_type
18083af6ab5fSopenharmony_ci        self.module_path_list = module_path_list
18093af6ab5fSopenharmony_ci        self.module_abc_path_set = set()
18103af6ab5fSopenharmony_ci
18113af6ab5fSopenharmony_ci    def split_version(self, version_str):
18123af6ab5fSopenharmony_ci        parts = version_str.split("API")[1].split("beta")
18133af6ab5fSopenharmony_ci        main_part = int(parts[0])
18143af6ab5fSopenharmony_ci        beta_part = int(parts[1]) if len(parts) > 1 else self.beta_version_default
18153af6ab5fSopenharmony_ci        return (main_part, beta_part)
18163af6ab5fSopenharmony_ci
18173af6ab5fSopenharmony_ci    def compare_two_versions(self, version1, version2):
18183af6ab5fSopenharmony_ci        version1_parsed = self.split_version(version1)
18193af6ab5fSopenharmony_ci        version2_parsed = self.split_version(version2)
18203af6ab5fSopenharmony_ci
18213af6ab5fSopenharmony_ci        if version1_parsed < version2_parsed:
18223af6ab5fSopenharmony_ci            return -1
18233af6ab5fSopenharmony_ci        elif version1_parsed > version2_parsed:
18243af6ab5fSopenharmony_ci            return 1
18253af6ab5fSopenharmony_ci        else:
18263af6ab5fSopenharmony_ci            return 0
18273af6ab5fSopenharmony_ci
18283af6ab5fSopenharmony_ci    def get_relative_path(self, from_dir, to_dir):
18293af6ab5fSopenharmony_ci        from_dir = os.path.normpath(from_dir)
18303af6ab5fSopenharmony_ci        to_dir = os.path.normpath(to_dir)
18313af6ab5fSopenharmony_ci        from_dir = os.path.abspath(from_dir)
18323af6ab5fSopenharmony_ci        to_dir = os.path.abspath(to_dir)
18333af6ab5fSopenharmony_ci        from_parts = from_dir.split(os.sep)
18343af6ab5fSopenharmony_ci        to_parts = to_dir.split(os.sep)
18353af6ab5fSopenharmony_ci        common_prefix_length = 0
18363af6ab5fSopenharmony_ci        for part1, part2 in zip(from_parts, to_parts):
18373af6ab5fSopenharmony_ci            if part1 == part2:
18383af6ab5fSopenharmony_ci                common_prefix_length += 1
18393af6ab5fSopenharmony_ci            else:
18403af6ab5fSopenharmony_ci                break
18413af6ab5fSopenharmony_ci        relative_parts = [".."] * (len(from_parts) - common_prefix_length) + to_parts[common_prefix_length:]
18423af6ab5fSopenharmony_ci        relative_path = os.path.join(*relative_parts)
18433af6ab5fSopenharmony_ci        return relative_path
18443af6ab5fSopenharmony_ci
18453af6ab5fSopenharmony_ci    def generate_single_module_abc(self, runner, module_path, target_version):
18463af6ab5fSopenharmony_ci        cmd = []
18473af6ab5fSopenharmony_ci        cmd.append(runner.es2panda)
18483af6ab5fSopenharmony_ci        cmd.append(module_path)
18493af6ab5fSopenharmony_ci        cmd.append("--module")
18503af6ab5fSopenharmony_ci        main_version, sub_version = self.split_version(target_version)
18513af6ab5fSopenharmony_ci        cmd.append("--target-api-version=%s" % (main_version))
18523af6ab5fSopenharmony_ci        if main_version == 12:
18533af6ab5fSopenharmony_ci            cmd.append("--target-api-sub-version=beta%s" % (sub_version))
18543af6ab5fSopenharmony_ci
18553af6ab5fSopenharmony_ci        basename = os.path.basename(module_path)
18563af6ab5fSopenharmony_ci        module_abc_name = "%s.abc" % (path.splitext(basename)[0])
18573af6ab5fSopenharmony_ci        relative_path = self.get_relative_path(path.split(self.path)[0], path.split(module_path)[0])
18583af6ab5fSopenharmony_ci        module_abc_dir = path.join(runner.build_dir, relative_path)
18593af6ab5fSopenharmony_ci        if not os.path.exists(module_abc_dir):
18603af6ab5fSopenharmony_ci            os.makedirs(module_abc_dir)
18613af6ab5fSopenharmony_ci        module_abc_path = path.join(module_abc_dir, module_abc_name)
18623af6ab5fSopenharmony_ci        self.module_abc_path_set.add(module_abc_path)
18633af6ab5fSopenharmony_ci        cmd.extend(["--output=%s" % (module_abc_path)])
18643af6ab5fSopenharmony_ci
18653af6ab5fSopenharmony_ci        self.process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
18663af6ab5fSopenharmony_ci        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
18673af6ab5fSopenharmony_ci        _, stderr = proc.communicate()
18683af6ab5fSopenharmony_ci        proc.wait()
18693af6ab5fSopenharmony_ci        if stderr:
18703af6ab5fSopenharmony_ci            print(stderr.decode("utf-8", errors="ignore"))
18713af6ab5fSopenharmony_ci
18723af6ab5fSopenharmony_ci    def generate_module_abc(self, runner, target_version):
18733af6ab5fSopenharmony_ci        for module_path in self.module_path_list:
18743af6ab5fSopenharmony_ci            self.generate_single_module_abc(runner, module_path, target_version)
18753af6ab5fSopenharmony_ci
18763af6ab5fSopenharmony_ci    def remove_module_abc(self):
18773af6ab5fSopenharmony_ci        for module_abc_path in self.module_abc_path_set:
18783af6ab5fSopenharmony_ci            if path.exists(module_abc_path):
18793af6ab5fSopenharmony_ci                os.remove(module_abc_path)
18803af6ab5fSopenharmony_ci
18813af6ab5fSopenharmony_ci    def get_path_to_expected(
18823af6ab5fSopenharmony_ci        self, is_support, expected_stage, target_api_version="", specific_api_version="", dump_type=""
18833af6ab5fSopenharmony_ci    ):
18843af6ab5fSopenharmony_ci        support_name = "supported" if is_support else "unsupported"
18853af6ab5fSopenharmony_ci        api_name = ""
18863af6ab5fSopenharmony_ci        # Higher than the specific API version, expected results may differ
18873af6ab5fSopenharmony_ci        if target_api_version != "" and specific_api_version != "":
18883af6ab5fSopenharmony_ci            if self.compare_two_versions(target_api_version, specific_api_version) >= 0:
18893af6ab5fSopenharmony_ci                api_name = "for_higher_or_equal_to_%s_" % (specific_api_version)
18903af6ab5fSopenharmony_ci            else:
18913af6ab5fSopenharmony_ci                api_name = "for_below_%s_" % (specific_api_version)
18923af6ab5fSopenharmony_ci        if dump_type == "ast":
18933af6ab5fSopenharmony_ci            dump_type = ""
18943af6ab5fSopenharmony_ci        elif dump_type == "asm":
18953af6ab5fSopenharmony_ci            dump_type = "asm_"
18963af6ab5fSopenharmony_ci        expected_path = "%s_%s_%s_%s%sversion-expected.txt" % (
18973af6ab5fSopenharmony_ci            path.splitext(self.path)[0],
18983af6ab5fSopenharmony_ci            support_name,
18993af6ab5fSopenharmony_ci            expected_stage,
19003af6ab5fSopenharmony_ci            api_name,
19013af6ab5fSopenharmony_ci            dump_type,
19023af6ab5fSopenharmony_ci        )
19033af6ab5fSopenharmony_ci        return expected_path
19043af6ab5fSopenharmony_ci
19053af6ab5fSopenharmony_ci    def get_path_to_runtime_output_below_version_expected(self):
19063af6ab5fSopenharmony_ci        expected_path = "%s_runtime_below_abc_api_version-expected.txt" % (
19073af6ab5fSopenharmony_ci            path.splitext(self.path)[0])
19083af6ab5fSopenharmony_ci        return expected_path
19093af6ab5fSopenharmony_ci
19103af6ab5fSopenharmony_ci    def get_path_to_runtime_output_expected(self, is_support, target_api_version, is_below_abc_api_version):
19113af6ab5fSopenharmony_ci        path_expected = None
19123af6ab5fSopenharmony_ci        if is_below_abc_api_version:
19133af6ab5fSopenharmony_ci            path_expected = self.get_path_to_runtime_output_below_version_expected()
19143af6ab5fSopenharmony_ci            return path_expected
19153af6ab5fSopenharmony_ci        for specific_api_version in self.specific_api_version_list:
19163af6ab5fSopenharmony_ci            if self.compare_two_versions(target_api_version, specific_api_version) > 0:
19173af6ab5fSopenharmony_ci                continue
19183af6ab5fSopenharmony_ci            path_expected = self.get_path_to_expected(is_support, "runtime", target_api_version, specific_api_version)
19193af6ab5fSopenharmony_ci            if path.exists(path_expected):
19203af6ab5fSopenharmony_ci                return path_expected
19213af6ab5fSopenharmony_ci        return self.get_path_to_expected(is_support, "runtime", target_api_version)
19223af6ab5fSopenharmony_ci
19233af6ab5fSopenharmony_ci    def get_path_to_compile_ast_output_expected(self, is_support):
19243af6ab5fSopenharmony_ci        return self.get_path_to_expected(is_support, "compile")
19253af6ab5fSopenharmony_ci
19263af6ab5fSopenharmony_ci    def get_path_to_compile_asm_output_expected(self, is_support, target_api_version):
19273af6ab5fSopenharmony_ci        path_expected = None
19283af6ab5fSopenharmony_ci        for specific_api_version in self.specific_api_version_list:
19293af6ab5fSopenharmony_ci            if self.compare_two_versions(target_api_version, specific_api_version) > 0:
19303af6ab5fSopenharmony_ci                continue
19313af6ab5fSopenharmony_ci            path_expected = self.get_path_to_expected(
19323af6ab5fSopenharmony_ci                is_support, "compile", target_api_version, specific_api_version, "asm"
19333af6ab5fSopenharmony_ci            )
19343af6ab5fSopenharmony_ci            if path.exists(path_expected):
19353af6ab5fSopenharmony_ci                return path_expected
19363af6ab5fSopenharmony_ci        return self.get_path_to_expected(is_support, "compile", "", "", "asm")
19373af6ab5fSopenharmony_ci
19383af6ab5fSopenharmony_ci    def run_process(self, cmd):
19393af6ab5fSopenharmony_ci        self.process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
19403af6ab5fSopenharmony_ci        stdout, stderr = self.process.communicate()
19413af6ab5fSopenharmony_ci        self.output = stdout.decode("utf-8", errors="ignore") + stderr.decode("utf-8", errors="ignore").split("\n")[0]
19423af6ab5fSopenharmony_ci        return stdout, stderr
19433af6ab5fSopenharmony_ci
19443af6ab5fSopenharmony_ci    def run_process_compile(self, runner, target_api_version, target_api_sub_version="bata3", dump_type=""):
19453af6ab5fSopenharmony_ci        cmd = []
19463af6ab5fSopenharmony_ci        cmd.append(runner.es2panda)
19473af6ab5fSopenharmony_ci        cmd.append(self.path)
19483af6ab5fSopenharmony_ci        cmd.extend(self.flags)
19493af6ab5fSopenharmony_ci        cmd.append("--target-api-version=%s" % (target_api_version))
19503af6ab5fSopenharmony_ci        test_abc_name = ("%s.abc" % (path.splitext(self.path)[0])).replace("/", "_")
19513af6ab5fSopenharmony_ci        self.test_abc_path = path.join(runner.build_dir, test_abc_name)
19523af6ab5fSopenharmony_ci        cmd.extend(["--output=%s" % (self.test_abc_path)])
19533af6ab5fSopenharmony_ci        if target_api_version == "12":
19543af6ab5fSopenharmony_ci            cmd.append("--target-api-sub-version=%s" % (target_api_sub_version))
19553af6ab5fSopenharmony_ci        if dump_type == "ast":
19563af6ab5fSopenharmony_ci            cmd.append("--dump-ast")
19573af6ab5fSopenharmony_ci        elif dump_type == "assembly":
19583af6ab5fSopenharmony_ci            cmd.append("--dump-assembly")
19593af6ab5fSopenharmony_ci        stdout, stderr = self.run_process(cmd)
19603af6ab5fSopenharmony_ci        return stdout, stderr
19613af6ab5fSopenharmony_ci
19623af6ab5fSopenharmony_ci    def generate_ast_of_target_version(self, runner, target_api_version, target_api_sub_version="bata3"):
19633af6ab5fSopenharmony_ci        return self.run_process_compile(runner, target_api_version, target_api_sub_version, dump_type="ast")
19643af6ab5fSopenharmony_ci
19653af6ab5fSopenharmony_ci    def generate_asm_of_target_version(self, runner, target_api_version, target_api_sub_version="bata3"):
19663af6ab5fSopenharmony_ci        return self.run_process_compile(runner, target_api_version, target_api_sub_version, dump_type="assembly")
19673af6ab5fSopenharmony_ci
19683af6ab5fSopenharmony_ci    def runtime_for_target_version(self, runner, target_api_version, target_api_sub_version="bata3"):
19693af6ab5fSopenharmony_ci        cmd = []
19703af6ab5fSopenharmony_ci        if target_api_version != "12":
19713af6ab5fSopenharmony_ci            target_api_sub_version = ""
19723af6ab5fSopenharmony_ci        # there is no virtual machine with version api12beta2 available.
19733af6ab5fSopenharmony_ci        # We have chosen api12beta1 as a replacement.
19743af6ab5fSopenharmony_ci        if target_api_version == "12" and target_api_sub_version == "beta2":
19753af6ab5fSopenharmony_ci            target_api_sub_version = "beta1"
19763af6ab5fSopenharmony_ci        ark_js_vm_dir = os.path.join(
19773af6ab5fSopenharmony_ci            runner.build_dir,
19783af6ab5fSopenharmony_ci            "ark_js_vm_version",
19793af6ab5fSopenharmony_ci            "API%s%s" % (target_api_version, target_api_sub_version),
19803af6ab5fSopenharmony_ci        )
19813af6ab5fSopenharmony_ci        ld_library_path = os.path.join(ark_js_vm_dir, "lib")
19823af6ab5fSopenharmony_ci        os.environ["LD_LIBRARY_PATH"] = ld_library_path
19833af6ab5fSopenharmony_ci        ark_js_vm_path = os.path.join(ark_js_vm_dir, "ark_js_vm")
19843af6ab5fSopenharmony_ci        cmd.append(ark_js_vm_path)
19853af6ab5fSopenharmony_ci        cmd.append(self.test_abc_path)
19863af6ab5fSopenharmony_ci        self.process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
19873af6ab5fSopenharmony_ci        stdout, stderr = self.process.communicate()
19883af6ab5fSopenharmony_ci        self.output = stdout.decode("utf-8", errors="ignore") + stderr.decode("utf-8", errors="ignore").split("\n")[0]
19893af6ab5fSopenharmony_ci        return stdout, stderr
19903af6ab5fSopenharmony_ci
19913af6ab5fSopenharmony_ci    def run_for_single_version(self, runner, target_api_version, target_api_sub_version="beta3"):
19923af6ab5fSopenharmony_ci        cur_api_version = "API" + target_api_version + target_api_sub_version
19933af6ab5fSopenharmony_ci        is_support = True if self.compare_two_versions(cur_api_version, self.test_version) >= 0 else False
19943af6ab5fSopenharmony_ci        compile_expected_path = None
19953af6ab5fSopenharmony_ci        stderr = None
19963af6ab5fSopenharmony_ci        if self.feature_type == "syntax_feature":
19973af6ab5fSopenharmony_ci            compile_expected_path = self.get_path_to_compile_ast_output_expected(is_support)
19983af6ab5fSopenharmony_ci            _, stderr = self.generate_ast_of_target_version(runner, target_api_version, target_api_sub_version)
19993af6ab5fSopenharmony_ci        elif self.feature_type == "bytecode_feature":
20003af6ab5fSopenharmony_ci            compile_expected_path = self.get_path_to_compile_asm_output_expected(is_support, cur_api_version)
20013af6ab5fSopenharmony_ci            _, stderr = self.generate_asm_of_target_version(
20023af6ab5fSopenharmony_ci                runner, target_api_version, target_api_sub_version
20033af6ab5fSopenharmony_ci            )
20043af6ab5fSopenharmony_ci        try:
20053af6ab5fSopenharmony_ci            with open(compile_expected_path, "r") as fp:
20063af6ab5fSopenharmony_ci                expected = fp.read()
20073af6ab5fSopenharmony_ci                self.passed = expected == self.output and self.process.returncode in [0, 1]
20083af6ab5fSopenharmony_ci        except Exception:
20093af6ab5fSopenharmony_ci            self.passed = False
20103af6ab5fSopenharmony_ci        if not self.passed or (stderr and self.passed):
20113af6ab5fSopenharmony_ci            return stderr
20123af6ab5fSopenharmony_ci        for api_version in self.target_api_version_list:
20133af6ab5fSopenharmony_ci            # The interception capability of API9 version of ark_js_vm has not yet been launched.
20143af6ab5fSopenharmony_ci            if api_version == "9":
20153af6ab5fSopenharmony_ci                continue
20163af6ab5fSopenharmony_ci            for api_sub_version in self.target_api_sub_version_list:
20173af6ab5fSopenharmony_ci                if not api_version in self.version_with_sub_version_list and api_sub_version != "beta3":
20183af6ab5fSopenharmony_ci                    continue
20193af6ab5fSopenharmony_ci                cur_runtime_api_version = "API" + api_version + api_sub_version
20203af6ab5fSopenharmony_ci                is_below_abc_version = (
20213af6ab5fSopenharmony_ci                    False if self.compare_two_versions(cur_runtime_api_version, cur_api_version) >= 0 else True
20223af6ab5fSopenharmony_ci                )
20233af6ab5fSopenharmony_ci                self.generate_module_abc(runner, cur_runtime_api_version)
20243af6ab5fSopenharmony_ci                _, stderr = self.runtime_for_target_version(runner, api_version, api_sub_version)
20253af6ab5fSopenharmony_ci                runtime_expected_path = self.get_path_to_runtime_output_expected(
20263af6ab5fSopenharmony_ci                    is_support, cur_api_version, is_below_abc_version
20273af6ab5fSopenharmony_ci                )
20283af6ab5fSopenharmony_ci                self.remove_module_abc()
20293af6ab5fSopenharmony_ci                try:
20303af6ab5fSopenharmony_ci                    with open(runtime_expected_path, "r") as fp:
20313af6ab5fSopenharmony_ci                        expected = fp.read()
20323af6ab5fSopenharmony_ci                    if is_below_abc_version:
20333af6ab5fSopenharmony_ci                        self.passed = expected in self.output
20343af6ab5fSopenharmony_ci                    else:
20353af6ab5fSopenharmony_ci                        self.passed = expected == self.output
20363af6ab5fSopenharmony_ci                except Exception:
20373af6ab5fSopenharmony_ci                    self.passed = False
20383af6ab5fSopenharmony_ci                if not self.passed:
20393af6ab5fSopenharmony_ci                    return stderr
20403af6ab5fSopenharmony_ci        return stderr
20413af6ab5fSopenharmony_ci
20423af6ab5fSopenharmony_ci    def run(self, runner):
20433af6ab5fSopenharmony_ci        for target_api_version in self.target_api_version_list:
20443af6ab5fSopenharmony_ci            stderr = None
20453af6ab5fSopenharmony_ci            if target_api_version == "12":
20463af6ab5fSopenharmony_ci                for target_api_sub_version in self.target_api_sub_version_list:
20473af6ab5fSopenharmony_ci                    stderr = self.run_for_single_version(runner, target_api_version, target_api_sub_version)
20483af6ab5fSopenharmony_ci                    if path.exists(self.test_abc_path):
20493af6ab5fSopenharmony_ci                        os.remove(self.test_abc_path)
20503af6ab5fSopenharmony_ci                    if not self.passed:
20513af6ab5fSopenharmony_ci                        self.error = stderr.decode("utf-8", errors="ignore")
20523af6ab5fSopenharmony_ci                        return self
20533af6ab5fSopenharmony_ci            else:
20543af6ab5fSopenharmony_ci                stderr = self.run_for_single_version(runner, target_api_version)
20553af6ab5fSopenharmony_ci                if not self.passed:
20563af6ab5fSopenharmony_ci                    self.error = stderr.decode("utf-8", errors="ignore")
20573af6ab5fSopenharmony_ci                    return self
20583af6ab5fSopenharmony_ci        return self
20593af6ab5fSopenharmony_ci
20603af6ab5fSopenharmony_ci
20613af6ab5fSopenharmony_ciclass CompilerTestInfo(object):
20623af6ab5fSopenharmony_ci    def __init__(self, directory, extension, flags):
20633af6ab5fSopenharmony_ci        self.directory = directory
20643af6ab5fSopenharmony_ci        self.extension = extension
20653af6ab5fSopenharmony_ci        self.flags = flags
20663af6ab5fSopenharmony_ci
20673af6ab5fSopenharmony_ci    def update_dir(self, prefiex_dir):
20683af6ab5fSopenharmony_ci        self.directory = os.path.sep.join([prefiex_dir, self.directory])
20693af6ab5fSopenharmony_ci
20703af6ab5fSopenharmony_ci
20713af6ab5fSopenharmony_ci# Copy compiler directory to test/.local directory, and do inplace obfuscation.
20723af6ab5fSopenharmony_cidef prepare_for_obfuscation(compiler_test_infos, test_root):
20733af6ab5fSopenharmony_ci    tmp_dir_name = ".local"
20743af6ab5fSopenharmony_ci    tmp_path = os.path.join(test_root, tmp_dir_name)
20753af6ab5fSopenharmony_ci    if not os.path.exists(tmp_path):
20763af6ab5fSopenharmony_ci        os.mkdir(tmp_path)
20773af6ab5fSopenharmony_ci
20783af6ab5fSopenharmony_ci    test_root_dirs = set()
20793af6ab5fSopenharmony_ci    for info in compiler_test_infos:
20803af6ab5fSopenharmony_ci        root_dir = info.directory.split("/")[0]
20813af6ab5fSopenharmony_ci        test_root_dirs.add(root_dir)
20823af6ab5fSopenharmony_ci
20833af6ab5fSopenharmony_ci    for test_dir in test_root_dirs:
20843af6ab5fSopenharmony_ci        src_dir = os.path.join(test_root, test_dir)
20853af6ab5fSopenharmony_ci        target_dir = os.path.join(tmp_path, test_dir)
20863af6ab5fSopenharmony_ci        if os.path.exists(target_dir):
20873af6ab5fSopenharmony_ci            shutil.rmtree(target_dir)
20883af6ab5fSopenharmony_ci        shutil.copytree(src_dir, target_dir)
20893af6ab5fSopenharmony_ci
20903af6ab5fSopenharmony_ci    for info in compiler_test_infos:
20913af6ab5fSopenharmony_ci        info.update_dir(tmp_dir_name)
20923af6ab5fSopenharmony_ci
20933af6ab5fSopenharmony_ci
20943af6ab5fSopenharmony_cidef add_directory_for_version_control(runners, args):
20953af6ab5fSopenharmony_ci    ark_js_vm_prepared = ArkJsVmDownload(args)
20963af6ab5fSopenharmony_ci    ark_js_vm_prepared.run()
20973af6ab5fSopenharmony_ci    runner = VersionControlRunner(args)
20983af6ab5fSopenharmony_ci    runner.add_directory(
20993af6ab5fSopenharmony_ci        "version_control/API11/syntax_feature",
21003af6ab5fSopenharmony_ci        "js",
21013af6ab5fSopenharmony_ci        ["--module"],
21023af6ab5fSopenharmony_ci        "API11",
21033af6ab5fSopenharmony_ci        "syntax_feature",
21043af6ab5fSopenharmony_ci    )
21053af6ab5fSopenharmony_ci    runner.add_directory(
21063af6ab5fSopenharmony_ci        "version_control/API11/syntax_feature",
21073af6ab5fSopenharmony_ci        "ts",
21083af6ab5fSopenharmony_ci        ["--module"],
21093af6ab5fSopenharmony_ci        "API11",
21103af6ab5fSopenharmony_ci        "syntax_feature",
21113af6ab5fSopenharmony_ci    )
21123af6ab5fSopenharmony_ci    runner.add_directory(
21133af6ab5fSopenharmony_ci        "version_control/API12beta1_and_beta2/syntax_feature",
21143af6ab5fSopenharmony_ci        "ts", ["--module"],
21153af6ab5fSopenharmony_ci        "API12beta1",
21163af6ab5fSopenharmony_ci        "syntax_feature",
21173af6ab5fSopenharmony_ci    )
21183af6ab5fSopenharmony_ci    runner.add_directory(
21193af6ab5fSopenharmony_ci        "version_control/API12beta1_and_beta2/syntax_feature",
21203af6ab5fSopenharmony_ci        "js",
21213af6ab5fSopenharmony_ci        ["--module"],
21223af6ab5fSopenharmony_ci        "API12beta1",
21233af6ab5fSopenharmony_ci        "syntax_feature",
21243af6ab5fSopenharmony_ci    )
21253af6ab5fSopenharmony_ci    runner.add_directory(
21263af6ab5fSopenharmony_ci        "version_control/API12beta3/syntax_feature",
21273af6ab5fSopenharmony_ci        "ts",
21283af6ab5fSopenharmony_ci        ["--module"],
21293af6ab5fSopenharmony_ci        "API12beta3",
21303af6ab5fSopenharmony_ci        "syntax_feature",
21313af6ab5fSopenharmony_ci        "version_control/API12beta3/syntax_feature/import_target",
21323af6ab5fSopenharmony_ci    )
21333af6ab5fSopenharmony_ci    runner.add_directory(
21343af6ab5fSopenharmony_ci        "version_control/API12beta3/syntax_feature",
21353af6ab5fSopenharmony_ci        "js",
21363af6ab5fSopenharmony_ci        ["--module"],
21373af6ab5fSopenharmony_ci        "API12beta3",
21383af6ab5fSopenharmony_ci        "syntax_feature",
21393af6ab5fSopenharmony_ci        "version_control/API12beta3/syntax_feature/import_target",
21403af6ab5fSopenharmony_ci    )
21413af6ab5fSopenharmony_ci    runner.add_directory(
21423af6ab5fSopenharmony_ci        "version_control/API11/bytecode_feature",
21433af6ab5fSopenharmony_ci        "ts",
21443af6ab5fSopenharmony_ci        ["--module"],
21453af6ab5fSopenharmony_ci        "API11",
21463af6ab5fSopenharmony_ci        "bytecode_feature",
21473af6ab5fSopenharmony_ci    )
21483af6ab5fSopenharmony_ci    runner.add_directory(
21493af6ab5fSopenharmony_ci        "version_control/API11/bytecode_feature",
21503af6ab5fSopenharmony_ci        "js",
21513af6ab5fSopenharmony_ci        ["--module"],
21523af6ab5fSopenharmony_ci        "API11",
21533af6ab5fSopenharmony_ci        "bytecode_feature",
21543af6ab5fSopenharmony_ci    )
21553af6ab5fSopenharmony_ci    runner.add_directory(
21563af6ab5fSopenharmony_ci        "version_control/API12beta1_and_beta2/bytecode_feature",
21573af6ab5fSopenharmony_ci        "ts",
21583af6ab5fSopenharmony_ci        ["--module"],
21593af6ab5fSopenharmony_ci        "API12beta1",
21603af6ab5fSopenharmony_ci        "bytecode_feature",
21613af6ab5fSopenharmony_ci        "version_control/API12beta1_and_beta2/bytecode_feature/import_target",
21623af6ab5fSopenharmony_ci    )
21633af6ab5fSopenharmony_ci    runner.add_directory(
21643af6ab5fSopenharmony_ci        "version_control/API12beta1_and_beta2/bytecode_feature",
21653af6ab5fSopenharmony_ci        "js",
21663af6ab5fSopenharmony_ci        ["--module"],
21673af6ab5fSopenharmony_ci        "API12beta1",
21683af6ab5fSopenharmony_ci        "bytecode_feature",
21693af6ab5fSopenharmony_ci        "version_control/API12beta1_and_beta2/bytecode_feature/import_target",
21703af6ab5fSopenharmony_ci    )
21713af6ab5fSopenharmony_ci    runner.add_directory(
21723af6ab5fSopenharmony_ci        "version_control/API12beta3/bytecode_feature",
21733af6ab5fSopenharmony_ci        "ts",
21743af6ab5fSopenharmony_ci        ["--module"],
21753af6ab5fSopenharmony_ci        "API12beta3",
21763af6ab5fSopenharmony_ci        "bytecode_feature",
21773af6ab5fSopenharmony_ci        "version_control/API12beta3/bytecode_feature/import_target",
21783af6ab5fSopenharmony_ci    )
21793af6ab5fSopenharmony_ci    runner.add_directory(
21803af6ab5fSopenharmony_ci        "version_control/API12beta3/bytecode_feature",
21813af6ab5fSopenharmony_ci        "js",
21823af6ab5fSopenharmony_ci        ["--module"],
21833af6ab5fSopenharmony_ci        "API12beta3",
21843af6ab5fSopenharmony_ci        "bytecode_feature",
21853af6ab5fSopenharmony_ci        "version_control/API12beta3/bytecode_feature/import_target",
21863af6ab5fSopenharmony_ci    )
21873af6ab5fSopenharmony_ci    runners.append(runner)
21883af6ab5fSopenharmony_ci
21893af6ab5fSopenharmony_ci    abc_tests_prepare = AbcTestCasesPrepare(args)
21903af6ab5fSopenharmony_ci    abc_tests_prepare.gen_abc_tests(
21913af6ab5fSopenharmony_ci        "version_control/bytecode_version_control/non_merge_mode",
21923af6ab5fSopenharmony_ci        "js",
21933af6ab5fSopenharmony_ci        ["--module"],
21943af6ab5fSopenharmony_ci        "non_merge_mode",
21953af6ab5fSopenharmony_ci    )
21963af6ab5fSopenharmony_ci    abc_tests_prepare.gen_abc_tests(
21973af6ab5fSopenharmony_ci        "version_control/bytecode_version_control/merge_mode",
21983af6ab5fSopenharmony_ci        "js",
21993af6ab5fSopenharmony_ci        ["--module", "--merge-abc"],
22003af6ab5fSopenharmony_ci        "merge_mode",
22013af6ab5fSopenharmony_ci    )
22023af6ab5fSopenharmony_ci    abc_tests_prepare.gen_abc_tests(
22033af6ab5fSopenharmony_ci        "version_control/bytecode_version_control/mixed_compile",
22043af6ab5fSopenharmony_ci        "js",
22053af6ab5fSopenharmony_ci        ["--module", "--merge-abc"],
22063af6ab5fSopenharmony_ci        "merge_mode",
22073af6ab5fSopenharmony_ci    )
22083af6ab5fSopenharmony_ci
22093af6ab5fSopenharmony_ci    args.abc_tests_prepare = abc_tests_prepare
22103af6ab5fSopenharmony_ci    abc_version_control_runner = AbcVersionControlRunner(args)
22113af6ab5fSopenharmony_ci    abc_version_control_runner.add_directory(
22123af6ab5fSopenharmony_ci        "version_control/bytecode_version_control/non_merge_mode",
22133af6ab5fSopenharmony_ci        "abc",
22143af6ab5fSopenharmony_ci        ["--module", "--enable-abc-input"],
22153af6ab5fSopenharmony_ci        "non_merge_mode",
22163af6ab5fSopenharmony_ci    )
22173af6ab5fSopenharmony_ci    abc_version_control_runner.add_directory(
22183af6ab5fSopenharmony_ci        "version_control/bytecode_version_control/merge_mode",
22193af6ab5fSopenharmony_ci        "abc",
22203af6ab5fSopenharmony_ci        ["--module", "--enable-abc-input", "--merge-abc"],
22213af6ab5fSopenharmony_ci        "merge_mode",
22223af6ab5fSopenharmony_ci    )
22233af6ab5fSopenharmony_ci    abc_version_control_runner.add_directory(
22243af6ab5fSopenharmony_ci        "version_control/bytecode_version_control/mixed_compile",
22253af6ab5fSopenharmony_ci        "txt",
22263af6ab5fSopenharmony_ci        ["--module", "--enable-abc-input", "--merge-abc"],
22273af6ab5fSopenharmony_ci        "mix_compile_mode",
22283af6ab5fSopenharmony_ci    )
22293af6ab5fSopenharmony_ci    runners.append(abc_version_control_runner)
22303af6ab5fSopenharmony_ci
22313af6ab5fSopenharmony_cidef add_directory_for_regression(runners, args):
22323af6ab5fSopenharmony_ci    runner = RegressionRunner(args)
22333af6ab5fSopenharmony_ci    runner.add_directory("parser/concurrent", "js", ["--module", "--dump-ast"])
22343af6ab5fSopenharmony_ci    runner.add_directory("parser/js", "js", ["--parse-only", "--dump-ast"])
22353af6ab5fSopenharmony_ci    runner.add_directory("parser/script", "ts", ["--parse-only", "--dump-ast"])
22363af6ab5fSopenharmony_ci    runner.add_directory("parser/ts", "ts",
22373af6ab5fSopenharmony_ci                         ["--parse-only", "--module", "--dump-ast"])
22383af6ab5fSopenharmony_ci    runner.add_directory("parser/ts/type_checker", "ts",
22393af6ab5fSopenharmony_ci                         ["--parse-only", "--enable-type-check", "--module", "--dump-ast"])
22403af6ab5fSopenharmony_ci    runner.add_directory("parser/ts/cases/declaration", "d.ts",
22413af6ab5fSopenharmony_ci                         ["--parse-only", "--module", "--dump-ast"], TSDeclarationTest)
22423af6ab5fSopenharmony_ci    runner.add_directory("parser/commonjs", "js", ["--commonjs", "--parse-only", "--dump-ast"])
22433af6ab5fSopenharmony_ci    runner.add_directory("parser/binder", "js", ["--dump-assembly", "--dump-literal-buffer", "--module", "--target-api-sub-version=beta3"])
22443af6ab5fSopenharmony_ci    runner.add_directory("parser/binder", "ts", ["--dump-assembly", "--dump-literal-buffer", "--module", "--target-api-sub-version=beta3"])
22453af6ab5fSopenharmony_ci    runner.add_directory("parser/binder/noModule", "ts", ["--dump-assembly", "--dump-literal-buffer", "--target-api-sub-version=beta3"])
22463af6ab5fSopenharmony_ci    runner.add_directory("parser/binder/api12beta2", "js", ["--dump-assembly", "--target-api-version=12", "--target-api-sub-version=beta2"])
22473af6ab5fSopenharmony_ci    runner.add_directory("parser/js/emptySource", "js", ["--dump-assembly"])
22483af6ab5fSopenharmony_ci    runner.add_directory("parser/js/language/arguments-object", "js", ["--parse-only"])
22493af6ab5fSopenharmony_ci    runner.add_directory("parser/js/language/statements/for-statement", "js", ["--parse-only", "--dump-ast"])
22503af6ab5fSopenharmony_ci    runner.add_directory("parser/js/language/expressions/optional-chain", "js", ["--parse-only", "--dump-ast"])
22513af6ab5fSopenharmony_ci    runner.add_directory("parser/js/language/import/syntax", "js",
22523af6ab5fSopenharmony_ci                         ["--parse-only", "--module", "--target-api-sub-version=beta3"])
22533af6ab5fSopenharmony_ci    runner.add_directory("parser/js/language/import/syntax/beta2", "js",
22543af6ab5fSopenharmony_ci                         ["--parse-only", "--module", "--target-api-version=12", "--target-api-sub-version=beta2"])
22553af6ab5fSopenharmony_ci    runner.add_directory("parser/js/language/import", "ts",
22563af6ab5fSopenharmony_ci                         ["--dump-assembly", "--dump-literal-buffer", "--module", "--target-api-sub-version=beta3"])
22573af6ab5fSopenharmony_ci    runner.add_directory("parser/sendable_class", "ts",
22583af6ab5fSopenharmony_ci                         ["--dump-assembly", "--dump-literal-buffer", "--module", "--target-api-sub-version=beta3"])
22593af6ab5fSopenharmony_ci    runner.add_directory("parser/sendable_class/api12beta2", "ts",
22603af6ab5fSopenharmony_ci                         ["--dump-assembly", "--dump-literal-buffer", "--module", "--target-api-version=12", "--target-api-sub-version=beta2"])
22613af6ab5fSopenharmony_ci    runner.add_directory("parser/unicode", "js", ["--parse-only"])
22623af6ab5fSopenharmony_ci    runner.add_directory("parser/ts/stack_overflow", "ts", ["--parse-only", "--dump-ast"])
22633af6ab5fSopenharmony_ci    runner.add_directory("parser/js/module-record/module-record-field-name-option.js", "js",
22643af6ab5fSopenharmony_ci                         ["--module-record-field-name=abc", "--source-file=abc", "--module", "--dump-normalized-asm-program"])
22653af6ab5fSopenharmony_ci    runner.add_directory("parser/annotations", "ts", ["--module", "--dump-ast", "--enable-annotations"])
22663af6ab5fSopenharmony_ci
22673af6ab5fSopenharmony_ci    runners.append(runner)
22683af6ab5fSopenharmony_ci
22693af6ab5fSopenharmony_ci    transformer_runner = TransformerRunner(args)
22703af6ab5fSopenharmony_ci    transformer_runner.add_directory("parser/ts/transformed_cases", "ts",
22713af6ab5fSopenharmony_ci                                     ["--parse-only", "--module", "--dump-transformed-ast",
22723af6ab5fSopenharmony_ci                                     "--check-transformed-ast-structure"])
22733af6ab5fSopenharmony_ci
22743af6ab5fSopenharmony_ci    runners.append(transformer_runner)
22753af6ab5fSopenharmony_ci
22763af6ab5fSopenharmony_ci    bc_version_runner = BcVersionRunner(args)
22773af6ab5fSopenharmony_ci    bc_version_runner.add_cmd()
22783af6ab5fSopenharmony_ci
22793af6ab5fSopenharmony_ci    runners.append(bc_version_runner)
22803af6ab5fSopenharmony_ci
22813af6ab5fSopenharmony_ci    transformer_api_version_10_runner = TransformerInTargetApiVersion10Runner(args)
22823af6ab5fSopenharmony_ci    transformer_api_version_10_runner.add_directory("parser/ts/transformed_cases_api_version_10", "ts",
22833af6ab5fSopenharmony_ci                                                    ["--parse-only", "--module", "--target-api-version=10",
22843af6ab5fSopenharmony_ci                                                    "--dump-transformed-ast"])
22853af6ab5fSopenharmony_ci
22863af6ab5fSopenharmony_ci    runners.append(transformer_api_version_10_runner)
22873af6ab5fSopenharmony_ci
22883af6ab5fSopenharmony_cidef add_directory_for_asm(runners, args, mode=""):
22893af6ab5fSopenharmony_ci    runner = AbcToAsmRunner(args, True if mode == "debug" else False)
22903af6ab5fSopenharmony_ci    runner.add_directory("abc2asm/js", "js", [])
22913af6ab5fSopenharmony_ci    runner.add_directory("abc2asm/ts", "ts", [])
22923af6ab5fSopenharmony_ci    runner.add_directory("compiler/js", "js", [])
22933af6ab5fSopenharmony_ci    runner.add_directory("compiler/ts/cases/compiler", "ts", [])
22943af6ab5fSopenharmony_ci    runner.add_directory("compiler/ts/projects", "ts", ["--module"])
22953af6ab5fSopenharmony_ci    runner.add_directory("compiler/ts/projects", "ts", ["--module", "--merge-abc"])
22963af6ab5fSopenharmony_ci    runner.add_directory("compiler/dts", "d.ts", ["--module", "--opt-level=0"])
22973af6ab5fSopenharmony_ci    runner.add_directory("compiler/commonjs", "js", ["--commonjs"])
22983af6ab5fSopenharmony_ci    runner.add_directory("parser/concurrent", "js", ["--module"])
22993af6ab5fSopenharmony_ci    runner.add_directory("parser/js", "js", [])
23003af6ab5fSopenharmony_ci    runner.add_directory("parser/script", "ts", [])
23013af6ab5fSopenharmony_ci    runner.add_directory("parser/ts", "ts", ["--module"])
23023af6ab5fSopenharmony_ci    runner.add_directory("parser/ts/type_checker", "ts", ["--enable-type-check", "--module"])
23033af6ab5fSopenharmony_ci    runner.add_directory("parser/commonjs", "js", ["--commonjs"])
23043af6ab5fSopenharmony_ci    runner.add_directory("parser/binder", "js", ["--dump-assembly", "--dump-literal-buffer", "--module"])
23053af6ab5fSopenharmony_ci    runner.add_directory("parser/binder", "ts", ["--dump-assembly", "--dump-literal-buffer", "--module"])
23063af6ab5fSopenharmony_ci    runner.add_directory("parser/binder/noModule", "ts", ["--dump-assembly", "--dump-literal-buffer"])
23073af6ab5fSopenharmony_ci    runner.add_directory("parser/js/emptySource", "js", [])
23083af6ab5fSopenharmony_ci    runner.add_directory("parser/js/language/arguments-object", "js", [])
23093af6ab5fSopenharmony_ci    runner.add_directory("parser/js/language/statements/for-statement", "js", [])
23103af6ab5fSopenharmony_ci    runner.add_directory("parser/js/language/expressions/optional-chain", "js", [])
23113af6ab5fSopenharmony_ci    runner.add_directory("parser/sendable_class", "ts", ["--module"])
23123af6ab5fSopenharmony_ci    runner.add_directory("parser/unicode", "js", [])
23133af6ab5fSopenharmony_ci    runner.add_directory("parser/ts/stack_overflow", "ts", [])
23143af6ab5fSopenharmony_ci
23153af6ab5fSopenharmony_ci    runners.append(runner)
23163af6ab5fSopenharmony_ci
23173af6ab5fSopenharmony_ci
23183af6ab5fSopenharmony_cidef add_directory_for_compiler(runners, args):
23193af6ab5fSopenharmony_ci    runner = CompilerRunner(args)
23203af6ab5fSopenharmony_ci    compiler_test_infos = []
23213af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("compiler/js", "js", ["--module"]))
23223af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("compiler/ts/cases", "ts", []))
23233af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("compiler/ts/projects", "ts", ["--module"]))
23243af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("compiler/ts/projects", "ts", ["--module", "--merge-abc"]))
23253af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("compiler/annotations-projects", "ts", ["--module", "--enable-annotations", "--merge-abc"]))
23263af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("compiler/dts", "d.ts", ["--module", "--opt-level=0"]))
23273af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("compiler/commonjs", "js", ["--commonjs"]))
23283af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("compiler/interpreter/lexicalEnv", "js", []))
23293af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("compiler/sendable", "ts", ["--module", "--target-api-sub-version=beta3"]))
23303af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("optimizer/js/branch-elimination", "js",
23313af6ab5fSopenharmony_ci                                                ["--module", "--branch-elimination", "--dump-assembly"]))
23323af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("optimizer/js/opt-try-catch-func", "js",
23333af6ab5fSopenharmony_ci                                                ["--module", "--dump-assembly"]))
23343af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("compiler/debugInfo/", "js",
23353af6ab5fSopenharmony_ci                                                ["--debug-info", "--dump-debug-info", "--source-file", "debug-info.js"]))
23363af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("compiler/js/module-record-field-name-option.js", "js",
23373af6ab5fSopenharmony_ci                                                ["--module", "--module-record-field-name=abc"]))
23383af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("compiler/annotations", "ts", ["--module", "--enable-annotations"]))
23393af6ab5fSopenharmony_ci    # Following directories of test cases are for dump-assembly comparison only, and is not executed.
23403af6ab5fSopenharmony_ci    # Check CompilerProjectTest for more details.
23413af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("optimizer/ts/branch-elimination/projects", "ts",
23423af6ab5fSopenharmony_ci                                                ["--module", "--branch-elimination", "--merge-abc", "--dump-assembly",
23433af6ab5fSopenharmony_ci                                                "--file-threads=8"]))
23443af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("compiler/bytecodehar/projects", "ts",
23453af6ab5fSopenharmony_ci                                                ["--merge-abc", "--dump-assembly", "--enable-abc-input",
23463af6ab5fSopenharmony_ci                                                 "--dump-deps-info", "--remove-redundant-file",
23473af6ab5fSopenharmony_ci                                                 "--dump-literal-buffer", "--dump-string", "--abc-class-threads=4"]))
23483af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("compiler/bytecodehar/js/projects", "js",
23493af6ab5fSopenharmony_ci                                                ["--merge-abc", "--dump-assembly", "--enable-abc-input",
23503af6ab5fSopenharmony_ci                                                 "--dump-deps-info", "--remove-redundant-file",
23513af6ab5fSopenharmony_ci                                                 "--dump-literal-buffer", "--dump-string", "--abc-class-threads=4"]))
23523af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("compiler/bytecodehar/merge_abc_consistence_check/projects", "js",
23533af6ab5fSopenharmony_ci                                                ["--merge-abc", "--dump-assembly", "--enable-abc-input",
23543af6ab5fSopenharmony_ci                                                 "--abc-class-threads=4"]))
23553af6ab5fSopenharmony_ci
23563af6ab5fSopenharmony_ci    compiler_test_infos.append(CompilerTestInfo("compiler/ts/shared_module/projects", "ts",
23573af6ab5fSopenharmony_ci                                                ["--module", "--merge-abc", "--dump-assembly"]))
23583af6ab5fSopenharmony_ci
23593af6ab5fSopenharmony_ci    if args.enable_arkguard:
23603af6ab5fSopenharmony_ci        prepare_for_obfuscation(compiler_test_infos, runner.test_root)
23613af6ab5fSopenharmony_ci
23623af6ab5fSopenharmony_ci    for info in compiler_test_infos:
23633af6ab5fSopenharmony_ci        runner.add_directory(info.directory, info.extension, info.flags)
23643af6ab5fSopenharmony_ci
23653af6ab5fSopenharmony_ci    runners.append(runner)
23663af6ab5fSopenharmony_ci
23673af6ab5fSopenharmony_ci
23683af6ab5fSopenharmony_cidef add_directory_for_bytecode(runners, args):
23693af6ab5fSopenharmony_ci    runner = BytecodeRunner(args)
23703af6ab5fSopenharmony_ci    runner.add_directory("bytecode/commonjs", "js", ["--commonjs", "--dump-assembly"])
23713af6ab5fSopenharmony_ci    runner.add_directory("bytecode/js", "js", ["--dump-assembly"])
23723af6ab5fSopenharmony_ci    runner.add_directory("bytecode/ts/cases", "ts", ["--dump-assembly"])
23733af6ab5fSopenharmony_ci    runner.add_directory("bytecode/ts/ic", "ts", ["--dump-assembly"])
23743af6ab5fSopenharmony_ci    runner.add_directory("bytecode/ts/api11", "ts", ["--dump-assembly", "--module", "--target-api-version=11"])
23753af6ab5fSopenharmony_ci    runner.add_directory("bytecode/ts/api12", "ts", ["--dump-assembly", "--module", "--target-api-version=12"])
23763af6ab5fSopenharmony_ci    runner.add_directory("bytecode/watch-expression", "js", ["--debugger-evaluate-expression", "--dump-assembly"])
23773af6ab5fSopenharmony_ci
23783af6ab5fSopenharmony_ci    runners.append(runner)
23793af6ab5fSopenharmony_ci
23803af6ab5fSopenharmony_ci
23813af6ab5fSopenharmony_cidef add_directory_for_debug(runners, args):
23823af6ab5fSopenharmony_ci    runner = RegressionRunner(args)
23833af6ab5fSopenharmony_ci    runner.add_directory("debug/parser", "js", ["--parse-only", "--dump-ast"])
23843af6ab5fSopenharmony_ci
23853af6ab5fSopenharmony_ci    runners.append(runner)
23863af6ab5fSopenharmony_ci
23873af6ab5fSopenharmony_ci
23883af6ab5fSopenharmony_cidef add_cmd_for_aop_transform(runners, args):
23893af6ab5fSopenharmony_ci    runner = AopTransform(args)
23903af6ab5fSopenharmony_ci
23913af6ab5fSopenharmony_ci    aop_file_path = path.join(runner.test_root, "aop")
23923af6ab5fSopenharmony_ci    lib_suffix = '.so'
23933af6ab5fSopenharmony_ci    #cpp src, deal type, result compare str, abc compare str
23943af6ab5fSopenharmony_ci    msg_list = [
23953af6ab5fSopenharmony_ci        ["correct_modify.cpp", "compile", "aop_transform_start", "new_abc_content"],
23963af6ab5fSopenharmony_ci        ["correct_no_modify.cpp", "compile", "aop_transform_start", ""],
23973af6ab5fSopenharmony_ci        ["exec_error.cpp", "compile", "Transform exec fail", ""],
23983af6ab5fSopenharmony_ci        ["no_func_transform.cpp", "compile", "os::library_loader::ResolveSymbol get func Transform error", ""],
23993af6ab5fSopenharmony_ci        ["error_format.cpp", "copy_lib", "os::library_loader::Load error", ""],
24003af6ab5fSopenharmony_ci        ["".join(["no_exist", lib_suffix]), "dirct_use", "Failed to find file", ""],
24013af6ab5fSopenharmony_ci        ["error_suffix.xxx", "direct_use", "aop transform file suffix support", ""]
24023af6ab5fSopenharmony_ci    ]
24033af6ab5fSopenharmony_ci    for msg in msg_list:
24043af6ab5fSopenharmony_ci        cpp_file = path.join(aop_file_path, msg[0])
24053af6ab5fSopenharmony_ci        if msg[1] == 'compile':
24063af6ab5fSopenharmony_ci            lib_file = cpp_file.replace('.cpp', lib_suffix)
24073af6ab5fSopenharmony_ci            remove_file = lib_file
24083af6ab5fSopenharmony_ci            runner.add_cmd(["g++", "--share", "-o", lib_file, cpp_file], "", "", "")
24093af6ab5fSopenharmony_ci        elif msg[1] == 'copy_lib':
24103af6ab5fSopenharmony_ci            lib_file = cpp_file.replace('.cpp', lib_suffix)
24113af6ab5fSopenharmony_ci            remove_file = lib_file
24123af6ab5fSopenharmony_ci            if not os.path.exists(lib_file):
24133af6ab5fSopenharmony_ci                with open(cpp_file, "r") as source_file:
24143af6ab5fSopenharmony_ci                    fd = os.open(lib_file, os.O_RDWR | os.O_CREAT | os.O_TRUNC)
24153af6ab5fSopenharmony_ci                    target_file = os.fdopen(fd, 'w')
24163af6ab5fSopenharmony_ci                    target_file.write(source_file.read())
24173af6ab5fSopenharmony_ci        elif msg[1] == 'direct_use':
24183af6ab5fSopenharmony_ci            lib_file = cpp_file
24193af6ab5fSopenharmony_ci            remove_file = ""
24203af6ab5fSopenharmony_ci
24213af6ab5fSopenharmony_ci        js_file = path.join(aop_file_path, "test_aop.js")
24223af6ab5fSopenharmony_ci        runner.add_cmd([runner.es2panda, "--merge-abc", "--transform-lib", lib_file, js_file], msg[2], msg[3], remove_file)
24233af6ab5fSopenharmony_ci
24243af6ab5fSopenharmony_ci    runners.append(runner)
24253af6ab5fSopenharmony_ci
24263af6ab5fSopenharmony_ci
24273af6ab5fSopenharmony_ciclass AopTransform(Runner):
24283af6ab5fSopenharmony_ci    def __init__(self, args):
24293af6ab5fSopenharmony_ci        Runner.__init__(self, args, "AopTransform")
24303af6ab5fSopenharmony_ci
24313af6ab5fSopenharmony_ci    def add_cmd(self, cmd, compare_str, compare_abc_str, remove_file, func=TestAop):
24323af6ab5fSopenharmony_ci        self.tests += [func(cmd, compare_str, compare_abc_str, remove_file)]
24333af6ab5fSopenharmony_ci
24343af6ab5fSopenharmony_ci    def test_path(self, src):
24353af6ab5fSopenharmony_ci        return src
24363af6ab5fSopenharmony_ci
24373af6ab5fSopenharmony_ci
24383af6ab5fSopenharmony_cidef main():
24393af6ab5fSopenharmony_ci    args = get_args()
24403af6ab5fSopenharmony_ci
24413af6ab5fSopenharmony_ci    runners = []
24423af6ab5fSopenharmony_ci
24433af6ab5fSopenharmony_ci    if args.regression:
24443af6ab5fSopenharmony_ci        add_directory_for_regression(runners, args)
24453af6ab5fSopenharmony_ci
24463af6ab5fSopenharmony_ci    if args.abc_to_asm:
24473af6ab5fSopenharmony_ci        add_directory_for_asm(runners, args)
24483af6ab5fSopenharmony_ci        add_directory_for_asm(runners, args, "debug")
24493af6ab5fSopenharmony_ci
24503af6ab5fSopenharmony_ci    if args.tsc:
24513af6ab5fSopenharmony_ci        runners.append(TSCRunner(args))
24523af6ab5fSopenharmony_ci
24533af6ab5fSopenharmony_ci    if args.compiler:
24543af6ab5fSopenharmony_ci        add_directory_for_compiler(runners, args)
24553af6ab5fSopenharmony_ci
24563af6ab5fSopenharmony_ci    if args.hotfix:
24573af6ab5fSopenharmony_ci        runners.append(HotfixRunner(args))
24583af6ab5fSopenharmony_ci
24593af6ab5fSopenharmony_ci    if args.hotreload:
24603af6ab5fSopenharmony_ci        runners.append(HotreloadRunner(args))
24613af6ab5fSopenharmony_ci
24623af6ab5fSopenharmony_ci    if args.coldfix:
24633af6ab5fSopenharmony_ci        runners.append(ColdfixRunner(args))
24643af6ab5fSopenharmony_ci
24653af6ab5fSopenharmony_ci    if args.coldreload:
24663af6ab5fSopenharmony_ci        runners.append(ColdreloadRunner(args))
24673af6ab5fSopenharmony_ci
24683af6ab5fSopenharmony_ci    if args.debugger:
24693af6ab5fSopenharmony_ci        runners.append(DebuggerRunner(args))
24703af6ab5fSopenharmony_ci
24713af6ab5fSopenharmony_ci    if args.base64:
24723af6ab5fSopenharmony_ci        runners.append(Base64Runner(args))
24733af6ab5fSopenharmony_ci
24743af6ab5fSopenharmony_ci    if args.bytecode:
24753af6ab5fSopenharmony_ci        add_directory_for_bytecode(runners, args)
24763af6ab5fSopenharmony_ci
24773af6ab5fSopenharmony_ci    if args.aop_transform:
24783af6ab5fSopenharmony_ci        add_cmd_for_aop_transform(runners, args)
24793af6ab5fSopenharmony_ci
24803af6ab5fSopenharmony_ci    if args.debug:
24813af6ab5fSopenharmony_ci        add_directory_for_debug(runners, args)
24823af6ab5fSopenharmony_ci
24833af6ab5fSopenharmony_ci    if args.version_control:
24843af6ab5fSopenharmony_ci        add_directory_for_version_control(runners, args)
24853af6ab5fSopenharmony_ci
24863af6ab5fSopenharmony_ci    failed_tests = 0
24873af6ab5fSopenharmony_ci
24883af6ab5fSopenharmony_ci    for runner in runners:
24893af6ab5fSopenharmony_ci        runner.run()
24903af6ab5fSopenharmony_ci        failed_tests += runner.summarize()
24913af6ab5fSopenharmony_ci
24923af6ab5fSopenharmony_ci    # TODO: exit 1 when we have failed tests after all tests are fixed
24933af6ab5fSopenharmony_ci    exit(0)
24943af6ab5fSopenharmony_ci
24953af6ab5fSopenharmony_ci
24963af6ab5fSopenharmony_ciif __name__ == "__main__":
24973af6ab5fSopenharmony_ci    main()
2498