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