#! /usr/bin/env bash # # Framework script tailored for the @CPU@/@BSP@ # # NOTE: If the does not have the name of a specific CPU/BSP pair, then # this is the source file. If it does have specific CPU/BSP pair, # then this is generated output and should NOT be edited. # trap "test_exit 1" 1 2 3 13 14 15 inGDBScript=no test_exit() { exit_code=$1 exit $exit_code } progname=${0##*/} # fast basename hack for ksh, bash USAGE=\ "usage: $progname [ -opts ] test [ test ... ] -v -- verbose -c -- enabled coverage (default=no) -C -- cat test output if not interactive (default=no) -g -- generate device tree and exit (default=no) -D -- enable use of display adapter (default=no) -N -- enable use of network adapter (default=no) -T -- specify TAP network interface (none by default) -G -- put simulator in GDB server mode (default=no) -i -- interactive (default=no time limit) -p cores -- number of cores for SMP -s -- force System V IPC support (default=no) -S -- skip Interrupt Critical Section Tests (default=no) -l limit -- specify time limit (default is 'BSP dependent') -L dir -- specify log directory (default is 'log') NOTES: + Most simulators do not support multicore support. + System V IPC and Coverage are not supported by all BSPs or simulators. + GDB Server mode is only supported by stand-along simulators. + When you generate a device tree and exit, remember to specify an executable. Otherwise, the script won't know what to generate it for. " # log an error to stderr prerr() { echo "$*" >&2 } fatal() { [ "$1" ] && prerr $* prerr "$USAGE" exit 1 } warn() { [ "$1" ] && prerr $* } check_status() { if [ $1 -ne 0 ] ; then shift echo "FAILED: " "$*" >&2 exit 1 fi } # # process the options # # defaults for getopt vars # doCatOutput="no" coverage="no" verbose="no" defaultLimit="not_set" interactive="no" gdb_server_mode="no" use_sysv_ipc="no" generate_tree_and_exit="no" logdir="log" doTrace="no" enable_display_adapter="no" enable_network="no" tap_network_interface="" skip_interrupt_critical_section_tests="no" number_of_cores= while getopts "vcCgGil:L:p:DsNT:" OPT do case "$OPT" in v) verbose="yes";; c) coverage="yes";; C) doCatOutput="yes";; D) enable_display_adapter="yes";; g) generate_tree_and_exit="yes" ;; G) gdb_server_mode="yes" ;; N) enable_network="yes" ;; T) tap_network_interface="$OPTARG" ;; i) interactive="yes";; l) defaultLimit="$OPTARG";; L) logdir="$OPTARG";; p) number_of_cores="$OPTARG";; s) use_sysv_ipc="yes";; S) skip_interrupt_critical_section_tests="yes";; t) doTrace="yes";; *) fatal;; esac done shiftcount=`expr $OPTIND - 1` shift $shiftcount args=$* case ${number_of_cores} in "");; [1-9]) ;; [1-9][0-9]) ;; 0) echo "Zero cores does not make sense" exit 1 ;; *) echo "Cores specified (${number_of_cores}) is either not a valid" echo " number or supported quantity." exit 1 esac if [ ${interactive} = "yes" ] ; then defaultLimit=0 else if [ ! -d ${logdir} ] ; then mkdir $logdir || fatal "could not create log directory ($logdir)" fi fi ### Set BSP defaults. If BSP does not have default, it will override bspGeneratesDeviceTree="no" bspSupportsSystemVIPC="no" bspUsesGDBSimulator="yes" bspNeedsDos2Unix="no" bspSimTrustedToExit="no" bspSupportsGDBServerMode="no" bspSupportsDisplayAdapter="no" bspSupportsNIC="no" bspNeedsSttySane="yes" bspNeedsTraceConversion="no" bspRunsFailRandomly="no" bspInputDevice=/dev/console bspRedirectInput=no bspSkipInterruptCriticalSectionTests="no" bspSupportsSMP="no" for v in 4.11 4.10 4.9 4.8 4.7 "" do type @CPU_TARGET@-rtems${v}-run >/dev/null 2>&1 if [ $? -eq 0 ] ; then defaultRUN=@CPU_TARGET@-rtems${v}-run break fi done test ${verbose} = "yes" && echo Default program to run is ${defaultRUN} runBSP=${defaultRUN} ################################################################### ################################################################### ################################################################### ##INSERT BSP SUPPORT HERE ################################################################### ################################################################### ################################################################### if [ ${bspSupportsSystemVIPC} = "no" -a ${use_sysv_ipc} = "yes" ]; then echo "Simulator does not support System V IPC." exit 1 fi if [ ${bspSupportsNIC} = "no" -a ${enable_network} = "yes" ]; then echo "Simulator does not support a Network Interface Controller." exit 1 fi if [ ${bspSupportsDisplayAdapter} = "no" -a \ ${enable_display_adapter} = "yes" ]; then echo "Simulator does not support Graphics Display Adapter." exit 1 fi if [ ${bspSupportsSMP} = "no" -a ${number_of_cores:-1} != 1 ] ; then echo "Simulator does not support multiple cores." exit 1 fi if [ X${runBSP} = X ] ; then echo "Unable to find a way to run @CPU_TARGET@/@BSP@" exit 1 fi test ${verbose} = "yes" && echo Using ${runBSP} type ${runBSP} check_status $? "Path appears to be broken (cannot find ${runBSP})" killpid() { pid=$1 kill -2 $pid 2> /dev/null if [ ${coverage} = "yes" ] ; then sleep 1 else usleep 1000 fi kill -9 $pid 2> /dev/null } ## These are faults any BSP may generate. They are common to RTEMS. checkGenericExits() { logfile=$1 ## Clean exit patterns -- delay for coverage to get written for pattern in \ "^\*\*\* END OF " \ "^.*EXECUTIVE SHUTDOWN" \ "^assertion .* failed: file .*, line .*, function:" \ "\*\*\*.*FAILED.*\*\*\*" \ "===.*PASSED.*===" \ "^raised .*_ERROR" \ "FAULTY THREAD WILL BE " \ "\*\*\* EXIT code " do grep "${pattern}" ${logfile} >/dev/null 2>&1 if [ $? -eq 0 ] ; then if [ ${coverage} = "yes" ] ; then # give the simulator a chance to write the coverage # ASSUME: It will exit # TODO: Add timeout logic here while : do kill -0 $pid 2> /dev/null running=$? if [ $running -eq 0 ] ; then killpid ${pid} else return 1 fi done fi return 1 fi done ## Error exit patterns -- should not happen on coverage runs for pattern in \ "Suspending faulting task" \ "assertion failed" do grep "${pattern}" ${logfile} >/dev/null 2>&1 if [ $? -eq 0 ] ; then return 1 fi done return 0 } catLog() { logfile=${1} if [ ${doCatOutput} = "no" ] ; then return fi if [ ${bspNeedsDos2Unix} = "yes" ] ; then dos2unix ${logfile} fi tr -d "\015" <${logfile} echo } get_tname() { echo $1 | grep "exe$" >/dev/null if [ $? -eq 0 ] ; then ext=.exe else ext=.ralf fi tfile=`basename $1` echo `basename $tfile ${ext}` } runtest() { testname=${1} testtype=${2} max_run_time=${3} # Just in case the simulator aborts and messes up the terminal trap "test ${bspNeedsSttySane} = yes && stty sane 2>/dev/null" SIGABRT return test ${verbose} == 'yes' && echo ${runBSP} `runARGS ${testname}` if [ ${max_run_time} -eq 0 ] ; then #echo run ${testname} forever if [ ${bspRedirectInput} = yes ] ; then ${runBSP} `runARGS ${testname}` <${bspInputDevice} else ${runBSP} `runARGS ${testname}` fi return fi echo $testname | grep "exe$" >/dev/null tname=`get_tname $testname` logfile=${logdir}/${tname} if [ ${bspSimTrustedToExit} = "yes" ] ; then if [ ${bspRedirectInput} = yes ] ; then ${runBSP} `runARGS ${testname}` <${bspInputDevice} >${logfile} 2>&1 else ${runBSP} `runARGS ${testname}` >${logfile} 2>&1 fi catLog ${logfile} return fi if [ ${bspRedirectInput} = yes ] ; then ${runBSP} `runARGS ${testname}` <${bspInputDevice} >${logfile} 2>&1 & else ${runBSP} `runARGS ${testname}` >${logfile} 2>&1 & fi pid=$! # Make sure it won't run forever... millilimit=`expr ${max_run_time} \* 1000` milliseconds=0 echo -n "running ${testname} for maximum ${max_run_time} seconds... " while : do # sleep 50ms at a time waiting for job to finish or timer to expire # if job has exited, then we exit, too. usleep 50000 # fifty milliseconds milliseconds=`expr ${milliseconds} + 50` kill -0 $pid 2> /dev/null running=$? if [ $running -eq 0 ] ; then if [ ${milliseconds} -ge ${millilimit} ]; then killpid ${pid} echo -n "killed due to over time... " break fi if [ ! -r ${logfile} ] ; then continue fi # check for BSP specific messages which indicate program ended checkBSPFaults ${logfile} >/dev/null 2>&1 if [ $? -ne 0 ] ; then killpid ${pid} echo -n "killed due to BSP fault... " break fi # check for cross platform messages which indicate program ended checkGenericExits ${logfile} #>/dev/null 2>&1 if [ $? -ne 0 ] ; then killpid ${pid} echo -n "killed due to generic exit... " break fi else # done normally break fi done catLog ${logfile} echo "${milliseconds} ms run time" } if [ "X${args}" = "X" ] ; then echo no tests to run exit 1 fi ## Now run the tests test ${verbose} = "yes" && \ echo TESTS TO RUN: ${args} for toRun in $args do baseToRun=`basename ${toRun}` case ${baseToRun} in *-node*) testtype="mp" ;; *) testtype="single" ;; esac # calculate the limit in case it is used by the simulator script if [ ${defaultLimit} = "not_set" ] ; then limit=`bspLimit ${toRun}` else limit=${defaultLimit} fi ## Some BSPs must generate device trees or scripts to provide to the simulator if [ ${bspGeneratesDeviceTree} = "yes" ] ; then bspGenerateDeviceTree ${baseToRun} ${toRun} >${bspTreeFile} if [ ${generate_tree_and_exit} = "yes" ] ; then echo "Device tree generated and in ${bspTreeFile}" exit 0 fi if [ ${verbose} = "yes" ] ; then echo "==================================================" cat ${bspTreeFile} echo "==================================================" fi fi if [ ${bspSupportsGDBServerMode} = "yes" -a ${gdb_server_mode} = "yes" ];then test ${verbose} == 'yes' && echo ${runBSP} `runARGS ${toRun}` ${runBSP} `gdbServerARGS ${toRun}` <${bspInputDevice} exit 0 fi if [ ${interactive} = "yes" ] ; then test ${verbose} = "yes" && \ echo INTERACTIVE runtest ${toRun} ${testtype} 0 runtest ${toRun} ${testtype} 0 continue fi ## If the test is known to be interactive or locks up and we are ## in batch mode, skip it. case ${baseToRun} in appstart*) warn "skipping intermediate file ${baseToRun}" continue ;; *-node2*) fatal "MP tests not supported" warn "Skipping ${baseToRun}; 'runtest' runs both nodes when for *-node1" continue ;; *-node1*) warn "Running both nodes associated with ${baseToRun}" ;; spintr*|psxintr*) if [ ${skip_interrupt_critical_section_tests} = "yes" -o \ ${bspSkipInterruptCriticalSectionTests} = "yes" ]; then warn "Skipping interrupt critical section test ${baseToRun}" continue fi ;; fileio.*|termios.*) warn "skipping interactive ${baseToRun}" continue ;; pppd*) warn "skipping long running ${baseToRun}" continue ;; esac test ${verbose} = "yes" && \ echo BACKGROUND runtest ${toRun} ${testtype} ${limit} runtest ${toRun} ${testtype} ${limit} # Some simulators fail to work correctly all the time. If this is one AND # the run looks like it did not work right, then run again until it does if [ ${bspRunsFailRandomly} = "yes" ] ; then tries=1 while [ `bspCheckRunWasOK` -eq 1 -a ${tries} -lt 3 ] do tries=`expr ${tries} + 1` echo "Rerunning ${toRun} due to random run failure (try=${tries})" runtest ${toRun} ${testtype} ${limit} done if [ ${tries} -eq 3 ] ; then echo "WARNING ${toRun} does not look like it had any output" fi fi # some BSPs produce trace oriented files which need to be converted # to object coverage maps if [ ${coverage} = "yes" -a ${bspNeedsTraceConversion} = "yes" ] ; then test ${verbose} = "yes" && echo Converting trace map for ${toRun} convertTraceToCoverageMap ${toRun} fi if [ ${bspGeneratesDeviceTree} = "yes" ] ; then rm -f ${bspTreeFile} fi done exit $?