| #!/bin/bash -ex |
| |
| # Test for APLOGNO() macro errors (duplicates, empty args) etc. For |
| # trunk, run the updater script to see if it fails. If it succeeds |
| # and changes any files (because there was a missing argument), the |
| # git diff will be non-empty, so fail for that case too. For |
| # non-trunk use a grep and only catch the empty argument case. |
| if test -v TEST_LOGNO; then |
| if test -f docs/log-message-tags/update-log-msg-tags; then |
| find server modules os -name \*.c | \ |
| xargs perl docs/log-message-tags/update-log-msg-tags |
| git diff --exit-code . |
| : PASSED |
| exit 0 |
| else |
| set -o pipefail |
| if find server modules os -name \*.c | \ |
| xargs grep -C1 --color=always 'APLOGNO()'; then |
| : FAILED |
| exit 1 |
| else |
| : PASSED |
| exit 0 |
| fi |
| fi |
| fi |
| |
| ### Installed apr/apr-util don't include the *.m4 files but the |
| ### Debian packages helpfully install them, so use the system APR to buildconf |
| ./buildconf --with-apr=/usr/bin/apr-1-config ${BUILDCONFIG} |
| |
| PREFIX=${PREFIX:-$HOME/build/httpd-root} |
| |
| # If perl-framework testing is required it is checked out here by |
| # _before_linux.sh: |
| if test -d test/perl-framework; then |
| CONFIG="$CONFIG --enable-load-all-modules" |
| if grep -q ^check: Makefile.in; then |
| CONFIG="--with-test-suite=test/perl-framework $CONFIG" |
| WITH_TEST_SUITE=1 |
| fi |
| |
| # Use the CPAN environment. |
| eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib) |
| fi |
| if test -v APR_VERSION; then |
| CONFIG="$CONFIG --with-apr=$HOME/root/apr-${APR_VERSION}" |
| else |
| CONFIG="$CONFIG --with-apr=/usr" |
| fi |
| if test -v APU_VERSION; then |
| CONFIG="$CONFIG --with-apr-util=$HOME/root/apr-util-${APU_VERSION}" |
| else |
| CONFIG="$CONFIG --with-apr-util=/usr" |
| fi |
| |
| # Pick up the rustls install built previously. |
| if test -v TEST_MOD_TLS -a RUSTLS_VERSION; then |
| CONFIG="$CONFIG --with-tls --with-rustls=$HOME/root/rustls" |
| fi |
| |
| if test -v TEST_OPENSSL3; then |
| CONFIG="$CONFIG --with-ssl=$HOME/root/openssl3" |
| # Temporarily set LD_RUN_PATH so that httpd/mod_ssl binaries pick |
| # up the custom OpenSSL build |
| export LD_RUN_PATH=$HOME/root/openssl3/lib:$HOME/root/openssl3/lib64 |
| export PATH=$HOME/root/openssl3/bin:$PATH |
| openssl version |
| fi |
| |
| srcdir=$PWD |
| |
| if test -v TEST_VPATH; then |
| mkdir ../vpath |
| cd ../vpath |
| fi |
| |
| builddir=$PWD |
| |
| $srcdir/configure --prefix=$PREFIX $CONFIG |
| make $MFLAGS |
| |
| if test -v TEST_OPENSSL3; then |
| # Clear the library/run paths so that anything else run during |
| # testing is not forced to use the custom OpenSSL build; e.g. perl, |
| # php-fpm, ... |
| unset LD_LIBRARY_PATH |
| unset LD_RUN_PATH |
| fi |
| |
| if test -v TEST_INSTALL; then |
| make install |
| pushd $PREFIX |
| # Basic sanity tests of the installed server. |
| ./bin/apachectl -V |
| test `./bin/apxs -q PREFIX` = $PREFIX |
| test `$PWD/bin/apxs -q PREFIX` = $PREFIX |
| ./bin/apxs -g -n foobar |
| cd foobar; make |
| popd |
| fi |
| |
| if test -v SKIP_TESTING; then |
| # Check that httpd was built successfully, nothing more. |
| ./httpd -V |
| exit 0 |
| fi |
| |
| ############################################################### |
| ### Everything below is only run if SKIP_TESTING was not set ## |
| ############################################################### |
| |
| : Running tests... |
| |
| set +e |
| RV=0 |
| |
| if test -v TEST_MALLOC; then |
| # Enable enhanced glibc malloc debugging, see mallopt(3) |
| export MALLOC_PERTURB_=65 MALLOC_CHECK_=3 |
| export LIBC_FATAL_STDERR_=1 |
| fi |
| |
| if test -v TEST_UBSAN; then |
| export UBSAN_OPTIONS="log_path=$PWD/ubsan.log" |
| fi |
| |
| if test -v TEST_ASAN; then |
| export ASAN_OPTIONS="log_path=$PWD/asan.log:detect_leaks=0" |
| fi |
| |
| if test -v PHP_FPM; then |
| # Sanity test the executable exists. |
| $PHP_FPM --version |
| fi |
| |
| # Try to keep all potential coredumps from all processes |
| sudo sysctl -w kernel.core_uses_pid=1 2>/dev/null || true |
| # Systemd based systems might process core dumps via systemd-coredump. |
| # But we want to have local unprocessed files. |
| sudo sysctl -w kernel.core_pattern=core || true |
| ulimit -c unlimited 2>/dev/null || true |
| |
| if ! test -v NO_TEST_FRAMEWORK; then |
| if test -v WITH_TEST_SUITE; then |
| make check TESTS="${TESTS}" TEST_CONFIG="${TEST_ARGS}" | tee test.log |
| RV=${PIPESTATUS[0]} |
| # re-run failing tests with -v, avoiding set -e |
| if [ $RV -ne 0 ]; then |
| # mv test/perl-framework/t/logs/error_log test/perl-framework/t/logs/error_log_save |
| FAILERS="" |
| while read FAILER; do |
| FAILERS="$FAILERS $FAILER" |
| done < <(awk '/Failed:/{print $1}' test.log) |
| if [ -n "$FAILERS" ]; then |
| make check TESTS="-v $FAILERS" || true |
| fi |
| # set -e would have killed us after the original t/TEST |
| rm -f test.log |
| # mv test/perl-framework/t/logs/error_log_save test/perl-framework/t/logs/error_log |
| false |
| fi |
| else |
| test -v TEST_INSTALL || make install |
| pushd test/perl-framework |
| perl Makefile.PL -apxs $PREFIX/bin/apxs |
| make test APACHE_TEST_EXTRA_ARGS="${TEST_ARGS} ${TESTS}" | tee test.log |
| RV=${PIPESTATUS[0]} |
| # re-run failing tests with -v, avoiding set -e |
| if [ $RV -ne 0 ]; then |
| # mv t/logs/error_log t/logs/error_log_save |
| FAILERS="" |
| while read FAILER; do |
| FAILERS="$FAILERS $FAILER" |
| done < <(awk '/Failed:/{print $1}' test.log) |
| if [ -n "$FAILERS" ]; then |
| t/TEST -v $FAILERS || true |
| fi |
| # set -e would have killed us after the original t/TEST |
| rm -f test.log |
| # mv t/logs/error_log_save t/logs/error_log |
| false |
| fi |
| popd |
| fi |
| |
| # Skip further testing if a core dump was created during the test |
| # suite run above. |
| if test $RV -eq 0 && test -n "`ls test/perl-framework/t/core{,.*} 2>/dev/null`"; then |
| RV=4 |
| fi |
| fi |
| |
| if test \( -v TEST_SSL -o -v TEST_OPENSSL3 \) \ |
| -a -f test/perl-framework/t/logs/error_log; then |
| : -- Check OpenSSL version used by mod_ssl at compile- and run-time -- |
| grep 'mod_ssl.*compiled against' test/perl-framework/t/logs/error_log | tail -n1 | grep --color=always 'OpenSSL/[^ ]*' |
| grep 'resuming normal operations' test/perl-framework/t/logs/error_log | tail -n1 | grep --color=always 'OpenSSL/[^ ]*' |
| fi |
| |
| if test -v TEST_SSL -a $RV -eq 0; then |
| pushd test/perl-framework |
| # Test loading encrypted private keys |
| ./t/TEST -defines "TEST_SSL_DES3_KEY TEST_SSL_PASSPHRASE_EXEC" t/ssl |
| RV=$? |
| |
| # Test various session cache backends |
| for cache in shmcb redis:localhost:6379 memcache:localhost:11211; do |
| test $RV -eq 0 || break |
| |
| SSL_SESSCACHE=$cache ./t/TEST -sslproto TLSv1.2 -defines TEST_SSL_SESSCACHE -start |
| ./t/TEST t/ssl |
| RV=$? |
| if test $RV -eq 0; then |
| # TODO: only really useful in e.g. triggering |
| # server segfaults which are caught later, doesn't |
| # directly catch non-200 responses etc. |
| $builddir/support/ab -qd -n 4000 -c 20 -f TLS1.2 https://localhost:8532/ |
| RV=$? |
| fi |
| ./t/TEST -stop |
| SRV=$? |
| if test $RV -eq 0 -a $SRV -ne 0; then |
| RV=$SRV |
| fi |
| done |
| popd |
| fi |
| |
| if test -v LITMUS -a $RV -eq 0; then |
| pushd test/perl-framework |
| mkdir -p t/htdocs/modules/dav |
| ./t/TEST -start |
| # litmus uses $TESTS, so unset it. |
| unset TESTS |
| litmus http://localhost:8529/modules/dav/ |
| RV=$? |
| ./t/TEST -stop |
| popd |
| fi |
| |
| if test -v TEST_CORE -a $RV -eq 0; then |
| # Run HTTP/2 tests. |
| MPM=event py.test-3 test/modules/core |
| RV=$? |
| fi |
| |
| if test -v TEST_PROXY -a $RV -eq 0; then |
| # Run proxy tests. |
| py.test-3 test/modules/proxy |
| RV=$? |
| fi |
| |
| if test -v TEST_H2 -a $RV -eq 0; then |
| # Build the test clients |
| (cd test/clients && make) |
| # Run HTTP/2 tests. |
| MPM=event py.test-3 test/modules/http2 |
| RV=$? |
| if test $RV -eq 0; then |
| MPM=worker py.test-3 test/modules/http2 |
| RV=$? |
| fi |
| fi |
| |
| if test -v TEST_MD -a $RV -eq 0; then |
| # Run ACME tests. |
| # need the go based pebble as ACME test server |
| # which is a package on debian sid, but not on focal |
| # FAILS on TRAVIS with |
| # package github.com/letsencrypt/pebble/cmd/pebble |
| # imports crypto/ed25519: unrecognized import path "crypto/ed25519" (import path does not begin with hostname) |
| # |
| # but works on a docker ubuntu-focal image. ??? |
| export GOPATH=${PREFIX}/gocode |
| mkdir -p "${GOPATH}" |
| export PATH="${GOROOT}/bin:${GOPATH}/bin:${PATH}" |
| go get -u github.com/letsencrypt/pebble/... |
| (cd $GOPATH/src/github.com/letsencrypt/pebble && go install ./...) |
| |
| py.test-3 test/modules/md |
| RV=$? |
| fi |
| |
| # Catch cases where abort()s get logged to stderr by libraries but |
| # only cause child processes to terminate e.g. during shutdown, |
| # which may not otherwise trigger test failures. |
| |
| # "glibc detected": printed with LIBC_FATAL_STDERR_/MALLOC_CHECK_ |
| # glibc will abort when malloc errors are detected. This will get |
| # caught by the segfault grep as well. |
| |
| # "pool concurrency check": printed by APR built with |
| # --enable-thread-debug when an APR pool concurrency check aborts |
| |
| for phrase in 'Segmentation fault' 'glibc detected' 'pool concurrency check:' 'Assertion.*failed'; do |
| # Ignore IO/debug logs |
| if grep -v ':\(debug\|trace[12345678]\)\]' test/perl-framework/t/logs/error_log | grep -q "$phrase"; then |
| grep --color=always -C5 "$phrase" test/perl-framework/t/logs/error_log |
| RV=2 |
| fi |
| done |
| |
| if test -v TEST_UBSAN && test -n "`ls ubsan.log.* 2>/dev/null`"; then |
| cat ubsan.log.* |
| RV=3 |
| fi |
| |
| if test -v TEST_ASAN && test -n "`ls asan.log.* 2>/dev/null`"; then |
| cat asan.log.* |
| |
| # ASan can report memory leaks, fail on errors only |
| if grep -q "ERROR: AddressSanitizer:" `ls asan.log.*`; then |
| RV=4 |
| fi |
| fi |
| |
| for core in `ls test/perl-framework/t/core{,.*} test/gen/apache/core{,.*} 2>/dev/null`; do |
| gdb -ex 'thread apply all backtrace full' -batch ./httpd "$core" |
| RV=5 |
| done |
| |
| exit $RV |