mirror of
https://github.com/wolfcw/libfaketime.git
synced 2026-05-17 08:36:28 +03:00
Merge pull request #2 from dfong/master
new framework for functional tests
This commit is contained in:
@@ -14,10 +14,14 @@ all: timetest test
|
||||
timetest: ${OBJ}
|
||||
${CC} -o $@ ${OBJ} ${LDFLAGS}
|
||||
|
||||
test: timetest
|
||||
test: timetest functest
|
||||
@echo
|
||||
@./test.sh
|
||||
|
||||
# run functional tests
|
||||
functest:
|
||||
./testframe.sh functests
|
||||
|
||||
clean:
|
||||
@rm -f ${OBJ} timetest
|
||||
|
||||
|
||||
39
test/README-testframe.txt
Normal file
39
test/README-testframe.txt
Normal file
@@ -0,0 +1,39 @@
|
||||
# here's how the testframe script works.
|
||||
#
|
||||
# Usage for testing:
|
||||
# usage: testframe.sh DIR
|
||||
# testframe.sh runs each testsuite script found within DIR.
|
||||
# (in the context of libfaketime, the DIR is functest.)
|
||||
# exits with status 0 if all tests succeed.
|
||||
#
|
||||
# Interface:
|
||||
# by convention, each testsuite script (within DIR) must be
|
||||
# a bash script named test_*.sh. the script must define a
|
||||
# function named "run". run takes no arguments. run is
|
||||
# expected to call the framework-provided function
|
||||
# run_testcase once for each test function. run_testcase
|
||||
# uses the global vars NFAIL and NSUCC to keep track of how
|
||||
# many testcases failed/succeeded.
|
||||
#
|
||||
# the test function is expected to call something like
|
||||
# asserteq or assertneq (again, framework-provided).
|
||||
#
|
||||
# fine print: for each testsuite, the framework creates a
|
||||
# subshell and dots in the script. also dotted in are
|
||||
# testframe.inc and DIR/common.inc (if it exists). the
|
||||
# testsuite script can make use of any functions defined
|
||||
# in these inc files. the environment variable
|
||||
# TESTSUITE_NAME is set to the filename of the testsuite
|
||||
# script, for possible use in warning or info messages.
|
||||
#
|
||||
# see functests/test_true.sh for a simple example of
|
||||
# a test suite script.
|
||||
#
|
||||
# Simple steps to add a new testsuite:
|
||||
# 1. decide its name - eg, XXX.
|
||||
# 2. choose a DIR of similar testsuites to put it in, or create a new one.
|
||||
# 3. create DIR/test_XXX.sh.
|
||||
# 4. write a run function and testcase functions in DIR/test_XXX.sh.
|
||||
# 5. within the run function, call run_testcase for each testcase function.
|
||||
# 6. within each testcase funtion, call assertneq or asserteq, or do
|
||||
# the equivalent.
|
||||
52
test/functests/common.inc
Normal file
52
test/functests/common.inc
Normal file
@@ -0,0 +1,52 @@
|
||||
# libfaketime-specific common support routines for tests
|
||||
|
||||
# say which *_fakecmd wrapper to use
|
||||
platform()
|
||||
{
|
||||
# may want to expand the pattern for linuxlike
|
||||
typeset out=$(uname)
|
||||
case "$out" in
|
||||
*OSX*) echo "mac" ;;
|
||||
*Linux*) echo "linuxlike" ;;
|
||||
*) echo 1>&2 unsupported platform, uname=\"$out\" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# run faked command on a mac
|
||||
# UNTESTED
|
||||
mac_fakecmd()
|
||||
{
|
||||
typeset timestring="$1"; shift
|
||||
typeset fakelib=../src/libfaketime.so.1
|
||||
export DYLD_INSERT_LIBRARIES=$fakelib
|
||||
export DYLD_FORCE_FLAT_NAMESPACE=1
|
||||
FAKETIME="$timestring" \
|
||||
"$@"
|
||||
}
|
||||
|
||||
# run faked command on linuxlike OS
|
||||
linuxlike_fakecmd()
|
||||
{
|
||||
typeset timestring="$1"; shift
|
||||
typeset fakelib=../src/libfaketime.so.1
|
||||
export LD_PRELOAD=$fakelib
|
||||
FAKETIME="$timestring" \
|
||||
"$@"
|
||||
}
|
||||
|
||||
# run a command with libfaketime using the given timestring
|
||||
fakecmd()
|
||||
{
|
||||
${PLATFORM}_fakecmd "$@"
|
||||
}
|
||||
|
||||
# generate a sequence of numbers from a to b
|
||||
range()
|
||||
{
|
||||
typeset a=$1 b=$2
|
||||
typeset i=$a
|
||||
while ((i <= b)); do
|
||||
echo $i
|
||||
((i = i+1))
|
||||
done
|
||||
}
|
||||
7
test/functests/dont_test_false.sh
Normal file
7
test/functests/dont_test_false.sh
Normal file
@@ -0,0 +1,7 @@
|
||||
# a testsuite that will force failure - for testing purposes
|
||||
|
||||
run()
|
||||
{
|
||||
run_testcase false
|
||||
}
|
||||
|
||||
13
test/functests/test_null.sh
Normal file
13
test/functests/test_null.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
# check that the date doesn't happen to be 0.
|
||||
|
||||
run()
|
||||
{
|
||||
run_testcase nulltest
|
||||
}
|
||||
|
||||
nulltest()
|
||||
{
|
||||
typeset tdate=${I2DATES[0]}
|
||||
|
||||
assertneq 0 "$(date +%s)" "($tdate)"
|
||||
}
|
||||
8
test/functests/test_true.sh
Normal file
8
test/functests/test_true.sh
Normal file
@@ -0,0 +1,8 @@
|
||||
# test suite that always succeds - for testing framework
|
||||
|
||||
run()
|
||||
{
|
||||
run_testcase true
|
||||
return 0
|
||||
}
|
||||
|
||||
55
test/functests/test_walkone.sh
Executable file
55
test/functests/test_walkone.sh
Executable file
@@ -0,0 +1,55 @@
|
||||
# walking-1 test.
|
||||
# sourced in from testframe.sh.
|
||||
#
|
||||
# this script defines a suite of functional tests
|
||||
# that verifies the correct operation of libfaketime
|
||||
# with the date command.
|
||||
|
||||
run()
|
||||
{
|
||||
init
|
||||
|
||||
for i in $(range 0 30); do
|
||||
run_testcase test_with_i $i
|
||||
done
|
||||
}
|
||||
|
||||
# ----- support routines
|
||||
init()
|
||||
{
|
||||
typeset testsuite="$1"
|
||||
PLATFORM=$(platform)
|
||||
if [ -z "$PLATFORM" ]; then
|
||||
echo "$testsuite: unknown platform! quitting"
|
||||
return 1
|
||||
fi
|
||||
echo "# PLATFORM=$PLATFORM"
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
# run date cmd under faketime, print time in secs
|
||||
fakedate()
|
||||
{
|
||||
#
|
||||
# let the time format be raw seconds since Epoch
|
||||
# for both input to libfaketime, and output of the date cmd.
|
||||
#
|
||||
typeset fmt='%s'
|
||||
export FAKETIME_FMT=$fmt
|
||||
fakecmd "$1" date +$fmt
|
||||
}
|
||||
|
||||
pow()
|
||||
{
|
||||
dc -e "$1 $2 ^ p"
|
||||
}
|
||||
|
||||
# run a fakedate test with a given time t
|
||||
test_with_i()
|
||||
{
|
||||
typeset i="$1"
|
||||
typeset t=$(pow 2 $i)
|
||||
|
||||
asserteq $(fakedate $t) $t "(secs since Epoch)"
|
||||
}
|
||||
55
test/testframe.inc
Normal file
55
test/testframe.inc
Normal file
@@ -0,0 +1,55 @@
|
||||
# framework common functions for use in test suites and test cases
|
||||
|
||||
#
|
||||
# run a test and keep stats on success/failure.
|
||||
# arguments: a command, possibly a shell function.
|
||||
# return value: 0 on success, 1 on failure.
|
||||
# side effects: increments global var NSUCC on success, NFAIL on failure.
|
||||
#
|
||||
run_testcase()
|
||||
{
|
||||
if "$@"; then
|
||||
((NSUCC++))
|
||||
return 0
|
||||
else
|
||||
((NFAIL++))
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# verbosely check that the test output matches the expected value.
|
||||
# arguments: the test output, the expected value, and a description.
|
||||
# return value: 0 on if test output equals expected value; 1 otherwise.
|
||||
# side effects: prints a descriptive message.
|
||||
#
|
||||
asserteq()
|
||||
{
|
||||
typeset out="$1" expected="$2" desc="$3"
|
||||
echo -n "out=$out $desc"
|
||||
if [ "$out" = "$expected" ]; then
|
||||
echo " - ok"
|
||||
return 0
|
||||
else
|
||||
echo " expected=$expected - bad"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# verbosely check that the test output doesn't match the reference value.
|
||||
# return value: 1 on if test output equals expected value; 0 if not equal.
|
||||
# side effects: prints descriptive message.
|
||||
#
|
||||
assertneq()
|
||||
{
|
||||
typeset out="$1" ref="$2" desc="$3"
|
||||
echo -n "out=$out $desc"
|
||||
if [ "$out" = "$ref" ]; then
|
||||
echo " ref=$ref - bad"
|
||||
return 1
|
||||
else
|
||||
echo " ref=$ref - ok"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
99
test/testframe.sh
Executable file
99
test/testframe.sh
Executable file
@@ -0,0 +1,99 @@
|
||||
#! /bin/bash
|
||||
# testframe.sh DIR
|
||||
# bare-bones testing framework.
|
||||
# run the test suites in the given DIR;
|
||||
# exit with nonzero status if any of them failed.
|
||||
# see README.testframe.txt for details.
|
||||
#
|
||||
|
||||
# echo labelled error/warning message to stderr
|
||||
report()
|
||||
{
|
||||
echo $PROG: $* 1>&2
|
||||
}
|
||||
|
||||
# echo OK or BAD depending on argument (0 or not)
|
||||
status_word()
|
||||
{
|
||||
if [ "$1" -eq 0 ]; then
|
||||
echo OK
|
||||
else
|
||||
echo BAD
|
||||
fi
|
||||
}
|
||||
|
||||
# run the given testsuite, return nonzero if any testcase failed.
|
||||
run_testsuite()
|
||||
{
|
||||
typeset testsuite="$1"
|
||||
|
||||
NFAIL=0
|
||||
NSUCC=0
|
||||
|
||||
# add testsuite dir to PATH for convenience
|
||||
typeset dir=$(dirname $testsuite)
|
||||
PATH=$dir:$PATH
|
||||
. testframe.inc
|
||||
if [ -f $dir/common.inc ]; then
|
||||
. $dir/common.inc
|
||||
fi
|
||||
. $testsuite
|
||||
export TESTSUITE_NAME=$testsuite
|
||||
|
||||
echo ""
|
||||
echo "# Begin $testsuite"
|
||||
|
||||
run
|
||||
typeset runstat=$?
|
||||
|
||||
echo "# $testsuite summary: $NSUCC succeeded, $NFAIL failed"
|
||||
if [ $runstat -ne 0 ]; then
|
||||
((NFAIL++))
|
||||
report "error: $testsuite run exit_status=$runstat!"
|
||||
fi
|
||||
echo "# End $testsuite -" $(status_word $NFAIL)
|
||||
[ $NFAIL -eq 0 ]
|
||||
}
|
||||
|
||||
#
|
||||
# list all testsuite scripts in the given directories.
|
||||
# a testsuite file must be a bash script whose name is of the form test_*.sh .
|
||||
#
|
||||
list_testsuites()
|
||||
{
|
||||
for dir in "$@"; do
|
||||
ls $dir/test_*.sh 2>/dev/null
|
||||
done
|
||||
}
|
||||
|
||||
main()
|
||||
{
|
||||
TS_NFAIL=0
|
||||
TS_NSUCC=0
|
||||
|
||||
echo "# Begin Test Suites in $*"
|
||||
typeset testsuites=$(list_testsuites "$@")
|
||||
|
||||
if [ -z "$testsuites" ]; then
|
||||
report "error: no testsuites found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for testsuite in $testsuites; do
|
||||
if run_testsuite $testsuite; then
|
||||
((TS_NSUCC++))
|
||||
else
|
||||
((TS_NFAIL++))
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "# Test Suites summary: $TS_NSUCC succeeded, $TS_NFAIL failed"
|
||||
echo "# End Test Suites -" $(status_word $TS_NFAIL)
|
||||
[ $TS_NFAIL -eq 0 ]
|
||||
}
|
||||
|
||||
# ----- start of mainline code
|
||||
PROG=${0##*/}
|
||||
|
||||
main "${@:-.}"
|
||||
Reference in New Issue
Block a user