run-tests.sh revision 1.1.1.1
1#!/bin/sh
2
3usage() {
4	cat <<-EOF
5	Usage: $0 [-rs] [-rj <board>] [-rh <board ip>] [tests]
6
7	If no tests are specified, all tests are processed.
8
9	Options:
10	  -rs          Run on simulator
11	  -rj <board>  Run on board via JTAG
12	  -rh <ip>     Run on board ip
13	  -j <num>     Num jobs to run
14	EOF
15	exit ${1:-1}
16}
17
18: ${MAKE:=make}
19boardip=
20boardjtag=
21run_sim=false
22run_jtag=false
23run_host=false
24jobs=`getconf _NPROCESSORS_ONLN 2>/dev/null || echo 1`
25: $(( jobs += 1 ))
26while [ -n "$1" ] ; do
27	case $1 in
28		-rs) run_sim=true;;
29		-rj) boardjtag=$2; shift; run_jtag=true;;
30		-rh) boardip=$2; shift; run_host=true;;
31		-j)  jobs=$2; shift;;
32		-*)  usage;;
33		*)   break;;
34	esac
35	shift
36done
37${run_jtag} || ${run_host} || ${run_sim} || run_sim=true
38
39if ${run_host} && [ -z "${boardip}" ] ; then
40	usage
41fi
42
43cd "${0%/*}" || exit 1
44
45dorsh() {
46	# rsh sucks and does not pass up its exit status, so we have to:
47	#  on board:
48	#    - send all output to stdout
49	#    - send exit status to stderr
50	#  on host:
51	#    - swap stdout and stderr
52	#    - pass exit status to `exit`
53	#    - send stderr back to stdout and up
54	(exit \
55		$(rsh -l root $boardip \
56			'(/tmp/'$1') 2>&1; ret=$?; echo $ret 1>&2; [ $ret -eq 0 ] && rm -f /tmp/'$1 \
57			3>&1 1>&2 2>&3) \
58		2>&1) 2>&1
59}
60
61dojtag() {
62	if grep -q CHECKREG ${1%.x} ; then
63		echo "DBGA does not work via JTAG"
64		exit 77
65	fi
66
67	cat <<-EOF > commands
68		target remote localhost:2000
69		load
70
71		b *_pass
72		commands
73		exit 0
74		end
75
76		b *_fail
77		commands
78		exit 1
79		end
80
81		# we're executing at EVT1, so this doesn't really help ...
82		set ((long *)0xFFE02000)[3] = _fail
83		set ((long *)0xFFE02000)[5] = _fail
84
85		c
86	EOF
87	bfin-elf-gdb -x commands "$1"
88	ret=$?
89	rm -f commands
90	exit ${ret}
91}
92
93testit() {
94	local name=$1 x=$2 y=`echo $2 | sed 's:\.[xX]$::'` out rsh_out addr
95	shift; shift
96	local fail=`grep xfail ${y}`
97	if [ "${name}" = "HOST" -a ! -f $x ] ; then
98		return
99	fi
100	printf '%-5s %-40s' ${name} ${x}
101	out=`"$@" ${x} 2>&1`
102	(pf "${out}")
103	if [ $? -ne 0 ] ; then
104		if [ "${name}" = "SIM" ] ; then
105			tmp=`echo ${out} | awk '{print $3}' | sed 's/://'`
106			tmp1=`expr index "${out}" "program stopped with signal 4"`
107			if [ ${tmp1} -eq 1 ] ; then
108				 printf 'illegal instruction\n'
109			elif [ -n "${tmp}" ] ; then
110				printf 'FAIL at line '
111				addr=`echo $out | sed 's:^[A-Za-z ]*::' | sed 's:^0x[0-9][0-9] ::' | sed 's:^[A-Za-z ]*::' | awk '{print $1}'`
112				bfin-elf-addr2line -e ${x} ${addr} | awk -F "/" '{print $NF}'
113			fi
114		elif [ "${name}" = "HOST" ] ; then
115			rsh_out=`rsh -l root $boardip '/bin/dmesg -c | /bin/grep -e DBGA -e "FAULT "'`
116			tmp=`echo ${rsh_out} | sed 's:\].*$::' | awk '{print $NF}' | awk -F ":" '{print $NF}'`
117			if [ -n "${tmp}" ] ; then
118				echo "${rsh_out}"
119				printf 'FAIL at line '
120				bfin-elf-addr2line -e ${x} $(echo ${rsh_out} | sed 's:\].*$::' | awk '{print $NF}') | awk -F "/" '{print $NF}'
121			fi
122		fi
123		ret=$(( ret + 1 ))
124		if [ -z "${fail}" ] ; then
125			unexpected_fail=$(( unexpected_fail + 1 ))
126			echo "!!!Expected Pass, but fail"
127		fi
128	else
129		if [ ! -z "${fail}" ] ; then
130			unexpected_pass=$(( unexpected_pass + 1 ))
131			echo "!!!Expected fail, but pass"
132		else
133			expected_pass=$(( expected_pass + 1 ))
134		fi
135	fi
136}
137
138pf() {
139	local ret=$?
140	if [ ${ret} -eq 0 ] ; then
141		echo "PASS"
142	elif [ ${ret} -eq 77 ] ; then
143		echo "SKIP $*"
144	else
145		echo "FAIL! $*"
146		exit 1
147	fi
148}
149
150[ $# -eq 0 ] && set -- *.[Ss]
151bins_hw=$( (${run_sim} || ${run_jtag}) && printf '%s.x ' "$@")
152if ${run_host} ; then
153	for files in "$@" ; do
154		tmp=`grep -e CYCLES -e TESTSET -e CLI -e STI -e RTX -e RTI -e SEQSTAT $files -l`
155		if [ -z "${tmp}" ] ; then
156			bins_host=`echo "${bins_host} ${files}.X"`
157		else
158			echo "skipping ${files}, since it isn't userspace friendly"
159		fi
160	done
161fi
162if [ -n "${bins_hw}" ] ; then
163	bins_all="${bins_hw}"
164fi
165
166if [ -n "${bins_host}" ] ; then
167	bins_all="${bins_all} ${bins_host}"
168fi
169
170if [ -z "${bins_all}" ] ; then
171	exit
172fi
173
174printf 'Compiling tests: '
175${MAKE} -s -j ${bins_all}
176pf
177
178if ${run_jtag} ; then
179	printf 'Setting up gdbproxy (see gdbproxy.log): '
180	killall -q bfin-gdbproxy
181	bfin-gdbproxy -q bfin --reset --board=${boardjtag} --init-sdram >gdbproxy.log 2>&1 &
182	t=0
183	while [ ${t} -lt 5 ] ; do
184		if netstat -nap 2>&1 | grep -q ^tcp.*:2000.*gdbproxy ; then
185			break
186		else
187			: $(( t += 1 ))
188			sleep 1
189		fi
190	done
191	pf
192fi
193
194if ${run_host} ; then
195	printf 'Uploading tests to board "%s": ' "${boardip}"
196	rcp ${bins_host} root@${boardip}:/tmp/
197	pf
198	rsh -l root $boardip '/bin/dmesg -c' > /dev/null
199fi
200
201SIM="../../../bfin/run"
202if [ ! -x ${SIM} ] ; then
203	SIM="bfin-elf-run"
204fi
205echo "Using sim: ${SIM}"
206
207ret=0
208unexpected_fail=0
209unexpected_pass=0
210expected_pass=0
211pids=()
212for s in "$@" ; do
213	(
214	out=$(
215	${run_sim}  && testit SIM  ${s}.x ${SIM} `sed -n '/^# sim:/s|^[^:]*:||p' ${s}`
216	${run_jtag} && testit JTAG ${s}.x dojtag
217	${run_host} && testit HOST ${s}.X dorsh
218	)
219	case $out in
220	*PASS*) ;;
221	*) echo "$out" ;;
222	esac
223	) &
224	pids+=( $! )
225	if [[ ${#pids[@]} -gt ${jobs} ]] ; then
226		wait ${pids[0]}
227		pids=( ${pids[@]:1} )
228	fi
229done
230wait
231
232killall -q bfin-gdbproxy
233if [ ${ret} -eq 0 ] ; then
234	rm -f gdbproxy.log
235#	${MAKE} -s clean &
236	exit 0
237else
238	echo number of failures ${ret}
239	if [ ${unexpected_pass} -gt 0 ] ; then
240		echo "Unexpected passes: ${unexpected_pass}"
241	fi
242	if [ ${unexpected_fail} -gt 0 ] ; then
243		echo "Unexpected fails: ${unexpected_fail}"
244	fi
245	if [ ${expected_pass} -gt 0 ] ; then
246		echo "passes : ${expected_pass}"
247	fi
248	exit 1
249fi
250