test at [5421b32beb]

File build/test/test artifact 2b7bb890ec part of check-in 5421b32beb


#! /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

# 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; 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-*)
			kitcreator="./build/make-kit-linux-amd64"
			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
				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