#! /bin/bash
VERSIONS="8.4.19 8.5.10 cvs_HEAD"
# Find the base directory
for x in 1 2 3 __fail__; do
if [ "${x}" = "${fail}" ]; then
echo 'Unable to find KitCreator, aborting.' >&2
exit 1
fi
if [ -x kitcreator ]; then
break
fi
cd ..
done
ROOTDIR="$(pwd)"
TESTDIR="${ROOTDIR}/build/test"
export ROOTDIR TESTDIR
# Handle command-line arguments
if [ "$1" = "clean" ]; then
rm -rf "${TESTDIR}/kits"
fi
# Create place to put kits
mkdir "${TESTDIR}/kits" >/dev/null 2>/dev/null
mkdir "${TESTDIR}/kits/failed" >/dev/null 2>/dev/null
if [ ! -d "${TESTDIR}/kits" ]; then
echo 'Unable to create kits/ directory, aborting.' >&2
exit 1
fi
# Cleanup
for file in "${TESTDIR}"/kits/*.log; do
if echo "${file}" | grep -- '-build.log$' >/dev/null; then
continue
fi
rm -f "${file}"
done
# Disable WINE debugging
WINEPREFIX="${TESTDIR}/.wine"
export WINEPREFIX
rm -rf "${WINEPREFIX}"
mkdir "${WINEPREFIX}"
cat << \_EOF_ > "${WINEPREFIX}/update-reg"
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\AeDebug]
"Auto"=dword:00000001
"Debugger"="false"
_EOF_
regedit "${WINEPREFIX}/update-reg" >/dev/null 2>/dev/null
# Start Xvfb for X11-based tests
XVFB_PID="$(
Xvfb :31 -screen 0 800x600x24 -nolisten tcp >/dev/null 2>/dev/null &
echo "$!"
)"
DISPLAY=:31
export DISPLAY
failed=""
for kit in normal normal-zip normal-threaded normal-threaded-zip normal-statictk normal-notk normal-threaded-notk normal-threaded-zip-notk normal-nomk4 min min-static normal-kitdll normal-threaded-kitdll normal-notk-kitdll normal-nomk4-kitdll normal-nomk4-notk-kitdll normal-threaded-nomk4-kitdll normal-threaded-notk-nomk4-kitdll min-kitdll win32-i586 win32-i586-zip win32-i586-threaded win32-i586-threaded-zip win32-i586-notk win32-i586-threaded-notk win32-i586-nomk4 win32-i586-kitdll win32-i586-threaded-kitdll win32-i586-notk-kitdll win32-i586-nomk4-kitdll win32-i586-nomk4-notk-kitdll win32-i586-threaded-nomk4-kitdll win32-i586-threaded-notk-nomk4-kitdll linux-mipsel-min linux-mipsel-min-kitdll linux-amd64-notk linux-amd64-notk-kitdll solaris-i386 solaris-i386-kitdll solaris-amd64 solaris-amd64-kitdll solaris-sparc solaris-sparc-kitdll solaris-sparc64 solaris-sparc64-kitdll hpux-hppa64-notk hpux-hppa64-notk-kitdll freebsd-amd64 freebsd-amd64-kitdll netbsd-i386 netbsd-i386-kitdll netbsd-amd64 netbsd-amd64-kitdll; do
kitcreator="./kitcreator"
args=""
runnable="1"
iszip="0"
statictk="0"
notk="0"
nomk4="0"
xcompile="0"
kitdll="0"
kitruncmd=""
# Handle base configuration
os="$(uname -s | dd conv=lcase 2>/dev/null)"
cpu="$(uname -m | dd conv=lcase 2>/dev/null)"
case "${kit}" in
normal|normal-*)
kit="$(echo "${kit}" | sed "s@^normal@$os-$cpu@")"
;;
min|min-kitdll)
kitcreator="./build/make-minkit"
iszip="1"
notk="1"
kit="$(echo "${kit}" | sed "s@^min@$os-$cpu-min@")"
;;
min-static)
kitcreator="./build/make-minkit-static"
iszip="1"
notk="1"
kit="${os}-${cpu}-min-static"
;;
win32|win32-*)
kitcreator="./build/make-kit-win32"
xcompile="1"
kitruncmd="wine"
;;
linux-mipsel-min|linux-mipsel-min-kitdll)
kitcreator="./build/make-kit-mipsel"
runnable="0"
xcompile="1"
notk="1"
iszip="1"
;;
linux-amd64|linux-amd64-*|\
solaris-i386|solaris-i386-*|\
solaris-amd64|solaris-amd64-*|\
solaris-sparc|solaris-sparc-*|\
solaris-sparc64|solaris-sparc64-*|\
freebsd-amd64|freebsd-amd64-*|\
netbsd-i386|netbsd-i386-*|\
netbsd-amd64|netbsd-amd64-*|\
hpux-hppa64|hpux-hppa64-*)
platform="$(echo "${kit}" | cut -f 1-2 -d '-')"
kitcreator="./build/make-kit-${platform}"
runnable="0"
xcompile="1"
iszip="0"
;;
esac
if [ "${xcompile}" != "0" ]; then
kit="${kit}-xcompile"
fi
# Handle additional configuration
tempkit="-${kit}-"
for try in 1 2 3 4 5 6 7 8 9; do
case "-${tempkit}-" in
*-threaded-*)
tempkit="$(echo "${tempkit}" | sed 's@-threaded-@-@')"
args="${args} --enable-threads"
;;
*-zip-*)
tempkit="$(echo "${tempkit}" | sed 's@-zip-@-@')"
args="${args} --enable-kit-storage=zip"
iszip="1"
;;
*-statictk-*)
tempkit="$(echo "${tempkit}" | sed 's@-statictk-@-@')"
if [ "${notk}" = "0" ]; then
statictk="1"
else
echo "${kit}: Unable to create StaticTk and NoTk, ignoring StaticTk" >&2
fi
;;
*-notk-*)
tempkit="$(echo "${tempkit}" | sed 's@-notk-@-@')"
if [ "${statictk}" = "0" ]; then
notk="1"
else
echo "${kit}: Unable to create StaticTk and NoTk, ignoring NoTk" >&2
fi
;;
*-nomk4-*)
tempkit="$(echo "${tempkit}" | sed 's@-nomk4-@-@')"
nomk4="1"
iszip="1"
;;
*-kitdll-*)
kitdll="1"
;;
esac
done
if [ "${kitdll}" = "1" ]; then
# Currently no KitDLL uses Zip
iszip="0"
fi
for version in ${VERSIONS}; do
# Work around changes in default behaviour
if [ "${version}" = "cvs_HEAD" ]; then
kit="$(echo "${kit}" | sed 's@-threaded@-unthreaded@')"
args="$(echo "${args}" | sed 's@ --enable-threads@ --disable-threads@')"
fi
# Create Tclkit
if [ "${kitdll}" = "1" ]; then
createdkit="libtclkit*.dll libtclkit*.*"
outputname="${TESTDIR}/kits/libtclkit-${version}-${kit}"
failoutputname="${TESTDIR}/kits/failed/libtclkit-${version}-${kit}"
else
createdkit="tclkit-${version}"
outputname="${TESTDIR}/kits/tclkit-${version}-${kit}"
failoutputname="${TESTDIR}/kits/failed/tclkit-${version}-${kit}"
fi
buildlog="${outputname}-build.log"
failbuildlog="${failoutputname}-build.log"
testresultslog="${outputname}-tests.log"
if [ ! -f "${outputname}" ]; then
unset KITCREATOR_PKGS STATICTK
if [ -f "${failoutputname}" ]; then
echo "Skipping rebuilding failed kit ${version}/${kit} ..."
failed="${failed} ${version}/${kit}-build"
continue
fi
rm -f tclsh
./kitcreator clean >/dev/null 2>/dev/null
echo "Creating Tclkit ${version}/${kit}..."
echo " *** Build started $(whoami)@$(hostname) on $(date)" > "${buildlog}"
echo '' >> "${buildlog}"
echo " *** Build Script" >> "${buildlog}"
if [ "${notk}" = "1" ]; then
KITCREATOR_PKGS='itcl mk4tcl'
fi
if [ "${nomk4}" = "1" ]; then
if [ -z "${KITCREATOR_PKGS}" ]; then
KITCREATOR_PKGS='itcl tk'
else
KITCREATOR_PKGS="$(echo "${KITCREATOR_PKGS}" | sed 's@mk4tcl@@')"
fi
fi
if [ "${kitdll}" = "1" ]; then
if [ -z "${KITCREATOR_PKGS}" ]; then
KITCREATOR_PKGS='tk itcl mk4tcl kitdll'
else
KITCREATOR_PKGS="${KITCREATOR_PKGS} kitdll"
fi
fi
export KITCREATOR_PKGS
if [ -n "${KITCREATOR_PKGS}" ]; then
echo " KITCREATOR_PKGS=\"${KITCREATOR_PKGS}\"" >> "${buildlog}"
echo " export KITCREATOR_PKGS" >> "${buildlog}"
fi
if [ "${statictk}" = "1" ]; then
STATICTK="1"
export STATICTK
echo " STATICTK=\"${STATICTK}\"" >> "${buildlog}"
echo " export STATICTK" >> "${buildlog}"
fi
if [ "${kitcreator}" != "./kitcreator" ]; then
echo " mkdir build" >> "${buildlog}"
# Several build scripts rely on minkit to work
if grep './build/make-minkit' "${kitcreator}" >/dev/null 2>/dev/null; then
echo " cat << \__EOF__ > ./build/make-minkit" >> "${buildlog}"
sed 's@^@ @' './build/make-minkit' >> "${buildlog}"
echo " __EOF__" >> "${buildlog}"
echo '' >> "${buildlog}"
fi
# Several build scripts rely on make-kit-crosscompile to work
if grep './build/make-kit-crosscompile' "${kitcreator}" >/dev/null 2>/dev/null; then
echo " cat << \__EOF__ > ./build/make-kit-crosscompile" >> "${buildlog}"
sed 's@^@ @' './build/make-kit-crosscompile' >> "${buildlog}"
echo " __EOF__" >> "${buildlog}"
echo '' >> "${buildlog}"
fi
echo " cat << \__EOF__ > ${kitcreator}" >> "${buildlog}"
sed 's@^@ @' "${kitcreator}" >> "${buildlog}"
echo " __EOF__" >> "${buildlog}"
echo '' >> "${buildlog}"
fi
echo " \"${kitcreator}\" \"${version}\" ${args}" >> "${buildlog}"
echo '' >> "${buildlog}"
echo '' >> "${buildlog}"
echo '' >> "${buildlog}"
echo " *** Build Results" >> "${buildlog}"
echo '' >> "${buildlog}"
buildfailed="0"
"${kitcreator}" "${version}" ${args} >> "${buildlog}" 2>&1 || buildfailed="1"
grep -n '^' */build.log >> "${buildlog}" 2>&1
if [ "${kitdll}" = "1" ]; then
# Create test drivers for KitDLL
(
echo ""
echo ""
echo ""
echo " *** Building KitDLL test driver (tclsh)"
echo ""
cd kitsh/build/kitsh-*/ || exit 1
make tclsh
cp tclsh ../../../
) >> "${buildlog}" 2>&1
fi
# Perform wildcard expansion
createdkit="$(ls -f1 ${createdkit} 2>/dev/null | head -n 1)"
if [ ! -f "${createdkit}" ]; then
echo "Failed to create kit ${version}/${kit}" >&2
failed="${failed} ${version}/${kit}-build"
touch "${failoutputname}"
mv "${buildlog}" "${failbuildlog}"
rm -f tclsh
continue
fi
# Verify sanity of created kit
issane=1
## Verify that Win32 builds are of correct type
## Verify that DLL builds are of correct type
case "-${version}-${kit}-" in
*-win32-kitdll-*|*-win32-*-kitdll-*)
if ! file "${createdkit}" | grep 'MS Windows (DLL)' >/dev/null; then
issane=0
fi
;;
*-kitdll-*)
if ! file "${createdkit}" | grep 'shared object' >/dev/null; then
issane=0
fi
;;
*-win32-notk-*|*-win32-*-notk-*)
if ! file "${createdkit}" | grep 'MS Windows (console)' >/dev/null; then
echo "Kit failed sanity check for being a console application" >&2
issane=0
fi
;;
*-win32-*)
if ! file "${createdkit}" | grep 'MS Windows (GUI)' >/dev/null; then
echo "Kit failed sanity check for being a GUI application" >&2
issane=0
fi
;;
esac
## Verify the build completed without warnings
if [ "${buildfailed}" = "1" ]; then
echo "Kit failed sanity check for Building" >&2
issane=0
fi
# Make note of sanity failure
if [ "${issane}" != "1" ]; then
echo "Kit failed sanity ${version}/${kit}" >&2
failed="${failed} ${version}/${kit}-sanity"
mv "${createdkit}" "${failoutputname}"
mv "${buildlog}" "${failbuildlog}"
rm -f tclsh
continue
fi
# Rename created kit to final destination
mv "${createdkit}" "${outputname}"
if [ -f "tclsh" ]; then
mv "tclsh" "${outputname}-tclsh"
fi
# For KitDLL, make a note of the original name
if [ "${kitdll}" = "1" ]; then
echo "${createdkit}" > "${outputname}-origname"
fi
fi
# Test zip status
if unzip -l "${outputname}" 2>&1 | grep 'boot\.tcl' >/dev/null; then
canunzip="1"
else
canunzip="0"
fi
if [ "${iszip}" != "${canunzip}" ]; then
echo "Failed to unzip zipkit or was able to unzip non-zipkit ${version}/${kit}" >&2
failed="${failed} ${version}/${kit}-zip"
continue
fi
# Do not continue past here for un-runnable kits
if [ "${runnable}" != "1" ]; then
continue
fi
# If the name of the original build matters, symlink it up
if [ -f "${outputname}-origname" ]; then
createdkit="$(cat "${outputname}-origname")"
ln -s "${outputname}" "${createdkit}"
fi
# Perform battery of tests
## Clean tests log
rm -f "${testresultslog}"
for testscp in "${TESTDIR}"/tests/*.tcl; do
testscp_tag="$(basename "${testscp}" .tcl)"
testscppre="$(dirname "${testscp}")/${testscp_tag}.sh"
scplogfile="${outputname}-${testscp_tag}.log"
# If a command is required to start the kit, prepare to kill it
# in case of timeout.
## Temporarily disabled since currently it is causing
## more problems in the form of tests being killed
## prematurely than we are having issues with tests
## hanging
kitrunkillpid=""
if [ "1" = "0" -a -n "${kitruncmd}" ]; then
(
sleep 120
killall "$(basename "${outputname}")" >/dev/null 2>/dev/null
) >/dev/null 2>/dev/null &
kitrunkillpid="$!"
fi
(
if [ -f "${testscppre}" ]; then
. "${testscppre}"
fi
if [ "${kitdll}" = "1" ]; then
${kitruncmd} "${outputname}-tclsh" "${testscp}" "${outputname}" "${kit}" "${version}"
else
${kitruncmd} "${outputname}" "${testscp}" "${outputname}" "${kit}" "${version}"
fi
) > "${scplogfile}" 2>&1
if [ "$?" != "0" ]; then
echo "Script failed: ${testscp_tag} on ${version}/${kit}" >&2
failed="${failed} ${version}/${kit}-test-${testscp_tag}"
echo "${testscp_tag}: FAIL" >> "${testresultslog}"
continue
fi
# Kill the watchdog for this iteration
if [ -n "${kitrunkillpid}" ]; then
kill -9 "${kitrunkillpid}" >/dev/null 2>/dev/null
fi
echo "${testscp_tag}: PASS" >> "${testresultslog}"
rm -f "${scplogfile}"
done
if [ -f "${outputname}-origname" ]; then
rm -f "${createdkit}"
fi
done
done
if [ -n "${failed}" ]; then
echo "Failed: ${failed}"
fi
# Terminate Xvfb
kill -9 "${XVFB_PID}"
# Cleanup
./kitcreator clean
rm -f tclsh