run.sh.in 9.14 KB
Newer Older
Andreas Gustafsson's avatar
Andreas Gustafsson committed
1
#!/bin/sh
Michael Sawyer's avatar
Michael Sawyer committed
2
#
3
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
Mark Andrews's avatar
Mark Andrews committed
4
#
5 6 7
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 9 10
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
Mark Andrews's avatar
Mark Andrews committed
11

Andreas Gustafsson's avatar
Andreas Gustafsson committed
12 13 14
#
# Run a system test.
#
15

16 17 18
top_builddir=@top_builddir@
builddir=@abs_builddir@
srcdir=@abs_srcdir@
Andreas Gustafsson's avatar
Andreas Gustafsson committed
19

20
# shellcheck source=conf.sh
21 22
. ${builddir}/conf.sh

23 24 25 26 27
if [ "$(id -u)" -eq "0" ] && [ "@DEVELOPER_MODE@" != "yes" ]; then
	echofail "Refusing to run test as root. Build with --enable-developer to override." >&2
	exit 1
fi

28 29 30 31
export builddir
export srcdir

date_with_args() (
32
    date "+%Y-%m-%dT%T%z"
33
)
34

35
stopservers=true
36 37
# baseport == 0 means random
baseport=0
38

39
if [ "${SYSTEMTEST_NO_CLEAN:-0}" -eq 1 ]; then
40 41 42 43 44
	clean=false
else
	clean=true
fi

45 46
do_run=false
log_flags="-r"
47
while getopts "sknp:r-:" OPT; do
48 49 50 51 52 53 54
	log_flags="$log_flags -$OPT$OPTARG"
	if [ "$OPT" = "-" ] && [ -n "$OPTARG" ]; then
		OPT="${OPTARG%%=*}"
		OPTARG="${OPTARG#$OPT}"
		OPTARG="${OPTARG#=}"
	fi

55
	# shellcheck disable=SC2214
56 57 58 59 60 61 62 63 64
	case "$OPT" in
		k | keep) stopservers=false ;;
		n | noclean) clean=false ;;
		p | port) baseport=$OPTARG ;;
		r | run) do_run=true ;;
		s | skip) exit 77 ;;
		-) break ;;
		*) echo "invalid option" >&2; exit 1 ;;
	esac
65
done
66

67
shift $((OPTIND-1))
68

69
if ! $do_run; then
70 71 72
    if [ "$baseport" -eq 0 ]; then
	log_flags="$log_flags -p 5300"
    fi
73
    env - PATH="$PATH" ${LD_LIBRARY_PATH:+"LD_LIBRARY_PATH=${LD_LIBRARY_PATH}"} TESTS="$*" TEST_SUITE_LOG=run.log LOG_DRIVER_FLAGS="--verbose yes --color-tests yes" LOG_FLAGS="$log_flags" make -e check
74
    exit $?
75 76
fi

