mirror of
https://github.com/harfbuzz/harfbuzz.git
synced 2025-04-13 08:42:59 +00:00
[test/fuzzing] Port all to TAP
This commit is contained in:
parent
58d7ab2d59
commit
ba309a1826
2 changed files with 71 additions and 127 deletions
|
@ -6,8 +6,7 @@ tests = [
|
|||
'hb-repacker-fuzzer.cc',
|
||||
]
|
||||
|
||||
run_fuzzer_tests = find_program('run-fuzzer-tests.py', required: true)
|
||||
|
||||
# Build the binaries
|
||||
foreach file_name : tests
|
||||
test_name = file_name.split('.')[0]
|
||||
|
||||
|
@ -36,60 +35,60 @@ foreach file_name : tests
|
|||
set_variable('@0@_exe'.format(test_name.underscorify()), exe)
|
||||
endforeach
|
||||
|
||||
test('shape-fuzzer', run_fuzzer_tests,
|
||||
args: [
|
||||
hb_shape_fuzzer_exe,
|
||||
meson.current_source_dir() / 'fonts',
|
||||
],
|
||||
workdir: meson.current_build_dir() / '..' / '..',
|
||||
priority: 1,
|
||||
suite: ['fuzzing'],
|
||||
)
|
||||
|
||||
test('repacker-fuzzer', run_fuzzer_tests,
|
||||
args: [
|
||||
hb_repacker_fuzzer_exe,
|
||||
meson.current_source_dir() / 'graphs',
|
||||
],
|
||||
workdir: meson.current_build_dir() / '..' / '..',
|
||||
priority: 1,
|
||||
suite: ['fuzzing'],
|
||||
)
|
||||
|
||||
test('draw-fuzzer', run_fuzzer_tests,
|
||||
args: [
|
||||
hb_draw_fuzzer_exe,
|
||||
meson.current_source_dir() / 'fonts',
|
||||
],
|
||||
workdir: meson.current_build_dir() / '..' / '..',
|
||||
suite: ['fuzzing'],
|
||||
)
|
||||
|
||||
glob_cmd = find_program('glob.py', required: true)
|
||||
# Subset fuzzer: feed the fuzzer directly, without run-fuzzer-tests.py
|
||||
font_dirs = [
|
||||
meson.current_source_dir() / 'fonts',
|
||||
meson.current_source_dir() / '..' / 'subset' / 'data' / 'fonts',
|
||||
]
|
||||
glob = run_command(glob_cmd, font_dirs, check:true).stdout().strip().split('\n')
|
||||
|
||||
# Chunk glob and call runner for each chunk
|
||||
fonts_glob = run_command(glob_cmd, meson.current_source_dir() / 'fonts', check:true).stdout().strip().split('\n')
|
||||
subset_fonts_glob = run_command(glob_cmd, meson.current_source_dir() / '..' / 'subset' / 'data' / 'fonts', check:true).stdout().strip().split('\n')
|
||||
graphs_glob = run_command(glob_cmd, meson.current_source_dir() / 'graphs', check:true).stdout().strip().split('\n')
|
||||
sets_glob = run_command(glob_cmd, meson.current_source_dir() / 'sets', check:true).stdout().strip().split('\n')
|
||||
|
||||
# Chunk the glob lists to avoid command line length limits, and for parallelization
|
||||
chunk_size = 64
|
||||
chunks = []
|
||||
chunk = []
|
||||
foreach item : glob
|
||||
if chunk.length() >= chunk_size
|
||||
foreach glob_name : ['fonts_glob', 'subset_fonts_glob', 'graphs_glob', 'sets_glob']
|
||||
glob = get_variable(glob_name)
|
||||
chunks = []
|
||||
chunk = []
|
||||
foreach item : glob
|
||||
if chunk.length() >= chunk_size
|
||||
chunks += [chunk]
|
||||
chunk = []
|
||||
endif
|
||||
chunk += [item]
|
||||
endforeach
|
||||
if chunk.length() > 0
|
||||
chunks += [chunk]
|
||||
chunk = []
|
||||
endif
|
||||
chunk += [item]
|
||||
set_variable('@0@_chunks'.format(glob_name), chunks)
|
||||
endforeach
|
||||
if chunk.length() > 0
|
||||
chunks += [chunk]
|
||||
endif
|
||||
|
||||
# Run fuzzers
|
||||
|
||||
i = 0
|
||||
foreach chunk : chunks
|
||||
foreach chunk : fonts_glob_chunks
|
||||
test('shape-fuzzer-chunk-@0@'.format(i),
|
||||
hb_shape_fuzzer_exe,
|
||||
args: chunk,
|
||||
workdir: meson.current_build_dir() / '..' / '..',
|
||||
protocol: 'tap',
|
||||
suite: ['fuzzing'],
|
||||
)
|
||||
i += 1
|
||||
endforeach
|
||||
|
||||
i = 0
|
||||
foreach chunk : fonts_glob_chunks
|
||||
test('draw-fuzzer-chunk-@0@'.format(i),
|
||||
hb_draw_fuzzer_exe,
|
||||
args: chunk,
|
||||
workdir: meson.current_build_dir() / '..' / '..',
|
||||
protocol: 'tap',
|
||||
suite: ['fuzzing'],
|
||||
)
|
||||
i += 1
|
||||
endforeach
|
||||
|
||||
i = 0
|
||||
foreach chunk : fonts_glob_chunks + subset_fonts_glob_chunks
|
||||
test('subset-fuzzer-chunk-@0@'.format(i),
|
||||
hb_subset_fuzzer_exe,
|
||||
args: chunk,
|
||||
|
@ -99,3 +98,27 @@ foreach chunk : chunks
|
|||
)
|
||||
i += 1
|
||||
endforeach
|
||||
|
||||
i = 0
|
||||
foreach chunk : graphs_glob_chunks
|
||||
test('repacker-fuzzer-chunk-@0@'.format(i),
|
||||
hb_repacker_fuzzer_exe,
|
||||
args: chunk,
|
||||
workdir: meson.current_build_dir() / '..' / '..',
|
||||
protocol: 'tap',
|
||||
suite: ['fuzzing'],
|
||||
)
|
||||
i += 1
|
||||
endforeach
|
||||
|
||||
i = 0
|
||||
foreach chunk : sets_glob_chunks
|
||||
test('set-fuzzer-chunk-@0@'.format(i),
|
||||
hb_set_fuzzer_exe,
|
||||
args: chunk,
|
||||
workdir: meson.current_build_dir() / '..' / '..',
|
||||
protocol: 'tap',
|
||||
suite: ['fuzzing'],
|
||||
)
|
||||
i += 1
|
||||
endforeach
|
||||
|
|
|
@ -1,79 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import pathlib
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
EXE_WRAPPER = os.environ.get("MESON_EXE_WRAPPER")
|
||||
|
||||
|
||||
def run_command(command):
|
||||
"""
|
||||
Run a command, capturing potentially large output in a temp file.
|
||||
Returns (output_string, exit_code).
|
||||
"""
|
||||
global EXE_WRAPPER
|
||||
if EXE_WRAPPER:
|
||||
command = [EXE_WRAPPER] + command
|
||||
|
||||
with tempfile.TemporaryFile() as tempf:
|
||||
p = subprocess.Popen(command, stdout=tempf, stderr=tempf)
|
||||
p.wait()
|
||||
tempf.seek(0)
|
||||
output = tempf.read().decode("utf-8", errors="replace").strip()
|
||||
return output, p.returncode
|
||||
|
||||
|
||||
def chunkify(lst, chunk_size=64):
|
||||
"""
|
||||
Yield successive chunk_size-sized slices from lst.
|
||||
"""
|
||||
for i in range(0, len(lst), chunk_size):
|
||||
yield lst[i : i + chunk_size]
|
||||
|
||||
|
||||
def main():
|
||||
assert len(sys.argv) > 2, "Please provide fuzzer binary and fonts directory paths."
|
||||
|
||||
fuzzer = pathlib.Path(sys.argv[1])
|
||||
assert fuzzer.is_file(), f"Fuzzer binary not found: {fuzzer}"
|
||||
print("Using fuzzer:", fuzzer)
|
||||
|
||||
# Gather all test files
|
||||
files_to_test = []
|
||||
for fonts_dir in sys.argv[2:]:
|
||||
fonts_dir = pathlib.Path(fonts_dir)
|
||||
assert fonts_dir.is_dir(), f"Fonts directory not found: {fonts_dir}"
|
||||
test_files = [str(f) for f in fonts_dir.iterdir() if f.is_file()]
|
||||
assert test_files, f"No files found in {fonts_dir}"
|
||||
files_to_test += test_files
|
||||
|
||||
if not files_to_test:
|
||||
print("No test files found")
|
||||
sys.exit(0)
|
||||
|
||||
fails = 0
|
||||
batch_index = 0
|
||||
|
||||
for chunk in chunkify(files_to_test):
|
||||
batch_index += 1
|
||||
cmd_line = [fuzzer] + chunk
|
||||
output, returncode = run_command(cmd_line)
|
||||
|
||||
if output:
|
||||
print(output)
|
||||
|
||||
if returncode != 0:
|
||||
print(f"Failure in batch #{batch_index}")
|
||||
fails += 1
|
||||
|
||||
if fails > 0:
|
||||
sys.exit(f"{fails} fuzzer batch(es) failed.")
|
||||
|
||||
print("All fuzzer tests passed successfully.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Add table
Reference in a new issue