Replace test-bash-tool with test-bash-functions. Begin revamping the Bash tests.

This commit is contained in:
Daniel Nichter
2011-08-17 12:14:06 -06:00
parent c49ecdbaaa
commit 918c4c4bb2
8 changed files with 216 additions and 180 deletions

148
util/test-bash-functions Executable file
View File

@@ -0,0 +1,148 @@
#!/usr/bin/env bash
# This script is a test harness and TAP producer for testing bash functions
# in a bash file. A bash and test file are sourced; the former provides the
# functions to test and the latter provides the testing.
# ############################################################################
# Standard startup, find the branch's root directory
# ############################################################################
die() {
echo $1 >&2
exit 255
}
(
if [ -n "$PERCONA_TOOLKIT_BRANCH" ]; then
BRANCH=$PERCONA_TOOLKIT_BRANCH
cd $BRANCH
else
while [ ! -f Makefile.PL ] && [ $(pwd) != "/" ]; do
cd ..
done
if [ ! -f Makefile.PL ]; then
die "Cannot find the root directory of the Percona Toolkit branch"
exit 1
fi
BRANCH=`pwd`
fi
)
# ############################################################################
# Paths
# ############################################################################
TMPDIR="/tmp/percona-toolkit.test"
if [ ! -d $TMPDIR ]; then
mkdir $TMPDIR
fi
# ############################################################################
# Subroutines
# ############################################################################
# Load (count) the tests and print a TAP-style test plan.
load_tests() {
local test_files="$@"
local i=0
for t in $test_files; do
# Return unless the test file is bash. There may be other types of
# files in the tool's test dir.
if [ ! -f $t ]; then
continue
fi
head -n 1 $t | grep -q bash || continue
tests[$i]=$t
number_of_tests=$(grep --max-count 1 '^TESTS=[0-9]' $t | cut -d'=' -f2)
if [ -z "$number_of_tests" ]; then
i=$(( i + 1 ))
else
i=$(( i + $number_of_tests ))
fi
done
echo "1..$i"
}
# Source a test file to run whatever it contains (hopefully tests!).
run_test() {
local t=$1 # test file name, e.g. "group-by-all-01" for pt-diskstats
rm -rf $TMPDIR/* >/dev/null 2>&1
# Tests assume that they're being ran from their own dir, so they access
# sample files like "samples/foo.txt". So cd to the dir of the test file
# and run it. But the test file may have been given as a relative path,
# so run its basename after cd'ing to its directory. Then cd back in case
# other test files are in other dirs.
cwd="$PWD"
local t_dir=$(dirname $t)
local t_file=$(basename $t)
cd $t_dir
source $t_file
cd $cwd
return $?
}
# Print a TAP-style test result.
result() {
local result=$1
local test_name=${TEST_NAME:-"$t"}
if [ $result -eq 0 ]; then
echo "ok $testno - $test_name"
else
echo "not ok $testno - $test_name"
failed_tests=$(( failed_tests + 1))
echo "# Failed '$test_command'" >&2
cat $TMPDIR/failed_result | sed -e 's/^/# /' -e '30q' >&2
fi
testno=$(( testno + 1))
return $result
}
#
# The following subs are for the test files to call.
#
no_diff() {
local got=$1
local expected=$2
local test_command="diff $got $expected"
eval $test_command > $TMPDIR/failed_result 2>&1
result $?
}
# ############################################################################
# Script starts here
# ############################################################################
if [ $# -lt 2 ]; then
die "Usage: test-back-functions FILE TESTS"
fi
# Check and source the bash file. This is the code being tested.
# All its global vars and subs will be imported.
bash_file=$1
shift
if [ ! -f "$bash_file" ]; then
die "$bash_file does not exist"
fi
head -n1 $bash_file | grep -q -E 'bash|sh' || die "$bash_file is not a bash file"
source $bash_file
# Load (count) the tests so that we can write a TAP test plan like 1..5
# for expecting 5 tests. Perl prove needs this.
declare -a tests
load_tests "$@"
# Run the test files.
testno=1
failed_tests=0
for t in "${tests[@]}"; do
run_test $t
done
rm -rf $TMPDIR
exit $failed_tests

View File

@@ -1,120 +0,0 @@
#!/usr/bin/env bash
die() {
echo $1 >&2
exit 255
}
if [ -n "$PERCONA_TOOLKIT_BRANCH" ]; then
BRANCH=$PERCONA_TOOLKIT_BRANCH
cd $BRANCH
else
while [ ! -f Makefile.PL ] && [ $(pwd) != "/" ]; do
cd ..
done
if [ ! -f Makefile.PL ]; then
die "Cannot find the root directory of the Percona Toolkit branch"
exit 1
fi
BRANCH=`pwd`
fi
result() {
result=$1
if [ $result -eq 0 ]; then
echo "ok $testno - $t"
else
echo "not ok $testno - $t"
failed_tests=$(( failed_tests + 1))
# Indent and display the first 30 lines
diff "${GL_result}" "${GL_expected}" | sed -e 's/^/# /' -e '30q'
fi
testno=$(( testno + 1))
}
# All variables are named GL_whatever so they don't get overwritten with stuff
# that happens in the functions sourced.
GL_input="/tmp/percona-toolkit"
GL_expected="/tmp/percona-toolkit-reference"
GL_result="/tmp/percona-toolkit-result"
run_test() {
t=$1 # test file name, e.g. "group-by-all-01" for pt-diskstats
# The format of the test file is as follows:
# - line 1 is the shebang
# - line 2 is the command to run, commented out
# - argument 1 is the file to which the expected result should be printed
# - argument 2 is the file to which the input should be printed
# Get the command to run
GL_cmd="$(head -n2 $t | tail -n1 | cut -b2-)"
# Execute the file and tell it where to save the input & expected result
if [ -x "${t}" ]; then
./$t "${GL_expected}" "${GL_input}"
else
die "$t is not executable"
fi
# Execute the command
${GL_cmd} > "${GL_result}"
# Is the result the same as the expected result?
diff -q "${GL_result}" "${GL_expected}" >/dev/null
result $?
# Clean up
rm -f /tmp/percona-toolkit*
}
load_tests() {
test_files="$@"
i=0
for t in $test_files; do
# Return unless the test file is bash. There may be other types of
# files in the tool's test dir.
if [ ! -f $t ]; then
continue
fi
head -n 1 $t | grep -q bash || continue
tests[$i]=$t
i=$(( i + 1 ))
done
echo "1..$i"
}
tool=$1 # bash tool, e.g. pt-diskstats
t=$2 # optional test file, e.g. group-by-all-01
if [ -z "$tool" ]; then
die "No tool specified"
fi
cd $BRANCH/bin
if [ ! -f $tool ]; then
die "$tool does not exist"
fi
head -n1 $tool | grep -q -E 'bash|sh' || die "$tool is not a bash file"
# Source the tool, i.e. import its functions.
source $tool
cd $BRANCH/t/$tool
testno=1
failed_tests=0
declare -a tests
if [ -z "$t" ]; then
# Run all the tool's tests.
load_tests *
else
# Run just the specified test.
load_tests $t
fi
for t in "${tests[@]}"; do
run_test $t
done
exit $failed_tests