1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4"""
5Copyright (c) 2021 Huawei Device Co., Ltd.
6Licensed under the Apache License, Version 2.0 (the "License");
7you may not use this file except in compliance with the License.
8You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12Unless required by applicable law or agreed to in writing, software
13distributed under the License is distributed on an "AS IS" BASIS,
14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15See the License for the specific language governing permissions and
16limitations under the License.
17
18Description: Use ark to execute test 262 test suite
19"""
20
21import argparse
22import datetime
23import collections
24import json
25import os
26import shutil
27import sys
28import subprocess
29from multiprocessing import Pool
30import platform
31from typing import List
32
33from utils import *
34from config import *
35
36
37def parse_args():
38    parser = argparse.ArgumentParser()
39    parser.add_argument('--dir', metavar='DIR',
40                        help='Directory to test. And support multiple directories and files separated by ":"')
41    parser.add_argument('--file', metavar='FILE',
42                        help='File to test')
43    parser.add_argument('--mode',
44                        nargs='?', choices=[1, 2, 3], type=int,
45                        help='selection information as: ' +
46                        '1: only default \n ' +
47                        '2: only strict mode \n' +
48                        '3: both default and strict mode\n')
49    parser.add_argument('--es51', action='store_true',
50                        help='Run test262 ES5.1 version')
51    parser.add_argument('--es2021', default=False, const='all',
52                        nargs='?', choices=['all', 'only', 'other'],
53                        help='Run test262 - ES2021. ' +
54                        'all: Contains all use cases for es5_tests and es2015_tests and es2021_tests and intl_tests' +
55                        'only: Only include use cases for ES2021' +
56                        'other: Contains all use cases for es5_tests and es2015_tests and es2021_tests and intl_tests' +
57                        'and other_tests')
58    parser.add_argument('--sendable', default=False, const='sendable',
59                        nargs='?', choices=['sendable'],
60                        help='Run test262 - sendable. ' +
61                        'sendable: Contains all use cases for sendable')
62    parser.add_argument('--es2022', default=False, const='all',
63                        nargs='?', choices=['all', 'only', 'other'],
64                        help='Run test262 - ES2022. ' +
65                        'all: Contains all use cases for es5_tests and es2015_tests and es2021_tests' +
66                        'and es2022_tests and intl_tests' +
67                        'only: Only include use cases for ES2022' +
68                        'other: Contains all use cases for es5_tests and es2015_tests and es2021_tests' +
69                        'and es2022_tests and intl_tests and other_tests')
70    parser.add_argument('--es2023', default=False, const='all',
71                        nargs='?', choices=['all', 'only', 'other'],
72                        help='Run test262 - ES2023. ' +
73                        'all: Contains all use cases for es5_tests and es2015_tests and es2021_tests' +
74                        'and es2022_tests and es2023_tests and intl_tests' +
75                        'only: Only include use cases for ES2023' +
76                        'other: Contains all use cases for es5_tests and es2015_tests and es2021_tests' +
77                        'and es2022_tests and es2023_tests and intl_tests and other_tests')
78    parser.add_argument('--intl', default=False, const='intl',
79                        nargs='?', choices=['intl'],
80                        help='Run test262 - Intltest. ' +
81                        'intl: Only include use cases for intlcsae')
82    parser.add_argument('--other', default=False, const='other',
83                        nargs='?', choices=['other'],
84                        help='Run test262 - other_tests ' +
85                        'other_tests: Only include use cases for other_tests')
86    parser.add_argument('--es2015', default=False, const='es2015',
87                        nargs='?', choices=['es2015'],
88                        help='Run test262 - es2015. ' +
89                        'es2015: Only include use cases for es2015')
90    parser.add_argument('--ci-build', action='store_true',
91                        help='Run test262 ES2015 filter cases for build version')
92    parser.add_argument('--esnext', action='store_true',
93                        help='Run test262 - ES.next.')
94    parser.add_argument('--test-list', metavar='FILE', dest="test_list", default=None,
95                        help='File with list of tests to run')
96    parser.add_argument('--engine', metavar='FILE',
97                        help='Other engine binarys to run tests(as:d8,qjs...)')
98    parser.add_argument('--babel', action='store_true',
99                        help='Whether to use Babel conversion')
100    parser.add_argument('--skip-list',action='append',dest='skip_list',
101                        help='Use explicitly specify skip list in txt format. Can be set several times')
102    parser.add_argument('--timeout', default=DEFAULT_TIMEOUT, type=int,
103                        help='Set a custom test timeout in milliseconds !!!\n')
104    parser.add_argument('--threads', default=DEFAULT_THREADS, type=int,
105                        help="Run this many tests in parallel.")
106    parser.add_argument('--hostArgs',
107                        help="command-line arguments to pass to eshost host\n")
108    parser.add_argument('--ark-tool',
109                        help="ark's binary tool")
110    parser.add_argument('--ark-aot', action='store_true',
111                        help="Run test262 with aot")
112    parser.add_argument('--ark-aot-tool',
113                        help="ark's aot tool")
114    parser.add_argument("--libs-dir",
115                        help="The path collection of dependent so has been divided by':'")
116    parser.add_argument('--ark-frontend',
117                        nargs='?', choices=ARK_FRONTEND_LIST, type=str,
118                        help="Choose one of them")
119    parser.add_argument('--ark-frontend-binary',
120                        help="ark frontend conversion binary tool")
121    parser.add_argument('--ark-arch',
122                        default=DEFAULT_ARK_ARCH,
123                        nargs='?', choices=ARK_ARCH_LIST, type=str,
124                        help="Choose one of them")
125    parser.add_argument('--ark-arch-root',
126                        default=DEFAULT_ARK_ARCH,
127                        help="the root path for qemu-aarch64 or qemu-arm")
128    parser.add_argument('--opt-level',
129                        default=DEFAULT_OPT_LEVEL,
130                        help="the opt level for es2abc")
131    parser.add_argument('--es2abc-thread-count',
132                        default=DEFAULT_ES2ABC_THREAD_COUNT,
133                        help="the thread count for es2abc")
134    parser.add_argument('--merge-abc-binary',
135                        help="frontend merge abc binary tool")
136    parser.add_argument('--merge-abc-mode',
137                        help="run test for merge abc mode")
138    parser.add_argument('--product-name',
139                        default=DEFAULT_PRODUCT_NAME,
140                        help="ark's product name")
141    parser.add_argument('--run-pgo', action='store_true',
142                        help="Run test262 with aot pgo")
143    parser.add_argument('--enable-litecg', action='store_true',
144                        help="Run test262 with aot litecg enabled")
145    parser.add_argument('--run-jit', action='store_true',
146                        help="Run test262 with JIT")
147    parser.add_argument('--run-baseline-jit', action='store_true',
148                        help="Run test262 with baseline JIT")
149    parser.add_argument('--enable-rm', action='store_true',
150                        help="Enable force remove of the data directory")
151    parser.add_argument('--abc2program', action='store_true',
152                        help="Use abc2prog to generate abc, aot or pgo is not supported yet under this option")
153    parser.add_argument('--stub-file',
154                        default=DEFAULT_STUB_FILE,
155                        help="stub file")
156    parser.add_argument('--disable-force-gc', action='store_true',
157                        help="Run test262 with close force-gc")
158    parser.add_argument('--enable-arkguard', action='store_true',
159                        help="enable arkguard for 262 tests")
160
161    args = parser.parse_args()
162    if args.abc2program and (args.run_pgo or args.ark_aot):
163        sys.exit("Error: '--abc2program' used together with  '--ark-aot' or '--run-pgo' is not supported")
164    return args
165
166
167def run_check(runnable, env=None):
168    report_command('Test command:', runnable, env=env)
169
170    if env is not None:
171        full_env = dict(os.environ)
172        full_env.update(env)
173        env = full_env
174
175    proc = subprocess.Popen(runnable, env=env)
176    proc.wait()
177    return proc.returncode
178
179
180def excuting_npm_install(args):
181    ark_frontend = DEFAULT_ARK_FRONTEND
182    if args.ark_frontend:
183        ark_frontend = args.ark_frontend
184
185    if ark_frontend != ARK_FRONTEND_LIST[0]:
186        return
187
188    ark_frontend_binary = os.path.join(ARK_FRONTEND_BINARY_LIST[0])
189    if args.ark_frontend_binary:
190        ark_frontend_binary = os.path.join(args.ark_frontend_binary)
191
192    ts2abc_build_dir = os.path.join(os.path.dirname(
193        os.path.realpath(ark_frontend_binary)), "..")
194
195    if not os.path.exists(os.path.join(ts2abc_build_dir, "package.json")) and \
196        not os.path.exists(os.path.join(ts2abc_build_dir, "..", "package.json")):
197        return
198
199    if os.path.exists(os.path.join(ts2abc_build_dir, "..", "package.json")) and \
200        not os.path.exists(os.path.join(ts2abc_build_dir, "package.json")):
201        ts2abc_build_dir = os.path.join(ts2abc_build_dir, "..")
202    # copy deps/ohos-typescript
203    deps_dir = os.path.join(ts2abc_build_dir, "deps")
204    mkdir(deps_dir)
205
206    shutil.copyfile(OHOS_TYPESCRIPT_TGZ_PATH, os.path.join(deps_dir, OHOS_TYPESCRIPT))
207
208    npm_install(ts2abc_build_dir)
209
210
211def init(args):
212    remove_dir(BASE_OUT_DIR)
213    remove_dir(TEST_ES5_DIR)
214    remove_dir(TEST_ES2015_DIR)
215    remove_dir(TEST_INTL_DIR)
216    remove_dir(TEST_ES2021_DIR)
217    remove_dir(TEST_SENDABLE_DIR)
218    remove_dir(TEST_ES2022_DIR)
219    remove_dir(TEST_ES2023_DIR)
220    remove_dir(TEST_CI_DIR)
221    get_all_skip_tests(args)
222    excuting_npm_install(args)
223
224
225def get_all_skip_tests(args):
226    # !!! plz correct the condition when changing the default frontend
227    if args.ark_frontend and args.ark_frontend == ARK_FRONTEND_LIST[1]:
228        SKIP_LIST_FILES.append(ES2ABC_SKIP_LIST_FILE)
229    else:
230        SKIP_LIST_FILES.append(TS2ABC_SKIP_LIST_FILE)
231
232    if args.skip_list:
233        SKIP_LIST_FILES.append(os.path.join("test262", args.skip_list[0]))
234
235    for file in SKIP_LIST_FILES:
236        if file.endswith('.txt'):
237            with open(file, 'r') as txtfile:
238                for line in txtfile:
239                    # skip "#"
240                    line = line.strip()
241                    if line and not line.startswith('#'):
242                        new_line = "/".join(line.split("/")[3:])
243                        ALL_SKIP_TESTS.append(new_line)
244        else:
245            with open(file) as jsonfile:
246                json_data = json.load(jsonfile)
247                for key in json_data:
248                    ALL_SKIP_TESTS.extend(key["files"])
249
250
251def collect_files(path):
252    if os.path.isfile(path):
253        yield path
254        return
255
256    if not os.path.isdir(path):
257        raise ValueError(f'Not found: "{path}"')
258
259    for root, _, file_names in os.walk(path):
260        for file_name in file_names:
261            if file_name.startswith('.') or not file_name.endswith(".js"):
262                continue
263
264            yield os.path.join(root, file_name)
265
266
267def mkdstdir(file, src_dir, dist_dir):
268    idx = file.rfind(src_dir)
269    if idx == -1:
270        raise SystemExit(f'{file} can not found in {src_dir}')
271
272    fpath, fname = os.path.split(file[idx:])
273    fpath = fpath.replace(src_dir, dist_dir)
274    mkdir(fpath)
275
276
277class TestPrepare():
278    def __init__(self, args):
279        self.args = args
280        self.out_dir = BASE_OUT_DIR
281
282    @staticmethod
283    def get_tests_from_file(file):
284        with open(file) as fopen:
285            files = [line.strip() for line in fopen.readlines() if not line.startswith("#") and line.strip()]
286        return files
287
288    def prepare_test262_code(self):
289        if not os.path.isdir(os.path.join(DATA_DIR, '.git')):
290            if self.args.run_jit:
291                git_clone(TEST262_JIT_GIT_URL, DATA_DIR)
292                git_checkout(TEST262_JIT_GIT_HASH, DATA_DIR)
293            elif self.args.sendable == "sendable":
294                git_clone(SENDABLE_GIT_URL, DATA_DIR)
295                git_checkout(SENDABLE_GIT_HASH, DATA_DIR)
296            else:
297                git_clone(TEST262_GIT_URL, DATA_DIR)
298                git_checkout(TEST262_GIT_HASH, DATA_DIR)
299
300        if self.args.enable_rm and self.args.run_jit and not os.path.isfile(TEST262_JIT_LABEL):
301            remove_dir(DATA_DIR)
302            git_clone(TEST262_JIT_GIT_URL, DATA_DIR)
303            git_checkout(TEST262_JIT_GIT_HASH, DATA_DIR)
304
305        if not os.path.isdir(os.path.join(ESHOST_DIR, '.git')):
306            git_clone(ESHOST_GIT_URL, ESHOST_DIR)
307            git_checkout(ESHOST_GIT_HASH, ESHOST_DIR)
308            git_apply('../eshost.patch', ESHOST_DIR)
309
310        npm_install(ESHOST_DIR)
311
312        if not os.path.isdir(os.path.join(HARNESS_DIR, '.git')):
313            git_clone(HARNESS_GIT_URL, HARNESS_DIR)
314            git_checkout(HARNESS_GIT_HASH, HARNESS_DIR)
315            git_apply('../harness.patch', HARNESS_DIR)
316
317        npm_install(HARNESS_DIR)
318
319    def prepare_clean_data(self):
320        git_clean(DATA_DIR)
321        if self.args.run_jit:
322            git_checkout(TEST262_JIT_GIT_HASH, DATA_DIR)
323        elif self.args.sendable == "sendable":
324            git_checkout(SENDABLE_GIT_HASH, DATA_DIR)
325        else:
326            git_checkout(TEST262_GIT_HASH, DATA_DIR)
327
328    def patching_the_plugin(self):
329        remove_file(os.path.join(ESHOST_DIR, "lib/agents/panda.js"))
330        remove_file(os.path.join(ESHOST_DIR, "runtimes/panda.js"))
331
332        git_clean(ESHOST_DIR)
333        git_apply("../eshost.patch", ESHOST_DIR)
334        git_clean(HARNESS_DIR)
335        git_apply("../harness.patch", HARNESS_DIR)
336
337    def prepare_args_es51_es2021(self):
338        if self.args.dir:
339            if TEST_ES5_DIR in self.args.dir:
340                self.args.es51 = True
341            elif TEST_ES2015_DIR in self.args.dir:
342                self.args.es2015 = "es2015"
343            elif TEST_INTL_DIR in self.args.dir:
344                self.args.intl = "intl"
345            elif TEST_ES2021_DIR in self.args.dir:
346                self.args.es2021 = "all"
347            elif TEST_ES2022_DIR in self.args.dir:
348                self.args.es2022 = "all"
349            elif TEST_ES2023_DIR in self.args.dir:
350                self.args.es2023 = "all"
351            elif TEST_OTHERTESTS_DIR in self.args.dir:
352                self.args.other = "other"
353
354        if self.args.file:
355            if TEST_ES5_DIR in self.args.file:
356                self.args.es51 = True
357            elif TEST_ES2015_DIR in self.args.file:
358                self.args.es2015 = "es2015"
359            elif TEST_INTL_DIR in self.args.file:
360                self.args.intl = "intl"
361            elif TEST_ES2021_DIR in self.args.file:
362                self.args.es2021 = "all"
363            elif TEST_ES2022_DIR in self.args.file:
364                self.args.es2022 = "all"
365            elif TEST_ES2023_DIR in self.args.file:
366                self.args.es2023 = "all"
367            elif TEST_OTHERTESTS_DIR in self.args.file:
368                self.args.other = "other"
369
370    def prepare_out_dir(self):
371        if self.args.es51:
372            self.out_dir = os.path.join(BASE_OUT_DIR, "test_es51")
373        elif self.args.es2015:
374            self.out_dir = os.path.join(BASE_OUT_DIR, "test_es2015")
375        elif self.args.intl:
376            self.out_dir = os.path.join(BASE_OUT_DIR, "test_intl")
377        elif self.args.es2021:
378            self.out_dir = os.path.join(BASE_OUT_DIR, "test_es2021")
379        elif self.args.es2022:
380            self.out_dir = os.path.join(BASE_OUT_DIR, "test_es2022")
381        elif self.args.es2023:
382            self.out_dir = os.path.join(BASE_OUT_DIR, "test_es2023")
383        elif self.args.ci_build:
384            self.out_dir = os.path.join(BASE_OUT_DIR, "test_CI")
385        elif self.args.sendable:
386            self.out_dir = os.path.join(BASE_OUT_DIR, "test_sendable")
387        elif self.args.other:
388            self.out_dir = os.path.join(BASE_OUT_DIR, "other_tests")
389        else:
390            self.out_dir = os.path.join(BASE_OUT_DIR, "test")
391
392    def prepare_args_testdir(self):
393        if self.args.dir:
394            return
395
396        if self.args.es51:
397            self.args.dir = TEST_ES5_DIR
398        elif self.args.es2015:
399            self.args.dir = TEST_ES2015_DIR
400        elif self.args.intl:
401            self.args.dir = TEST_INTL_DIR
402        elif self.args.es2021:
403            self.args.dir = TEST_ES2021_DIR
404        elif self.args.sendable:
405            self.args.dir = TEST_SENDABLE_DIR
406        elif self.args.es2022:
407            self.args.dir = TEST_ES2022_DIR
408        elif self.args.es2023:
409            self.args.dir = TEST_ES2023_DIR
410        elif self.args.other:
411            self.args.dir = TEST_OTHERTESTS_DIR
412        elif self.args.ci_build:
413            self.args.dir = TEST_CI_DIR
414        else:
415            self.args.dir = os.path.join(DATA_DIR, "test")
416
417    def copyfile(self, file, all_skips):
418        dstdir = os.path.join(DATA_DIR, "test")
419        file = file.strip()
420        file = file.strip('\n')
421        file = file.replace("\\", "/")
422        if file in all_skips:
423            return
424
425        srcdir = os.path.join(DATA_DIR, "test", file)
426        if self.args.es51:
427            dstdir = os.path.join(TEST_ES5_DIR, file)
428        elif self.args.es2015:
429            dstdir = os.path.join(TEST_ES2015_DIR, file)
430        elif self.args.intl:
431            dstdir = os.path.join(TEST_INTL_DIR, file)
432        elif self.args.es2021:
433            dstdir = os.path.join(TEST_ES2021_DIR, file)
434        elif self.args.sendable:
435            dstdir = os.path.join(TEST_SENDABLE_DIR, file)
436        elif self.args.es2022:
437            dstdir = os.path.join(TEST_ES2022_DIR, file)
438        elif self.args.es2023:
439            dstdir = os.path.join(TEST_ES2023_DIR, file)
440        elif self.args.other:
441            dstdir = os.path.join(TEST_OTHERTESTS_DIR, file)
442        elif self.args.ci_build:
443            dstdir = os.path.join(TEST_CI_DIR, file)
444
445        if os.path.isfile(srcdir):
446            shutil.copyfile(srcdir, dstdir)
447
448
449    def collect_tests(self):
450        files = []
451        origin_dir = os.path.join(DATA_DIR, "test/")
452        file_names = collect_files(origin_dir)
453        esid = ""
454        if self.args.es51:
455            esid = "es5id"
456        elif self.args.es2021 or self.args.es2022 or self.args.es2023:
457            esid = "es6id"
458
459        for file_name in file_names:
460            with open(file_name, 'r', encoding='utf-8') as file:
461                file_content = file.read()
462                if esid in file_content:
463                    files.append(file_name.split(origin_dir)[1])
464        return files
465
466    def prepare_es2021_tests(self):
467        files = []
468        files = self.collect_tests()
469        files.extend(self.get_tests_from_file(ES2021_LIST_FILE))
470        if self.args.es2021 == "all":
471            files.extend(self.get_tests_from_file(ES5_LIST_FILE))
472            files.extend(self.get_tests_from_file(INTL_LIST_FILE))
473            files.extend(self.get_tests_from_file(ES2015_LIST_FILE))
474        if self.args.es2021 == "other":
475            files.extend(self.get_tests_from_file(ES5_LIST_FILE))
476            files.extend(self.get_tests_from_file(INTL_LIST_FILE))
477            files.extend(self.get_tests_from_file(ES2015_LIST_FILE))
478            files.extend(self.get_tests_from_file(OTHER_LIST_FILE))
479        return files
480
481    def prepare_sendable_tests(self):
482        files = []
483        if self.args.sendable == "sendable":
484            files.extend(self.get_tests_from_file(SENDABLE_LIST_FILE))
485        return files
486
487    def prepare_es2022_tests(self):
488        files = []
489        files.extend(self.get_tests_from_file(ES2022_LIST_FILE))
490        if self.args.es2022 == "all":
491            files.extend(self.get_tests_from_file(ES5_LIST_FILE))
492            files.extend(self.get_tests_from_file(INTL_LIST_FILE))
493            files.extend(self.get_tests_from_file(ES2015_LIST_FILE))
494            files.extend(self.collect_tests())
495            files.extend(self.get_tests_from_file(ES2021_LIST_FILE))
496        if self.args.es2022 == "other":
497            files.extend(self.get_tests_from_file(ES5_LIST_FILE))
498            files.extend(self.get_tests_from_file(INTL_LIST_FILE))
499            files.extend(self.get_tests_from_file(ES2015_LIST_FILE))
500            files.extend(self.collect_tests())
501            files.extend(self.get_tests_from_file(ES2021_LIST_FILE))
502            files.extend(self.get_tests_from_file(OTHER_LIST_FILE))
503        return files
504
505    def prepare_es2023_tests(self):
506        files = []
507        files.extend(self.get_tests_from_file(ES2023_LIST_FILE))
508        if self.args.es2023 == "all":
509            files.extend(self.get_tests_from_file(ES5_LIST_FILE))
510            files.extend(self.get_tests_from_file(INTL_LIST_FILE))
511            files.extend(self.get_tests_from_file(ES2015_LIST_FILE))
512            files.extend(self.collect_tests())
513            files.extend(self.get_tests_from_file(ES2021_LIST_FILE))
514            files.extend(self.get_tests_from_file(ES2022_LIST_FILE))
515        if self.args.es2023 == "other":
516            files.extend(self.get_tests_from_file(ES5_LIST_FILE))
517            files.extend(self.get_tests_from_file(INTL_LIST_FILE))
518            files.extend(self.get_tests_from_file(ES2015_LIST_FILE))
519            files.extend(self.collect_tests())
520            files.extend(self.get_tests_from_file(ES2021_LIST_FILE))
521            files.extend(self.get_tests_from_file(ES2022_LIST_FILE))
522            files.extend(self.get_tests_from_file(OTHER_LIST_FILE))
523        return files
524
525    def prepare_intl_tests(self):
526        files = []
527        files = self.collect_tests()
528        if self.args.intl:
529            files = self.get_tests_from_file(INTL_LIST_FILE)
530        return files
531
532    def prepare_other_tests(self):
533        files = []
534        files = self.collect_tests()
535        if self.args.other:
536            files = self.get_tests_from_file(OTHER_LIST_FILE)
537        return files
538
539    def prepare_es2015_tests(self):
540        files = []
541        files = self.collect_tests()
542        if self.args.es2015:
543            files = self.get_tests_from_file(ES2015_LIST_FILE)
544        return files
545
546    def prepare_test_suit(self):
547        files = []
548        test_dir = ""
549        if self.args.es51:
550            test_dir = TEST_ES5_DIR
551            files = self.get_tests_from_file(ES5_LIST_FILE)
552        elif self.args.es2015:
553            test_dir = TEST_ES2015_DIR
554            files = self.prepare_es2015_tests()
555        elif self.args.intl:
556            test_dir = TEST_INTL_DIR
557            files = self.prepare_intl_tests()
558        elif self.args.other:
559            test_dir = TEST_OTHERTESTS_DIR
560            files = self.prepare_other_tests()
561        elif self.args.es2021:
562            test_dir = TEST_ES2021_DIR
563            files = self.prepare_es2021_tests()
564        elif self.args.es2022:
565            test_dir = TEST_ES2022_DIR
566            files = self.prepare_es2022_tests()
567        elif self.args.es2023:
568            test_dir = TEST_ES2023_DIR
569            files = self.prepare_es2023_tests()
570        elif self.args.sendable:
571            test_dir = TEST_SENDABLE_DIR
572            files = self.prepare_sendable_tests()
573        elif self.args.ci_build:
574            test_dir = TEST_CI_DIR
575            files = self.get_tests_from_file(CI_LIST_FILE)
576
577        for file in files:
578            path = os.path.split(file)[0]
579            if not path.startswith(test_dir):
580                path = os.path.join(test_dir, path)
581            mkdir(path)
582
583            self.copyfile(file, ALL_SKIP_TESTS)
584
585    def prepare_test262_test(self):
586        src_dir = TEST_FULL_DIR
587        if self.args.es51:
588            self.prepare_test_suit()
589            src_dir = TEST_ES5_DIR
590        elif self.args.es2015:
591            self.prepare_test_suit()
592            src_dir = TEST_ES2015_DIR
593        elif self.args.intl:
594            self.prepare_test_suit()
595            src_dir = TEST_INTL_DIR
596        elif self.args.other:
597            self.prepare_test_suit()
598            src_dir = TEST_OTHERTESTS_DIR
599        elif self.args.es2021:
600            self.prepare_test_suit()
601            src_dir = TEST_ES2021_DIR
602        elif self.args.sendable:
603            self.prepare_test_suit()
604            src_dir = TEST_SENDABLE_DIR
605        elif self.args.es2022:
606            self.prepare_test_suit()
607            src_dir = TEST_ES2022_DIR
608        elif self.args.es2023:
609            self.prepare_test_suit()
610            src_dir = TEST_ES2023_DIR
611        elif self.args.ci_build:
612            self.prepare_test_suit()
613            src_dir = TEST_CI_DIR
614        elif self.args.esnext:
615            git_checkout(ESNEXT_GIT_HASH, DATA_DIR)
616        else:
617            if self.args.run_jit:
618                git_checkout(TEST262_JIT_GIT_HASH, DATA_DIR)
619            else:
620                git_checkout(TEST262_GIT_HASH, DATA_DIR)
621
622        if self.args.file:
623            mkdstdir(self.args.file, src_dir, self.out_dir)
624            return
625
626        files = []
627        if ':' in self.args.dir:
628            path = self.args.dir.split(':')
629            for p in path:
630                files.extend(collect_files(p))
631        else:
632            files = collect_files(self.args.dir)
633        for file in files:
634            mkdstdir(file, src_dir, self.out_dir)
635
636    def get_code(self):
637        self.prepare_test262_code()
638        self.prepare_clean_data()
639        self.patching_the_plugin()
640
641    def run(self):
642        self.prepare_args_es51_es2021()
643        self.prepare_out_dir()
644        self.prepare_args_testdir()
645        self.prepare_test262_test()
646
647
648def modetype_to_string(mode):
649    if mode == 1:
650        return "only default"
651    if mode == 2:
652        return "only strict mode"
653    return "both default and strict mode"
654
655
656def run_test262_mode(args):
657    if args.mode:
658        return modetype_to_string(args.mode)
659    return modetype_to_string(DEFAULT_MODE)
660
661
662def get_execute_arg(args) -> list[str]:
663    execute_args = []
664
665    if args.file:
666        execute_args.append(args.file)
667    else:
668        path = args.dir.split(':')
669        for p in path:
670            if not p.endswith('.js'):
671                execute_args.append(os.path.join(p, "**", "*.js"))
672            else:
673                execute_args.append(p)
674    return execute_args
675
676
677def get_host_path_type(args):
678    host_path = DEFAULT_HOST_PATH
679    host_type = DEFAULT_HOST_TYPE
680    if args.engine:
681        host_path = args.engine
682        host_type = os.path.split(args.engine.strip())[1]
683    return host_path, host_type
684
685
686def get_timeout(args, threads):
687    timeout = DEFAULT_TIMEOUT * threads
688    if args.timeout:
689        timeout = args.timeout
690    return timeout
691
692
693def get_threads(args):
694    threads = DEFAULT_THREADS
695    if args.threads:
696        threads = args.threads
697    return threads
698
699
700def get_host_args_of_product_name(args):
701    product_name = args.product_name
702    ark_dir = f"{ARGS_PREFIX}{product_name}/{ARK_DIR_SUFFIX}"
703    icui_dir = f"{ARGS_PREFIX}{product_name}/{ICUI_DIR_SUFFIX}"
704    ark_js_runtime_dir = f"{ARGS_PREFIX}{product_name}/{ARK_JS_RUNTIME_DIR_SUFFIX}"
705    zlib_dir = f"{ARGS_PREFIX}{product_name}/{ZLIB_DIR_SUFFIX}"
706
707    ark_tool = os.path.join(ark_js_runtime_dir, "ark_js_vm")
708    libs_dir = f"{icui_dir}:{LLVM_DIR}:{ark_js_runtime_dir}:{zlib_dir}"
709    ark_aot_tool = os.path.join(ark_js_runtime_dir, "ark_aot_compiler")
710    merge_abc_binary = os.path.join(ark_dir, "merge_abc")
711
712    return ark_tool, libs_dir, ark_aot_tool, merge_abc_binary
713
714
715def get_host_args_of_host_type(args, host_args, ark_tool, ark_aot_tool, libs_dir, ark_frontend,
716                               ark_frontend_binary, opt_level, es2abc_thread_count,
717                               merge_abc_binary, merge_abc_mode, product_name):
718    host_args = f"-B test262/run_sunspider.py "
719    host_args += f"--ark-tool={ark_tool} "
720    if args.ark_aot:
721        host_args += f"--ark-aot "
722    if args.run_pgo:
723        host_args += f"--run-pgo "
724    if args.enable_litecg:
725        host_args += f"--enable-litecg "
726    if args.run_jit:
727        host_args += f"--run-jit "
728    if args.run_baseline_jit:
729        host_args += f"--run-baseline-jit "
730    host_args += f"--ark-aot-tool={ark_aot_tool} "
731    host_args += f"--libs-dir={libs_dir} "
732    host_args += f"--ark-frontend={ark_frontend} "
733    host_args += f"--ark-frontend-binary={ark_frontend_binary} "
734    host_args += f"--opt-level={opt_level} "
735    host_args += f"--es2abc-thread-count={es2abc_thread_count} "
736    host_args += f"--merge-abc-binary={merge_abc_binary} "
737    host_args += f"--merge-abc-mode={merge_abc_mode} "
738    host_args += f"--product-name={product_name} "
739    if args.abc2program:
740        host_args = f"{host_args}--abc2program "
741    if args.enable_arkguard:
742        host_args = f"{host_args}--enable-arkguard "
743
744    return host_args
745
746
747def get_host_args_of_ark_arch(args, host_args):
748    host_args += f"--ark-arch={args.ark_arch} "
749    host_args += f"--ark-arch-root={args.ark_arch_root} "
750
751    return host_args
752
753
754def get_disable_force_gc(host_args, args):
755    host_args += f"--disable-force-gc "
756
757    return host_args
758
759
760def get_host_args_of_stub_file(args, host_args):
761    host_args += f"--stub-file={args.stub_file} "
762
763    return host_args
764
765
766def get_host_args(args, host_type):
767    host_args = ""
768    ark_tool = DEFAULT_ARK_TOOL
769    ark_aot_tool = DEFAULT_ARK_AOT_TOOL
770    libs_dir = DEFAULT_LIBS_DIR
771    ark_frontend = DEFAULT_ARK_FRONTEND
772    ark_frontend_binary = DEFAULT_ARK_FRONTEND_BINARY
773    ark_arch = DEFAULT_ARK_ARCH
774    stub_file = DEFAULT_STUB_FILE
775    opt_level = DEFAULT_OPT_LEVEL
776    es2abc_thread_count = DEFAULT_ES2ABC_THREAD_COUNT
777    merge_abc_binary = DEFAULT_MERGE_ABC_BINARY
778    merge_abc_mode = DEFAULT_MERGE_ABC_MODE
779    product_name = DEFAULT_PRODUCT_NAME
780
781    if args.product_name:
782        ark_tool, libs_dir, ark_aot_tool, merge_abc_binary = get_host_args_of_product_name(args)
783
784    if args.hostArgs:
785        host_args = args.hostArgs
786
787    if args.ark_tool:
788        ark_tool = args.ark_tool
789
790    if args.ark_aot_tool:
791        ark_aot_tool = args.ark_aot_tool
792
793    if args.libs_dir:
794        libs_dir = args.libs_dir
795
796    if args.ark_frontend:
797        ark_frontend = args.ark_frontend
798
799    if args.ark_frontend_binary:
800        ark_frontend_binary = args.ark_frontend_binary
801
802    if args.opt_level:
803        opt_level = args.opt_level
804
805    if args.es2abc_thread_count:
806        es2abc_thread_count = args.es2abc_thread_count
807
808    if args.merge_abc_binary:
809        merge_abc_binary = args.merge_abc_binary
810
811    if args.merge_abc_mode:
812        merge_abc_mode = args.merge_abc_mode
813
814    if host_type == DEFAULT_HOST_TYPE:
815        host_args = get_host_args_of_host_type(args, host_args, ark_tool, ark_aot_tool, libs_dir, ark_frontend,
816                                               ark_frontend_binary, opt_level, es2abc_thread_count,
817                                               merge_abc_binary, merge_abc_mode, product_name)
818
819    if args.ark_arch != ark_arch:
820        host_args = get_host_args_of_ark_arch(args, host_args)
821
822    if args.stub_file != stub_file:
823        host_args = get_host_args_of_stub_file(args, host_args)
824
825    if args.disable_force_gc:
826        host_args = get_disable_force_gc(host_args, args)
827
828    return host_args
829
830
831def run_test262_test(args):
832    execute_args = get_execute_arg(args)
833    host_path, host_type = get_host_path_type(args)
834    host_args = get_host_args(args, host_type)
835    threads = get_threads(args)
836    timeout = get_timeout(args, threads)
837
838    test_cmd = ["node", TEST262_RUNNER_SCRIPT]
839    test_cmd.append(f"--hostType={host_type}")
840    test_cmd.append(f"--hostPath={host_path}")
841    if host_args != "":
842        test_cmd.append(f"--hostArgs='{host_args}'")
843    test_cmd.append(f"--threads={threads}")
844    test_cmd.append(f"--mode={run_test262_mode(args)}")
845    test_cmd.append(f"--timeout={timeout}")
846    if platform.system() == "Windows" :
847        global BASE_OUT_DIR
848        global DATA_DIR
849        BASE_OUT_DIR = BASE_OUT_DIR.replace("/","\\")
850        DATA_DIR = DATA_DIR.replace("/","\\")
851        execute_args = [p.replace("/","\\") for p in execute_args]
852    test_cmd.append(f"--tempDir={BASE_OUT_DIR}")
853    test_cmd.append(f"--test262Dir={DATA_DIR}")
854    if args.test_list:
855        test_cmd.append("--isTestListSet")
856
857    if args.babel:
858        test_cmd.append("--preprocessor='test262/babel-preprocessor.js'")
859    test_cmd.append(DEFAULT_OTHER_ARGS)
860    test_cmd.extend(execute_args)
861
862    run_check(test_cmd)
863
864Check = collections.namedtuple('Check', ['enabled', 'runner', 'arg'])
865
866
867def prepare_test_list(args) -> List[str]:
868    if not os.path.exists(args.test_list):
869        args.test_list = os.path.join("test262", args.test_list)
870    test_list = TestPrepare.get_tests_from_file(args.test_list)
871    dirs: List[str] = []
872    for test in test_list:
873        parts = test.split(os.path.sep)[:3]
874        dirs.append(os.path.sep.join(parts))
875    return list(set(dirs))
876
877
878def reset_args(args):
879    args.es51 = None
880    args.es2015 = None
881    args.intl = None
882    args.other = None
883    args.es2021 = None
884    args.es2022 = None
885    args.es2023 = None
886    args.ci_build = None
887    args.esnext = None
888    args.dir = None
889
890
891def prepare_file_from_test_list(args, test_prepare):
892    folders = prepare_test_list(args)
893    for folder in folders:
894        reset_args(args)
895        args.dir = folder
896        test_prepare.run()
897    args.file = args.test_list
898
899
900def run(args):
901    init(args)
902
903    test_prepare = TestPrepare(args)
904    test_prepare.get_code()
905    if args.test_list:
906        prepare_file_from_test_list(args, test_prepare)
907    else:
908        test_prepare.run()
909    check = Check(True, run_test262_test, args)
910    check.runner(check.arg)
911
912
913def main(args):
914    print("\nWait a moment..........\n")
915    starttime = datetime.datetime.now()
916    run(args)
917    endtime = datetime.datetime.now()
918    print(f"used time is: {str(endtime - starttime)}")
919
920
921if __name__ == "__main__":
922    #  Script returns 0 if it's completed despite whether there are some failed tests or no
923    sys.exit(main(parse_args()))
924