77
if [ $# -eq 0 ]; then
78 79
	echofail "Usage: $0 [-k] [-n] [-p <PORT>] test-directory [test-options]" >&2;
	exit 1
80
fi
Andreas Gustafsson's avatar
Andreas Gustafsson committed
81

82
systest=$(basename "${1%%/}")
Andreas Gustafsson's avatar
Andreas Gustafsson committed
83 84
shift

85 86 87 88 89 90 91 92 93
if [ ! -d "${srcdir}/$systest" ]; then
    echofail "$0: $systest: no such test" >&2
    exit 1
fi

if [ "${srcdir}" != "${builddir}" ]; then
    if [ ! -d common ] || [ ! -r common/.prepared ]; then
	cp -a "${srcdir}/common" "${builddir}"
    fi
94 95 96 97 98 99
    # Some tests require additional files to work for out-of-tree test runs.
    for file in ckdnsrps.sh digcomp.pl ditch.pl packet.pl start.pl stop.pl; do
        if [ ! -r "${file}" ]; then
            cp -a "${srcdir}/${file}" "${builddir}"
        fi
    done
100 101 102 103 104 105 106 107
    if [ ! -d "$systest" ] || [ ! -r "$systest/.prepared" ]; then
	mkdir -p "${builddir}/$systest"
	cp -a "${srcdir}/$systest" "${builddir}/"
	touch "$systest/.prepared"
    fi
fi

if [ ! -d "${systest}" ]; then
108
    echofail "$0: $systest: no such test" >&2
109 110
    exit 1
fi
Andreas Gustafsson's avatar
Andreas Gustafsson committed
111

112

113
# Get the first 10 ports in the set (it is assumed that each test has access
114 115 116 117
# to ten or more ports): the query port, the control port and eight extra
# ports.  Since the lowest numbered port (specified in the command line)
# will usually be a multiple of 10, the names are chosen so that if this is
# true, the last digit of EXTRAPORTn is "n".
118
eval "$(${srcdir}/get_ports.sh -p "$baseport")"
119

Ondřej Surý's avatar
Ondřej Surý committed
120 121 122 123 124 125 126 127 128 129 130 131
restart=false

start_servers_failed() {
    echoinfo "I:$systest:starting servers failed"
    echofail "R:$systest:FAIL"
    echoend  "E:$systest:$(date_with_args)"
    exit 1
}

start_servers() {
    echoinfo "I:$systest:starting servers"
    if $restart; then
132
        $PERL start.pl --restart --port "$PORT" "$systest" || start_servers_failed
Ondřej Surý's avatar
Ondřej Surý committed
133 134
    else
        restart=true
135
        $PERL start.pl --port "$PORT" "$systest" || start_servers_failed
Ondřej Surý's avatar
Ondřej Surý committed
136 137 138 139 140 141
    fi
}

stop_servers() {
    if $stopservers; then
        echoinfo "I:$systest:stopping servers"
142 143 144 145
        if ! $PERL stop.pl "$systest"; then
            echoinfo "I:$systest:stopping servers failed"
            return 1
        fi
Ondřej Surý's avatar
Ondřej Surý committed
146 147 148
    fi
}

149
echostart "S:$systest:$(date_with_args)"
150 151
echoinfo  "T:$systest:1:A"
echoinfo  "A:$systest:System test $systest"
152
echoinfo  "I:$systest:PORTS:${PORT},${EXTRAPORT1},${EXTRAPORT2},${EXTRAPORT3},${EXTRAPORT4},${EXTRAPORT5},${EXTRAPORT6},${EXTRAPORT7},${EXTRAPORT8},${CONTROLPORT}"
153

154
$PERL ${srcdir}/testsock.pl -p "$PORT"  || {
155
    echowarn "I:$systest:Network interface aliases not set up.  Skipping test."
156 157 158
    echowarn "R:$systest:FAIL"
    echoend  "E:$systest:$(date_with_args)"
    exit 1;
159 160
}

Andreas Gustafsson's avatar
typo  
Andreas Gustafsson committed
161
# Check for test-specific prerequisites.
162
test ! -f "$systest/prereq.sh" || ( cd "${systest}" && $SHELL prereq.sh "$@" )
163 164 165
result=$?

if [ $result -eq 0 ]; then
166 167
    : prereqs ok
else
168
    echowarn "I:$systest:Prerequisites missing, skipping test."
169 170 171 172 173 174
    if [ $result -eq 255 ]; then
	echowarn "R:$systest:SKIPPED";
    else
	echowarn "R:$systest:UNTESTED"
    fi
    echoend "E:$systest:$(date_with_args)"
175 176 177
    exit 0
fi

178 179
# Check for PKCS#11 support
if
180
    test ! -f "$systest/usepkcs11" || $SHELL cleanpkcs11.sh
181 182 183
then
    : pkcs11 ok
else
184 185
    echowarn "I:$systest:Need PKCS#11, skipping test."
    echowarn "R:$systest:PKCS11ONLY"
186
    echoend  "E:$systest:$(date_with_args)"
187 188 189
    exit 0
fi

190
# Clean up files left from any potential previous runs
191
if test -f "$systest/clean.sh"
192
then
193 194
    if ! ( cd "${systest}" && $SHELL clean.sh "$@" ); then
	echowarn "I:$systest:clean.sh script failed"
195 196 197
	echofail "R:$systest:FAIL"
	echoend  "E:$systest:$(date_with_args)"
	exit 1
198 199
    fi

200 201
fi

Andreas Gustafsson's avatar
Andreas Gustafsson committed
202
# Set up any dynamically generated test data
203
if test -f "$systest/setup.sh"
Andreas Gustafsson's avatar
Andreas Gustafsson committed
204
then
205
    if ! ( cd "${systest}" && $SHELL setup.sh "$@" ); then
206 207 208 209
	echowarn "I:$systest:setup.sh script failed"
	echofail "R:$systest:FAIL"
	echoend  "E:$systest:$(date_with_args)"
	exit 1
210
    fi
Andreas Gustafsson's avatar
Andreas Gustafsson committed
211 212
fi

Ondřej Surý's avatar
Ondřej Surý committed
213 214
status=0
run=0
215
# Run the tests
Ondřej Surý's avatar
Ondřej Surý committed
216 217 218 219 220
if [ -r "$systest/tests.sh" ]; then
    start_servers
    ( cd "$systest" && $SHELL tests.sh "$@" )
    status=$?
    run=$((run+1))
221
    stop_servers || status=1
Ondřej Surý's avatar
Ondřej Surý committed
222 223 224 225 226 227 228 229 230 231 232 233 234 235
fi

if [ -n "$PYTEST" ]; then
    run=$((run+1))
    for test in $(cd "${systest}" && find . -name "tests*.py"); do
	start_servers
	rm -f "$systest/$test.status"
	test_status=0
	(cd "$systest" && "$PYTEST" -v "$test" "$@" || echo "$?" > "$test.status") | SYSTESTDIR="$systest" cat_d
	if [ -f "$systest/$test.status" ]; then
	    echo_i "FAILED"
	    test_status=$(cat "$systest/$test.status")
	fi
	status=$((status+test_status))
236
	stop_servers || status=1
Ondřej Surý's avatar
Ondřej Surý committed
237 238 239 240 241 242 243 244 245
    done
else
    echoinfo "I:$systest:pytest not installed, skipping python tests"
fi

if [ "$run" -eq "0" ]; then
    echoinfo "I:$systest:No tests were found and run"
    status=255
fi
246

247
if $stopservers
248
then
249 250
    :
else
251 252 253
    exit $status
fi

Michal Nowak's avatar
Michal Nowak committed
254 255 256 257
get_core_dumps() {
    find "$systest/" \( -name 'core*' -or -name '*.core' \) ! -name '*.gz' ! -name '*.txt' | sort
}

258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
core_dumps=$(get_core_dumps | tr '\n' ' ')
assertion_failures=$(find "$systest/" -name named.run -print0 | xargs -0 grep "assertion failure" | wc -l)
sanitizer_summaries=$(find "$systest/" -name 'tsan.*' | wc -l)
if [ -n "$core_dumps" ]; then
    status=1
    echoinfo "I:$systest:Core dump(s) found: $core_dumps"
    get_core_dumps | while read -r coredump; do
        export SYSTESTDIR="$systest"
        echoinfo "D:$systest:backtrace from $coredump:"
        echoinfo "D:$systest:--------------------------------------------------------------------------------"
        binary=$(gdb --batch --core="$coredump" 2>/dev/null | sed -ne "s/Core was generated by \`//;s/ .*'.$//p;")
        "${top_builddir}/libtool" --mode=execute gdb \
                                  -batch \
                                  -ex bt \
                                  -core="$coredump" \
                                  -- \
                                  "$binary" 2>/dev/null | sed -n '/^Core was generated by/,$p' | cat_d
        echoinfo "D:$systest:--------------------------------------------------------------------------------"
        coredump_backtrace=$(basename "${coredump}")-backtrace.txt
        echoinfo "D:$systest:full backtrace from $coredump saved in $coredump_backtrace"
        "${top_builddir}/libtool" --mode=execute gdb \
                                  -batch \
                                  -command=run.gdb \
                                  -core="$coredump" \
                                  -- \
                                  "$binary" > "$coredump_backtrace" 2>&1
        echoinfo "D:$systest:core dump $coredump archived as $coredump.gz"
        gzip -1 "${coredump}"
    done
elif [ "$assertion_failures" -ne 0 ]; then
    status=1
    SYSTESTDIR="$systest"
    echoinfo "I:$systest:$assertion_failures assertion failure(s) found"
    find "$systest/" -name 'tsan.*' -print0 | xargs -0 grep "SUMMARY: " | sort -u | cat_d
elif [ "$sanitizer_summaries" -ne 0 ]; then
    status=1
    echoinfo "I:$systest:$sanitizer_summaries sanitizer report(s) found"
fi

297 298 299 300 301 302 303 304 305
print_outstanding_files() {
    if test -d ${srcdir}/../../../.git; then
        git status -su --ignored "${systest}" 2>/dev/null | \
        sed -n -e 's|^?? \(.*\)|\1|p' \
            -e 's|^!! \(.*/named.run\)$|\1|p' \
            -e 's|^!! \(.*/named.memstats\)$|\1|p'
    fi
}

306
if [ $status -ne 0 ]; then
307
    echofail "R:$systest:FAIL"
308
else
309 310
    echopass "R:$systest:PASS"
    if $clean; then
311 312 313 314 315 316 317
        ( cd "${systest}" && $SHELL clean.sh "$@" )
        if [ "${srcdir}" = "${builddir}" ]; then
            print_outstanding_files
        else
            print_outstanding_files | xargs rm -rf
            find "./${systest}" \( -type d -empty -o -name Makefile.in \) -delete 2>/dev/null
        fi
318
    fi
319
fi
320

321
echoend "E:$systest:$(date_with_args)"
322

323
exit $status