tests/pngtest-all: detect failures add tests

This change is only verifiable in configure builds; cmake only executes
the basic test.

The previous version of tests/pngtest-all only returned the status code
of the final test.  Apparently it could never fail.  This adds checking
of all return status codes.

The change also adds a basic approach for regression testing with PNGs
that should fail a test; --strict ensures that PNGs which are valid do
not start to be reported as erroneous, this is the inverse.

At present the code (minimal traditional Bourne shell) only tests the
palette index checking code, a potentially important check if apps rely
on it.

The changes have been tested using the configure build both with a
regression which causes the libpng checking to cease to work and with a
corrected (reverted regression).  The regression test verifies that the
intended check works as expected.

Signed-off-by: John Bowler <jbowler@acm.org>
This commit is contained in:
John Bowler 2024-01-18 15:58:32 -08:00
parent 269b753496
commit 6f8257e437

View File

@ -1,16 +1,84 @@
#!/bin/sh
# normal execution
st=0 # exit status (set to 1 if a test fails)
fail="**FAIL**"
success=" SUCCESS"
TEST(){
# Try to make the log file easier to read:
test_status="$success"
echo "=============== PNGTEST $* ===================="
./pngtest "$@" || {
st=$?
test_status="$fail"
}
echo "===============$test_status $* ===================="
}
./pngtest --strict ${srcdir}/pngtest.png
# The "standard" test
TEST --strict "${srcdir}"/pngtest.png
# various crashers
# using --relaxed because some come from fuzzers that don't maintain CRC's
# Various crashers
# Use --relaxed because some come from fuzzers that don't maintain CRCs
TEST --relaxed "${srcdir}"/contrib/testpngs/crashers/badcrc.png
TEST --relaxed "${srcdir}"/contrib/testpngs/crashers/badadler.png
TEST --xfail "${srcdir}"/contrib/testpngs/crashers/bad_iCCP.png
TEST --xfail "${srcdir}"/contrib/testpngs/crashers/empty_ancillary_chunks.png
for file in "${srcdir}"/contrib/testpngs/crashers/huge_*_chunk.png
do
TEST --xfail "$file"
done
for file in "${srcdir}"/contrib/testpngs/crashers/huge_*safe_to_copy.png
do
TEST --xfail "$file"
done
TEST --xfail "${srcdir}"/contrib/testpngs/crashers/huge_IDAT.png
./pngtest --relaxed ${srcdir}/contrib/testpngs/crashers/badcrc.png
./pngtest --relaxed ${srcdir}/contrib/testpngs/crashers/badadler.png
./pngtest --xfail ${srcdir}/contrib/testpngs/crashers/bad_iCCP.png
./pngtest --xfail ${srcdir}/contrib/testpngs/crashers/empty_ancillary_chunks.png
./pngtest --xfail ${srcdir}/contrib/testpngs/crashers/huge_*_chunk.png \
${srcdir}/contrib/testpngs/crashers/huge_*safe_to_copy.png
./pngtest --xfail ${srcdir}/contrib/testpngs/crashers/huge_IDAT.png
# Regression tests for required warnings (or errors):
check_stdout(){
# $1: the test file (a bad PNG which must produce a warning, etc)
# $2: a string which must occur at the end of line on stdout for success
# result: an error message on descriptor 3 if the string is NOT found
found=
while read line
do
case "$line" in
*"$2") found=1;;
esac
echo "$line" # preserve the original output verbatim
done
# output the missing warning on descriptor 3:
test -z "$found" && echo "$1: $2" >&3
}
# NOTE: traditionally the Bourne shell executed the last element in a pipe
# sequence in the original shell so it could set variables in the original
# shell however this is not reliable and doesn't work in bash.
#
# It *is* reliable to use the actual exit status of the last command in
# the pipeline.
exec 4>&1 # original stdout - the log file
{
exec 3>&1 # stdout is the pipe at this point
fail=" FAIL(EXPECTED)" # runtime scope
success=" SUCCESS(UNEXPECTED)" # there should be a write error
for file in "${srcdir}"/contrib/testpngs/badpal/*.png
do
# The exit code is ignored here, the test is that the particular errors
# (warnings) are produced. The original output still ends up in the log
# file.
TEST "$file" |
check_stdout "$file" 'IDAT: Read palette index exceeding num_palette' |
check_stdout "$file" 'Wrote palette index exceeding num_palette' >&4
done
exec 3>&-
} | {
# This may not be a sub-shell, if it is 'st' is undefined and the exit
# just ends up as 'exit'.
while read error
do
echo "MISSING REPORT: $error"
st=1
done
exit $st
} || st=$?
exit $st