1263346Sjmmv# $FreeBSD: releng/11.0/usr.bin/bmake/tests/common.sh 263346 2014-03-19 12:29:20Z jmmv $
2145620Sharti#
3145620Sharti# Common code used run regression tests for usr.bin/make.
4145620Sharti
5145620Sharti#
6146822Sharti# Output a message and exit with an error.
7145620Sharti#
8146822Shartifatal()
9145620Sharti{
10146822Sharti	echo "fatal: $*" >/dev/stderr
11146822Sharti	exit 1
12145620Sharti}
13145620Sharti
14263082Sjmmvmake_is_fmake() {
15263082Sjmmv	# This test is not very reliable but works for now: the old fmake
16263082Sjmmv	# does have a -v option while bmake doesn't.
17263082Sjmmv	${MAKE_PROG} -f Makefile.non-existent -v 2>&1 | \
18263082Sjmmv	    grep -q "cannot open.*non-existent"
19263082Sjmmv}
20263082Sjmmv
21145620Sharti#
22146822Sharti# Check whether the working directory exists - it must.
23145620Sharti#
24146822Shartiensure_workdir()
25146822Sharti{
26146822Sharti	if [ ! -d ${WORK_DIR} ] ; then
27146822Sharti		fatal "working directory ${WORK_DIR} does not exist."
28146822Sharti	fi
29146822Sharti}
30146822Sharti
31145620Sharti#
32146822Sharti# Make sure all tests have been run
33146822Sharti#
34146822Shartiensure_run()
35145620Sharti{
36146822Sharti	if [ -z "${TEST_N}" ] ; then
37146822Sharti		TEST_N=1
38146822Sharti	fi
39145620Sharti
40146822Sharti	FAIL=
41146822Sharti	N=1
42146822Sharti	while [ ${N} -le ${TEST_N} ] ; do
43146855Sharti		if ! skip_test ${N} ; then
44146822Sharti			if [ ! -f ${OUTPUT_DIR}/status.${N} -o \
45146822Sharti			     ! -f ${OUTPUT_DIR}/stdout.${N} -o \
46146822Sharti			     ! -f ${OUTPUT_DIR}/stderr.${N} ] ; then
47146822Sharti				echo "Test ${SUBDIR}/${N} no yet run"
48146822Sharti				FAIL=yes
49146822Sharti			fi
50146822Sharti		fi
51146822Sharti		N=$((N + 1))
52146822Sharti	done
53146822Sharti
54146822Sharti	if [ ! -z "${FAIL}" ] ; then
55146822Sharti		exit 1
56145620Sharti	fi
57145620Sharti}
58145620Sharti
59145620Sharti#
60146822Sharti# Output usage messsage.
61145620Sharti#
62146822Shartiprint_usage()
63146822Sharti{
64146822Sharti	echo "Usage: sh -v -m <path> -w <dir> $0 command(s)"
65146822Sharti	echo " setup	- setup working directory"
66146822Sharti	echo " run	- run the tests"
67146822Sharti	echo " show	- show test results"
68146822Sharti	echo " compare	- compare actual and expected results"
69146822Sharti	echo " diff	- diff actual and expected results"
70146822Sharti	echo " reset	- reset the test to its initial state"
71146822Sharti	echo " clean	- delete working and output directory"
72146822Sharti	echo " test	- setup + run + compare"
73146822Sharti	echo " prove	- setup + run + compare + clean"
74146822Sharti	echo " desc	- print short description"
75146822Sharti	echo " update	- update the expected results with the current results"
76146822Sharti	echo " help	- show this information"
77146822Sharti}
78146822Sharti
79145620Sharti#
80146855Sharti# Return 0 if we should skip the test. 1 otherwise
81146855Sharti#
82146855Shartiskip_test()
83146855Sharti{
84146855Sharti	eval skip=\${TEST_${1}_SKIP}
85146855Sharti	if [ -z "${skip}" ] ; then
86146855Sharti		return 1
87146855Sharti	else
88146855Sharti		return 0
89146855Sharti	fi
90146855Sharti}
91146855Sharti
92146855Sharti#
93146822Sharti# Common function for setup and reset.
94146822Sharti#
95146822Sharticommon_setup()
96145620Sharti{
97146822Sharti	#
98146822Sharti	# If a Makefile exists in the source directory - copy it over
99146822Sharti	#
100263346Sjmmv	if [ -e ${SRC_DIR}/Makefile.test -a ! -e ${WORK_DIR}/Makefile ] ; then
101263346Sjmmv		cp ${SRC_DIR}/Makefile.test ${WORK_DIR}/Makefile
102146822Sharti	fi
103145620Sharti
104146822Sharti	#
105146822Sharti	# If the TEST_MAKE_DIRS variable is set, create those directories
106146822Sharti	#
107146822Sharti	set -- ${TEST_MAKE_DIRS}
108146822Sharti	while [ $# -ne 0 ] ; do
109146822Sharti		if [ ! -d ${WORK_DIR}/${1} ] ; then
110146822Sharti			mkdir -p -m ${2} ${WORK_DIR}/${1}
111146822Sharti		else
112146822Sharti			chmod ${2} ${WORK_DIR}/${1}
113146822Sharti		fi
114146822Sharti		shift ; shift
115146822Sharti	done
116146822Sharti
117146822Sharti	#
118146822Sharti	# If the TEST_COPY_FILES variable is set, copy those files over to
119146822Sharti	# the working directory. The value is assumed to be pairs of
120146822Sharti	# filenames and modes.
121146822Sharti	#
122146822Sharti	set -- ${TEST_COPY_FILES}
123146822Sharti	while [ $# -ne 0 ] ; do
124263346Sjmmv		local dstname="$(echo ${1} | sed -e 's,Makefile.test,Makefile,')"
125263346Sjmmv		if [ ! -e ${WORK_DIR}/${dstname} ] ; then
126263346Sjmmv			cp ${SRC_DIR}/${1} ${WORK_DIR}/${dstname}
127146822Sharti		fi
128263346Sjmmv		chmod ${2} ${WORK_DIR}/${dstname}
129146822Sharti		shift ; shift
130146822Sharti	done
131146822Sharti
132146822Sharti	#
133146822Sharti	# If the TEST_TOUCH variable is set, it is taken to be a list
134146822Sharti	# of pairs of filenames and arguments to touch(1). The arguments
135146822Sharti	# to touch must be surrounded by single quotes if there are more
136146822Sharti	# than one argument.
137146822Sharti	#
138146822Sharti	eval set -- ${TEST_TOUCH}
139146822Sharti	while [ $# -ne 0 ] ; do
140146822Sharti		eval touch ${2} ${WORK_DIR}/${1}
141146822Sharti		shift ; shift
142146822Sharti	done
143146822Sharti
144146822Sharti	#
145146822Sharti	# Now create links
146146822Sharti	#
147146822Sharti	eval set -- ${TEST_LINKS}
148146822Sharti	while [ $# -ne 0 ] ; do
149146822Sharti		eval ln ${WORK_DIR}/${1} ${WORK_DIR}/${2}
150146822Sharti		shift ; shift
151146822Sharti	done
152145620Sharti}
153145620Sharti
154145620Sharti#
155146822Sharti# Setup the test. This creates the working and output directories and
156146822Sharti# populates it with files. If there is a setup_test() function - call it.
157145620Sharti#
158146822Shartieval_setup()
159146822Sharti{
160146822Sharti	#
161146822Sharti	# Check whether the working directory exists. If it does exit
162146822Sharti	# fatally so that we don't clobber a test the user is working on.
163146822Sharti	#
164146822Sharti	if [ -d ${WORK_DIR} ] ; then
165146822Sharti		fatal "working directory ${WORK_DIR} already exists."
166146822Sharti	fi
167146822Sharti
168146822Sharti	#
169146822Sharti	# Now create it and the output directory
170146822Sharti	#
171146822Sharti	mkdir -p ${WORK_DIR}
172146822Sharti	rm -rf ${OUTPUT_DIR}
173146822Sharti	mkdir -p ${OUTPUT_DIR}
174146822Sharti
175146822Sharti	#
176146822Sharti	# Common stuff
177146822Sharti	#
178146822Sharti	common_setup
179146822Sharti
180146822Sharti	#
181146822Sharti	# Now after all execute the user's setup function if it exists.
182146822Sharti	#
183146822Sharti	setup_test
184146822Sharti}
185146822Sharti
186145620Sharti#
187146822Sharti# Default setup_test function does nothing. This may be overriden by
188146822Sharti# the test.
189145620Sharti#
190145620Shartisetup_test()
191145620Sharti{
192145620Sharti}
193145620Sharti
194145620Sharti#
195146822Sharti# Reset the test. Here we need to rely on information from the test.
196146822Sharti# We executed the same steps as in the setup, by try not to clobber existing
197146822Sharti# files.
198146822Sharti# All files and directories that are listed on the TEST_CLEAN_FILES
199146822Sharti# variable are removed. Then the TEST_TOUCH list is executed and finally
200146822Sharti# the reset_test() function called if it exists.
201145620Sharti#
202146822Shartieval_reset()
203146822Sharti{
204146822Sharti	ensure_workdir
205146822Sharti
206146822Sharti	#
207146822Sharti	# Clean the output directory
208146822Sharti	#
209146822Sharti	rm -rf ${OUTPUT_DIR}/*
210146822Sharti
211146822Sharti	#
212146822Sharti	# Common stuff
213146822Sharti	#
214146822Sharti	common_setup
215146822Sharti
216146822Sharti	#
217146822Sharti	# Remove files.
218146822Sharti	#
219146822Sharti	for f in ${TEST_CLEAN_FILES} ; do
220146822Sharti		rm -rf ${WORK_DIR}/${f}
221146822Sharti	done
222146822Sharti
223146822Sharti	#
224146822Sharti	# Execute test's function
225146822Sharti	#
226146822Sharti	reset_test
227146822Sharti}
228146822Sharti
229145620Sharti#
230146822Sharti# Default reset_test function does nothing. This may be overriden by
231146822Sharti# the test.
232145620Sharti#
233146822Shartireset_test()
234145620Sharti{
235145620Sharti}
236145620Sharti
237145620Sharti#
238146822Sharti# Clean the test. This simply removes the working and output directories.
239145620Sharti#
240146822Shartieval_clean()
241145620Sharti{
242201526Sobrien	#
243201526Sobrien	# If you have special cleaning needs, provide a 'cleanup' shell script.
244201526Sobrien	#
245201526Sobrien	if [ -n "${TEST_CLEANUP}" ] ; then
246201526Sobrien		. ${SRC_DIR}/cleanup
247201526Sobrien	fi
248237344Sobrien	if [ -z "${NO_TEST_CLEANUP}" ] ; then
249237344Sobrien		rm -rf ${WORK_DIR}
250237344Sobrien		rm -rf ${OUTPUT_DIR}
251237344Sobrien	fi
252145620Sharti}
253145620Sharti
254145620Sharti#
255146822Sharti# Run the test.
256145620Sharti#
257146822Shartieval_run()
258145620Sharti{
259146822Sharti	ensure_workdir
260146822Sharti
261146822Sharti	if [ -z "${TEST_N}" ] ; then
262146822Sharti		TEST_N=1
263146822Sharti	fi
264146822Sharti
265146822Sharti	N=1
266146822Sharti	while [ ${N} -le ${TEST_N} ] ; do
267146855Sharti		if ! skip_test ${N} ; then
268146822Sharti			( cd ${WORK_DIR} ;
269146822Sharti			  exec 1>${OUTPUT_DIR}/stdout.${N} 2>${OUTPUT_DIR}/stderr.${N}
270146822Sharti			  run_test ${N}
271146822Sharti			  echo $? >${OUTPUT_DIR}/status.${N}
272146822Sharti			)
273146822Sharti		fi
274146822Sharti		N=$((N + 1))
275146822Sharti	done
276145620Sharti}
277145620Sharti
278145620Sharti#
279146822Sharti# Default run_test() function.  It can be replaced by the
280146822Sharti# user specified regression test. The argument to this function is
281146822Sharti# the test number.
282146822Sharti#
283146822Shartirun_test()
284146822Sharti{
285146822Sharti	eval args=\${TEST_${1}-test${1}}
286146822Sharti        ${MAKE_PROG} $args
287146822Sharti}
288146822Sharti
289146822Sharti#
290146822Sharti# Show test results.
291146822Sharti#
292146822Shartieval_show()
293146822Sharti{
294146822Sharti	ensure_workdir
295146822Sharti
296146822Sharti	if [ -z "${TEST_N}" ] ; then
297146822Sharti		TEST_N=1
298146822Sharti	fi
299146822Sharti
300146822Sharti	N=1
301146822Sharti	while [ ${N} -le ${TEST_N} ] ; do
302146855Sharti		if ! skip_test ${N} ; then
303146822Sharti			echo "=== Test ${N} Status =================="
304146822Sharti			cat ${OUTPUT_DIR}/status.${N}
305146822Sharti			echo ".......... Stdout .................."
306146822Sharti			cat ${OUTPUT_DIR}/stdout.${N}
307146822Sharti			echo ".......... Stderr .................."
308146822Sharti			cat ${OUTPUT_DIR}/stderr.${N}
309146822Sharti		fi
310146822Sharti		N=$((N + 1))
311146822Sharti	done
312146822Sharti}
313146822Sharti
314146822Sharti#
315145620Sharti# Compare results with expected results
316145620Sharti#
317145620Shartieval_compare()
318145620Sharti{
319146822Sharti	ensure_workdir
320146822Sharti	ensure_run
321145620Sharti
322146822Sharti	if [ -z "${TEST_N}" ] ; then
323146822Sharti		TEST_N=1
324145620Sharti	fi
325146822Sharti
326146822Sharti	echo "1..${TEST_N}"
327146822Sharti	N=1
328146822Sharti	while [ ${N} -le ${TEST_N} ] ; do
329146855Sharti		fail=
330146855Sharti		todo=
331263082Sjmmv		skip=
332146855Sharti		if ! skip_test ${N} ; then
333146855Sharti			do_compare stdout ${N} || fail="${fail}stdout "
334146855Sharti			do_compare stderr ${N} || fail="${fail}stderr "
335146855Sharti			do_compare status ${N} || fail="${fail}status "
336146855Sharti			eval todo=\${TEST_${N}_TODO}
337263082Sjmmv		else
338263082Sjmmv			eval skip=\${TEST_${N}_SKIP}
339146822Sharti		fi
340263346Sjmmv		msg=
341146855Sharti		if [ ! -z "$fail" ]; then
342263346Sjmmv			msg="${msg}not "
343146855Sharti		fi
344263346Sjmmv		msg="${msg}ok ${N} ${SUBDIR}/${N}"
345263082Sjmmv		if [ ! -z "$fail" -o ! -z "$todo" -o ! -z "$skip" ]; then
346263346Sjmmv			msg="${msg} # "
347146855Sharti		fi
348263082Sjmmv		if [ ! -z "$skip" ] ; then
349263346Sjmmv			msg="${msg}skip ${skip}; "
350263082Sjmmv		fi
351146855Sharti		if [ ! -z "$todo" ] ; then
352263346Sjmmv			msg="${msg}TODO ${todo}; "
353146855Sharti		fi
354146855Sharti		if [ ! -z "$fail" ] ; then
355263346Sjmmv			msg="${msg}reason: ${fail}"
356146855Sharti		fi
357263346Sjmmv		echo ${msg}
358146822Sharti		N=$((N + 1))
359146822Sharti	done
360145620Sharti}
361145620Sharti
362145620Sharti#
363146822Sharti# Check if the test result is the same as the expected result.
364145620Sharti#
365146822Sharti# $1	Input file
366146822Sharti# $2	Test number
367146822Sharti#
368146822Shartido_compare()
369145620Sharti{
370146822Sharti	local EXPECTED RESULT
371263346Sjmmv	EXPECTED="${SRC_DIR}/expected.$1.$2"
372146822Sharti	RESULT="${OUTPUT_DIR}/$1.$2"
373145620Sharti
374146822Sharti	if [ -f $EXPECTED ]; then
375263346Sjmmv		cat $RESULT | sed -e "s,^$(basename $MAKE_PROG):,make:," | \
376263346Sjmmv		diff -u $EXPECTED -
377263346Sjmmv		#diff -q $EXPECTED - 1>/dev/null 2>/dev/null
378146822Sharti		return $?
379145620Sharti	else
380146822Sharti		return 1	# FAIL
381145620Sharti	fi
382145620Sharti}
383145620Sharti
384145620Sharti#
385146822Sharti# Diff current and expected results
386145620Sharti#
387146822Shartieval_diff()
388145620Sharti{
389146822Sharti	ensure_workdir
390146822Sharti	ensure_run
391146822Sharti
392146822Sharti	if [ -z "${TEST_N}" ] ; then
393146822Sharti		TEST_N=1
394146822Sharti	fi
395146822Sharti
396146822Sharti	N=1
397146822Sharti	while [ ${N} -le ${TEST_N} ] ; do
398146855Sharti		if ! skip_test ${N} ; then
399146822Sharti			FAIL=
400146822Sharti			do_diff stdout ${N}
401146822Sharti			do_diff stderr ${N}
402146822Sharti			do_diff status ${N}
403146822Sharti		fi
404146822Sharti		N=$((N + 1))
405146822Sharti	done
406145620Sharti}
407145620Sharti
408145620Sharti#
409146822Sharti# Check if the test result is the same as the expected result.
410145620Sharti#
411146822Sharti# $1	Input file
412146822Sharti# $2	Test number
413146822Sharti#
414146822Shartido_diff()
415145620Sharti{
416146822Sharti	local EXPECTED RESULT
417263346Sjmmv	EXPECTED="${SRC_DIR}/expected.$1.$2"
418146822Sharti	RESULT="${OUTPUT_DIR}/$1.$2"
419146822Sharti
420146822Sharti	echo diff -u $EXPECTED $RESULT
421146822Sharti	if [ -f $EXPECTED ]; then
422146822Sharti		diff -u $EXPECTED $RESULT
423146822Sharti	else
424146822Sharti		echo "${EXPECTED} does not exist"
425145620Sharti	fi
426145620Sharti}
427145620Sharti
428145620Sharti#
429146822Sharti# Update expected results
430145620Sharti#
431146822Shartieval_update()
432145620Sharti{
433146822Sharti	ensure_workdir
434146822Sharti	ensure_run
435146822Sharti
436146822Sharti	if [ -z "${TEST_N}" ] ; then
437146822Sharti		TEST_N=1
438146822Sharti	fi
439146822Sharti
440146822Sharti	FAIL=
441146822Sharti	N=1
442146822Sharti	while [ ${N} -le ${TEST_N} ] ; do
443146855Sharti		if ! skip_test ${N} ; then
444146822Sharti			cp ${OUTPUT_DIR}/stdout.${N} expected.stdout.${N}
445146822Sharti			cp ${OUTPUT_DIR}/stderr.${N} expected.stderr.${N}
446146822Sharti			cp ${OUTPUT_DIR}/status.${N} expected.status.${N}
447146822Sharti		fi
448146822Sharti		N=$((N + 1))
449146822Sharti	done
450145620Sharti}
451145620Sharti
452145620Sharti#
453146822Sharti# Print description
454145620Sharti#
455146822Shartieval_desc()
456145620Sharti{
457146822Sharti	echo "${SUBDIR}: ${DESC}"
458145620Sharti}
459145620Sharti
460145620Sharti#
461145620Sharti# Run the test
462145620Sharti#
463146822Shartieval_test()
464145620Sharti{
465146822Sharti	eval_setup
466146822Sharti	eval_run
467145620Sharti	eval_compare
468145620Sharti}
469145620Sharti
470145620Sharti#
471146822Sharti# Run the test for prove(1)
472145620Sharti#
473146822Shartieval_prove()
474145620Sharti{
475146822Sharti	eval_setup
476146822Sharti	eval_run
477146822Sharti	eval_compare
478146822Sharti	eval_clean
479145620Sharti}
480145620Sharti
481145620Sharti#
482146822Sharti# Main function. Execute the command(s) on the command line.
483145620Sharti#
484145620Shartieval_cmd()
485145620Sharti{
486145620Sharti	if [ $# -eq 0 ] ; then
487146822Sharti		# if no arguments given default to 'prove'
488146822Sharti		set -- prove
489145620Sharti	fi
490145620Sharti
491263082Sjmmv	if ! make_is_fmake ; then
492263082Sjmmv		for i in $(jot ${TEST_N:-1}) ; do
493263082Sjmmv			eval TEST_${i}_SKIP=\"make is not fmake\"
494263082Sjmmv		done
495263082Sjmmv	fi
496263082Sjmmv
497146822Sharti	for i
498146822Sharti	do
499146822Sharti		case $i in
500146822Sharti
501146822Sharti		setup | run | compare | diff | clean | reset | show | \
502146822Sharti		test | prove | desc | update)
503146822Sharti			eval eval_$i
504146822Sharti			;;
505146822Sharti		* | help)
506146822Sharti			print_usage
507146822Sharti			;;
508146822Sharti		esac
509146822Sharti	done
510145620Sharti}
511145620Sharti
512146822Sharti##############################################################################
513145620Sharti#
514146822Sharti# Main code
515146822Sharti#
516146822Sharti
517146822Sharti#
518145620Sharti# Determine our sub-directory. Argh.
519145620Sharti#
520263346SjmmvSRC_DIR=$(dirname $0)
521263346SjmmvSRC_BASE=`cd ${SRC_DIR} ; while [ ! -f common.sh ] ; do cd .. ; done ; pwd`
522145620ShartiSUBDIR=`echo ${SRC_DIR} | sed "s@${SRC_BASE}/@@"`
523145620Sharti
524146822Sharti#
525146822Sharti# Construct working directory
526146822Sharti#
527263346SjmmvWORK_DIR=$(pwd)/work/${SUBDIR}
528146822ShartiOUTPUT_DIR=${WORK_DIR}.OUTPUT
529146822Sharti
530146822Sharti#
531146822Sharti# Make to use
532146822Sharti#
533145620ShartiMAKE_PROG=${MAKE_PROG:-/usr/bin/make}
534