11cb0ef41Sopenharmony_ci#!/usr/bin/env python3 21cb0ef41Sopenharmony_ci# 31cb0ef41Sopenharmony_ci# Copyright 2017 the V8 project authors. All rights reserved. 41cb0ef41Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be 51cb0ef41Sopenharmony_ci# found in the LICENSE file. 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ciimport random 81cb0ef41Sopenharmony_ciimport sys 91cb0ef41Sopenharmony_ci 101cb0ef41Sopenharmony_ci# Adds testrunner to the path hence it has to be imported at the beggining. 111cb0ef41Sopenharmony_cifrom . import base_runner 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_cifrom testrunner.local import utils 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_cifrom testrunner.testproc import fuzzer 161cb0ef41Sopenharmony_cifrom testrunner.testproc.base import TestProcProducer 171cb0ef41Sopenharmony_cifrom testrunner.testproc.combiner import CombinerProc 181cb0ef41Sopenharmony_cifrom testrunner.testproc.execution import ExecutionProc 191cb0ef41Sopenharmony_cifrom testrunner.testproc.expectation import ExpectationProc 201cb0ef41Sopenharmony_cifrom testrunner.testproc.filter import StatusFileFilterProc, NameFilterProc 211cb0ef41Sopenharmony_cifrom testrunner.testproc.loader import LoadProc 221cb0ef41Sopenharmony_cifrom testrunner.testproc.progress import ResultsTracker 231cb0ef41Sopenharmony_cifrom testrunner.utils import random_utils 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ci 261cb0ef41Sopenharmony_ciDEFAULT_SUITES = ["mjsunit", "webkit", "benchmarks"] 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ciclass NumFuzzer(base_runner.BaseTestRunner): 301cb0ef41Sopenharmony_ci def __init__(self, *args, **kwargs): 311cb0ef41Sopenharmony_ci super(NumFuzzer, self).__init__(*args, **kwargs) 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ci @property 341cb0ef41Sopenharmony_ci def framework_name(self): 351cb0ef41Sopenharmony_ci return 'num_fuzzer' 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ci def _add_parser_options(self, parser): 381cb0ef41Sopenharmony_ci parser.add_option("--fuzzer-random-seed", default=0, 391cb0ef41Sopenharmony_ci help="Default seed for initializing fuzzer random " 401cb0ef41Sopenharmony_ci "generator") 411cb0ef41Sopenharmony_ci parser.add_option("--tests-count", default=5, type="int", 421cb0ef41Sopenharmony_ci help="Number of tests to generate from each base test. " 431cb0ef41Sopenharmony_ci "Can be combined with --total-timeout-sec with " 441cb0ef41Sopenharmony_ci "value 0 to provide infinite number of subtests. " 451cb0ef41Sopenharmony_ci "When --combine-tests is set it indicates how many " 461cb0ef41Sopenharmony_ci "tests to create in total") 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci # Stress gc 491cb0ef41Sopenharmony_ci parser.add_option("--stress-marking", default=0, type="int", 501cb0ef41Sopenharmony_ci help="probability [0-10] of adding --stress-marking " 511cb0ef41Sopenharmony_ci "flag to the test") 521cb0ef41Sopenharmony_ci parser.add_option("--stress-scavenge", default=0, type="int", 531cb0ef41Sopenharmony_ci help="probability [0-10] of adding --stress-scavenge " 541cb0ef41Sopenharmony_ci "flag to the test") 551cb0ef41Sopenharmony_ci parser.add_option("--stress-compaction", default=0, type="int", 561cb0ef41Sopenharmony_ci help="probability [0-10] of adding --stress-compaction " 571cb0ef41Sopenharmony_ci "flag to the test") 581cb0ef41Sopenharmony_ci parser.add_option("--stress-gc", default=0, type="int", 591cb0ef41Sopenharmony_ci help="probability [0-10] of adding --random-gc-interval " 601cb0ef41Sopenharmony_ci "flag to the test") 611cb0ef41Sopenharmony_ci 621cb0ef41Sopenharmony_ci # Stress stack size 631cb0ef41Sopenharmony_ci parser.add_option("--stress-stack-size", default=0, type="int", 641cb0ef41Sopenharmony_ci help="probability [0-10] of adding --stack-size " 651cb0ef41Sopenharmony_ci "flag to the test") 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci # Stress tasks 681cb0ef41Sopenharmony_ci parser.add_option("--stress-delay-tasks", default=0, type="int", 691cb0ef41Sopenharmony_ci help="probability [0-10] of adding --stress-delay-tasks " 701cb0ef41Sopenharmony_ci "flag to the test") 711cb0ef41Sopenharmony_ci parser.add_option("--stress-thread-pool-size", default=0, type="int", 721cb0ef41Sopenharmony_ci help="probability [0-10] of adding --thread-pool-size " 731cb0ef41Sopenharmony_ci "flag to the test") 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_ci # Stress compiler 761cb0ef41Sopenharmony_ci parser.add_option("--stress-deopt", default=0, type="int", 771cb0ef41Sopenharmony_ci help="probability [0-10] of adding --deopt-every-n-times " 781cb0ef41Sopenharmony_ci "flag to the test") 791cb0ef41Sopenharmony_ci parser.add_option("--stress-deopt-min", default=1, type="int", 801cb0ef41Sopenharmony_ci help="extends --stress-deopt to have minimum interval " 811cb0ef41Sopenharmony_ci "between deopt points") 821cb0ef41Sopenharmony_ci parser.add_option("--stress-interrupt-budget", default=0, type="int", 831cb0ef41Sopenharmony_ci help="probability [0-10] of adding the --interrupt-budget " 841cb0ef41Sopenharmony_ci "flag to the test") 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci # Combine multiple tests 871cb0ef41Sopenharmony_ci parser.add_option("--combine-tests", default=False, action="store_true", 881cb0ef41Sopenharmony_ci help="Combine multiple tests as one and run with " 891cb0ef41Sopenharmony_ci "try-catch wrapper") 901cb0ef41Sopenharmony_ci parser.add_option("--combine-max", default=100, type="int", 911cb0ef41Sopenharmony_ci help="Maximum number of tests to combine") 921cb0ef41Sopenharmony_ci parser.add_option("--combine-min", default=2, type="int", 931cb0ef41Sopenharmony_ci help="Minimum number of tests to combine") 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci # Miscellaneous 961cb0ef41Sopenharmony_ci parser.add_option("--variants", default='default', 971cb0ef41Sopenharmony_ci help="Comma-separated list of testing variants") 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ci return parser 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci 1021cb0ef41Sopenharmony_ci def _process_options(self, options): 1031cb0ef41Sopenharmony_ci if not options.fuzzer_random_seed: 1041cb0ef41Sopenharmony_ci options.fuzzer_random_seed = random_utils.random_seed() 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci if options.total_timeout_sec: 1071cb0ef41Sopenharmony_ci options.tests_count = 0 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci if options.combine_tests: 1101cb0ef41Sopenharmony_ci if options.combine_min > options.combine_max: 1111cb0ef41Sopenharmony_ci print(('min_group_size (%d) cannot be larger than max_group_size (%d)' % 1121cb0ef41Sopenharmony_ci options.min_group_size, options.max_group_size)) 1131cb0ef41Sopenharmony_ci raise base_runner.TestRunnerError() 1141cb0ef41Sopenharmony_ci 1151cb0ef41Sopenharmony_ci if options.variants != 'default': 1161cb0ef41Sopenharmony_ci print ('Only default testing variant is supported with numfuzz') 1171cb0ef41Sopenharmony_ci raise base_runner.TestRunnerError() 1181cb0ef41Sopenharmony_ci 1191cb0ef41Sopenharmony_ci return True 1201cb0ef41Sopenharmony_ci 1211cb0ef41Sopenharmony_ci def _get_default_suite_names(self): 1221cb0ef41Sopenharmony_ci return DEFAULT_SUITES 1231cb0ef41Sopenharmony_ci 1241cb0ef41Sopenharmony_ci def _runner_flags(self): 1251cb0ef41Sopenharmony_ci """Extra default flags specific to the test runner implementation.""" 1261cb0ef41Sopenharmony_ci return [ 1271cb0ef41Sopenharmony_ci '--no-abort-on-contradictory-flags', 1281cb0ef41Sopenharmony_ci '--testing-d8-test-runner', 1291cb0ef41Sopenharmony_ci '--no-fail' 1301cb0ef41Sopenharmony_ci ] 1311cb0ef41Sopenharmony_ci 1321cb0ef41Sopenharmony_ci def _get_statusfile_variables(self, options): 1331cb0ef41Sopenharmony_ci variables = ( 1341cb0ef41Sopenharmony_ci super(NumFuzzer, self)._get_statusfile_variables(options)) 1351cb0ef41Sopenharmony_ci variables.update({ 1361cb0ef41Sopenharmony_ci 'deopt_fuzzer': bool(options.stress_deopt), 1371cb0ef41Sopenharmony_ci 'endurance_fuzzer': bool(options.combine_tests), 1381cb0ef41Sopenharmony_ci 'gc_stress': bool(options.stress_gc), 1391cb0ef41Sopenharmony_ci 'gc_fuzzer': bool(max([options.stress_marking, 1401cb0ef41Sopenharmony_ci options.stress_scavenge, 1411cb0ef41Sopenharmony_ci options.stress_compaction, 1421cb0ef41Sopenharmony_ci options.stress_gc, 1431cb0ef41Sopenharmony_ci options.stress_delay_tasks, 1441cb0ef41Sopenharmony_ci options.stress_stack_size, 1451cb0ef41Sopenharmony_ci options.stress_thread_pool_size])), 1461cb0ef41Sopenharmony_ci }) 1471cb0ef41Sopenharmony_ci return variables 1481cb0ef41Sopenharmony_ci 1491cb0ef41Sopenharmony_ci def _do_execute(self, tests, args, options): 1501cb0ef41Sopenharmony_ci loader = LoadProc(tests) 1511cb0ef41Sopenharmony_ci fuzzer_rng = random.Random(options.fuzzer_random_seed) 1521cb0ef41Sopenharmony_ci 1531cb0ef41Sopenharmony_ci combiner = self._create_combiner(fuzzer_rng, options) 1541cb0ef41Sopenharmony_ci results = self._create_result_tracker(options) 1551cb0ef41Sopenharmony_ci execproc = ExecutionProc(options.j) 1561cb0ef41Sopenharmony_ci sigproc = self._create_signal_proc() 1571cb0ef41Sopenharmony_ci indicators = self._create_progress_indicators( 1581cb0ef41Sopenharmony_ci tests.test_count_estimate, options) 1591cb0ef41Sopenharmony_ci procs = [ 1601cb0ef41Sopenharmony_ci loader, 1611cb0ef41Sopenharmony_ci NameFilterProc(args) if args else None, 1621cb0ef41Sopenharmony_ci StatusFileFilterProc(None, None), 1631cb0ef41Sopenharmony_ci # TODO(majeski): Improve sharding when combiner is present. Maybe select 1641cb0ef41Sopenharmony_ci # different random seeds for shards instead of splitting tests. 1651cb0ef41Sopenharmony_ci self._create_shard_proc(options), 1661cb0ef41Sopenharmony_ci ExpectationProc(), 1671cb0ef41Sopenharmony_ci combiner, 1681cb0ef41Sopenharmony_ci self._create_fuzzer(fuzzer_rng, options), 1691cb0ef41Sopenharmony_ci sigproc, 1701cb0ef41Sopenharmony_ci ] + indicators + [ 1711cb0ef41Sopenharmony_ci results, 1721cb0ef41Sopenharmony_ci self._create_timeout_proc(options), 1731cb0ef41Sopenharmony_ci self._create_rerun_proc(options), 1741cb0ef41Sopenharmony_ci execproc, 1751cb0ef41Sopenharmony_ci ] 1761cb0ef41Sopenharmony_ci self._prepare_procs(procs) 1771cb0ef41Sopenharmony_ci loader.load_initial_tests(initial_batch_size=float('inf')) 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_ci # TODO(majeski): maybe some notification from loader would be better? 1801cb0ef41Sopenharmony_ci if combiner: 1811cb0ef41Sopenharmony_ci combiner.generate_initial_tests(options.j * 4) 1821cb0ef41Sopenharmony_ci 1831cb0ef41Sopenharmony_ci # This starts up worker processes and blocks until all tests are 1841cb0ef41Sopenharmony_ci # processed. 1851cb0ef41Sopenharmony_ci execproc.run() 1861cb0ef41Sopenharmony_ci 1871cb0ef41Sopenharmony_ci for indicator in indicators: 1881cb0ef41Sopenharmony_ci indicator.finished() 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ci print('>>> %d tests ran' % results.total) 1911cb0ef41Sopenharmony_ci if results.failed: 1921cb0ef41Sopenharmony_ci return utils.EXIT_CODE_FAILURES 1931cb0ef41Sopenharmony_ci 1941cb0ef41Sopenharmony_ci # Indicate if a SIGINT or SIGTERM happened. 1951cb0ef41Sopenharmony_ci return sigproc.exit_code 1961cb0ef41Sopenharmony_ci 1971cb0ef41Sopenharmony_ci def _is_testsuite_supported(self, suite, options): 1981cb0ef41Sopenharmony_ci return not options.combine_tests or suite.test_combiner_available() 1991cb0ef41Sopenharmony_ci 2001cb0ef41Sopenharmony_ci def _create_combiner(self, rng, options): 2011cb0ef41Sopenharmony_ci if not options.combine_tests: 2021cb0ef41Sopenharmony_ci return None 2031cb0ef41Sopenharmony_ci return CombinerProc(rng, options.combine_min, options.combine_max, 2041cb0ef41Sopenharmony_ci options.tests_count) 2051cb0ef41Sopenharmony_ci 2061cb0ef41Sopenharmony_ci def _create_fuzzer(self, rng, options): 2071cb0ef41Sopenharmony_ci return fuzzer.FuzzerProc( 2081cb0ef41Sopenharmony_ci rng, 2091cb0ef41Sopenharmony_ci self._tests_count(options), 2101cb0ef41Sopenharmony_ci self._create_fuzzer_configs(options), 2111cb0ef41Sopenharmony_ci self._disable_analysis(options), 2121cb0ef41Sopenharmony_ci ) 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ci def _tests_count(self, options): 2151cb0ef41Sopenharmony_ci if options.combine_tests: 2161cb0ef41Sopenharmony_ci return 1 2171cb0ef41Sopenharmony_ci return options.tests_count 2181cb0ef41Sopenharmony_ci 2191cb0ef41Sopenharmony_ci def _disable_analysis(self, options): 2201cb0ef41Sopenharmony_ci """Disable analysis phase when options are used that don't support it.""" 2211cb0ef41Sopenharmony_ci return options.combine_tests 2221cb0ef41Sopenharmony_ci 2231cb0ef41Sopenharmony_ci def _create_fuzzer_configs(self, options): 2241cb0ef41Sopenharmony_ci fuzzers = [] 2251cb0ef41Sopenharmony_ci def add(name, prob, *args): 2261cb0ef41Sopenharmony_ci if prob: 2271cb0ef41Sopenharmony_ci fuzzers.append(fuzzer.create_fuzzer_config(name, prob, *args)) 2281cb0ef41Sopenharmony_ci 2291cb0ef41Sopenharmony_ci add('compaction', options.stress_compaction) 2301cb0ef41Sopenharmony_ci add('marking', options.stress_marking) 2311cb0ef41Sopenharmony_ci add('scavenge', options.stress_scavenge) 2321cb0ef41Sopenharmony_ci add('gc_interval', options.stress_gc) 2331cb0ef41Sopenharmony_ci add('stack', options.stress_stack_size) 2341cb0ef41Sopenharmony_ci add('threads', options.stress_thread_pool_size) 2351cb0ef41Sopenharmony_ci add('delay', options.stress_delay_tasks) 2361cb0ef41Sopenharmony_ci add('deopt', options.stress_deopt, options.stress_deopt_min) 2371cb0ef41Sopenharmony_ci return fuzzers 2381cb0ef41Sopenharmony_ci 2391cb0ef41Sopenharmony_ci 2401cb0ef41Sopenharmony_ciif __name__ == '__main__': 2411cb0ef41Sopenharmony_ci sys.exit(NumFuzzer().execute()) 242