aboutsummaryrefslogtreecommitdiff
path: root/test/fuzz/test_runner.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/fuzz/test_runner.py')
-rwxr-xr-xtest/fuzz/test_runner.py46
1 files changed, 31 insertions, 15 deletions
diff --git a/test/fuzz/test_runner.py b/test/fuzz/test_runner.py
index 4e24c07699..a635175e7c 100755
--- a/test/fuzz/test_runner.py
+++ b/test/fuzz/test_runner.py
@@ -11,13 +11,15 @@ import argparse
import configparser
import logging
import os
+import platform
+import random
import subprocess
import sys
def get_fuzz_env(*, target, source_dir):
symbolizer = os.environ.get('LLVM_SYMBOLIZER_PATH', "/usr/bin/llvm-symbolizer")
- return {
+ fuzz_env = {
'FUZZ': target,
'UBSAN_OPTIONS':
f'suppressions={source_dir}/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1',
@@ -26,6 +28,10 @@ def get_fuzz_env(*, target, source_dir):
'ASAN_SYMBOLIZER_PATH':symbolizer,
'MSAN_SYMBOLIZER_PATH':symbolizer,
}
+ if platform.system() == "Windows":
+ # On Windows, `env` option must include valid `SystemRoot`.
+ fuzz_env = {**fuzz_env, 'SystemRoot': os.environ.get('SystemRoot')}
+ return fuzz_env
def main():
@@ -103,8 +109,13 @@ def main():
logging.error("Must have fuzz executable built")
sys.exit(1)
+ fuzz_bin=os.getenv("BITCOINFUZZ", default=os.path.join(config["environment"]["BUILDDIR"], 'src', 'test', 'fuzz', 'fuzz'))
+
# Build list of tests
- test_list_all = parse_test_list(fuzz_bin=os.path.join(config["environment"]["BUILDDIR"], 'src', 'test', 'fuzz', 'fuzz'))
+ test_list_all = parse_test_list(
+ fuzz_bin=fuzz_bin,
+ source_dir=config['environment']['SRCDIR'],
+ )
if not test_list_all:
logging.error("No fuzz targets found")
@@ -147,7 +158,7 @@ def main():
try:
help_output = subprocess.run(
args=[
- os.path.join(config["environment"]["BUILDDIR"], 'src', 'test', 'fuzz', 'fuzz'),
+ fuzz_bin,
'-help=1',
],
env=get_fuzz_env(target=test_list_selection[0], source_dir=config['environment']['SRCDIR']),
@@ -169,7 +180,7 @@ def main():
return generate_corpus(
fuzz_pool=fuzz_pool,
src_dir=config['environment']['SRCDIR'],
- build_dir=config["environment"]["BUILDDIR"],
+ fuzz_bin=fuzz_bin,
corpus_dir=args.corpus_dir,
targets=test_list_selection,
)
@@ -180,7 +191,7 @@ def main():
corpus=args.corpus_dir,
test_list=test_list_selection,
src_dir=config['environment']['SRCDIR'],
- build_dir=config["environment"]["BUILDDIR"],
+ fuzz_bin=fuzz_bin,
merge_dirs=[Path(m_dir) for m_dir in args.m_dir],
)
return
@@ -190,7 +201,7 @@ def main():
corpus=args.corpus_dir,
test_list=test_list_selection,
src_dir=config['environment']['SRCDIR'],
- build_dir=config["environment"]["BUILDDIR"],
+ fuzz_bin=fuzz_bin,
using_libfuzzer=using_libfuzzer,
use_valgrind=args.valgrind,
empty_min_time=args.empty_min_time,
@@ -233,7 +244,7 @@ def transform_rpc_target(targets, src_dir):
return targets
-def generate_corpus(*, fuzz_pool, src_dir, build_dir, corpus_dir, targets):
+def generate_corpus(*, fuzz_pool, src_dir, fuzz_bin, corpus_dir, targets):
"""Generates new corpus.
Run {targets} without input, and outputs the generated corpus to
@@ -264,9 +275,13 @@ def generate_corpus(*, fuzz_pool, src_dir, build_dir, corpus_dir, targets):
for target, t_env in targets:
target_corpus_dir = corpus_dir / target
os.makedirs(target_corpus_dir, exist_ok=True)
+ use_value_profile = int(random.random() < .3)
command = [
- os.path.join(build_dir, 'src', 'test', 'fuzz', 'fuzz'),
- "-runs=100000",
+ fuzz_bin,
+ "-rss_limit_mb=8000",
+ "-max_total_time=6000",
+ "-reload=0",
+ f"-use_value_profile={use_value_profile}",
target_corpus_dir,
]
futures.append(fuzz_pool.submit(job, command, target, t_env))
@@ -275,12 +290,12 @@ def generate_corpus(*, fuzz_pool, src_dir, build_dir, corpus_dir, targets):
future.result()
-def merge_inputs(*, fuzz_pool, corpus, test_list, src_dir, build_dir, merge_dirs):
+def merge_inputs(*, fuzz_pool, corpus, test_list, src_dir, fuzz_bin, merge_dirs):
logging.info(f"Merge the inputs from the passed dir into the corpus_dir. Passed dirs {merge_dirs}")
jobs = []
for t in test_list:
args = [
- os.path.join(build_dir, 'src', 'test', 'fuzz', 'fuzz'),
+ fuzz_bin,
'-rss_limit_mb=8000',
'-set_cover_merge=1',
# set_cover_merge is used instead of -merge=1 to reduce the overall
@@ -317,13 +332,13 @@ def merge_inputs(*, fuzz_pool, corpus, test_list, src_dir, build_dir, merge_dirs
future.result()
-def run_once(*, fuzz_pool, corpus, test_list, src_dir, build_dir, using_libfuzzer, use_valgrind, empty_min_time):
+def run_once(*, fuzz_pool, corpus, test_list, src_dir, fuzz_bin, using_libfuzzer, use_valgrind, empty_min_time):
jobs = []
for t in test_list:
corpus_path = corpus / t
os.makedirs(corpus_path, exist_ok=True)
args = [
- os.path.join(build_dir, 'src', 'test', 'fuzz', 'fuzz'),
+ fuzz_bin,
]
empty_dir = not any(corpus_path.iterdir())
if using_libfuzzer:
@@ -378,11 +393,12 @@ def run_once(*, fuzz_pool, corpus, test_list, src_dir, build_dir, using_libfuzze
print(f"{t}{s}")
-def parse_test_list(*, fuzz_bin):
+def parse_test_list(*, fuzz_bin, source_dir):
test_list_all = subprocess.run(
fuzz_bin,
env={
- 'PRINT_ALL_FUZZ_TARGETS_AND_ABORT': ''
+ 'PRINT_ALL_FUZZ_TARGETS_AND_ABORT': '',
+ **get_fuzz_env(target="", source_dir=source_dir)
},
stdout=subprocess.PIPE,
text=True,