1425bb815Sopenharmony_ci#!/usr/bin/env python
2425bb815Sopenharmony_ci
3425bb815Sopenharmony_ci# Copyright JS Foundation and other contributors, http://js.foundation
4425bb815Sopenharmony_ci#
5425bb815Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
6425bb815Sopenharmony_ci# you may not use this file except in compliance with the License.
7425bb815Sopenharmony_ci# You may obtain a copy of the License at
8425bb815Sopenharmony_ci#
9425bb815Sopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
10425bb815Sopenharmony_ci#
11425bb815Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software
12425bb815Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS
13425bb815Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14425bb815Sopenharmony_ci# See the License for the specific language governing permissions and
15425bb815Sopenharmony_ci# limitations under the License.
16425bb815Sopenharmony_ci
17425bb815Sopenharmony_cifrom __future__ import print_function
18425bb815Sopenharmony_ci
19425bb815Sopenharmony_ciimport argparse
20425bb815Sopenharmony_ciimport collections
21425bb815Sopenharmony_ciimport hashlib
22425bb815Sopenharmony_ciimport os
23425bb815Sopenharmony_ciimport platform
24425bb815Sopenharmony_ciimport subprocess
25425bb815Sopenharmony_ciimport sys
26425bb815Sopenharmony_ciimport settings
27425bb815Sopenharmony_ci
28425bb815Sopenharmony_ciOUTPUT_DIR = os.path.join(settings.PROJECT_DIR, 'build', 'tests')
29425bb815Sopenharmony_ci
30425bb815Sopenharmony_ciOptions = collections.namedtuple('Options', ['name', 'build_args', 'test_args', 'skip'])
31425bb815Sopenharmony_ciOptions.__new__.__defaults__ = ([], [], False)
32425bb815Sopenharmony_ci
33425bb815Sopenharmony_cidef skip_if(condition, desc):
34425bb815Sopenharmony_ci    return desc if condition else False
35425bb815Sopenharmony_ci
36425bb815Sopenharmony_ciOPTIONS_COMMON = ['--lto=off']
37425bb815Sopenharmony_ciOPTIONS_PROFILE_MIN = ['--profile=minimal']
38425bb815Sopenharmony_ciOPTIONS_PROFILE_ES51 = [] # NOTE: same as ['--profile=es5.1']
39425bb815Sopenharmony_ciOPTIONS_PROFILE_ES2015 = ['--profile=es2015-subset']
40425bb815Sopenharmony_ciOPTIONS_STACK_LIMIT = ['--stack-limit=96']
41425bb815Sopenharmony_ciOPTIONS_GC_MARK_LIMIT = ['--gc-mark-limit=16']
42425bb815Sopenharmony_ciOPTIONS_DEBUG = ['--debug']
43425bb815Sopenharmony_ciOPTIONS_SNAPSHOT = ['--snapshot-save=on', '--snapshot-exec=on', '--jerry-cmdline-snapshot=on']
44425bb815Sopenharmony_ciOPTIONS_UNITTESTS = ['--unittests=on', '--jerry-cmdline=off', '--error-messages=on',
45425bb815Sopenharmony_ci                     '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on',
46425bb815Sopenharmony_ci                     '--line-info=on', '--mem-stats=on']
47425bb815Sopenharmony_ciOPTIONS_DOCTESTS = ['--doctests=on', '--jerry-cmdline=off', '--error-messages=on',
48425bb815Sopenharmony_ci                    '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on']
49425bb815Sopenharmony_ci
50425bb815Sopenharmony_ci# Test options for unittests
51425bb815Sopenharmony_ciJERRY_UNITTESTS_OPTIONS = [
52425bb815Sopenharmony_ci    Options('unittests-es2015_subset',
53425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_UNITTESTS + OPTIONS_PROFILE_ES2015),
54425bb815Sopenharmony_ci    Options('unittests-es2015_subset-debug',
55425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_UNITTESTS + OPTIONS_PROFILE_ES2015 + OPTIONS_DEBUG),
56425bb815Sopenharmony_ci    Options('doctests-es2015_subset',
57425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_DOCTESTS + OPTIONS_PROFILE_ES2015),
58425bb815Sopenharmony_ci    Options('doctests-es2015_subset-debug',
59425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_DOCTESTS + OPTIONS_PROFILE_ES2015 + OPTIONS_DEBUG),
60425bb815Sopenharmony_ci    Options('unittests-es5.1',
61425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_UNITTESTS + OPTIONS_PROFILE_ES51),
62425bb815Sopenharmony_ci    Options('unittests-es5.1-debug',
63425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_UNITTESTS + OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG),
64425bb815Sopenharmony_ci    Options('doctests-es5.1',
65425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_DOCTESTS + OPTIONS_PROFILE_ES51),
66425bb815Sopenharmony_ci    Options('doctests-es5.1-debug',
67425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_DOCTESTS + OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG),
68425bb815Sopenharmony_ci    Options('unittests-es5.1-debug-init-fini',
69425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_UNITTESTS + OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG
70425bb815Sopenharmony_ci            + ['--cmake-param=-DFEATURE_INIT_FINI=ON'],
71425bb815Sopenharmony_ci            skip=skip_if((sys.platform == 'win32'), 'FEATURE_INIT_FINI build flag isn\'t supported on Windows,' +
72425bb815Sopenharmony_ci                         ' because Microsoft Visual C/C++ Compiler doesn\'t support' +
73425bb815Sopenharmony_ci                         ' library constructors and destructors.')),
74425bb815Sopenharmony_ci]
75425bb815Sopenharmony_ci
76425bb815Sopenharmony_ci# Test options for jerry-tests
77425bb815Sopenharmony_ciJERRY_TESTS_OPTIONS = [
78425bb815Sopenharmony_ci    Options('jerry_tests-es2015_subset-debug',
79425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_PROFILE_ES2015 + OPTIONS_DEBUG + OPTIONS_STACK_LIMIT + OPTIONS_GC_MARK_LIMIT),
80425bb815Sopenharmony_ci    Options('jerry_tests-es5.1',
81425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_PROFILE_ES51 + OPTIONS_STACK_LIMIT + OPTIONS_GC_MARK_LIMIT),
82425bb815Sopenharmony_ci    Options('jerry_tests-es5.1-snapshot',
83425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_PROFILE_ES51 + OPTIONS_SNAPSHOT + OPTIONS_STACK_LIMIT + OPTIONS_GC_MARK_LIMIT,
84425bb815Sopenharmony_ci            ['--snapshot']),
85425bb815Sopenharmony_ci    Options('jerry_tests-es5.1-debug',
86425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG + OPTIONS_STACK_LIMIT + OPTIONS_GC_MARK_LIMIT),
87425bb815Sopenharmony_ci    Options('jerry_tests-es5.1-debug-snapshot',
88425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_PROFILE_ES51 + OPTIONS_SNAPSHOT + OPTIONS_DEBUG + OPTIONS_STACK_LIMIT
89425bb815Sopenharmony_ci            + OPTIONS_GC_MARK_LIMIT, ['--snapshot']),
90425bb815Sopenharmony_ci    Options('jerry_tests-es5.1-debug-cpointer_32bit',
91425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG + OPTIONS_STACK_LIMIT + OPTIONS_GC_MARK_LIMIT
92425bb815Sopenharmony_ci            + ['--cpointer-32bit=on', '--mem-heap=1024']),
93425bb815Sopenharmony_ci    Options('jerry_tests-es5.1-debug-external_context',
94425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG + OPTIONS_STACK_LIMIT + OPTIONS_GC_MARK_LIMIT
95425bb815Sopenharmony_ci            + ['--external-context=on']),
96425bb815Sopenharmony_ci]
97425bb815Sopenharmony_ci
98425bb815Sopenharmony_ci# Test options for jerry-test-suite
99425bb815Sopenharmony_ciJERRY_TEST_SUITE_OPTIONS = JERRY_TESTS_OPTIONS[:]
100425bb815Sopenharmony_ciJERRY_TEST_SUITE_OPTIONS.extend([
101425bb815Sopenharmony_ci    Options('jerry_test_suite-minimal',
102425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_PROFILE_MIN),
103425bb815Sopenharmony_ci    Options('jerry_test_suite-minimal-snapshot',
104425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_PROFILE_MIN + OPTIONS_SNAPSHOT,
105425bb815Sopenharmony_ci            ['--snapshot']),
106425bb815Sopenharmony_ci    Options('jerry_test_suite-minimal-debug',
107425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_PROFILE_MIN + OPTIONS_DEBUG),
108425bb815Sopenharmony_ci    Options('jerry_test_suite-minimal-debug-snapshot',
109425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_PROFILE_MIN + OPTIONS_SNAPSHOT + OPTIONS_DEBUG,
110425bb815Sopenharmony_ci            ['--snapshot']),
111425bb815Sopenharmony_ci    Options('jerry_test_suite-es2015_subset',
112425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_PROFILE_ES2015),
113425bb815Sopenharmony_ci    Options('jerry_test_suite-es2015_subset-snapshot',
114425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_PROFILE_ES2015 + OPTIONS_SNAPSHOT,
115425bb815Sopenharmony_ci            ['--snapshot']),
116425bb815Sopenharmony_ci    Options('jerry_test_suite-es2015_subset-debug-snapshot',
117425bb815Sopenharmony_ci            OPTIONS_COMMON + OPTIONS_PROFILE_ES2015 + OPTIONS_SNAPSHOT + OPTIONS_DEBUG,
118425bb815Sopenharmony_ci            ['--snapshot']),
119425bb815Sopenharmony_ci])
120425bb815Sopenharmony_ci
121425bb815Sopenharmony_ci# Test options for test262
122425bb815Sopenharmony_ciTEST262_TEST_SUITE_OPTIONS = [
123425bb815Sopenharmony_ci    Options('test262_tests'),
124425bb815Sopenharmony_ci    Options('test262_tests-debug', OPTIONS_DEBUG)
125425bb815Sopenharmony_ci]
126425bb815Sopenharmony_ci
127425bb815Sopenharmony_ci# Test options for test262-es2015
128425bb815Sopenharmony_ciTEST262_ES2015_TEST_SUITE_OPTIONS = [
129425bb815Sopenharmony_ci    Options('test262_tests_es2015', OPTIONS_PROFILE_ES2015 + ['--line-info=on', '--error-messages=on']),
130425bb815Sopenharmony_ci]
131425bb815Sopenharmony_ci
132425bb815Sopenharmony_ci# Test options for jerry-debugger
133425bb815Sopenharmony_ciDEBUGGER_TEST_OPTIONS = [
134425bb815Sopenharmony_ci    Options('jerry_debugger_tests',
135425bb815Sopenharmony_ci            OPTIONS_DEBUG + ['--jerry-debugger=on'])
136425bb815Sopenharmony_ci]
137425bb815Sopenharmony_ci
138425bb815Sopenharmony_ci# Test options for buildoption-test
139425bb815Sopenharmony_ciJERRY_BUILDOPTIONS = [
140425bb815Sopenharmony_ci    Options('buildoption_test-lto',
141425bb815Sopenharmony_ci            ['--lto=on']),
142425bb815Sopenharmony_ci    Options('buildoption_test-error_messages',
143425bb815Sopenharmony_ci            ['--error-messages=on']),
144425bb815Sopenharmony_ci    Options('buildoption_test-logging',
145425bb815Sopenharmony_ci            ['--logging=on']),
146425bb815Sopenharmony_ci    Options('buildoption_test-all_in_one',
147425bb815Sopenharmony_ci            ['--all-in-one=on']),
148425bb815Sopenharmony_ci    Options('buildoption_test-valgrind',
149425bb815Sopenharmony_ci            ['--valgrind=on']),
150425bb815Sopenharmony_ci    Options('buildoption_test-mem_stats',
151425bb815Sopenharmony_ci            ['--mem-stats=on']),
152425bb815Sopenharmony_ci    Options('buildoption_test-show_opcodes',
153425bb815Sopenharmony_ci            ['--show-opcodes=on']),
154425bb815Sopenharmony_ci    Options('buildoption_test-show_regexp_opcodes',
155425bb815Sopenharmony_ci            ['--show-regexp-opcodes=on']),
156425bb815Sopenharmony_ci    Options('buildoption_test-cpointer_32bit',
157425bb815Sopenharmony_ci            ['--compile-flag=-m32', '--cpointer-32bit=on', '--system-allocator=on'],
158425bb815Sopenharmony_ci            skip=skip_if(
159425bb815Sopenharmony_ci                platform.system() != 'Linux' or (platform.machine() != 'i386' and platform.machine() != 'x86_64'),
160425bb815Sopenharmony_ci                '-m32 is only supported on x86[-64]-linux')
161425bb815Sopenharmony_ci           ),
162425bb815Sopenharmony_ci    Options('buildoption_test-no_jerry_libm',
163425bb815Sopenharmony_ci            ['--jerry-libm=off', '--link-lib=m'],
164425bb815Sopenharmony_ci            skip=skip_if((sys.platform == 'win32'), 'There is no separated libm on Windows')),
165425bb815Sopenharmony_ci    Options('buildoption_test-no_lcache_prophashmap',
166425bb815Sopenharmony_ci            ['--compile-flag=-DJERRY_LCACHE=0', '--compile-flag=-DJERRY_PROPRETY_HASHMAP=0']),
167425bb815Sopenharmony_ci    Options('buildoption_test-external_context',
168425bb815Sopenharmony_ci            ['--external-context=on']),
169425bb815Sopenharmony_ci    Options('buildoption_test-shared_libs',
170425bb815Sopenharmony_ci            ['--shared-libs=on'],
171425bb815Sopenharmony_ci            skip=skip_if((sys.platform == 'win32'), 'Not yet supported, link failure on Windows')),
172425bb815Sopenharmony_ci    Options('buildoption_test-cmdline_test',
173425bb815Sopenharmony_ci            ['--jerry-cmdline-test=on'],
174425bb815Sopenharmony_ci            skip=skip_if((sys.platform == 'win32'), 'rand() can\'t be overriden on Windows (benchmarking.c)')),
175425bb815Sopenharmony_ci    Options('buildoption_test-cmdline_snapshot',
176425bb815Sopenharmony_ci            ['--jerry-cmdline-snapshot=on']),
177425bb815Sopenharmony_ci    Options('buildoption_test-recursion_limit',
178425bb815Sopenharmony_ci            OPTIONS_STACK_LIMIT),
179425bb815Sopenharmony_ci    Options('buildoption_test-gc-mark_limit',
180425bb815Sopenharmony_ci            OPTIONS_GC_MARK_LIMIT),
181425bb815Sopenharmony_ci    Options('buildoption_test-single-source',
182425bb815Sopenharmony_ci            ['--cmake-param=-DENABLE_ALL_IN_ONE_SOURCE=ON']),
183425bb815Sopenharmony_ci    Options('buildoption_test-jerry-debugger',
184425bb815Sopenharmony_ci            ['--jerry-debugger=on']),
185425bb815Sopenharmony_ci]
186425bb815Sopenharmony_ci
187425bb815Sopenharmony_cidef get_arguments():
188425bb815Sopenharmony_ci    parser = argparse.ArgumentParser()
189425bb815Sopenharmony_ci    parser.add_argument('--toolchain', metavar='FILE',
190425bb815Sopenharmony_ci                        help='Add toolchain file')
191425bb815Sopenharmony_ci    parser.add_argument('-q', '--quiet', action='store_true',
192425bb815Sopenharmony_ci                        help='Only print out failing tests')
193425bb815Sopenharmony_ci    parser.add_argument('--buildoptions', metavar='LIST',
194425bb815Sopenharmony_ci                        help='Add a comma separated list of extra build options to each test')
195425bb815Sopenharmony_ci    parser.add_argument('--skip-list', metavar='LIST',
196425bb815Sopenharmony_ci                        help='Add a comma separated list of patterns of the excluded JS-tests')
197425bb815Sopenharmony_ci    parser.add_argument('--outdir', metavar='DIR', default=OUTPUT_DIR,
198425bb815Sopenharmony_ci                        help='Specify output directory (default: %(default)s)')
199425bb815Sopenharmony_ci    parser.add_argument('--check-signed-off', metavar='TYPE', nargs='?',
200425bb815Sopenharmony_ci                        choices=['strict', 'tolerant', 'travis'], const='strict',
201425bb815Sopenharmony_ci                        help='Run signed-off check (%(choices)s; default type if not given: %(const)s)')
202425bb815Sopenharmony_ci    parser.add_argument('--check-cppcheck', action='store_true',
203425bb815Sopenharmony_ci                        help='Run cppcheck')
204425bb815Sopenharmony_ci    parser.add_argument('--check-doxygen', action='store_true',
205425bb815Sopenharmony_ci                        help='Run doxygen')
206425bb815Sopenharmony_ci    parser.add_argument('--check-pylint', action='store_true',
207425bb815Sopenharmony_ci                        help='Run pylint')
208425bb815Sopenharmony_ci    parser.add_argument('--check-vera', action='store_true',
209425bb815Sopenharmony_ci                        help='Run vera check')
210425bb815Sopenharmony_ci    parser.add_argument('--check-license', action='store_true',
211425bb815Sopenharmony_ci                        help='Run license check')
212425bb815Sopenharmony_ci    parser.add_argument('--check-magic-strings', action='store_true',
213425bb815Sopenharmony_ci                        help='Run "magic string source code generator should be executed" check')
214425bb815Sopenharmony_ci    parser.add_argument('--jerry-debugger', action='store_true',
215425bb815Sopenharmony_ci                        help='Run jerry-debugger tests')
216425bb815Sopenharmony_ci    parser.add_argument('--jerry-tests', action='store_true',
217425bb815Sopenharmony_ci                        help='Run jerry-tests')
218425bb815Sopenharmony_ci    parser.add_argument('--jerry-test-suite', action='store_true',
219425bb815Sopenharmony_ci                        help='Run jerry-test-suite')
220425bb815Sopenharmony_ci    parser.add_argument('--test262', action='store_true',
221425bb815Sopenharmony_ci                        help='Run test262 - ES5.1')
222425bb815Sopenharmony_ci    parser.add_argument('--test262-es2015', action='store_true',
223425bb815Sopenharmony_ci                        help='Run test262 - ES2015')
224425bb815Sopenharmony_ci    parser.add_argument('--unittests', action='store_true',
225425bb815Sopenharmony_ci                        help='Run unittests (including doctests)')
226425bb815Sopenharmony_ci    parser.add_argument('--buildoption-test', action='store_true',
227425bb815Sopenharmony_ci                        help='Run buildoption-test')
228425bb815Sopenharmony_ci    parser.add_argument('--all', '--precommit', action='store_true',
229425bb815Sopenharmony_ci                        help='Run all tests')
230425bb815Sopenharmony_ci
231425bb815Sopenharmony_ci    if len(sys.argv) == 1:
232425bb815Sopenharmony_ci        parser.print_help()
233425bb815Sopenharmony_ci        sys.exit(1)
234425bb815Sopenharmony_ci
235425bb815Sopenharmony_ci    script_args = parser.parse_args()
236425bb815Sopenharmony_ci
237425bb815Sopenharmony_ci    return script_args
238425bb815Sopenharmony_ci
239425bb815Sopenharmony_ciBINARY_CACHE = {}
240425bb815Sopenharmony_ci
241425bb815Sopenharmony_ciTERM_NORMAL = '\033[0m'
242425bb815Sopenharmony_ciTERM_YELLOW = '\033[1;33m'
243425bb815Sopenharmony_ciTERM_BLUE = '\033[1;34m'
244425bb815Sopenharmony_ciTERM_RED = '\033[1;31m'
245425bb815Sopenharmony_ci
246425bb815Sopenharmony_cidef report_command(cmd_type, cmd, env=None):
247425bb815Sopenharmony_ci    sys.stderr.write('%s%s%s\n' % (TERM_BLUE, cmd_type, TERM_NORMAL))
248425bb815Sopenharmony_ci    if env is not None:
249425bb815Sopenharmony_ci        sys.stderr.write(''.join('%s%s=%r \\%s\n' % (TERM_BLUE, var, val, TERM_NORMAL)
250425bb815Sopenharmony_ci                                 for var, val in sorted(env.items())))
251425bb815Sopenharmony_ci    sys.stderr.write('%s%s%s\n' % (TERM_BLUE, (' \\%s\n\t%s' % (TERM_NORMAL, TERM_BLUE)).join(cmd), TERM_NORMAL))
252425bb815Sopenharmony_ci
253425bb815Sopenharmony_cidef report_skip(job):
254425bb815Sopenharmony_ci    sys.stderr.write('%sSkipping: %s' % (TERM_YELLOW, job.name))
255425bb815Sopenharmony_ci    if job.skip:
256425bb815Sopenharmony_ci        sys.stderr.write(' (%s)' % job.skip)
257425bb815Sopenharmony_ci    sys.stderr.write('%s\n' % TERM_NORMAL)
258425bb815Sopenharmony_ci
259425bb815Sopenharmony_cidef get_platform_cmd_prefix():
260425bb815Sopenharmony_ci    if sys.platform == 'win32':
261425bb815Sopenharmony_ci        return ['cmd', '/S', '/C']
262425bb815Sopenharmony_ci    return []
263425bb815Sopenharmony_ci
264425bb815Sopenharmony_cidef create_binary(job, options):
265425bb815Sopenharmony_ci    build_args = job.build_args[:]
266425bb815Sopenharmony_ci    if options.buildoptions:
267425bb815Sopenharmony_ci        for option in options.buildoptions.split(','):
268425bb815Sopenharmony_ci            if option not in build_args:
269425bb815Sopenharmony_ci                build_args.append(option)
270425bb815Sopenharmony_ci
271425bb815Sopenharmony_ci    build_cmd = get_platform_cmd_prefix()
272425bb815Sopenharmony_ci    build_cmd.append(settings.BUILD_SCRIPT)
273425bb815Sopenharmony_ci    build_cmd.extend(build_args)
274425bb815Sopenharmony_ci
275425bb815Sopenharmony_ci    build_dir_path = os.path.join(options.outdir, job.name)
276425bb815Sopenharmony_ci    build_cmd.append('--builddir=%s' % build_dir_path)
277425bb815Sopenharmony_ci
278425bb815Sopenharmony_ci    install_dir_path = os.path.join(build_dir_path, 'local')
279425bb815Sopenharmony_ci    build_cmd.append('--install=%s' % install_dir_path)
280425bb815Sopenharmony_ci
281425bb815Sopenharmony_ci    if options.toolchain:
282425bb815Sopenharmony_ci        build_cmd.append('--toolchain=%s' % options.toolchain)
283425bb815Sopenharmony_ci
284425bb815Sopenharmony_ci    report_command('Build command:', build_cmd)
285425bb815Sopenharmony_ci
286425bb815Sopenharmony_ci    binary_key = tuple(sorted(build_args))
287425bb815Sopenharmony_ci    if binary_key in BINARY_CACHE:
288425bb815Sopenharmony_ci        ret, build_dir_path = BINARY_CACHE[binary_key]
289425bb815Sopenharmony_ci        sys.stderr.write('(skipping: already built at %s with returncode %d)\n' % (build_dir_path, ret))
290425bb815Sopenharmony_ci        return ret, build_dir_path
291425bb815Sopenharmony_ci
292425bb815Sopenharmony_ci    try:
293425bb815Sopenharmony_ci        subprocess.check_output(build_cmd)
294425bb815Sopenharmony_ci        ret = 0
295425bb815Sopenharmony_ci    except subprocess.CalledProcessError as err:
296425bb815Sopenharmony_ci        print(err.output)
297425bb815Sopenharmony_ci        ret = err.returncode
298425bb815Sopenharmony_ci
299425bb815Sopenharmony_ci    BINARY_CACHE[binary_key] = (ret, build_dir_path)
300425bb815Sopenharmony_ci    return ret, build_dir_path
301425bb815Sopenharmony_ci
302425bb815Sopenharmony_cidef get_binary_path(build_dir_path):
303425bb815Sopenharmony_ci    executable_extension = '.exe' if sys.platform == 'win32' else ''
304425bb815Sopenharmony_ci    return os.path.join(build_dir_path, 'local', 'bin', 'jerry' + executable_extension)
305425bb815Sopenharmony_ci
306425bb815Sopenharmony_cidef hash_binary(bin_path):
307425bb815Sopenharmony_ci    blocksize = 65536
308425bb815Sopenharmony_ci    hasher = hashlib.sha1()
309425bb815Sopenharmony_ci    with open(bin_path, 'rb') as bin_file:
310425bb815Sopenharmony_ci        buf = bin_file.read(blocksize)
311425bb815Sopenharmony_ci        while buf:
312425bb815Sopenharmony_ci            hasher.update(buf)
313425bb815Sopenharmony_ci            buf = bin_file.read(blocksize)
314425bb815Sopenharmony_ci    return hasher.hexdigest()
315425bb815Sopenharmony_ci
316425bb815Sopenharmony_cidef iterate_test_runner_jobs(jobs, options):
317425bb815Sopenharmony_ci    tested_paths = set()
318425bb815Sopenharmony_ci    tested_hashes = {}
319425bb815Sopenharmony_ci
320425bb815Sopenharmony_ci    for job in jobs:
321425bb815Sopenharmony_ci        ret_build, build_dir_path = create_binary(job, options)
322425bb815Sopenharmony_ci        if ret_build:
323425bb815Sopenharmony_ci            yield job, ret_build, None
324425bb815Sopenharmony_ci
325425bb815Sopenharmony_ci        if build_dir_path in tested_paths:
326425bb815Sopenharmony_ci            sys.stderr.write('(skipping: already tested with %s)\n' % build_dir_path)
327425bb815Sopenharmony_ci            continue
328425bb815Sopenharmony_ci        else:
329425bb815Sopenharmony_ci            tested_paths.add(build_dir_path)
330425bb815Sopenharmony_ci
331425bb815Sopenharmony_ci        bin_path = get_binary_path(build_dir_path)
332425bb815Sopenharmony_ci        bin_hash = hash_binary(bin_path)
333425bb815Sopenharmony_ci
334425bb815Sopenharmony_ci        if bin_hash in tested_hashes:
335425bb815Sopenharmony_ci            sys.stderr.write('(skipping: already tested with equivalent %s)\n' % tested_hashes[bin_hash])
336425bb815Sopenharmony_ci            continue
337425bb815Sopenharmony_ci        else:
338425bb815Sopenharmony_ci            tested_hashes[bin_hash] = build_dir_path
339425bb815Sopenharmony_ci
340425bb815Sopenharmony_ci        test_cmd = get_platform_cmd_prefix()
341425bb815Sopenharmony_ci        test_cmd.extend([settings.TEST_RUNNER_SCRIPT, '--engine', bin_path])
342425bb815Sopenharmony_ci
343425bb815Sopenharmony_ci        yield job, ret_build, test_cmd
344425bb815Sopenharmony_ci
345425bb815Sopenharmony_cidef run_check(runnable, env=None):
346425bb815Sopenharmony_ci    report_command('Test command:', runnable, env=env)
347425bb815Sopenharmony_ci
348425bb815Sopenharmony_ci    if env is not None:
349425bb815Sopenharmony_ci        full_env = dict(os.environ)
350425bb815Sopenharmony_ci        full_env.update(env)
351425bb815Sopenharmony_ci        env = full_env
352425bb815Sopenharmony_ci
353425bb815Sopenharmony_ci    proc = subprocess.Popen(runnable, env=env)
354425bb815Sopenharmony_ci    proc.wait()
355425bb815Sopenharmony_ci    return proc.returncode
356425bb815Sopenharmony_ci
357425bb815Sopenharmony_cidef run_jerry_debugger_tests(options):
358425bb815Sopenharmony_ci    ret_build = ret_test = 0
359425bb815Sopenharmony_ci    for job in DEBUGGER_TEST_OPTIONS:
360425bb815Sopenharmony_ci        ret_build, build_dir_path = create_binary(job, options)
361425bb815Sopenharmony_ci        if ret_build:
362425bb815Sopenharmony_ci            print("\n%sBuild failed%s\n" % (TERM_RED, TERM_NORMAL))
363425bb815Sopenharmony_ci            break
364425bb815Sopenharmony_ci
365425bb815Sopenharmony_ci        for channel in ["websocket", "rawpacket"]:
366425bb815Sopenharmony_ci            for test_file in os.listdir(settings.DEBUGGER_TESTS_DIR):
367425bb815Sopenharmony_ci                if test_file.endswith(".cmd"):
368425bb815Sopenharmony_ci                    test_case, _ = os.path.splitext(test_file)
369425bb815Sopenharmony_ci                    test_case_path = os.path.join(settings.DEBUGGER_TESTS_DIR, test_case)
370425bb815Sopenharmony_ci                    test_cmd = [
371425bb815Sopenharmony_ci                        settings.DEBUGGER_TEST_RUNNER_SCRIPT,
372425bb815Sopenharmony_ci                        get_binary_path(build_dir_path),
373425bb815Sopenharmony_ci                        channel,
374425bb815Sopenharmony_ci                        settings.DEBUGGER_CLIENT_SCRIPT,
375425bb815Sopenharmony_ci                        os.path.relpath(test_case_path, settings.PROJECT_DIR)
376425bb815Sopenharmony_ci                    ]
377425bb815Sopenharmony_ci
378425bb815Sopenharmony_ci                    if job.test_args:
379425bb815Sopenharmony_ci                        test_cmd.extend(job.test_args)
380425bb815Sopenharmony_ci
381425bb815Sopenharmony_ci                    ret_test |= run_check(test_cmd)
382425bb815Sopenharmony_ci
383425bb815Sopenharmony_ci    return ret_build | ret_test
384425bb815Sopenharmony_ci
385425bb815Sopenharmony_cidef run_jerry_tests(options):
386425bb815Sopenharmony_ci    ret_build = ret_test = 0
387425bb815Sopenharmony_ci    for job, ret_build, test_cmd in iterate_test_runner_jobs(JERRY_TESTS_OPTIONS, options):
388425bb815Sopenharmony_ci        if ret_build:
389425bb815Sopenharmony_ci            break
390425bb815Sopenharmony_ci
391425bb815Sopenharmony_ci        test_cmd.append('--test-dir')
392425bb815Sopenharmony_ci        test_cmd.append(settings.JERRY_TESTS_DIR)
393425bb815Sopenharmony_ci
394425bb815Sopenharmony_ci        if options.quiet:
395425bb815Sopenharmony_ci            test_cmd.append("-q")
396425bb815Sopenharmony_ci
397425bb815Sopenharmony_ci        skip_list = []
398425bb815Sopenharmony_ci
399425bb815Sopenharmony_ci        if '--profile=es2015-subset' in job.build_args:
400425bb815Sopenharmony_ci            skip_list.append(os.path.join('es5.1', ''))
401425bb815Sopenharmony_ci        else:
402425bb815Sopenharmony_ci            skip_list.append(os.path.join('es2015', ''))
403425bb815Sopenharmony_ci
404425bb815Sopenharmony_ci        if options.skip_list:
405425bb815Sopenharmony_ci            skip_list.append(options.skip_list)
406425bb815Sopenharmony_ci
407425bb815Sopenharmony_ci        if skip_list:
408425bb815Sopenharmony_ci            test_cmd.append("--skip-list=" + ",".join(skip_list))
409425bb815Sopenharmony_ci
410425bb815Sopenharmony_ci        if job.test_args:
411425bb815Sopenharmony_ci            test_cmd.extend(job.test_args)
412425bb815Sopenharmony_ci
413425bb815Sopenharmony_ci        ret_test |= run_check(test_cmd, env=dict(TZ='UTC'))
414425bb815Sopenharmony_ci
415425bb815Sopenharmony_ci    return ret_build | ret_test
416425bb815Sopenharmony_ci
417425bb815Sopenharmony_cidef run_jerry_test_suite(options):
418425bb815Sopenharmony_ci    ret_build = ret_test = 0
419425bb815Sopenharmony_ci    for job, ret_build, test_cmd in iterate_test_runner_jobs(JERRY_TEST_SUITE_OPTIONS, options):
420425bb815Sopenharmony_ci        if ret_build:
421425bb815Sopenharmony_ci            break
422425bb815Sopenharmony_ci
423425bb815Sopenharmony_ci        skip_list = []
424425bb815Sopenharmony_ci
425425bb815Sopenharmony_ci        if '--profile=minimal' in job.build_args:
426425bb815Sopenharmony_ci            test_cmd.append('--test-list')
427425bb815Sopenharmony_ci            test_cmd.append(settings.JERRY_TEST_SUITE_MINIMAL_LIST)
428425bb815Sopenharmony_ci        else:
429425bb815Sopenharmony_ci            test_cmd.append('--test-dir')
430425bb815Sopenharmony_ci            test_cmd.append(settings.JERRY_TEST_SUITE_DIR)
431425bb815Sopenharmony_ci            if '--profile=es2015-subset' in job.build_args:
432425bb815Sopenharmony_ci                skip_list.append(os.path.join('es5.1', ''))
433425bb815Sopenharmony_ci            else:
434425bb815Sopenharmony_ci                skip_list.append(os.path.join('es2015', ''))
435425bb815Sopenharmony_ci
436425bb815Sopenharmony_ci        if options.quiet:
437425bb815Sopenharmony_ci            test_cmd.append("-q")
438425bb815Sopenharmony_ci
439425bb815Sopenharmony_ci        if options.skip_list:
440425bb815Sopenharmony_ci            skip_list.append(options.skip_list)
441425bb815Sopenharmony_ci
442425bb815Sopenharmony_ci        if skip_list:
443425bb815Sopenharmony_ci            test_cmd.append("--skip-list=" + ",".join(skip_list))
444425bb815Sopenharmony_ci
445425bb815Sopenharmony_ci        if job.test_args:
446425bb815Sopenharmony_ci            test_cmd.extend(job.test_args)
447425bb815Sopenharmony_ci
448425bb815Sopenharmony_ci        ret_test |= run_check(test_cmd)
449425bb815Sopenharmony_ci
450425bb815Sopenharmony_ci    return ret_build | ret_test
451425bb815Sopenharmony_ci
452425bb815Sopenharmony_cidef run_test262_test_suite(options):
453425bb815Sopenharmony_ci    ret_build = ret_test = 0
454425bb815Sopenharmony_ci
455425bb815Sopenharmony_ci    jobs = []
456425bb815Sopenharmony_ci    if options.test262:
457425bb815Sopenharmony_ci        jobs.extend(TEST262_TEST_SUITE_OPTIONS)
458425bb815Sopenharmony_ci    if options.test262_es2015:
459425bb815Sopenharmony_ci        jobs.extend(TEST262_ES2015_TEST_SUITE_OPTIONS)
460425bb815Sopenharmony_ci
461425bb815Sopenharmony_ci    for job in jobs:
462425bb815Sopenharmony_ci        ret_build, build_dir_path = create_binary(job, options)
463425bb815Sopenharmony_ci        if ret_build:
464425bb815Sopenharmony_ci            print("\n%sBuild failed%s\n" % (TERM_RED, TERM_NORMAL))
465425bb815Sopenharmony_ci            break
466425bb815Sopenharmony_ci
467425bb815Sopenharmony_ci        test_cmd = get_platform_cmd_prefix() + [
468425bb815Sopenharmony_ci            settings.TEST262_RUNNER_SCRIPT,
469425bb815Sopenharmony_ci            '--engine', get_binary_path(build_dir_path),
470425bb815Sopenharmony_ci            '--test-dir', settings.TEST262_TEST_SUITE_DIR
471425bb815Sopenharmony_ci        ]
472425bb815Sopenharmony_ci
473425bb815Sopenharmony_ci        if '--profile=es2015-subset' in job.build_args:
474425bb815Sopenharmony_ci            test_cmd.append('--es2015')
475425bb815Sopenharmony_ci        else:
476425bb815Sopenharmony_ci            test_cmd.append('--es51')
477425bb815Sopenharmony_ci
478425bb815Sopenharmony_ci        if job.test_args:
479425bb815Sopenharmony_ci            test_cmd.extend(job.test_args)
480425bb815Sopenharmony_ci
481425bb815Sopenharmony_ci        ret_test |= run_check(test_cmd, env=dict(TZ='America/Los_Angeles'))
482425bb815Sopenharmony_ci
483425bb815Sopenharmony_ci    return ret_build | ret_test
484425bb815Sopenharmony_ci
485425bb815Sopenharmony_cidef run_unittests(options):
486425bb815Sopenharmony_ci    ret_build = ret_test = 0
487425bb815Sopenharmony_ci    for job in JERRY_UNITTESTS_OPTIONS:
488425bb815Sopenharmony_ci        if job.skip:
489425bb815Sopenharmony_ci            report_skip(job)
490425bb815Sopenharmony_ci            continue
491425bb815Sopenharmony_ci        ret_build, build_dir_path = create_binary(job, options)
492425bb815Sopenharmony_ci        if ret_build:
493425bb815Sopenharmony_ci            print("\n%sBuild failed%s\n" % (TERM_RED, TERM_NORMAL))
494425bb815Sopenharmony_ci            break
495425bb815Sopenharmony_ci
496425bb815Sopenharmony_ci        if sys.platform == 'win32':
497425bb815Sopenharmony_ci            if "--debug" in job.build_args:
498425bb815Sopenharmony_ci                build_config = "Debug"
499425bb815Sopenharmony_ci            else:
500425bb815Sopenharmony_ci                build_config = "MinSizeRel"
501425bb815Sopenharmony_ci        else:
502425bb815Sopenharmony_ci            build_config = ""
503425bb815Sopenharmony_ci
504425bb815Sopenharmony_ci
505425bb815Sopenharmony_ci        ret_test |= run_check(
506425bb815Sopenharmony_ci            get_platform_cmd_prefix() +
507425bb815Sopenharmony_ci            [settings.UNITTEST_RUNNER_SCRIPT] +
508425bb815Sopenharmony_ci            [os.path.join(build_dir_path, 'tests', build_config)] +
509425bb815Sopenharmony_ci            (["-q"] if options.quiet else [])
510425bb815Sopenharmony_ci        )
511425bb815Sopenharmony_ci
512425bb815Sopenharmony_ci    return ret_build | ret_test
513425bb815Sopenharmony_ci
514425bb815Sopenharmony_cidef run_buildoption_test(options):
515425bb815Sopenharmony_ci    for job in JERRY_BUILDOPTIONS:
516425bb815Sopenharmony_ci        if job.skip:
517425bb815Sopenharmony_ci            report_skip(job)
518425bb815Sopenharmony_ci            continue
519425bb815Sopenharmony_ci
520425bb815Sopenharmony_ci        ret, _ = create_binary(job, options)
521425bb815Sopenharmony_ci        if ret:
522425bb815Sopenharmony_ci            print("\n%sBuild failed%s\n" % (TERM_RED, TERM_NORMAL))
523425bb815Sopenharmony_ci            break
524425bb815Sopenharmony_ci
525425bb815Sopenharmony_ci    return ret
526425bb815Sopenharmony_ci
527425bb815Sopenharmony_ciCheck = collections.namedtuple('Check', ['enabled', 'runner', 'arg'])
528425bb815Sopenharmony_ci
529425bb815Sopenharmony_cidef main(options):
530425bb815Sopenharmony_ci    checks = [
531425bb815Sopenharmony_ci        Check(options.check_signed_off, run_check, [settings.SIGNED_OFF_SCRIPT]
532425bb815Sopenharmony_ci              + {'tolerant': ['--tolerant'], 'travis': ['--travis']}.get(options.check_signed_off, [])),
533425bb815Sopenharmony_ci        Check(options.check_cppcheck, run_check, [settings.CPPCHECK_SCRIPT]),
534425bb815Sopenharmony_ci        Check(options.check_doxygen, run_check, [settings.DOXYGEN_SCRIPT]),
535425bb815Sopenharmony_ci        Check(options.check_pylint, run_check, [settings.PYLINT_SCRIPT]),
536425bb815Sopenharmony_ci        Check(options.check_vera, run_check, [settings.VERA_SCRIPT]),
537425bb815Sopenharmony_ci        Check(options.check_license, run_check, [settings.LICENSE_SCRIPT]),
538425bb815Sopenharmony_ci        Check(options.check_magic_strings, run_check, [settings.MAGIC_STRINGS_SCRIPT]),
539425bb815Sopenharmony_ci        Check(options.jerry_debugger, run_jerry_debugger_tests, options),
540425bb815Sopenharmony_ci        Check(options.jerry_tests, run_jerry_tests, options),
541425bb815Sopenharmony_ci        Check(options.jerry_test_suite, run_jerry_test_suite, options),
542425bb815Sopenharmony_ci        Check(options.test262 or options.test262_es2015, run_test262_test_suite, options),
543425bb815Sopenharmony_ci        Check(options.unittests, run_unittests, options),
544425bb815Sopenharmony_ci        Check(options.buildoption_test, run_buildoption_test, options),
545425bb815Sopenharmony_ci    ]
546425bb815Sopenharmony_ci
547425bb815Sopenharmony_ci    for check in checks:
548425bb815Sopenharmony_ci        if check.enabled or options.all:
549425bb815Sopenharmony_ci            ret = check.runner(check.arg)
550425bb815Sopenharmony_ci            if ret:
551425bb815Sopenharmony_ci                sys.exit(ret)
552425bb815Sopenharmony_ci
553425bb815Sopenharmony_ciif __name__ == "__main__":
554425bb815Sopenharmony_ci    main(get_arguments())
555