| 1 | #!/usr/bin/env python | 
|---|
| 2 | # vim: expandtab ft=python | 
|---|
| 3 |  | 
|---|
| 4 | # selftest main code. | 
|---|
| 5 |  | 
|---|
| 6 | import Scripting, os, Options, Utils, Environment, optparse, sys | 
|---|
| 7 | from samba_utils import * | 
|---|
| 8 | from samba_autoconf import * | 
|---|
| 9 |  | 
|---|
| 10 | def set_options(opt): | 
|---|
| 11 |  | 
|---|
| 12 | opt.add_option('--enable-selftest', | 
|---|
| 13 | help=("enable options necessary for selftest (default=no)"), | 
|---|
| 14 | action="store_true", dest='enable_selftest', default=False) | 
|---|
| 15 | opt.add_option('--with-selftest-prefix', | 
|---|
| 16 | help=("specify location of selftest directory (default=./st)"), | 
|---|
| 17 | action="store", dest='SELFTEST_PREFIX', default='./st') | 
|---|
| 18 |  | 
|---|
| 19 | opt.ADD_COMMAND('test', cmd_test) | 
|---|
| 20 | opt.ADD_COMMAND('testonly', cmd_testonly) | 
|---|
| 21 |  | 
|---|
| 22 | gr = opt.add_option_group('test options') | 
|---|
| 23 |  | 
|---|
| 24 | gr.add_option('--load-list', | 
|---|
| 25 | help=("Load a test id list from a text file"), | 
|---|
| 26 | action="store", dest='LOAD_LIST', default=None) | 
|---|
| 27 | gr.add_option('--list', | 
|---|
| 28 | help=("List available tests"), | 
|---|
| 29 | action="store_true", dest='LIST', default=False) | 
|---|
| 30 | gr.add_option('--tests', | 
|---|
| 31 | help=("wildcard pattern of tests to run"), | 
|---|
| 32 | action="store", dest='TESTS', default='') | 
|---|
| 33 | gr.add_option('--filtered-subunit', | 
|---|
| 34 | help=("output (xfail) filtered subunit"), | 
|---|
| 35 | action="store_true", dest='FILTERED_SUBUNIT', default=False) | 
|---|
| 36 | gr.add_option('--quick', | 
|---|
| 37 | help=("enable only quick tests"), | 
|---|
| 38 | action="store_true", dest='QUICKTEST', default=False) | 
|---|
| 39 | gr.add_option('--slow', | 
|---|
| 40 | help=("enable the really slow tests"), | 
|---|
| 41 | action="store_true", dest='SLOWTEST', default=False) | 
|---|
| 42 | gr.add_option('--testenv', | 
|---|
| 43 | help=("start a terminal with the test environment setup"), | 
|---|
| 44 | action="store_true", dest='TESTENV', default=False) | 
|---|
| 45 | gr.add_option('--valgrind', | 
|---|
| 46 | help=("use valgrind on client programs in the tests"), | 
|---|
| 47 | action="store_true", dest='VALGRIND', default=False) | 
|---|
| 48 | gr.add_option('--valgrind-log', | 
|---|
| 49 | help=("where to put the valgrind log"), | 
|---|
| 50 | action="store", dest='VALGRINDLOG', default=None) | 
|---|
| 51 | gr.add_option('--valgrind-server', | 
|---|
| 52 | help=("use valgrind on the server in the tests (opens an xterm)"), | 
|---|
| 53 | action="store_true", dest='VALGRIND_SERVER', default=False) | 
|---|
| 54 | gr.add_option('--screen', | 
|---|
| 55 | help=("run the samba servers in screen sessions"), | 
|---|
| 56 | action="store_true", dest='SCREEN', default=False) | 
|---|
| 57 | gr.add_option('--gdbtest', | 
|---|
| 58 | help=("run the servers within a gdb window"), | 
|---|
| 59 | action="store_true", dest='GDBTEST', default=False) | 
|---|
| 60 | gr.add_option('--fail-immediately', | 
|---|
| 61 | help=("stop tests on first failure"), | 
|---|
| 62 | action="store_true", dest='FAIL_IMMEDIATELY', default=False) | 
|---|
| 63 | gr.add_option('--socket-wrapper-pcap', | 
|---|
| 64 | help=("create a pcap file for each failing test"), | 
|---|
| 65 | action="store_true", dest='SOCKET_WRAPPER_PCAP', default=False) | 
|---|
| 66 | gr.add_option('--socket-wrapper-keep-pcap', | 
|---|
| 67 | help=("create a pcap file for all individual test"), | 
|---|
| 68 | action="store_true", dest='SOCKET_WRAPPER_KEEP_PCAP', default=False) | 
|---|
| 69 |  | 
|---|
| 70 | def configure(conf): | 
|---|
| 71 | conf.env.SELFTEST_PREFIX = Options.options.SELFTEST_PREFIX | 
|---|
| 72 |  | 
|---|
| 73 | def cmd_testonly(opt): | 
|---|
| 74 | '''run tests without doing a build first''' | 
|---|
| 75 | env = LOAD_ENVIRONMENT() | 
|---|
| 76 | opt.env = env | 
|---|
| 77 |  | 
|---|
| 78 | if (not CONFIG_SET(opt, 'NSS_WRAPPER') or | 
|---|
| 79 | not CONFIG_SET(opt, 'UID_WRAPPER') or | 
|---|
| 80 | not CONFIG_SET(opt, 'SOCKET_WRAPPER')): | 
|---|
| 81 | print("ERROR: You must use --enable-selftest to enable selftest") | 
|---|
| 82 | sys.exit(1) | 
|---|
| 83 |  | 
|---|
| 84 | os.environ['SAMBA_SELFTEST'] = '1' | 
|---|
| 85 |  | 
|---|
| 86 | env.TESTS  = Options.options.TESTS | 
|---|
| 87 |  | 
|---|
| 88 | env.SUBUNIT_FORMATTER = os.getenv('SUBUNIT_FORMATTER') | 
|---|
| 89 | if not env.SUBUNIT_FORMATTER: | 
|---|
| 90 | env.SUBUNIT_FORMATTER = '${PYTHON} -u ${srcdir}/selftest/format-subunit --prefix=${SELFTEST_PREFIX} --immediate' | 
|---|
| 91 | env.FILTER_XFAIL = '${PYTHON} -u ${srcdir}/selftest/filter-subunit --expected-failures=${srcdir}/source4/selftest/knownfail' | 
|---|
| 92 |  | 
|---|
| 93 | if Options.options.FAIL_IMMEDIATELY: | 
|---|
| 94 | env.FILTER_XFAIL += ' --fail-immediately' | 
|---|
| 95 |  | 
|---|
| 96 | env.FORMAT_TEST_OUTPUT = '${SUBUNIT_FORMATTER}' | 
|---|
| 97 |  | 
|---|
| 98 | # clean any previous temporary files | 
|---|
| 99 | os.system("rm -rf %s/tmp" % env.SELFTEST_PREFIX); | 
|---|
| 100 |  | 
|---|
| 101 | # put all command line options in the environment as TESTENV_*=* | 
|---|
| 102 | for o in dir(Options.options): | 
|---|
| 103 | if o[0:1] != '_': | 
|---|
| 104 | os.environ['TESTENV_%s' % o.upper()] = str(getattr(Options.options, o, '')) | 
|---|
| 105 |  | 
|---|
| 106 | env.OPTIONS = '' | 
|---|
| 107 | if not Options.options.SLOWTEST: | 
|---|
| 108 | env.OPTIONS += ' --exclude=${srcdir}/source4/selftest/slow' | 
|---|
| 109 | if Options.options.QUICKTEST: | 
|---|
| 110 | env.OPTIONS += ' --quick --include=${srcdir}/source4/selftest/quick' | 
|---|
| 111 | if Options.options.LOAD_LIST: | 
|---|
| 112 | env.OPTIONS += ' --load-list=%s' % Options.options.LOAD_LIST | 
|---|
| 113 | if Options.options.TESTENV: | 
|---|
| 114 | env.OPTIONS += ' --testenv' | 
|---|
| 115 | if Options.options.SOCKET_WRAPPER_PCAP: | 
|---|
| 116 | env.OPTIONS += ' --socket-wrapper-pcap' | 
|---|
| 117 | if Options.options.SOCKET_WRAPPER_KEEP_PCAP: | 
|---|
| 118 | env.OPTIONS += ' --socket-wrapper-keep-pcap' | 
|---|
| 119 | if Options.options.LIST: | 
|---|
| 120 | env.OPTIONS += ' --list' | 
|---|
| 121 | if os.environ.get('RUN_FROM_BUILD_FARM') is not None: | 
|---|
| 122 | env.FILTER_OPTIONS = '${FILTER_XFAIL} --strip-passed-output' | 
|---|
| 123 | else: | 
|---|
| 124 | env.FILTER_OPTIONS = '${FILTER_XFAIL}' | 
|---|
| 125 |  | 
|---|
| 126 | if Options.options.VALGRIND: | 
|---|
| 127 | os.environ['VALGRIND'] = 'valgrind -q --num-callers=30' | 
|---|
| 128 | if Options.options.VALGRINDLOG is not None: | 
|---|
| 129 | os.environ['VALGRIND'] += ' --log-file=%s' % Options.options.VALGRINDLOG | 
|---|
| 130 |  | 
|---|
| 131 | server_wrapper='' | 
|---|
| 132 |  | 
|---|
| 133 | if Options.options.VALGRIND_SERVER: | 
|---|
| 134 | server_wrapper = '${srcdir}/selftest/valgrind_run _DUMMY=X' | 
|---|
| 135 | elif Options.options.GDBTEST: | 
|---|
| 136 | server_wrapper = '${srcdir}/selftest/gdb_run _DUMMY=X' | 
|---|
| 137 |  | 
|---|
| 138 | if Options.options.SCREEN: | 
|---|
| 139 | server_wrapper = '${srcdir}/selftest/in_screen %s' % server_wrapper | 
|---|
| 140 | os.environ['TERMINAL'] = EXPAND_VARIABLES(opt, '${srcdir}/selftest/in_screen') | 
|---|
| 141 | elif server_wrapper != '': | 
|---|
| 142 | server_wrapper = 'xterm -n server -l -e %s' % server_wrapper | 
|---|
| 143 |  | 
|---|
| 144 | if server_wrapper != '': | 
|---|
| 145 | os.environ['SAMBA_VALGRIND'] = EXPAND_VARIABLES(opt, server_wrapper) | 
|---|
| 146 |  | 
|---|
| 147 | # this is needed for systems without rpath, or with rpath disabled | 
|---|
| 148 | ADD_LD_LIBRARY_PATH('bin/shared') | 
|---|
| 149 | ADD_LD_LIBRARY_PATH('bin/shared/private') | 
|---|
| 150 |  | 
|---|
| 151 | # if we are using a system version of ldb then we need to tell it to | 
|---|
| 152 | # load modules from our modules path | 
|---|
| 153 | if env.USING_SYSTEM_LDB: | 
|---|
| 154 | os.environ['LDB_MODULES_PATH'] = 'bin/modules/ldb' | 
|---|
| 155 |  | 
|---|
| 156 | # tell build system where to find config.h | 
|---|
| 157 | config_paths = [ 'bin/default/source4/include/config.h', | 
|---|
| 158 | 'bin/default/include/config.h' ] | 
|---|
| 159 | for p in config_paths: | 
|---|
| 160 | if os.path.exists(p): | 
|---|
| 161 | os.environ['CONFIG_H'] = p | 
|---|
| 162 | break | 
|---|
| 163 |  | 
|---|
| 164 | st_done = os.path.join(env.SELFTEST_PREFIX, 'st_done') | 
|---|
| 165 | if os.path.exists(st_done): | 
|---|
| 166 | os.unlink(st_done) | 
|---|
| 167 |  | 
|---|
| 168 | if not os.path.isdir(env.SELFTEST_PREFIX): | 
|---|
| 169 | os.makedirs(env.SELFTEST_PREFIX, int('755', 8)) | 
|---|
| 170 |  | 
|---|
| 171 | # We use the full path rather than relative path because it cause problems on some plateforms (ie. solaris 8). | 
|---|
| 172 | cmd = '(${PERL} ${srcdir}/selftest/selftest.pl --prefix=${SELFTEST_PREFIX} --builddir=. --srcdir=${srcdir} --exclude=${srcdir}/source4/selftest/skip --testlist="${PYTHON} ${srcdir}/source4/selftest/tests.py|" ${OPTIONS} --socket-wrapper ${TESTS} && touch ${SELFTEST_PREFIX}/st_done) | ${FILTER_OPTIONS} | tee ${SELFTEST_PREFIX}/subunit' | 
|---|
| 173 | if os.environ.get('RUN_FROM_BUILD_FARM') is None and not Options.options.FILTERED_SUBUNIT: | 
|---|
| 174 | cmd += ' | ${FORMAT_TEST_OUTPUT}' | 
|---|
| 175 | else: | 
|---|
| 176 | cmd += ' | ${PYTHON} -u ${srcdir}/selftest/filter-subunit' | 
|---|
| 177 | cmd = EXPAND_VARIABLES(opt, cmd) | 
|---|
| 178 |  | 
|---|
| 179 | print("test: running %s" % cmd) | 
|---|
| 180 | ret = RUN_COMMAND(cmd, env=env) | 
|---|
| 181 | if os.path.exists(".testrepository"): | 
|---|
| 182 | # "testr load -q" isn't | 
|---|
| 183 | cmd = 'testr load -q < ${SELFTEST_PREFIX}/subunit > /dev/null' | 
|---|
| 184 | cmd = EXPAND_VARIABLES(opt, cmd) | 
|---|
| 185 | RUN_COMMAND(cmd, env=env) | 
|---|
| 186 |  | 
|---|
| 187 | if ret != 0: | 
|---|
| 188 | print("ERROR: test failed with exit code %d" % ret) | 
|---|
| 189 | sys.exit(ret) | 
|---|
| 190 |  | 
|---|
| 191 | if not os.path.exists(st_done): | 
|---|
| 192 | print("ERROR: test command failed to complete") | 
|---|
| 193 | sys.exit(1) | 
|---|
| 194 |  | 
|---|
| 195 |  | 
|---|
| 196 | ######################################################################## | 
|---|
| 197 | # main test entry point | 
|---|
| 198 | def cmd_test(opt): | 
|---|
| 199 | '''Run the test suite (see test options below)''' | 
|---|
| 200 | Scripting.commands.append('build') | 
|---|
| 201 | Scripting.commands.append('testonly') | 
|---|