diff --git a/build/meson/tests/meson.build b/build/meson/tests/meson.build index c64ae7a7..4e127dec 100644 --- a/build/meson/tests/meson.build +++ b/build/meson/tests/meson.build @@ -8,58 +8,186 @@ # in the COPYING file in the root directory of this source tree). # ############################################################################# -zstd_source_dir = join_paths('..', '..', '..') -programs_dir = join_paths(zstd_source_dir, 'programs') -tests_dir = join_paths(zstd_source_dir, 'tests') +zstd_rootdir = '../../..' -datagen_c_file = join_paths(programs_dir, 'datagen.c') -util_c_file = join_paths(programs_dir, 'util.c') -benchfn_c_file = join_paths(programs_dir, 'benchfn.c') +tests_supported_oses = [os_linux, 'gnu/kfreebsd', os_darwin, 'gnu', 'openbsd', + os_freebsd, 'netbsd', 'dragonfly', os_sun] -datagen_sources = [datagen_c_file, - join_paths(tests_dir, 'datagencli.c')] -test_includes = libzstd_includes + [include_directories(programs_dir)] +# ============================================================================= +# Test flags +# ============================================================================= +FUZZER_FLAGS = ['--no-big-tests'] +FUZZERTEST = '-T200s' +ZSTREAM_TESTTIME = '-T90s' +DECODECORPUS_TESTTIME = '-T30' +ZSTDRTTEST = ['--test-large-data'] + +# ============================================================================= +# Executables +# ============================================================================= + +test_includes = [ include_directories(join_paths(zstd_rootdir, 'programs')) ] + +datagen_sources = [join_paths(zstd_rootdir, 'programs/datagen.c'), + join_paths(zstd_rootdir, 'tests/datagencli.c')] datagen = executable('datagen', - datagen_sources, - include_directories: test_includes, - link_with: libzstd, - install: false) -test('datagen', datagen) + datagen_sources, + c_args: [ '-DNDEBUG' ], + include_directories: test_includes, + dependencies: libzstd_dep, + install: false) -fullbench_sources = [datagen_c_file, - util_c_file, - benchfn_c_file, - join_paths(programs_dir, 'benchzstd.c'), - join_paths(tests_dir, 'fullbench.c')] +fullbench_sources = [join_paths(zstd_rootdir, 'programs/datagen.c'), + join_paths(zstd_rootdir, 'programs/util.c'), + join_paths(zstd_rootdir, 'programs/benchfn.c'), + join_paths(zstd_rootdir, 'programs/benchzstd.c'), + join_paths(zstd_rootdir, 'tests/fullbench.c')] fullbench = executable('fullbench', - fullbench_sources, - include_directories: test_includes, - link_with: libzstd, - install: false) -test('fullbench', fullbench) + fullbench_sources, + include_directories: test_includes, + dependencies: libzstd_dep, + install: false) -fuzzer_sources = [datagen_c_file, - util_c_file, - join_paths(tests_dir, 'fuzzer.c')] +fuzzer_sources = [join_paths(zstd_rootdir, 'programs/datagen.c'), + join_paths(zstd_rootdir, 'programs/util.c'), + join_paths(zstd_rootdir, 'tests/fuzzer.c')] fuzzer = executable('fuzzer', - fuzzer_sources, - include_directories: test_includes, - link_with: libzstd, - install: false) -test('fuzzer', fuzzer) + fuzzer_sources, + include_directories: test_includes, + dependencies: libzstd_dep, + install: false) -paramgrill_sources = [benchfn_c_file, - join_paths(programs_dir, 'benchzstd.c'), - datagen_c_file, - util_c_file, - join_paths(tests_dir, 'paramgrill.c')] -if host_machine.system() != 'windows' - paramgrill = executable('paramgrill', - paramgrill_sources, - include_directories: test_includes, - link_with: libzstd, - dependencies: libm_dep, - install: false) - test('paramgrill', paramgrill) +zbufftest_sources = [join_paths(zstd_rootdir, 'programs/datagen.c'), + join_paths(zstd_rootdir, 'programs/util.c'), + join_paths(zstd_rootdir, 'tests/zbufftest.c')] +zbufftest = executable('zbufftest', + zbufftest_sources, + c_args: ['-Wno-deprecated-declarations'], + include_directories: test_includes, + dependencies: libzstd_dep, + install: false) + +zstreamtest_sources = [join_paths(zstd_rootdir, 'programs/datagen.c'), + join_paths(zstd_rootdir, 'programs/util.c'), + join_paths(zstd_rootdir, 'tests/seqgen.c'), + join_paths(zstd_rootdir, 'tests/zstreamtest.c')] +zstreamtest = executable('zstreamtest', + zstreamtest_sources, + include_directories: test_includes, + dependencies: libzstd_dep, + install: false) + +paramgrill_sources = [join_paths(zstd_rootdir, 'programs/benchfn.c'), + join_paths(zstd_rootdir, 'programs/benchzstd.c'), + join_paths(zstd_rootdir, 'programs/datagen.c'), + join_paths(zstd_rootdir, 'programs/util.c'), + join_paths(zstd_rootdir, 'tests/paramgrill.c')] +paramgrill = executable('paramgrill', + paramgrill_sources, + include_directories: test_includes, + dependencies: [ libzstd_dep, libm_dep ], + install: false) + +roundTripCrash_sources = [join_paths(zstd_rootdir, 'tests/roundTripCrash.c')] +roundTripCrash = executable('roundTripCrash', + roundTripCrash_sources, + dependencies: [ libzstd_dep ], + install: false) + +longmatch_sources = [join_paths(zstd_rootdir, 'tests/longmatch.c')] +longmatch = executable('longmatch', + longmatch_sources, + dependencies: [ libzstd_dep ], + install: false) + +invalidDictionaries_sources = [join_paths(zstd_rootdir, 'tests/invalidDictionaries.c')] +invalidDictionaries = executable('invalidDictionaries', + invalidDictionaries_sources, + dependencies: [ libzstd_dep ], + install: false) + +legacy_sources = [join_paths(zstd_rootdir, 'tests/legacy.c')] +legacy = executable('legacy', + legacy_sources, + c_args: '-DZSTD_LEGACY_SUPPORT=4', + dependencies: [ libzstd_dep ], + install: false) + +decodecorpus_sources = [join_paths(zstd_rootdir, 'programs/util.c'), + join_paths(zstd_rootdir, 'tests/decodecorpus.c')] +decodecorpus = executable('decodecorpus', + decodecorpus_sources, + include_directories: test_includes, + dependencies: [ libzstd_dep, libm_dep ], + install: false) + +symbols_sources = [join_paths(zstd_rootdir, 'tests/symbols.c')] +symbols = executable('symbols', + symbols_sources, + include_directories: test_includes, + c_args: host_machine_os == os_windows ? '-DZSTD_DLL_IMPORT=1' : [], + dependencies: [ libzstd_dep ], + install: false) + +poolTests_sources = [join_paths(zstd_rootdir, 'programs/util.c'), + join_paths(zstd_rootdir, 'tests/poolTests.c'), + join_paths(zstd_rootdir, 'lib/common/pool.c'), + join_paths(zstd_rootdir, 'lib/common/threading.c'), + join_paths(zstd_rootdir, 'lib/common/zstd_common.c'), + join_paths(zstd_rootdir, 'lib/common/error_private.c')] +poolTests = executable('poolTests', + poolTests_sources, + include_directories: test_includes, + dependencies: [ libzstd_dep ], + install: false) + +checkTag_sources = [join_paths(zstd_rootdir, 'tests/checkTag.c')] +checkTag = executable('checkTag', + checkTag_sources, + dependencies: [ libzstd_dep ], + install: false) + +# ============================================================================= +# Tests (Use "meson test --list" to list all tests) +# ============================================================================= + +if tests_supported_oses.contains(host_machine_os) + valgrind_prog = find_program('valgrind', ['/usr/bin/valgrind'], required: true) + valgrindTest_py = files('valgrindTest.py') + test('valgrindTest', + valgrindTest_py, + args: [valgrind_prog.path(), zstd, datagen, fuzzer, fullbench], + depends: [zstd, datagen, fuzzer, fullbench], + timeout: 600) # Timeout should work on HDD drive endif + +if host_machine_os != os_windows + playTests_sh = find_program(join_paths(zstd_rootdir, 'tests/playTests.sh'), required: true) + test('test-zstd', + playTests_sh, + args: ZSTDRTTEST, + env: ['ZSTD=' + zstd.full_path()], + depends: [datagen], + timeout: 600) # Timeout should work on HDD drive +endif + +test('test-fullbench-1', fullbench, args: ['-i1'], + depends: [fullbench, datagen]) +test('test-fullbench-2', fullbench, args: ['-i1', '-P0'], + depends: [fullbench, datagen]) + +if enable_zlib + test('test-fuzzer', fuzzer, args: ['-v', FUZZERTEST] + FUZZER_FLAGS) +endif + +test('test-zbuff', zbufftest, args: [ZSTREAM_TESTTIME]) +test('test-zstream-1', zstreamtest, args: ['-v', ZSTREAM_TESTTIME] + FUZZER_FLAGS) +test('test-zstream-2', zstreamtest, args: ['-mt', '-t1', ZSTREAM_TESTTIME] + FUZZER_FLAGS) +test('test-zstream-3', zstreamtest, args: ['--newapi', '-t1', ZSTREAM_TESTTIME] + FUZZER_FLAGS) +test('test-longmatch', longmatch) +test('test-invalidDictionaries', invalidDictionaries) +test('test-symbols', symbols) +test('test-legacy', legacy) +test('test-decodecorpus', decodecorpus, args: ['-t', DECODECORPUS_TESTTIME]) +test('test-poolTests', poolTests) diff --git a/build/meson/tests/valgrindTest.py b/build/meson/tests/valgrindTest.py new file mode 100644 index 00000000..218f7458 --- /dev/null +++ b/build/meson/tests/valgrindTest.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +# ############################################################################# +# Copyright (c) 2018-present lzutao +# All rights reserved. +# +# This source code is licensed under both the BSD-style license (found in the +# LICENSE file in the root directory of this source tree) and the GPLv2 (found +# in the COPYING file in the root directory of this source tree). +# ############################################################################# +import os +import subprocess +import tempfile + + +def valgrindTest(valgrind, datagen, fuzzer, zstd, fullbench): + VALGRIND_ARGS = [valgrind, '--leak-check=full', '--show-leak-kinds=all', '--error-exitcode=1'] + + print('\n ---- valgrind tests : memory analyzer ----') + + subprocess.check_call([*VALGRIND_ARGS, datagen, '-g50M'], stdout=subprocess.DEVNULL) + + if subprocess.call([*VALGRIND_ARGS, zstd], + stdout=subprocess.DEVNULL) == 0: + raise subprocess.CalledProcessError('zstd without argument should have failed') + + with subprocess.Popen([datagen, '-g80'], stdout=subprocess.PIPE) as p1, \ + subprocess.Popen([*VALGRIND_ARGS, zstd, '-', '-c'], + stdin=p1.stdout, + stdout=subprocess.DEVNULL) as p2: + p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits. + p2.communicate() + if p2.returncode != 0: + raise subprocess.CalledProcessError() + + with subprocess.Popen([datagen, '-g16KB'], stdout=subprocess.PIPE) as p1, \ + subprocess.Popen([*VALGRIND_ARGS, zstd, '-vf', '-', '-c'], + stdin=p1.stdout, + stdout=subprocess.DEVNULL) as p2: + p1.stdout.close() + p2.communicate() + if p2.returncode != 0: + raise subprocess.CalledProcessError() + + with tempfile.NamedTemporaryFile() as tmp_fd: + with subprocess.Popen([datagen, '-g2930KB'], stdout=subprocess.PIPE) as p1, \ + subprocess.Popen([*VALGRIND_ARGS, zstd, '-5', '-vf', '-', '-o', tmp_fd.name], + stdin=p1.stdout) as p2: + p1.stdout.close() + p2.communicate() + if p2.returncode != 0: + raise subprocess.CalledProcessError() + + subprocess.check_call([*VALGRIND_ARGS, zstd, '-vdf', tmp_fd.name, '-c'], + stdout=subprocess.DEVNULL) + + with subprocess.Popen([datagen, '-g64MB'], stdout=subprocess.PIPE) as p1, \ + subprocess.Popen([*VALGRIND_ARGS, zstd, '-vf', '-', '-c'], + stdin=p1.stdout, + stdout=subprocess.DEVNULL) as p2: + p1.stdout.close() + p2.communicate() + if p2.returncode != 0: + raise subprocess.CalledProcessError() + + subprocess.check_call([*VALGRIND_ARGS, fuzzer, '-T1mn', '-t1']) + subprocess.check_call([*VALGRIND_ARGS, fullbench, '-i1']) + + +def main(): + import argparse + parser = argparse.ArgumentParser(description='Valgrind tests : memory analyzer') + parser.add_argument('valgrind', help='valgrind path') + parser.add_argument('zstd', help='zstd path') + parser.add_argument('datagen', help='datagen path') + parser.add_argument('fuzzer', help='fuzzer path') + parser.add_argument('fullbench', help='fullbench path') + + args = parser.parse_args() + + valgrind = args.valgrind + zstd = args.zstd + datagen = args.datagen + fuzzer = args.fuzzer + fullbench = args.fullbench + + valgrindTest(valgrind, datagen, fuzzer, zstd, fullbench) + + +if __name__ == '__main__': + main()