1#!/usr/bin/env python 2 3# Copyright JS Foundation and other contributors, http://js.foundation 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17from __future__ import print_function 18 19import argparse 20import collections 21import hashlib 22import os 23import platform 24import subprocess 25import sys 26import settings 27 28OUTPUT_DIR = os.path.join(settings.PROJECT_DIR, 'build', 'tests') 29 30Options = collections.namedtuple('Options', ['name', 'build_args', 'test_args', 'skip']) 31Options.__new__.__defaults__ = ([], [], False) 32 33def skip_if(condition, desc): 34 return desc if condition else False 35 36OPTIONS_COMMON = ['--lto=off'] 37OPTIONS_PROFILE_MIN = ['--profile=minimal'] 38OPTIONS_PROFILE_ES51 = [] # NOTE: same as ['--profile=es5.1'] 39OPTIONS_PROFILE_ES2015 = ['--profile=es2015-subset'] 40OPTIONS_STACK_LIMIT = ['--stack-limit=96'] 41OPTIONS_GC_MARK_LIMIT = ['--gc-mark-limit=16'] 42OPTIONS_DEBUG = ['--debug'] 43OPTIONS_SNAPSHOT = ['--snapshot-save=on', '--snapshot-exec=on', '--jerry-cmdline-snapshot=on'] 44OPTIONS_UNITTESTS = ['--unittests=on', '--jerry-cmdline=off', '--error-messages=on', 45 '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on', 46 '--line-info=on', '--mem-stats=on'] 47OPTIONS_DOCTESTS = ['--doctests=on', '--jerry-cmdline=off', '--error-messages=on', 48 '--snapshot-save=on', '--snapshot-exec=on', '--vm-exec-stop=on'] 49 50# Test options for unittests 51JERRY_UNITTESTS_OPTIONS = [ 52 Options('unittests-es2015_subset', 53 OPTIONS_COMMON + OPTIONS_UNITTESTS + OPTIONS_PROFILE_ES2015), 54 Options('unittests-es2015_subset-debug', 55 OPTIONS_COMMON + OPTIONS_UNITTESTS + OPTIONS_PROFILE_ES2015 + OPTIONS_DEBUG), 56 Options('doctests-es2015_subset', 57 OPTIONS_COMMON + OPTIONS_DOCTESTS + OPTIONS_PROFILE_ES2015), 58 Options('doctests-es2015_subset-debug', 59 OPTIONS_COMMON + OPTIONS_DOCTESTS + OPTIONS_PROFILE_ES2015 + OPTIONS_DEBUG), 60 Options('unittests-es5.1', 61 OPTIONS_COMMON + OPTIONS_UNITTESTS + OPTIONS_PROFILE_ES51), 62 Options('unittests-es5.1-debug', 63 OPTIONS_COMMON + OPTIONS_UNITTESTS + OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG), 64 Options('doctests-es5.1', 65 OPTIONS_COMMON + OPTIONS_DOCTESTS + OPTIONS_PROFILE_ES51), 66 Options('doctests-es5.1-debug', 67 OPTIONS_COMMON + OPTIONS_DOCTESTS + OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG), 68 Options('unittests-es5.1-debug-init-fini', 69 OPTIONS_COMMON + OPTIONS_UNITTESTS + OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG 70 + ['--cmake-param=-DFEATURE_INIT_FINI=ON'], 71 skip=skip_if((sys.platform == 'win32'), 'FEATURE_INIT_FINI build flag isn\'t supported on Windows,' + 72 ' because Microsoft Visual C/C++ Compiler doesn\'t support' + 73 ' library constructors and destructors.')), 74] 75 76# Test options for jerry-tests 77JERRY_TESTS_OPTIONS = [ 78 Options('jerry_tests-es2015_subset-debug', 79 OPTIONS_COMMON + OPTIONS_PROFILE_ES2015 + OPTIONS_DEBUG + OPTIONS_STACK_LIMIT + OPTIONS_GC_MARK_LIMIT), 80 Options('jerry_tests-es5.1', 81 OPTIONS_COMMON + OPTIONS_PROFILE_ES51 + OPTIONS_STACK_LIMIT + OPTIONS_GC_MARK_LIMIT), 82 Options('jerry_tests-es5.1-snapshot', 83 OPTIONS_COMMON + OPTIONS_PROFILE_ES51 + OPTIONS_SNAPSHOT + OPTIONS_STACK_LIMIT + OPTIONS_GC_MARK_LIMIT, 84 ['--snapshot']), 85 Options('jerry_tests-es5.1-debug', 86 OPTIONS_COMMON + OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG + OPTIONS_STACK_LIMIT + OPTIONS_GC_MARK_LIMIT), 87 Options('jerry_tests-es5.1-debug-snapshot', 88 OPTIONS_COMMON + OPTIONS_PROFILE_ES51 + OPTIONS_SNAPSHOT + OPTIONS_DEBUG + OPTIONS_STACK_LIMIT 89 + OPTIONS_GC_MARK_LIMIT, ['--snapshot']), 90 Options('jerry_tests-es5.1-debug-cpointer_32bit', 91 OPTIONS_COMMON + OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG + OPTIONS_STACK_LIMIT + OPTIONS_GC_MARK_LIMIT 92 + ['--cpointer-32bit=on', '--mem-heap=1024']), 93 Options('jerry_tests-es5.1-debug-external_context', 94 OPTIONS_COMMON + OPTIONS_PROFILE_ES51 + OPTIONS_DEBUG + OPTIONS_STACK_LIMIT + OPTIONS_GC_MARK_LIMIT 95 + ['--external-context=on']), 96] 97 98# Test options for jerry-test-suite 99JERRY_TEST_SUITE_OPTIONS = JERRY_TESTS_OPTIONS[:] 100JERRY_TEST_SUITE_OPTIONS.extend([ 101 Options('jerry_test_suite-minimal', 102 OPTIONS_COMMON + OPTIONS_PROFILE_MIN), 103 Options('jerry_test_suite-minimal-snapshot', 104 OPTIONS_COMMON + OPTIONS_PROFILE_MIN + OPTIONS_SNAPSHOT, 105 ['--snapshot']), 106 Options('jerry_test_suite-minimal-debug', 107 OPTIONS_COMMON + OPTIONS_PROFILE_MIN + OPTIONS_DEBUG), 108 Options('jerry_test_suite-minimal-debug-snapshot', 109 OPTIONS_COMMON + OPTIONS_PROFILE_MIN + OPTIONS_SNAPSHOT + OPTIONS_DEBUG, 110 ['--snapshot']), 111 Options('jerry_test_suite-es2015_subset', 112 OPTIONS_COMMON + OPTIONS_PROFILE_ES2015), 113 Options('jerry_test_suite-es2015_subset-snapshot', 114 OPTIONS_COMMON + OPTIONS_PROFILE_ES2015 + OPTIONS_SNAPSHOT, 115 ['--snapshot']), 116 Options('jerry_test_suite-es2015_subset-debug-snapshot', 117 OPTIONS_COMMON + OPTIONS_PROFILE_ES2015 + OPTIONS_SNAPSHOT + OPTIONS_DEBUG, 118 ['--snapshot']), 119]) 120 121# Test options for test262 122TEST262_TEST_SUITE_OPTIONS = [ 123 Options('test262_tests'), 124 Options('test262_tests-debug', OPTIONS_DEBUG) 125] 126 127# Test options for test262-es2015 128TEST262_ES2015_TEST_SUITE_OPTIONS = [ 129 Options('test262_tests_es2015', OPTIONS_PROFILE_ES2015 + ['--line-info=on', '--error-messages=on']), 130] 131 132# Test options for jerry-debugger 133DEBUGGER_TEST_OPTIONS = [ 134 Options('jerry_debugger_tests', 135 OPTIONS_DEBUG + ['--jerry-debugger=on']) 136] 137 138# Test options for buildoption-test 139JERRY_BUILDOPTIONS = [ 140 Options('buildoption_test-lto', 141 ['--lto=on']), 142 Options('buildoption_test-error_messages', 143 ['--error-messages=on']), 144 Options('buildoption_test-logging', 145 ['--logging=on']), 146 Options('buildoption_test-all_in_one', 147 ['--all-in-one=on']), 148 Options('buildoption_test-valgrind', 149 ['--valgrind=on']), 150 Options('buildoption_test-mem_stats', 151 ['--mem-stats=on']), 152 Options('buildoption_test-show_opcodes', 153 ['--show-opcodes=on']), 154 Options('buildoption_test-show_regexp_opcodes', 155 ['--show-regexp-opcodes=on']), 156 Options('buildoption_test-cpointer_32bit', 157 ['--compile-flag=-m32', '--cpointer-32bit=on', '--system-allocator=on'], 158 skip=skip_if( 159 platform.system() != 'Linux' or (platform.machine() != 'i386' and platform.machine() != 'x86_64'), 160 '-m32 is only supported on x86[-64]-linux') 161 ), 162 Options('buildoption_test-no_jerry_libm', 163 ['--jerry-libm=off', '--link-lib=m'], 164 skip=skip_if((sys.platform == 'win32'), 'There is no separated libm on Windows')), 165 Options('buildoption_test-no_lcache_prophashmap', 166 ['--compile-flag=-DJERRY_LCACHE=0', '--compile-flag=-DJERRY_PROPRETY_HASHMAP=0']), 167 Options('buildoption_test-external_context', 168 ['--external-context=on']), 169 Options('buildoption_test-shared_libs', 170 ['--shared-libs=on'], 171 skip=skip_if((sys.platform == 'win32'), 'Not yet supported, link failure on Windows')), 172 Options('buildoption_test-cmdline_test', 173 ['--jerry-cmdline-test=on'], 174 skip=skip_if((sys.platform == 'win32'), 'rand() can\'t be overriden on Windows (benchmarking.c)')), 175 Options('buildoption_test-cmdline_snapshot', 176 ['--jerry-cmdline-snapshot=on']), 177 Options('buildoption_test-recursion_limit', 178 OPTIONS_STACK_LIMIT), 179 Options('buildoption_test-gc-mark_limit', 180 OPTIONS_GC_MARK_LIMIT), 181 Options('buildoption_test-single-source', 182 ['--cmake-param=-DENABLE_ALL_IN_ONE_SOURCE=ON']), 183 Options('buildoption_test-jerry-debugger', 184 ['--jerry-debugger=on']), 185] 186 187def get_arguments(): 188 parser = argparse.ArgumentParser() 189 parser.add_argument('--toolchain', metavar='FILE', 190 help='Add toolchain file') 191 parser.add_argument('-q', '--quiet', action='store_true', 192 help='Only print out failing tests') 193 parser.add_argument('--buildoptions', metavar='LIST', 194 help='Add a comma separated list of extra build options to each test') 195 parser.add_argument('--skip-list', metavar='LIST', 196 help='Add a comma separated list of patterns of the excluded JS-tests') 197 parser.add_argument('--outdir', metavar='DIR', default=OUTPUT_DIR, 198 help='Specify output directory (default: %(default)s)') 199 parser.add_argument('--check-signed-off', metavar='TYPE', nargs='?', 200 choices=['strict', 'tolerant', 'travis'], const='strict', 201 help='Run signed-off check (%(choices)s; default type if not given: %(const)s)') 202 parser.add_argument('--check-cppcheck', action='store_true', 203 help='Run cppcheck') 204 parser.add_argument('--check-doxygen', action='store_true', 205 help='Run doxygen') 206 parser.add_argument('--check-pylint', action='store_true', 207 help='Run pylint') 208 parser.add_argument('--check-vera', action='store_true', 209 help='Run vera check') 210 parser.add_argument('--check-license', action='store_true', 211 help='Run license check') 212 parser.add_argument('--check-magic-strings', action='store_true', 213 help='Run "magic string source code generator should be executed" check') 214 parser.add_argument('--jerry-debugger', action='store_true', 215 help='Run jerry-debugger tests') 216 parser.add_argument('--jerry-tests', action='store_true', 217 help='Run jerry-tests') 218 parser.add_argument('--jerry-test-suite', action='store_true', 219 help='Run jerry-test-suite') 220 parser.add_argument('--test262', action='store_true', 221 help='Run test262 - ES5.1') 222 parser.add_argument('--test262-es2015', action='store_true', 223 help='Run test262 - ES2015') 224 parser.add_argument('--unittests', action='store_true', 225 help='Run unittests (including doctests)') 226 parser.add_argument('--buildoption-test', action='store_true', 227 help='Run buildoption-test') 228 parser.add_argument('--all', '--precommit', action='store_true', 229 help='Run all tests') 230 231 if len(sys.argv) == 1: 232 parser.print_help() 233 sys.exit(1) 234 235 script_args = parser.parse_args() 236 237 return script_args 238 239BINARY_CACHE = {} 240 241TERM_NORMAL = '\033[0m' 242TERM_YELLOW = '\033[1;33m' 243TERM_BLUE = '\033[1;34m' 244TERM_RED = '\033[1;31m' 245 246def report_command(cmd_type, cmd, env=None): 247 sys.stderr.write('%s%s%s\n' % (TERM_BLUE, cmd_type, TERM_NORMAL)) 248 if env is not None: 249 sys.stderr.write(''.join('%s%s=%r \\%s\n' % (TERM_BLUE, var, val, TERM_NORMAL) 250 for var, val in sorted(env.items()))) 251 sys.stderr.write('%s%s%s\n' % (TERM_BLUE, (' \\%s\n\t%s' % (TERM_NORMAL, TERM_BLUE)).join(cmd), TERM_NORMAL)) 252 253def report_skip(job): 254 sys.stderr.write('%sSkipping: %s' % (TERM_YELLOW, job.name)) 255 if job.skip: 256 sys.stderr.write(' (%s)' % job.skip) 257 sys.stderr.write('%s\n' % TERM_NORMAL) 258 259def get_platform_cmd_prefix(): 260 if sys.platform == 'win32': 261 return ['cmd', '/S', '/C'] 262 return [] 263 264def create_binary(job, options): 265 build_args = job.build_args[:] 266 if options.buildoptions: 267 for option in options.buildoptions.split(','): 268 if option not in build_args: 269 build_args.append(option) 270 271 build_cmd = get_platform_cmd_prefix() 272 build_cmd.append(settings.BUILD_SCRIPT) 273 build_cmd.extend(build_args) 274 275 build_dir_path = os.path.join(options.outdir, job.name) 276 build_cmd.append('--builddir=%s' % build_dir_path) 277 278 install_dir_path = os.path.join(build_dir_path, 'local') 279 build_cmd.append('--install=%s' % install_dir_path) 280 281 if options.toolchain: 282 build_cmd.append('--toolchain=%s' % options.toolchain) 283 284 report_command('Build command:', build_cmd) 285 286 binary_key = tuple(sorted(build_args)) 287 if binary_key in BINARY_CACHE: 288 ret, build_dir_path = BINARY_CACHE[binary_key] 289 sys.stderr.write('(skipping: already built at %s with returncode %d)\n' % (build_dir_path, ret)) 290 return ret, build_dir_path 291 292 try: 293 subprocess.check_output(build_cmd) 294 ret = 0 295 except subprocess.CalledProcessError as err: 296 print(err.output) 297 ret = err.returncode 298 299 BINARY_CACHE[binary_key] = (ret, build_dir_path) 300 return ret, build_dir_path 301 302def get_binary_path(build_dir_path): 303 executable_extension = '.exe' if sys.platform == 'win32' else '' 304 return os.path.join(build_dir_path, 'local', 'bin', 'jerry' + executable_extension) 305 306def hash_binary(bin_path): 307 blocksize = 65536 308 hasher = hashlib.sha1() 309 with open(bin_path, 'rb') as bin_file: 310 buf = bin_file.read(blocksize) 311 while buf: 312 hasher.update(buf) 313 buf = bin_file.read(blocksize) 314 return hasher.hexdigest() 315 316def iterate_test_runner_jobs(jobs, options): 317 tested_paths = set() 318 tested_hashes = {} 319 320 for job in jobs: 321 ret_build, build_dir_path = create_binary(job, options) 322 if ret_build: 323 yield job, ret_build, None 324 325 if build_dir_path in tested_paths: 326 sys.stderr.write('(skipping: already tested with %s)\n' % build_dir_path) 327 continue 328 else: 329 tested_paths.add(build_dir_path) 330 331 bin_path = get_binary_path(build_dir_path) 332 bin_hash = hash_binary(bin_path) 333 334 if bin_hash in tested_hashes: 335 sys.stderr.write('(skipping: already tested with equivalent %s)\n' % tested_hashes[bin_hash]) 336 continue 337 else: 338 tested_hashes[bin_hash] = build_dir_path 339 340 test_cmd = get_platform_cmd_prefix() 341 test_cmd.extend([settings.TEST_RUNNER_SCRIPT, '--engine', bin_path]) 342 343 yield job, ret_build, test_cmd 344 345def run_check(runnable, env=None): 346 report_command('Test command:', runnable, env=env) 347 348 if env is not None: 349 full_env = dict(os.environ) 350 full_env.update(env) 351 env = full_env 352 353 proc = subprocess.Popen(runnable, env=env) 354 proc.wait() 355 return proc.returncode 356 357def run_jerry_debugger_tests(options): 358 ret_build = ret_test = 0 359 for job in DEBUGGER_TEST_OPTIONS: 360 ret_build, build_dir_path = create_binary(job, options) 361 if ret_build: 362 print("\n%sBuild failed%s\n" % (TERM_RED, TERM_NORMAL)) 363 break 364 365 for channel in ["websocket", "rawpacket"]: 366 for test_file in os.listdir(settings.DEBUGGER_TESTS_DIR): 367 if test_file.endswith(".cmd"): 368 test_case, _ = os.path.splitext(test_file) 369 test_case_path = os.path.join(settings.DEBUGGER_TESTS_DIR, test_case) 370 test_cmd = [ 371 settings.DEBUGGER_TEST_RUNNER_SCRIPT, 372 get_binary_path(build_dir_path), 373 channel, 374 settings.DEBUGGER_CLIENT_SCRIPT, 375 os.path.relpath(test_case_path, settings.PROJECT_DIR) 376 ] 377 378 if job.test_args: 379 test_cmd.extend(job.test_args) 380 381 ret_test |= run_check(test_cmd) 382 383 return ret_build | ret_test 384 385def run_jerry_tests(options): 386 ret_build = ret_test = 0 387 for job, ret_build, test_cmd in iterate_test_runner_jobs(JERRY_TESTS_OPTIONS, options): 388 if ret_build: 389 break 390 391 test_cmd.append('--test-dir') 392 test_cmd.append(settings.JERRY_TESTS_DIR) 393 394 if options.quiet: 395 test_cmd.append("-q") 396 397 skip_list = [] 398 399 if '--profile=es2015-subset' in job.build_args: 400 skip_list.append(os.path.join('es5.1', '')) 401 else: 402 skip_list.append(os.path.join('es2015', '')) 403 404 if options.skip_list: 405 skip_list.append(options.skip_list) 406 407 if skip_list: 408 test_cmd.append("--skip-list=" + ",".join(skip_list)) 409 410 if job.test_args: 411 test_cmd.extend(job.test_args) 412 413 ret_test |= run_check(test_cmd, env=dict(TZ='UTC')) 414 415 return ret_build | ret_test 416 417def run_jerry_test_suite(options): 418 ret_build = ret_test = 0 419 for job, ret_build, test_cmd in iterate_test_runner_jobs(JERRY_TEST_SUITE_OPTIONS, options): 420 if ret_build: 421 break 422 423 skip_list = [] 424 425 if '--profile=minimal' in job.build_args: 426 test_cmd.append('--test-list') 427 test_cmd.append(settings.JERRY_TEST_SUITE_MINIMAL_LIST) 428 else: 429 test_cmd.append('--test-dir') 430 test_cmd.append(settings.JERRY_TEST_SUITE_DIR) 431 if '--profile=es2015-subset' in job.build_args: 432 skip_list.append(os.path.join('es5.1', '')) 433 else: 434 skip_list.append(os.path.join('es2015', '')) 435 436 if options.quiet: 437 test_cmd.append("-q") 438 439 if options.skip_list: 440 skip_list.append(options.skip_list) 441 442 if skip_list: 443 test_cmd.append("--skip-list=" + ",".join(skip_list)) 444 445 if job.test_args: 446 test_cmd.extend(job.test_args) 447 448 ret_test |= run_check(test_cmd) 449 450 return ret_build | ret_test 451 452def run_test262_test_suite(options): 453 ret_build = ret_test = 0 454 455 jobs = [] 456 if options.test262: 457 jobs.extend(TEST262_TEST_SUITE_OPTIONS) 458 if options.test262_es2015: 459 jobs.extend(TEST262_ES2015_TEST_SUITE_OPTIONS) 460 461 for job in jobs: 462 ret_build, build_dir_path = create_binary(job, options) 463 if ret_build: 464 print("\n%sBuild failed%s\n" % (TERM_RED, TERM_NORMAL)) 465 break 466 467 test_cmd = get_platform_cmd_prefix() + [ 468 settings.TEST262_RUNNER_SCRIPT, 469 '--engine', get_binary_path(build_dir_path), 470 '--test-dir', settings.TEST262_TEST_SUITE_DIR 471 ] 472 473 if '--profile=es2015-subset' in job.build_args: 474 test_cmd.append('--es2015') 475 else: 476 test_cmd.append('--es51') 477 478 if job.test_args: 479 test_cmd.extend(job.test_args) 480 481 ret_test |= run_check(test_cmd, env=dict(TZ='America/Los_Angeles')) 482 483 return ret_build | ret_test 484 485def run_unittests(options): 486 ret_build = ret_test = 0 487 for job in JERRY_UNITTESTS_OPTIONS: 488 if job.skip: 489 report_skip(job) 490 continue 491 ret_build, build_dir_path = create_binary(job, options) 492 if ret_build: 493 print("\n%sBuild failed%s\n" % (TERM_RED, TERM_NORMAL)) 494 break 495 496 if sys.platform == 'win32': 497 if "--debug" in job.build_args: 498 build_config = "Debug" 499 else: 500 build_config = "MinSizeRel" 501 else: 502 build_config = "" 503 504 505 ret_test |= run_check( 506 get_platform_cmd_prefix() + 507 [settings.UNITTEST_RUNNER_SCRIPT] + 508 [os.path.join(build_dir_path, 'tests', build_config)] + 509 (["-q"] if options.quiet else []) 510 ) 511 512 return ret_build | ret_test 513 514def run_buildoption_test(options): 515 for job in JERRY_BUILDOPTIONS: 516 if job.skip: 517 report_skip(job) 518 continue 519 520 ret, _ = create_binary(job, options) 521 if ret: 522 print("\n%sBuild failed%s\n" % (TERM_RED, TERM_NORMAL)) 523 break 524 525 return ret 526 527Check = collections.namedtuple('Check', ['enabled', 'runner', 'arg']) 528 529def main(options): 530 checks = [ 531 Check(options.check_signed_off, run_check, [settings.SIGNED_OFF_SCRIPT] 532 + {'tolerant': ['--tolerant'], 'travis': ['--travis']}.get(options.check_signed_off, [])), 533 Check(options.check_cppcheck, run_check, [settings.CPPCHECK_SCRIPT]), 534 Check(options.check_doxygen, run_check, [settings.DOXYGEN_SCRIPT]), 535 Check(options.check_pylint, run_check, [settings.PYLINT_SCRIPT]), 536 Check(options.check_vera, run_check, [settings.VERA_SCRIPT]), 537 Check(options.check_license, run_check, [settings.LICENSE_SCRIPT]), 538 Check(options.check_magic_strings, run_check, [settings.MAGIC_STRINGS_SCRIPT]), 539 Check(options.jerry_debugger, run_jerry_debugger_tests, options), 540 Check(options.jerry_tests, run_jerry_tests, options), 541 Check(options.jerry_test_suite, run_jerry_test_suite, options), 542 Check(options.test262 or options.test262_es2015, run_test262_test_suite, options), 543 Check(options.unittests, run_unittests, options), 544 Check(options.buildoption_test, run_buildoption_test, options), 545 ] 546 547 for check in checks: 548 if check.enabled or options.all: 549 ret = check.runner(check.arg) 550 if ret: 551 sys.exit(ret) 552 553if __name__ == "__main__": 554 main(get_arguments()) 555