mirror of
https://github.com/libyal/libexe
synced 2026-06-08 15:29:55 +00:00
1149 lines
33 KiB
Bash
1149 lines
33 KiB
Bash
#!/usr/bin/env bash
|
|
# Bash functions to run an executable for testing.
|
|
#
|
|
# Version: 20231119
|
|
#
|
|
# When CHECK_WITH_ASAN is set to a non-empty value the test executable
|
|
# is run with asan, otherwise it is run without.
|
|
#
|
|
# When CHECK_WITH_GDB is set to a non-empty value the test executable
|
|
# is run with gdb, otherwise it is run without.
|
|
#
|
|
# When CHECK_WITH_STDERR is set to a non-empty value the test executable
|
|
# is run with error output to stderr.
|
|
#
|
|
# When CHECK_WITH_VALGRIND is set to a non-empty value the test executable
|
|
# is run with valgrind, otherwise it is run without.
|
|
#
|
|
# PYTHON is used to determine the Python interpreter.
|
|
|
|
EXIT_SUCCESS=0;
|
|
EXIT_FAILURE=1;
|
|
EXIT_IGNORE=77;
|
|
|
|
# Checks the availability of a binary and exits if not available.
|
|
#
|
|
# Arguments:
|
|
# a string containing the name of the binary
|
|
#
|
|
assert_availability_binary()
|
|
{
|
|
local BINARY=$1;
|
|
|
|
which ${BINARY} > /dev/null 2>&1;
|
|
if test $? -ne ${EXIT_SUCCESS};
|
|
then
|
|
echo "Missing binary: ${BINARY}";
|
|
echo "";
|
|
|
|
exit ${EXIT_FAILURE};
|
|
fi
|
|
}
|
|
|
|
# Checks the availability of binaries and exits if not available.
|
|
#
|
|
# Globals:
|
|
# CHECK_WITH_GDB
|
|
# CHECK_WITH_VALGRIND
|
|
#
|
|
assert_availability_binaries()
|
|
{
|
|
assert_availability_binary cat;
|
|
assert_availability_binary cut;
|
|
assert_availability_binary diff;
|
|
assert_availability_binary file;
|
|
assert_availability_binary gzip;
|
|
assert_availability_binary ls;
|
|
assert_availability_binary readlink;
|
|
assert_availability_binary sed;
|
|
assert_availability_binary tr;
|
|
assert_availability_binary uname;
|
|
assert_availability_binary wc;
|
|
assert_availability_binary zcat;
|
|
|
|
if test -n "${CHECK_WITH_GDB}";
|
|
then
|
|
assert_availability_binary gdb;
|
|
|
|
elif test -n "${CHECK_WITH_VALGRIND}";
|
|
then
|
|
assert_availability_binary valgrind;
|
|
fi
|
|
}
|
|
|
|
# Checks if the test set is in the ignore list.
|
|
#
|
|
# Arguments:
|
|
# a string containing the test set
|
|
# a string containing space separated ignore list
|
|
#
|
|
# Returns:
|
|
# an integer containing the exit status to indicate the input directory
|
|
# was found in the ignore list.
|
|
#
|
|
check_for_test_set_in_ignore_list()
|
|
{
|
|
local TEST_SET=$1;
|
|
local IGNORE_LIST=$2;
|
|
|
|
local IFS=" ";
|
|
|
|
for LIST_ELEMENT in ${IGNORE_LIST};
|
|
do
|
|
if test "${LIST_ELEMENT}" = "${TEST_SET}";
|
|
then
|
|
return ${EXIT_SUCCESS};
|
|
fi
|
|
done
|
|
return ${EXIT_FAILURE};
|
|
}
|
|
|
|
# Checks if the input directory is in the ignore list.
|
|
#
|
|
# Arguments:
|
|
# a string containing the path of the test input directory
|
|
# a string containing space separated ignore list
|
|
#
|
|
# Returns:
|
|
# an integer containing the exit status to indicate the input directory
|
|
# was found in the ignore list.
|
|
#
|
|
check_for_directory_in_ignore_list()
|
|
{
|
|
local INPUT_DIRECTORY=$1;
|
|
local IGNORE_LIST=$2;
|
|
|
|
local INPUT_BASENAME=`basename ${INPUT_DIRECTORY}`;
|
|
|
|
local IFS=" ";
|
|
|
|
for LIST_ELEMENT in ${IGNORE_LIST};
|
|
do
|
|
if test "${LIST_ELEMENT}" = "${INPUT_BASENAME}";
|
|
then
|
|
return ${EXIT_SUCCESS};
|
|
fi
|
|
done
|
|
return ${EXIT_FAILURE};
|
|
}
|
|
|
|
# Searches for the binary variant of the executable in case the test executable
|
|
# refers to a libtool shell script.
|
|
#
|
|
# Arguments:
|
|
# a string containing the path of the test executable
|
|
#
|
|
# Returns:
|
|
# a string containing the path of the binary variant of the test executable
|
|
#
|
|
find_binary_executable()
|
|
{
|
|
local TEST_EXECUTABLE=$1;
|
|
|
|
TEST_EXECUTABLE=$( readlink_f "${TEST_EXECUTABLE}" );
|
|
|
|
# Note that the behavior of `file -bi` is not helpful on Mac OS X.
|
|
local EXECUTABLE_TYPE=`file -b ${TEST_EXECUTABLE}`;
|
|
|
|
# Check if the test executable is a libtool shell script.
|
|
# Linux: POSIX shell script, ASCII text executable, with very long lines
|
|
# Mac OS X: POSIX shell script text executable
|
|
echo "${EXECUTABLE_TYPE}" | grep "POSIX shell script" > /dev/null 2>&1;
|
|
RESULT=$?;
|
|
|
|
if test ${RESULT} -eq ${EXIT_SUCCESS};
|
|
then
|
|
local TEST_EXECUTABLE_BASENAME=`basename ${TEST_EXECUTABLE}`;
|
|
local TEST_EXECUTABLE_DIRNAME=`dirname ${TEST_EXECUTABLE}`;
|
|
|
|
TEST_EXECUTABLE="${TEST_EXECUTABLE_DIRNAME}/.libs/${TEST_EXECUTABLE_BASENAME}";
|
|
|
|
if test -x ${TEST_EXECUTABLE};
|
|
then
|
|
# Note that the behavior of `file -bi` is not helpful on Mac OS X.
|
|
EXECUTABLE_TYPE=`file -b ${TEST_EXECUTABLE}`;
|
|
|
|
# Linux: ELF 64-bit LSB executable, x86-64, ...
|
|
# Mac OS X: Mach-O 64-bit executable x86_64
|
|
echo "${EXECUTABLE_TYPE}" | grep "executable" > /dev/null 2>&1;
|
|
RESULT=$?;
|
|
|
|
if test ${RESULT} -ne ${EXIT_SUCCESS};
|
|
then
|
|
echo "Invalid test executable: ${TEST_EXECUTABLE}";
|
|
|
|
exit ${EXIT_FAILURE};
|
|
fi
|
|
fi
|
|
fi
|
|
echo ${TEST_EXECUTABLE};
|
|
}
|
|
|
|
# Searches for the path to the binary variant of the library.
|
|
#
|
|
# Arguments:
|
|
# a string containing the path of the test executable
|
|
#
|
|
# Returns:
|
|
# a string containing the path of the binary variant of the library.
|
|
#
|
|
find_binary_library_path()
|
|
{
|
|
local TEST_EXECUTABLE=$1;
|
|
local LIBRARY_NAME=`dirname ${TEST_EXECUTABLE}`;
|
|
|
|
local NAME=`basename ${LIBRARY_NAME}`;
|
|
|
|
if test ${NAME} = ".libs";
|
|
then
|
|
LIBRARY_NAME=`dirname ${LIBRARY_NAME}`;
|
|
NAME=`basename ${LIBRARY_NAME}`;
|
|
fi
|
|
if test ${NAME} = "tests";
|
|
then
|
|
LIBRARY_NAME=`dirname ${LIBRARY_NAME}`;
|
|
NAME=`basename ${LIBRARY_NAME}`;
|
|
fi
|
|
echo ${LIBRARY_NAME} | grep 'tools' > /dev/null 2>&1;
|
|
|
|
if test $? -eq ${EXIT_SUCCESS};
|
|
then
|
|
LIBRARY_NAME=`basename ${LIBRARY_NAME} | sed 's/\(.*\)tools$/lib\1/'`;
|
|
else
|
|
LIBRARY_NAME=`basename ${LIBRARY_NAME} | sed 's/^py//' | sed 's/^\([^_]*\)_test_.*$/lib\1/'`;
|
|
fi
|
|
TEST_EXECUTABLE=`dirname ${TEST_EXECUTABLE}`;
|
|
TEST_EXECUTABLE=`dirname ${TEST_EXECUTABLE}`;
|
|
TEST_EXECUTABLE=`dirname ${TEST_EXECUTABLE}`;
|
|
|
|
local LIBRARY_PATH="${TEST_EXECUTABLE}/${LIBRARY_NAME}/.libs";
|
|
|
|
if ! test -d "${LIBRARY_PATH}";
|
|
then
|
|
LIBRARY_PATH="../${LIBRARY_NAME}/.libs";
|
|
fi
|
|
echo "${LIBRARY_PATH}";
|
|
}
|
|
|
|
# Searches for the path to the binary variant of the Python module
|
|
#
|
|
# Arguments:
|
|
# a string containing the path of the test executable
|
|
#
|
|
# Returns:
|
|
# a string containing the path of the binary variant of the Python module
|
|
#
|
|
find_binary_python_module_path()
|
|
{
|
|
local TEST_EXECUTABLE=$1;
|
|
|
|
local PYTHON_MODULE_NAME=`basename ${TEST_EXECUTABLE} | sed 's/^py\(.*\)_test_.*$/py\1/'`;
|
|
|
|
TEST_EXECUTABLE=`dirname ${TEST_EXECUTABLE}`;
|
|
TEST_EXECUTABLE=`dirname ${TEST_EXECUTABLE}`;
|
|
TEST_EXECUTABLE=`dirname ${TEST_EXECUTABLE}`;
|
|
|
|
local PYTHON_MODULE_PATH="${TEST_EXECUTABLE}/${PYTHON_MODULE_NAME}/.libs";
|
|
|
|
if ! test -d "${PYTHON_MODULE_PATH}";
|
|
then
|
|
PYTHON_MODULE_PATH="../${PYTHON_MODULE_NAME}/.libs";
|
|
fi
|
|
echo "${PYTHON_MODULE_PATH}";
|
|
}
|
|
|
|
# Determines the test data option file.
|
|
#
|
|
# Arguments:
|
|
# a string containing the path of the test set directory
|
|
# a string containing the path of the test input file
|
|
# a string containing the name of the test data option set
|
|
#
|
|
# Returns:
|
|
# a string containing the test input files
|
|
#
|
|
get_test_data_option_file()
|
|
{
|
|
local TEST_SET_DIRECTORY=$1;
|
|
local INPUT_FILE=$2;
|
|
local OPTION_SET=$3;
|
|
|
|
local INPUT_NAME=`basename "${INPUT_FILE}"`;
|
|
local TEST_DATA_OPTION_FILE="${TEST_SET_DIRECTORY}/${INPUT_NAME}.${OPTION_SET}";
|
|
|
|
echo "${TEST_DATA_OPTION_FILE}";
|
|
}
|
|
|
|
# Determines the test profile directory.
|
|
# The directory is created if it does not exist.
|
|
#
|
|
# Arguments:
|
|
# a string containing the path of the test input directory
|
|
# a string containing the name of the test profile
|
|
#
|
|
# Returns:
|
|
# a string containing the path of the test profile directory
|
|
#
|
|
get_test_profile_directory()
|
|
{
|
|
local TEST_INPUT_DIRECTORY=$1;
|
|
local TEST_PROFILE=$2;
|
|
|
|
local TEST_PROFILE_DIRECTORY="${TEST_INPUT_DIRECTORY}/.${TEST_PROFILE}";
|
|
|
|
if ! test -d "${TEST_PROFILE_DIRECTORY}";
|
|
then
|
|
mkdir "${TEST_PROFILE_DIRECTORY}";
|
|
fi
|
|
echo "${TEST_PROFILE_DIRECTORY}";
|
|
}
|
|
|
|
# Determines the test set directory.
|
|
# The directory is created if it does not exist.
|
|
#
|
|
# Arguments:
|
|
# a string containing the path of the test profile directory
|
|
# a string containing the path of the test set input directory
|
|
#
|
|
# Returns:
|
|
# a string containing the path of the test set directory
|
|
#
|
|
get_test_set_directory()
|
|
{
|
|
local TEST_PROFILE_DIRECTORY=$1;
|
|
local TEST_SET_INPUT_DIRECTORY=$2;
|
|
|
|
local TEST_SET=`basename ${TEST_SET_INPUT_DIRECTORY}`;
|
|
local TEST_SET_DIRECTORY="${TEST_PROFILE_DIRECTORY}/${TEST_SET}";
|
|
|
|
if ! test -d "${TEST_SET_DIRECTORY}";
|
|
then
|
|
mkdir "${TEST_SET_DIRECTORY}";
|
|
fi
|
|
echo "${TEST_SET_DIRECTORY}";
|
|
}
|
|
|
|
# Provides a cross-platform variant of "readlink -f"
|
|
#
|
|
# Arguments:
|
|
# a string containing a path
|
|
#
|
|
# Returns:
|
|
# a string containing the path with all symbolic links resolved
|
|
#
|
|
readlink_f() {
|
|
local TARGET="$1"
|
|
|
|
if test -f "${TARGET}";
|
|
then
|
|
while test -L "${TARGET}";
|
|
do
|
|
TARGET=`readlink "${TARGET}"`;
|
|
done
|
|
fi
|
|
local BASENAME=`basename "${TARGET}"`;
|
|
local DIRNAME=`dirname "${TARGET}"`;
|
|
|
|
DIRNAME=`(cd "${DIRNAME}" && pwd -P)`;
|
|
|
|
echo "${DIRNAME}/${BASENAME}";
|
|
}
|
|
|
|
# Reads the test profile ignore file if it exists.
|
|
#
|
|
# Arguments:
|
|
# a string containing the path of the test profile directory
|
|
#
|
|
# Returns:
|
|
# a string containing a space separated ignore list
|
|
#
|
|
read_ignore_list()
|
|
{
|
|
local TEST_PROFILE_DIRECTORY=$1;
|
|
local IGNORE_FILE="${TEST_PROFILE_DIRECTORY}/ignore";
|
|
local IGNORE_LIST="";
|
|
|
|
if test -f "${IGNORE_FILE}";
|
|
then
|
|
IGNORE_LIST=`cat ${IGNORE_FILE} | sed '/^#/d' | tr '\n' ' '`;
|
|
fi
|
|
echo ${IGNORE_LIST};
|
|
}
|
|
|
|
# Reads a test data option file.
|
|
#
|
|
# Arguments:
|
|
# a string containing the path of the test set directory
|
|
# a string containing the path of the test input file
|
|
# a string containing the name of the test data option set
|
|
#
|
|
# Returns:
|
|
# a string containing the test data specific options
|
|
#
|
|
read_test_data_option_file()
|
|
{
|
|
local TEST_SET_DIRECTORY=$1;
|
|
local INPUT_FILE=$2;
|
|
local OPTION_SET=$3;
|
|
|
|
local TEST_DATA_OPTION_FILE="${INPUT_FILE}.${OPTION_SET}";
|
|
|
|
if ! test -f "${TEST_DATA_OPTION_FILE}";
|
|
then
|
|
TEST_DATA_OPTION_FILE=$(get_test_data_option_file "${TEST_SET_DIRECTORY}" "${INPUT_FILE}" "${OPTION_SET}");
|
|
fi
|
|
|
|
local OPTIONS_STRING=`head -n 1 "${TEST_DATA_OPTION_FILE}" | sed 's/[\r\n]*$//'`;
|
|
|
|
if test "${OPTIONS_STRING}" = "# libyal test data options";
|
|
then
|
|
OPTIONS_STRING=`tail -n +2 "${TEST_DATA_OPTION_FILE}" | sed 's/^offset=/-o/;s/^password=/-p/;s/^recovery_password=/-r/;s/^startup_key=/-s/;s/virtual_address=/-v/' | tr '\n' ' '`;
|
|
fi
|
|
echo "${OPTIONS_STRING}";
|
|
}
|
|
|
|
# Runs the test with optional arguments.
|
|
#
|
|
# Globals:
|
|
# CHECK_WITH_ASAN
|
|
# CHECK_WITH_GDB
|
|
# CHECK_WITH_STDERR
|
|
# CHECK_WITH_VALGRIND
|
|
#
|
|
# Arguments:
|
|
# a string containing the test description
|
|
# a string containing the path of the test executable
|
|
# an array containing the arguments for the test executable
|
|
#
|
|
# Returns:
|
|
# an integer containg the exit status of the test executable
|
|
#
|
|
run_test_with_arguments()
|
|
{
|
|
local TEST_DESCRIPTION=$1;
|
|
local TEST_EXECUTABLE=$2;
|
|
shift 2;
|
|
local ARGUMENTS=("$@");
|
|
|
|
if ! test -f "${TEST_EXECUTABLE}";
|
|
then
|
|
echo "Missing test executable: ${TEST_EXECUTABLE}";
|
|
echo "";
|
|
|
|
return ${EXIT_FAILURE};
|
|
fi
|
|
local PLATFORM=`uname -s | sed 's/-.*$//'`;
|
|
|
|
# Note that the behavior of `file -bi` is not helpful on Mac OS X.
|
|
local EXECUTABLE_TYPE=`file -b ${TEST_EXECUTABLE}`;
|
|
|
|
# Check if the test executable is a Python script.
|
|
# Linux: Python script, ASCII text executable
|
|
# Mac OS X: a python script text executable
|
|
echo "${EXECUTABLE_TYPE}" | grep -i "python script" > /dev/null 2>&1;
|
|
local IS_PYTHON_SCRIPT=$?;
|
|
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0 && test -z ${PYTHON};
|
|
then
|
|
local PYTHON=`which python 2> /dev/null`;
|
|
|
|
if ! test -x ${PYTHON};
|
|
then
|
|
echo "Missing executable: ${PYTHON}";
|
|
|
|
exit ${EXIT_FAILURE};
|
|
fi
|
|
fi
|
|
local RESULT=0;
|
|
|
|
if test -n "${CHECK_WITH_ASAN}";
|
|
then
|
|
local TEST_EXECUTABLE=$( find_binary_executable ${TEST_EXECUTABLE} );
|
|
local LIBRARY_PATH=$( find_binary_library_path ${TEST_EXECUTABLE} );
|
|
local PYTHON_MODULE_PATH=$( find_binary_python_module_path ${TEST_EXECUTABLE} );
|
|
|
|
local LSAN_SUPPRESSIONS="lsan.suppressions";
|
|
|
|
if ! test -f ${LSAN_SUPPRESSIONS};
|
|
then
|
|
LSAN_SUPPRESSIONS="../lsan.suppressions";
|
|
fi
|
|
if test "${PLATFORM}" = "Darwin";
|
|
then
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
LSAN_OPTIONS=suppressions="${LSAN_SUPPRESSIONS}" DYLD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
else
|
|
LSAN_OPTIONS=suppressions="${LSAN_SUPPRESSIONS}" DYLD_LIBRARY_PATH="${LIBRARY_PATH}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
fi
|
|
else
|
|
local CONFIG_LOG="../config.log";
|
|
|
|
if ! test -f ${CONFIG_LOG};
|
|
then
|
|
CONFIG_LOG="../../config.log";
|
|
fi
|
|
local CC=`cat ${CONFIG_LOG} | grep -e "^CC=" | sed "s/CC='\\(.*\\)'/\1/"`;
|
|
local LIBASAN="";
|
|
|
|
if test -z ${CC} || test ${CC} != "clang";
|
|
then
|
|
local LDCONFIG=`which ldconfig 2> /dev/null`;
|
|
|
|
if test -z ${LDCONFIG} || ! test -x ${LDCONFIG};
|
|
then
|
|
LDCONFIG="/sbin/ldconfig";
|
|
fi
|
|
if test -z ${LDCONFIG} || ! test -x ${LDCONFIG};
|
|
then
|
|
echo "Missing binary: ldconfig";
|
|
echo "";
|
|
|
|
exit ${EXIT_FAILURE};
|
|
fi
|
|
LIBASAN=`${LDCONFIG} -p | grep libasan | sed 's/^.* => //' | sort | tail -n 1`;
|
|
|
|
if ! test -f ${LIBASAN};
|
|
then
|
|
echo "Missing library: ${BINARY}";
|
|
echo "";
|
|
|
|
exit ${EXIT_FAILURE};
|
|
fi
|
|
fi
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
LSAN_OPTIONS=suppressions="${LSAN_SUPPRESSIONS}" LD_PRELOAD="${LIBASAN}" LD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
else
|
|
LSAN_OPTIONS=suppressions="${LSAN_SUPPRESSIONS}" LD_PRELOAD="${LIBASAN}" LD_LIBRARY_PATH="${LIBRARY_PATH}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
fi
|
|
fi
|
|
|
|
elif test -n "${CHECK_WITH_GDB}";
|
|
then
|
|
local TEST_EXECUTABLE=$( find_binary_executable ${TEST_EXECUTABLE} );
|
|
local LIBRARY_PATH=$( find_binary_library_path ${TEST_EXECUTABLE} );
|
|
local PYTHON_MODULE_PATH=$( find_binary_python_module_path ${TEST_EXECUTABLE} );
|
|
|
|
if test "${PLATFORM}" = "Darwin";
|
|
then
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
DYLD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" gdb -ex "set non-stop on" -ex "run" -ex "quit" --args "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
else
|
|
DYLD_LIBRARY_PATH="${LIBRARY_PATH}" gdb -ex "set non-stop on" -ex "run" -ex "quit" --args "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
fi
|
|
|
|
elif test "${PLATFORM}" = "CYGWIN_NT";
|
|
then
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
PATH="${LIBRARY_PATH}:${PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" gdb -ex "set non-stop on" -ex "run" -ex "quit" --args "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
else
|
|
PATH="${LIBRARY_PATH}:${PATH}" gdb -ex "set non-stop on" -ex "run" -ex "quit" --args "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
fi
|
|
|
|
else
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
LD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" gdb -ex "set non-stop on" -ex "run" -ex "quit" --args "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
else
|
|
LD_LIBRARY_PATH="${LIBRARY_PATH}" gdb -ex "set non-stop on" -ex "run" -ex "quit" --args "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
fi
|
|
fi
|
|
|
|
elif test -n "${CHECK_WITH_VALGRIND}";
|
|
then
|
|
local TEST_EXECUTABLE=$( find_binary_executable ${TEST_EXECUTABLE} );
|
|
local LIBRARY_PATH=$( find_binary_library_path ${TEST_EXECUTABLE} );
|
|
local PYTHON_MODULE_PATH=$( find_binary_python_module_path ${TEST_EXECUTABLE} );
|
|
|
|
local VALGRIND_LOG="valgrind.log-$$";
|
|
local VALGRIND_OPTIONS=("--tool=memcheck" "--leak-check=full" "--show-leak-kinds=definite,indirect,possible" "--track-origins=yes" "--log-file=${VALGRIND_LOG}");
|
|
|
|
if test "${PLATFORM}" = "Darwin";
|
|
then
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
DYLD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" valgrind ${VALGRIND_OPTIONS[@]} "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
else
|
|
DYLD_LIBRARY_PATH="${LIBRARY_PATH}" valgrind ${VALGRIND_OPTIONS[@]} "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
fi
|
|
|
|
elif test "${PLATFORM}" = "CYGWIN_NT";
|
|
then
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
PATH="${LIBRARY_PATH}:${PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" valgrind ${VALGRIND_OPTIONS[@]} "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
else
|
|
PATH="${LIBRARY_PATH}:${PATH}" valgrind ${VALGRIND_OPTIONS[@]} "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
fi
|
|
|
|
else
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
LD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" valgrind ${VALGRIND_OPTIONS[@]} "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
else
|
|
LD_LIBRARY_PATH="${LIBRARY_PATH}" valgrind ${VALGRIND_OPTIONS[@]} "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
fi
|
|
fi
|
|
if test ${RESULT} -eq ${EXIT_SUCCESS};
|
|
then
|
|
grep "All heap blocks were freed -- no leaks are possible" ${VALGRIND_LOG} > /dev/null 2>&1;
|
|
|
|
if test $? -ne ${EXIT_SUCCESS};
|
|
then
|
|
# Ignore "still reachable"
|
|
# Also see: http://valgrind.org/docs/manual/faq.html#faq.deflost
|
|
|
|
grep "definitely lost: 0 bytes in 0 blocks" ${VALGRIND_LOG} > /dev/null 2>&1;
|
|
RESULT_DIRECTLY_LOST=$?;
|
|
|
|
grep "indirectly lost: 0 bytes in 0 blocks" ${VALGRIND_LOG} > /dev/null 2>&1;
|
|
RESULT_INDIRECTLY_LOST=$?;
|
|
|
|
grep "possibly lost: 0 bytes in 0 blocks" ${VALGRIND_LOG} > /dev/null 2>&1;
|
|
RESULT_POSSIBLY_LOST=$?;
|
|
|
|
grep "suppressed: 0 bytes in 0 blocks" ${VALGRIND_LOG} > /dev/null 2>&1;
|
|
RESULT_SUPPRESSED=$?;
|
|
|
|
if test ${RESULT_DIRECTLY_LOST} -ne ${EXIT_SUCCESS} || test ${RESULT_INDIRECTLY_LOST} -ne ${EXIT_SUCCESS} || test ${RESULT_POSSIBLY_LOST} -ne ${EXIT_SUCCESS} || test ${RESULT_SUPPRESSED} -ne ${EXIT_SUCCESS};
|
|
then
|
|
echo "Memory leakage detected.";
|
|
cat ${VALGRIND_LOG};
|
|
|
|
RESULT=${EXIT_FAILURE};
|
|
fi
|
|
fi
|
|
# Detect valgrind warnings.
|
|
local NUMBER_OF_LINES=`wc -l ${VALGRIND_LOG} | awk '{ print $1 }'`;
|
|
|
|
if test ${NUMBER_OF_LINES} -ne 15 && test ${NUMBER_OF_LINES} -ne 22;
|
|
then
|
|
echo "Unsupported number of lines: ${NUMBER_OF_LINES}";
|
|
cat ${VALGRIND_LOG};
|
|
|
|
RESULT=${EXIT_FAILURE};
|
|
fi
|
|
fi
|
|
rm -f ${VALGRIND_LOG};
|
|
|
|
elif test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
if ! test -f "${TEST_EXECUTABLE}";
|
|
then
|
|
echo "Invalid test Python script: ${TEST_EXECUTABLE}";
|
|
echo "";
|
|
|
|
return ${EXIT_FAILURE};
|
|
fi
|
|
local TEST_EXECUTABLE=$( find_binary_executable ${TEST_EXECUTABLE} );
|
|
local LIBRARY_PATH=$( find_binary_library_path ${TEST_EXECUTABLE} );
|
|
local PYTHON_MODULE_PATH=$( find_binary_python_module_path ${TEST_EXECUTABLE} );
|
|
|
|
if test "${PLATFORM}" = "Darwin";
|
|
then
|
|
if test -n "${CHECK_WITH_STDERR}";
|
|
then
|
|
DYLD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
else
|
|
DYLD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} 2> /dev/null;
|
|
RESULT=$?;
|
|
fi
|
|
|
|
elif test "${PLATFORM}" = "CYGWIN_NT";
|
|
then
|
|
if test -n "${CHECK_WITH_STDERR}";
|
|
then
|
|
PATH="${LIBRARY_PATH}:${PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
else
|
|
PATH="${LIBRARY_PATH}:${PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} 2> /dev/null;
|
|
RESULT=$?;
|
|
fi
|
|
|
|
else
|
|
if test -n "${CHECK_WITH_STDERR}";
|
|
then
|
|
LD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
else
|
|
LD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} 2> /dev/null;
|
|
RESULT=$?;
|
|
fi
|
|
fi
|
|
else
|
|
if ! test -x "${TEST_EXECUTABLE}";
|
|
then
|
|
echo "Invalid test executable: ${TEST_EXECUTABLE}";
|
|
echo "";
|
|
|
|
return ${EXIT_FAILURE};
|
|
fi
|
|
|
|
if test -n "${CHECK_WITH_STDERR}";
|
|
then
|
|
${TEST_EXECUTABLE} ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
else
|
|
${TEST_EXECUTABLE} ${ARGUMENTS[@]} 2> /dev/null;
|
|
RESULT=$?;
|
|
fi
|
|
fi
|
|
if test -n "${TEST_DESCRIPTION}";
|
|
then
|
|
echo -n "${TEST_DESCRIPTION}";
|
|
|
|
if test ${RESULT} -ne ${EXIT_SUCCESS};
|
|
then
|
|
echo " (FAIL)";
|
|
else
|
|
echo " (PASS)";
|
|
fi
|
|
fi
|
|
return ${RESULT};
|
|
}
|
|
|
|
# Runs the test with an input file and optional arguments.
|
|
#
|
|
# Globals:
|
|
# CHECK_WITH_ASAN
|
|
# CHECK_WITH_GDB
|
|
# CHECK_WITH_STDERR
|
|
# CHECK_WITH_VALGRIND
|
|
#
|
|
# Arguments:
|
|
# a string containing the path of the test executable
|
|
# a string containing the path of the test input file
|
|
# an array containing the arguments for the test executable
|
|
#
|
|
# Returns:
|
|
# an integer containg the exit status of the test executable
|
|
#
|
|
run_test_with_input_and_arguments()
|
|
{
|
|
local TEST_EXECUTABLE=$1;
|
|
local INPUT_FILE=$2;
|
|
shift 2;
|
|
local ARGUMENTS=("$@");
|
|
|
|
if ! test -f "${TEST_EXECUTABLE}";
|
|
then
|
|
echo "Missing test executable: ${TEST_EXECUTABLE}";
|
|
echo "";
|
|
|
|
return ${EXIT_FAILURE};
|
|
fi
|
|
local PLATFORM=`uname -s | sed 's/-.*$//'`;
|
|
|
|
# Note that the behavior of `file -bi` is not helpful on Mac OS X.
|
|
local EXECUTABLE_TYPE=`file -b ${TEST_EXECUTABLE}`;
|
|
|
|
# Check if the test executable is a Python script.
|
|
# Linux: Python script, ASCII text executable
|
|
# Mac OS X: a python script text executable
|
|
echo "${EXECUTABLE_TYPE}" | grep -i "python script" > /dev/null 2>&1;
|
|
local IS_PYTHON_SCRIPT=$?;
|
|
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0 && test -z ${PYTHON};
|
|
then
|
|
local PYTHON=`which python 2> /dev/null`;
|
|
|
|
if ! test -x ${PYTHON};
|
|
then
|
|
echo "Missing executable: ${PYTHON}";
|
|
|
|
exit ${EXIT_FAILURE};
|
|
fi
|
|
fi
|
|
local RESULT=0;
|
|
|
|
if test -n "${CHECK_WITH_ASAN}";
|
|
then
|
|
local TEST_EXECUTABLE=$( find_binary_executable ${TEST_EXECUTABLE} );
|
|
local LIBRARY_PATH=$( find_binary_library_path ${TEST_EXECUTABLE} );
|
|
local PYTHON_MODULE_PATH=$( find_binary_python_module_path ${TEST_EXECUTABLE} );
|
|
|
|
local LSAN_SUPPRESSIONS="lsan.suppressions";
|
|
|
|
if ! test -f ${LSAN_SUPPRESSIONS};
|
|
then
|
|
LSAN_SUPPRESSIONS="../lsan.suppressions";
|
|
fi
|
|
if test "${PLATFORM}" = "Darwin";
|
|
then
|
|
# TODO DYLD_INSERT_LIBRARIES=/Library/Developer/CommandLineTools/usr/lib/clang/8.1.0/lib/darwin/libclang_rt.asan_osx_dynamic.dylib
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
LSAN_OPTIONS=suppressions="${LSAN_SUPPRESSIONS}" DYLD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
else
|
|
LSAN_OPTIONS=suppressions="${LSAN_SUPPRESSIONS}" DYLD_LIBRARY_PATH="${LIBRARY_PATH}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
fi
|
|
else
|
|
local CONFIG_LOG="../config.log";
|
|
|
|
if ! test -f ${CONFIG_LOG};
|
|
then
|
|
CONFIG_LOG="../../config.log";
|
|
fi
|
|
local CC=`cat ${CONFIG_LOG} | grep -e "^CC=" | sed "s/CC='\\(.*\\)'/\1/"`;
|
|
local LIBASAN="";
|
|
|
|
if test -z ${CC} || test ${CC} != "clang";
|
|
then
|
|
local LDCONFIG=`which ldconfig 2> /dev/null`;
|
|
|
|
if test -z ${LDCONFIG} || ! test -x ${LDCONFIG};
|
|
then
|
|
LDCONFIG="/sbin/ldconfig";
|
|
fi
|
|
if test -z ${LDCONFIG} || ! test -x ${LDCONFIG};
|
|
then
|
|
echo "Missing binary: ldconfig";
|
|
echo "";
|
|
|
|
exit ${EXIT_FAILURE};
|
|
fi
|
|
LIBASAN=`${LDCONFIG} -p | grep libasan | sed 's/^.* => //' | sort | tail -n 1`;
|
|
|
|
if ! test -f ${LIBASAN};
|
|
then
|
|
echo "Missing library: ${BINARY}";
|
|
echo "";
|
|
|
|
exit ${EXIT_FAILURE};
|
|
fi
|
|
fi
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
LSAN_OPTIONS=suppressions="${LSAN_SUPPRESSIONS}" LD_PRELOAD="${LIBASAN}" LD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
else
|
|
LSAN_OPTIONS=suppressions="${LSAN_SUPPRESSIONS}" LD_PRELOAD="${LIBASAN}" LD_LIBRARY_PATH="${LIBRARY_PATH}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
fi
|
|
fi
|
|
|
|
elif test -n "${CHECK_WITH_GDB}";
|
|
then
|
|
local TEST_EXECUTABLE=$( find_binary_executable ${TEST_EXECUTABLE} );
|
|
local LIBRARY_PATH=$( find_binary_library_path ${TEST_EXECUTABLE} );
|
|
local PYTHON_MODULE_PATH=$( find_binary_python_module_path ${TEST_EXECUTABLE} );
|
|
|
|
if test "${PLATFORM}" = "Darwin";
|
|
then
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
DYLD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" gdb -ex "set non-stop on" -ex "run" -ex "quit" --args "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
else
|
|
DYLD_LIBRARY_PATH="${LIBRARY_PATH}" gdb -ex "set non-stop on" -ex "run" -ex "quit" --args "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
fi
|
|
|
|
elif test "${PLATFORM}" = "CYGWIN_NT";
|
|
then
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
PATH="${LIBRARY_PATH}:${PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" gdb -ex "set non-stop on" -ex "run" -ex "quit" --args "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
else
|
|
PATH="${LIBRARY_PATH}:${PATH}" gdb -ex "set non-stop on" -ex "run" -ex "quit" --args "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
fi
|
|
|
|
else
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
LD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" gdb -ex "set non-stop on" -ex "run" -ex "quit" --args "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
else
|
|
LD_LIBRARY_PATH="${LIBRARY_PATH}" gdb -ex "set non-stop on" -ex "run" -ex "quit" --args "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
fi
|
|
fi
|
|
|
|
elif test -n "${CHECK_WITH_VALGRIND}";
|
|
then
|
|
local TEST_EXECUTABLE=$( find_binary_executable ${TEST_EXECUTABLE} );
|
|
local LIBRARY_PATH=$( find_binary_library_path ${TEST_EXECUTABLE} );
|
|
local PYTHON_MODULE_PATH=$( find_binary_python_module_path ${TEST_EXECUTABLE} );
|
|
|
|
local VALGRIND_LOG="valgrind.log-$$";
|
|
local VALGRIND_OPTIONS=("--tool=memcheck" "--leak-check=full" "--show-leak-kinds=definite,indirect,possible" "--track-origins=yes" "--log-file=${VALGRIND_LOG}");
|
|
|
|
if test "${PLATFORM}" = "Darwin";
|
|
then
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
DYLD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" valgrind ${VALGRIND_OPTIONS[@]} "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
else
|
|
DYLD_LIBRARY_PATH="${LIBRARY_PATH}" valgrind ${VALGRIND_OPTIONS[@]} "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
fi
|
|
|
|
elif test "${PLATFORM}" = "CYGWIN_NT";
|
|
then
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
PATH="${LIBRARY_PATH}:${PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" valgrind ${VALGRIND_OPTIONS[@]} "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
else
|
|
PATH="${LIBRARY_PATH}:${PATH}" valgrind ${VALGRIND_OPTIONS[@]} "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
fi
|
|
|
|
else
|
|
if test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
LD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" valgrind ${VALGRIND_OPTIONS[@]} "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
else
|
|
LD_LIBRARY_PATH="${LIBRARY_PATH}" valgrind ${VALGRIND_OPTIONS[@]} "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
fi
|
|
fi
|
|
if test ${RESULT} -eq ${EXIT_SUCCESS};
|
|
then
|
|
grep "All heap blocks were freed -- no leaks are possible" ${VALGRIND_LOG} > /dev/null 2>&1;
|
|
|
|
if test $? -ne ${EXIT_SUCCESS};
|
|
then
|
|
# Ignore "still reachable"
|
|
# Also see: http://valgrind.org/docs/manual/faq.html#faq.deflost
|
|
|
|
grep "definitely lost: 0 bytes in 0 blocks" ${VALGRIND_LOG} > /dev/null 2>&1;
|
|
RESULT_DIRECTLY_LOST=$?;
|
|
|
|
grep "indirectly lost: 0 bytes in 0 blocks" ${VALGRIND_LOG} > /dev/null 2>&1;
|
|
RESULT_INDIRECTLY_LOST=$?;
|
|
|
|
grep "possibly lost: 0 bytes in 0 blocks" ${VALGRIND_LOG} > /dev/null 2>&1;
|
|
RESULT_POSSIBLY_LOST=$?;
|
|
|
|
grep "suppressed: 0 bytes in 0 blocks" ${VALGRIND_LOG} > /dev/null 2>&1;
|
|
RESULT_SUPPRESSED=$?;
|
|
|
|
if test ${RESULT_DIRECTLY_LOST} -ne ${EXIT_SUCCESS} || test ${RESULT_INDIRECTLY_LOST} -ne ${EXIT_SUCCESS} || test ${RESULT_POSSIBLY_LOST} -ne ${EXIT_SUCCESS} || test ${RESULT_SUPPRESSED} -ne ${EXIT_SUCCESS};
|
|
then
|
|
echo "Memory leakage detected.";
|
|
cat ${VALGRIND_LOG};
|
|
|
|
RESULT=${EXIT_FAILURE};
|
|
fi
|
|
fi
|
|
# Detect valgrind warnings.
|
|
local NUMBER_OF_LINES=`wc -l ${VALGRIND_LOG} | awk '{ print $1 }'`;
|
|
|
|
if test ${NUMBER_OF_LINES} -ne 15 && test ${NUMBER_OF_LINES} -ne 22;
|
|
then
|
|
echo "Unsupported number of lines: ${NUMBER_OF_LINES}";
|
|
cat ${VALGRIND_LOG};
|
|
|
|
RESULT=${EXIT_FAILURE};
|
|
fi
|
|
fi
|
|
rm -f ${VALGRIND_LOG};
|
|
|
|
elif test ${IS_PYTHON_SCRIPT} -eq 0;
|
|
then
|
|
if ! test -f "${TEST_EXECUTABLE}";
|
|
then
|
|
echo "Invalid test Python script: ${TEST_EXECUTABLE}";
|
|
echo "";
|
|
|
|
return ${EXIT_FAILURE};
|
|
fi
|
|
local TEST_EXECUTABLE=$( find_binary_executable ${TEST_EXECUTABLE} );
|
|
local LIBRARY_PATH=$( find_binary_library_path ${TEST_EXECUTABLE} );
|
|
local PYTHON_MODULE_PATH=$( find_binary_python_module_path ${TEST_EXECUTABLE} );
|
|
|
|
if test "${PLATFORM}" = "Darwin";
|
|
then
|
|
if test -n "${CHECK_WITH_STDERR}";
|
|
then
|
|
DYLD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
else
|
|
DYLD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}" 2> /dev/null;
|
|
RESULT=$?;
|
|
fi
|
|
|
|
elif test "${PLATFORM}" = "CYGWIN_NT";
|
|
then
|
|
if test -n "${CHECK_WITH_STDERR}";
|
|
then
|
|
PATH="${LIBRARY_PATH}:${PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
else
|
|
PATH="${LIBRARY_PATH}:${PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}" 2> /dev/null;
|
|
RESULT=$?;
|
|
fi
|
|
|
|
else
|
|
if test -n "${CHECK_WITH_STDERR}";
|
|
then
|
|
LD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
else
|
|
LD_LIBRARY_PATH="${LIBRARY_PATH}" PYTHONPATH="${PYTHON_MODULE_PATH}" "${PYTHON}" "${TEST_EXECUTABLE}" ${ARGUMENTS[@]} "${INPUT_FILE}" 2> /dev/null;
|
|
RESULT=$?;
|
|
fi
|
|
fi
|
|
else
|
|
if ! test -x "${TEST_EXECUTABLE}";
|
|
then
|
|
echo "Invalid test executable: ${TEST_EXECUTABLE}";
|
|
echo "";
|
|
|
|
return ${EXIT_FAILURE};
|
|
fi
|
|
|
|
if test -n "${CHECK_WITH_STDERR}";
|
|
then
|
|
${TEST_EXECUTABLE} ${ARGUMENTS[@]} "${INPUT_FILE}";
|
|
RESULT=$?;
|
|
else
|
|
${TEST_EXECUTABLE} ${ARGUMENTS[@]} "${INPUT_FILE}" 2> /dev/null;
|
|
RESULT=$?;
|
|
fi
|
|
fi
|
|
return ${RESULT};
|
|
}
|
|
|
|
# Runs the test on the input file.
|
|
#
|
|
# Note that this function is not intended to be directly invoked
|
|
# from outside the test runner script.
|
|
#
|
|
# Arguments:
|
|
# a string containing the path of the test set directory
|
|
# a string containing the description of the test
|
|
# a string containing the test mode
|
|
# a string containing the name of the test data option set
|
|
# a string containing the path of the test executable
|
|
# a string containing the path of the test input file
|
|
# an array containing the arguments for the test executable
|
|
#
|
|
# Returns:
|
|
# an integer containg the exit status of the test executable
|
|
#
|
|
run_test_on_input_file()
|
|
{
|
|
local TEST_SET_DIRECTORY=$1;
|
|
local TEST_DESCRIPTION=$2;
|
|
local TEST_MODE=$3;
|
|
local OPTION_SET=$4;
|
|
local TEST_EXECUTABLE=$5;
|
|
local INPUT_FILE=$6;
|
|
shift 6;
|
|
local ARGUMENTS=("$@");
|
|
|
|
local INPUT_NAME=`basename "${INPUT_FILE}"`;
|
|
local TEST_OUTPUT="${INPUT_NAME}";
|
|
|
|
if test -n "${OPTION_SET}";
|
|
then
|
|
TEST_OUTPUT="${INPUT_NAME}-${OPTION_SET}";
|
|
fi
|
|
|
|
local TMPDIR="tmp$$";
|
|
local RESULT=0;
|
|
|
|
rm -rf ${TMPDIR};
|
|
mkdir ${TMPDIR};
|
|
|
|
if test "${TEST_MODE}" = "with_callback";
|
|
then
|
|
test_callback "${TMPDIR}" "${TEST_SET_DIRECTORY}" "${TEST_OUTPUT}" "${TEST_EXECUTABLE}" "${TEST_INPUT}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
|
|
elif test "${TEST_MODE}" = "with_stdout_reference";
|
|
then
|
|
TEST_EXECUTABLE=$( readlink_f "${TEST_EXECUTABLE}" );
|
|
|
|
if ! test -x ${TEST_EXECUTABLE};
|
|
then
|
|
echo "Invalid test executable: ${TEST_EXECUTABLE}";
|
|
echo "";
|
|
|
|
return ${EXIT_FAILURE};
|
|
fi
|
|
local INPUT_FILE_FULL_PATH=$( readlink_f "${INPUT_FILE}" );
|
|
local TEST_LOG="${TEST_OUTPUT}.log";
|
|
|
|
(cd ${TMPDIR} && run_test_with_input_and_arguments "${TEST_EXECUTABLE}" "${INPUT_FILE_FULL_PATH}" ${ARGUMENTS[@]} > "${TEST_LOG}");
|
|
RESULT=$?;
|
|
|
|
# Compare output if test ran successfully.
|
|
if test ${RESULT} -eq ${EXIT_SUCCESS};
|
|
then
|
|
local TEST_RESULTS="${TMPDIR}/${TEST_LOG}";
|
|
local STORED_TEST_RESULTS="${TEST_SET_DIRECTORY}/${TEST_LOG}.gz";
|
|
|
|
# Strip header with version.
|
|
sed -i'~' '1,2d' "${TEST_RESULTS}";
|
|
|
|
if test -f "${STORED_TEST_RESULTS}";
|
|
then
|
|
# Using zcat here since zdiff has issues on Mac OS X.
|
|
# Note that zcat on Mac OS X requires the input from stdin.
|
|
zcat < "${STORED_TEST_RESULTS}" | diff "${TEST_RESULTS}" -;
|
|
RESULT=$?;
|
|
else
|
|
gzip "${TEST_RESULTS}";
|
|
|
|
mv "${TEST_RESULTS}.gz" ${TEST_SET_DIRECTORY};
|
|
fi
|
|
fi
|
|
|
|
else
|
|
run_test_with_input_and_arguments "${TEST_EXECUTABLE}" "${INPUT_FILE}" ${ARGUMENTS[@]};
|
|
RESULT=$?;
|
|
fi
|
|
|
|
rm -rf ${TMPDIR};
|
|
|
|
if test -n "${TEST_DESCRIPTION}";
|
|
then
|
|
ARGUMENTS=`echo "${ARGUMENTS[*]}" | tr '\n' ' ' | sed 's/[ ]\$//'`;
|
|
|
|
if test -z "${ARGUMENTS}";
|
|
then
|
|
echo -n "${TEST_DESCRIPTION} with input: ${INPUT_FILE}";
|
|
else
|
|
echo -n "${TEST_DESCRIPTION} with options: '${ARGUMENTS}' and input: ${INPUT_FILE}";
|
|
fi
|
|
|
|
if test ${RESULT} -ne ${EXIT_SUCCESS};
|
|
then
|
|
echo " (FAIL)";
|
|
else
|
|
echo " (PASS)";
|
|
fi
|
|
fi
|
|
return ${RESULT};
|
|
}
|
|
|