From 8daa83a594a2e98f39d764422bfbdbc62c9efd44 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 19:20:00 +0200 Subject: Adding upstream version 2:4.20.0+dfsg. Signed-off-by: Daniel Baumann --- selftest/wscript | 403 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 403 insertions(+) create mode 100644 selftest/wscript (limited to 'selftest/wscript') diff --git a/selftest/wscript b/selftest/wscript new file mode 100644 index 0000000..daf497d --- /dev/null +++ b/selftest/wscript @@ -0,0 +1,403 @@ +#!/usr/bin/env python +# vim: expandtab ft=python + +# selftest main code. + +import sys +import os +from waflib import Options, Utils + +from samba_utils import ( + ADD_LD_LIBRARY_PATH, + CHECK_MAKEFLAGS, + EXPAND_VARIABLES, + LOAD_ENVIRONMENT, + RUN_COMMAND, +) +from samba_autoconf import CONFIG_GET, CONFIG_SET +import types + +DEFAULT_SELFTEST_PREFIX="./st" + +def options(opt): + + opt.add_option('--enable-selftest', + help=("enable options necessary for selftest (default=no)"), + action="store_true", dest='enable_selftest', default=False) + opt.add_option('--with-selftest-prefix', + help=("specify location of selftest directory " + "(default=%s)" % DEFAULT_SELFTEST_PREFIX), + action="store", dest='SELFTEST_PREFIX', default=DEFAULT_SELFTEST_PREFIX) + + opt.ADD_COMMAND('test', cmd_test) + opt.ADD_COMMAND('testonly', cmd_testonly) + + gr = opt.add_option_group('test options') + + gr.add_option('--load-list', + help=("Load a test id list from a text file"), + action="store", dest='LOAD_LIST', default=None) + gr.add_option('--list', + help=("List available tests"), + action="store_true", dest='LIST', default=False) + gr.add_option('--tests', + help=("wildcard pattern of tests to run"), + action="store", dest='TESTS', default='') + gr.add_option('--filtered-subunit', + help=("output (xfail) filtered subunit"), + action="store_true", dest='FILTERED_SUBUNIT', default=False) + gr.add_option('--quick', + help=("enable only quick tests"), + action="store_true", dest='QUICKTEST', default=False) + gr.add_option('--slow', + help=("enable the really slow tests"), + action="store_true", dest='SLOWTEST', default=False) + gr.add_option('--nb-slowest', + help=("Show the n slowest tests (default=10)"), + type=int, default=10, dest='NB_SLOWEST') + gr.add_option('--testenv', + help=("start a terminal with the test environment setup"), + action="store_true", dest='TESTENV', default=False) + gr.add_option('--valgrind', + help=("use valgrind on client programs in the tests"), + action="store_true", dest='VALGRIND', default=False) + gr.add_option('--valgrind-log', + help=("where to put the valgrind log"), + action="store", dest='VALGRINDLOG', default=None) + gr.add_option('--valgrind-server', + help=("use valgrind on the server in the tests (opens an xterm)"), + action="store_true", dest='VALGRIND_SERVER', default=False) + gr.add_option('--screen', + help=("run the samba servers in screen sessions"), + action="store_true", dest='SCREEN', default=False) + gr.add_option('--gdbtest', + help=("run the servers within a gdb window"), + action="store_true", dest='GDBTEST', default=False) + gr.add_option('--fail-immediately', + help=("stop tests on first failure"), + action="store_true", dest='FAIL_IMMEDIATELY', default=False) + gr.add_option('--socket-wrapper-pcap', + help=("create a pcap file for each failing test"), + action="store_true", dest='SOCKET_WRAPPER_PCAP', default=False) + gr.add_option('--socket-wrapper-keep-pcap', + help=("create a pcap file for all individual test"), + action="store_true", dest='SOCKET_WRAPPER_KEEP_PCAP', default=False) + gr.add_option('--random-order', dest='RANDOM_ORDER', default=False, + action="store_true", help="Run testsuites in random order") + gr.add_option('--perf-test', dest='PERF_TEST', default=False, + action="store_true", help="run performance tests only") + gr.add_option('--test-list', dest='TEST_LIST', default='', + help=("use tests listed here, not defaults " + "(--test-list='FOO|' will execute FOO; " + "--test-list='FOO' will read it)")) + gr.add_option('--no-subunit-filter', + help=("no (xfail) subunit filtering"), + action="store_true", dest='NO_SUBUNIT_FILTER', default=False) + + +def configure(conf): + conf.env.SELFTEST_PREFIX = Options.options.SELFTEST_PREFIX + if Options.options.enable_selftest or Options.options.developer: + conf.DEFINE('ENABLE_SELFTEST', 1) + + +def cmd_testonly(opt): + '''run tests without doing a build first''' + env = LOAD_ENVIRONMENT() + opt.env = env + + if Options.options.SELFTEST_PREFIX != DEFAULT_SELFTEST_PREFIX: + env.SELFTEST_PREFIX = Options.options.SELFTEST_PREFIX + + if (not CONFIG_SET(opt, 'NSS_WRAPPER') or + not CONFIG_SET(opt, 'UID_WRAPPER') or + not CONFIG_SET(opt, 'SOCKET_WRAPPER')): + print("ERROR: You must use --enable-selftest to enable selftest") + sys.exit(1) + + os.environ['SAMBA_SELFTEST'] = '1' + + env.TESTS = Options.options.TESTS + + env.SUBUNIT_FORMATTER = os.getenv('SUBUNIT_FORMATTER') + + # Lots of test scripts need to run with the correct version + # of python. With the correct shebang the script should run with the + # correct version, the problem is that not all scripts are part + # of the installation, some scripts are part of the source code, + # and the shebang is not dynamically generated as yet. + # It is safer if we are somewhat version neutral at the moment and + # ignore the shebang and always run scripts from the test environment + # with the python version (determined by PYTHON env variable) If this + # env variable isn't set then set it according to the python version + # that is running the tests + if not os.getenv('PYTHON', None): + from sys import executable as exe + os.environ['PYTHON'] = os.path.basename(exe) + + if not env.SUBUNIT_FORMATTER: + if Options.options.PERF_TEST: + env.SUBUNIT_FORMATTER = '${PYTHON} -u ${srcdir}/selftest/format-subunit-json --prefix=${SELFTEST_PREFIX}' + else: + env.SUBUNIT_FORMATTER = '${PYTHON} -u ${srcdir}/selftest/format-subunit --prefix=${SELFTEST_PREFIX} --immediate' + env.FILTER_XFAIL = ('${PYTHON} -u ${srcdir}/selftest/filter-subunit ' + '--expected-failures=${srcdir}/selftest/knownfail ' + '--expected-failures=${srcdir}/selftest/knownfail.d ' + '--expected-failures=${srcdir}/selftest/expectedfail.d ' + '--flapping=${srcdir}/selftest/flapping ' + '--flapping=${srcdir}/selftest/flapping.d') + + if Options.options.FAIL_IMMEDIATELY: + env.FILTER_XFAIL += ' --fail-immediately' + + env.FORMAT_TEST_OUTPUT = '${SUBUNIT_FORMATTER}' + + # clean any previous temporary files + os.system("rm -rf %s/tmp" % env.SELFTEST_PREFIX); + + # put all command line options in the environment as TESTENV_*=* + for o in dir(Options.options): + if o[0:1] != '_': + val = getattr(Options.options, o, '') + if not issubclass(type(val), types.FunctionType) \ + and not issubclass(type(val), types.MethodType): + os.environ['TESTENV_%s' % o.upper()] = str(getattr(Options.options, o, '')) + + env.OPTIONS = '' + if not Options.options.SLOWTEST: + env.OPTIONS += ' --exclude=${srcdir}/selftest/slow' + if Options.options.QUICKTEST: + env.OPTIONS += ' --quick --include=${srcdir}/selftest/quick' + if Options.options.LOAD_LIST: + env.OPTIONS += ' --load-list=%s' % Options.options.LOAD_LIST + if Options.options.TESTENV: + env.OPTIONS += ' --testenv' + if Options.options.SOCKET_WRAPPER_PCAP: + env.OPTIONS += ' --socket-wrapper-pcap' + if Options.options.SOCKET_WRAPPER_KEEP_PCAP: + env.OPTIONS += ' --socket-wrapper-keep-pcap' + if Options.options.RANDOM_ORDER: + env.OPTIONS += ' --random-order' + if Options.options.PERF_TEST: + env.FILTER_OPTIONS = ('${PYTHON} -u ${srcdir}/selftest/filter-subunit ' + '--perf-test-output') + else: + env.FILTER_OPTIONS = '${FILTER_XFAIL}' + + if Options.options.VALGRIND: + os.environ['VALGRIND'] = 'valgrind -q --num-callers=30' + if Options.options.VALGRINDLOG is not None: + os.environ['VALGRIND'] += ' --log-file=%s' % Options.options.VALGRINDLOG + + server_wrapper='' + + if Options.options.VALGRIND_SERVER: + server_wrapper = '${srcdir}/selftest/valgrind_run _DUMMY=X' + elif Options.options.GDBTEST: + server_wrapper = '${srcdir}/selftest/gdb_run _DUMMY=X' + + if Options.options.SCREEN: + server_wrapper = '${srcdir}/selftest/in_screen %s' % server_wrapper + os.environ['TERMINAL'] = EXPAND_VARIABLES(opt, '${srcdir}/selftest/in_screen') + elif server_wrapper != '': + server_wrapper = 'xterm -n server -l -e %s' % server_wrapper + + if server_wrapper != '': + os.environ['SAMBA_VALGRIND'] = EXPAND_VARIABLES(opt, server_wrapper) + os.environ['NMBD_VALGRIND'] = EXPAND_VARIABLES(opt, server_wrapper) + os.environ['WINBINDD_VALGRIND'] = EXPAND_VARIABLES(opt, server_wrapper) + os.environ['SMBD_VALGRIND'] = EXPAND_VARIABLES(opt, server_wrapper) + os.environ['SAMBA_DCERPCD_VALGRIND'] = EXPAND_VARIABLES(opt, server_wrapper) + + # this is needed for systems without rpath, or with rpath disabled + ADD_LD_LIBRARY_PATH('bin/shared') + ADD_LD_LIBRARY_PATH('bin/shared/private') + + # if we are using a system version of ldb then we need to tell it to + # load modules from our modules path + if env.USING_SYSTEM_LDB: + os.environ['LDB_MODULES_PATH'] = os.path.abspath( + os.path.join(*(env.cwd + ['bin/modules/ldb']))) + + # tell build system where to find config.h + os.environ['CONFIG_H'] = 'bin/default/include/config.h' + + # tell the test system where perl is + if isinstance(env.PERL, list): + perl = ' '.join(env.PERL) + else: + perl = env.PERL + os.environ['PERL'] = perl + + st_done = os.path.join(env.SELFTEST_PREFIX, 'st_done') + if os.path.exists(st_done): + os.unlink(st_done) + + if not os.path.isdir(env.SELFTEST_PREFIX): + os.makedirs(env.SELFTEST_PREFIX, int('755', 8)) + + if Options.options.TEST_LIST: + env.TESTLISTS = '--testlist=%r' % Options.options.TEST_LIST + elif Options.options.PERF_TEST: + env.TESTLISTS = '--testlist="${PYTHON} ${srcdir}/selftest/perf_tests.py|" ' + else: + env.TESTLISTS = ('--testlist="${PYTHON} ${srcdir}/selftest/tests.py|" ' + + '--testlist="${PYTHON} ${srcdir}/source3/selftest/tests.py|" ' + + '--testlist="${PYTHON} ${srcdir}/source4/selftest/tests.py|"') + + if CONFIG_SET(opt, 'AD_DC_BUILD_IS_ENABLED'): + env.SELFTEST_TARGET = "samba" + else: + env.SELFTEST_TARGET = "samba3" + + env.OPTIONS += " --nss_wrapper_so_path=" + CONFIG_GET(opt, 'LIBNSS_WRAPPER_SO_PATH') + env.OPTIONS += " --resolv_wrapper_so_path=" + CONFIG_GET(opt, 'LIBRESOLV_WRAPPER_SO_PATH') + env.OPTIONS += " --uid_wrapper_so_path=" + CONFIG_GET(opt, 'LIBUID_WRAPPER_SO_PATH') + + # selftest can optionally use kernel namespaces instead of socket-wrapper + if os.environ.get('USE_NAMESPACES') is None: + env.OPTIONS += " --socket_wrapper_so_path=" + CONFIG_GET(opt, 'LIBSOCKET_WRAPPER_SO_PATH') + + if not CONFIG_SET(opt, 'HAVE_RESOLV_CONF_SUPPORT'): + env.OPTIONS += " --use-dns-faking" + + if CONFIG_GET(opt, 'USING_SYSTEM_KRB5'): + env.OPTIONS += " --mitkrb5" + + if CONFIG_GET(opt, 'USING_SYSTEM_KRB5') and CONFIG_GET(opt, 'MIT_KDC_PATH'): + env.OPTIONS += " --exclude=${srcdir}/selftest/skip_mit_kdc" + env.FILTER_XFAIL += " --expected-failures=${srcdir}/selftest/"\ + "knownfail_mit_kdc" + + env.FILTER_XFAIL += ' --expected-failures=${srcdir}/selftest/knownfail_mit_kdc_1_20' + else: + env.FILTER_XFAIL += " --expected-failures=${srcdir}/selftest/"\ + "knownfail_heimdal_kdc" + + if CONFIG_GET(opt, 'SIZEOF_VOID_P') == 4: + env.FILTER_XFAIL += " --expected-failures=${srcdir}/selftest/knownfail-32bit" + env.OPTIONS += " --default-ldb-backend=tdb --exclude=${srcdir}/selftest/skip-32bit" + + if not CONFIG_GET(opt, 'HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X'): + # older MIT krb5 libraries (< 1.14) don't have + # GSS_KRB5_CRED_NO_CI_FLAGS_X + env.OPTIONS += " --exclude=${srcdir}/selftest/skip.no-GSS_KRB5_CRED_NO_CI_FLAGS_X" + + if os.environ.get('DISABLE_OPATH'): + env.OPTIONS += " --exclude=${srcdir}/selftest/skip.opath-required" + + libasan = None + if env.ADDRESS_SANITIZER: + # We try to find the correct libasan automatically + libasan = Utils.cmd_output( + r'ldd bin/texpect | grep libasan| cut -f 3 -d \ ', + silent=True).strip() + libasan = libasan.decode('utf8') + + # Have the selftest.pl LD_PRELOAD libasan in the right spot + env.OPTIONS += " --asan_so_path=" + libasan + + if CONFIG_SET(opt, 'HAVE_CRYPT_R'): + # We try to find the correct libcrypt automatically + libcrypt = Utils.cmd_output( + 'ldd bin/modules/ldb/password_hash.so | awk \'/libcrypt.so/ { print $3 }\'', + silent=True).strip() + libcrypt = libcrypt.decode('utf8') + env.OPTIONS += " --crypt_so_path=" + libcrypt + + subunit_cache = None + # We use the full path rather than relative path to avoid problems on some platforms (ie. solaris 8). + env.CORE_COMMAND = '${PERL} ${srcdir}/selftest/selftest.pl --target=${SELFTEST_TARGET} --prefix=${SELFTEST_PREFIX} --srcdir=${srcdir} --exclude=${srcdir}/selftest/skip ${TESTLISTS} ${OPTIONS} ${TESTS}' + + # If using namespaces (rather than socket-wrapper), run the selftest script + # in its own network namespace (by doing an 'unshare'). (To create a new + # namespace as a non-root user, we have to also unshare the current user + # namespace, and remap ourself as root in the namespace created) + if os.environ.get('USE_NAMESPACES') is not None: + env.CORE_COMMAND = 'unshare --net --user --map-root-user ' + env.CORE_COMMAND + + if env.ADDRESS_SANITIZER and libasan: + # For now we cannot run with leak and odr detection + asan_options = "ASAN_OPTIONS=detect_leaks=0" + asan_options += ":detect_odr_violation=0" + # uncomment if you need asan logs + # asan_options += ":verbosity=111" + asan_options += ":suppressions=${srcdir}/selftest/sanitizer/asan.supp" + asan_options += " " + + # And we need to disable RTLD_DEEPBIND in ldb and socket wrapper + no_leak_check = "LDB_MODULES_DISABLE_DEEPBIND=1 " + no_leak_check += "SOCKET_WRAPPER_DISABLE_DEEP_BIND=1" + no_leak_check += " " + env.CORE_COMMAND = asan_options + no_leak_check + env.CORE_COMMAND + + # We need to have the subunit filter and formatter preload + # libasan otherwise the tests fail at startup. + # + # Also, we do not care about leaks in python + + asan_envs = (asan_options + no_leak_check + "LD_PRELOAD=" + libasan + + ' ') + env.FILTER_OPTIONS = asan_envs + env.FILTER_OPTIONS + env.SUBUNIT_FORMATTER = asan_envs + env.SUBUNIT_FORMATTER + + if env.UNDEFINED_SANITIZER: + # print a stack trace with the error. + print_stack_trace = "UBSAN_OPTIONS=print_stacktrace=1" + print_stack_trace += ",suppressions=${srcdir}/selftest/ubsan.supp" + env.CORE_COMMAND = print_stack_trace + " " + env.CORE_COMMAND + + if Options.options.LIST: + cmd = '${CORE_COMMAND} --list' + else: + env.OPTIONS += ' --socket-wrapper' + cmd = '(${CORE_COMMAND} && touch ${SELFTEST_PREFIX}/st_done) | ${FILTER_OPTIONS}' + + if Options.options.NO_SUBUNIT_FILTER: + # Skip subunit filtering (i.e. because python is disabled). + # Use --one to bail out upon any failure + cmd = '(${CORE_COMMAND} --one && touch ${SELFTEST_PREFIX}/st_done)' + elif not Options.options.FILTERED_SUBUNIT: + subunit_cache = os.path.join(env.SELFTEST_PREFIX, "subunit") + cmd += ' | tee %s | ${FORMAT_TEST_OUTPUT}' % subunit_cache + else: + cmd += ' | ${FILTER_OPTIONS}' + + runcmd = EXPAND_VARIABLES(opt, cmd) + + print("test: running %s" % runcmd) + ret = RUN_COMMAND(cmd, env=env) + + if (os.path.exists(".testrepository") and + not Options.options.LIST and + not Options.options.LOAD_LIST and + subunit_cache is not None): + testrcmd = 'testr load -q < %s > /dev/null' % subunit_cache + runcmd = EXPAND_VARIABLES(opt, testrcmd) + RUN_COMMAND(runcmd, env=env) + + if subunit_cache is not None: + nb = Options.options.NB_SLOWEST + cmd = "./script/show_testsuite_time %s %d" % (subunit_cache, nb) + runcmd = EXPAND_VARIABLES(opt, cmd) + RUN_COMMAND(runcmd, env=env) + + if ret != 0: + print("ERROR: test failed with exit code %d" % ret) + sys.exit(ret) + + if not Options.options.LIST and not os.path.exists(st_done): + print("ERROR: test command failed to complete") + sys.exit(1) + + +######################################################################## +# main test entry point +def cmd_test(opt): + '''Run the test suite (see test options below)''' + + # if running all tests, then force a symbol check + env = LOAD_ENVIRONMENT() + CHECK_MAKEFLAGS(env) + Options.commands.append('build') + Options.commands.append('testonly') -- cgit v1.2.3