#!/bin/bash # Library for acctest acceptance tests done by ssh/rsh access to the target # To be sourced at beginning of tests/acctest bash script # # 2007-08, 2008-06 jfr@pengutronix.de # Choose the communication method: 'ssh' or 'rsh' SSH_COMMAND_DEFAULT='rsh' SSH_COMMAND=${SSH_COMMAND:-${SSH_COMMAND_DEFAULT}} LOGFILE="${PTXDIST_WORKSPACE}/test${PTXDIST_PLATFORMSUFFIX}.log" REPORTFILE="${PTXDIST_WORKSPACE}/test${PTXDIST_PLATFORMSUFFIX}.report" TESTRUNDIRBASE="${PTXDIST_WORKSPACE}/results/result${PTXDIST_PLATFORMSUFFIX}" [ -d "$TESTRUNDIRBASE" ] || mkdir -p "$TESTRUNDIRBASE" RED='\0033[1;31m' GREEN='\0033[1;32m' BLUE='\0033[1;34m' NC='\0033[0m' # No Color OKSTRING="OK" FAILSTRING="FAILED" ok_count=0 fail_count=0 testseq=0 datenohyphen=$(date +%Y%m%d) lastrundir=$(find ${TESTRUNDIRBASE} -name "${datenohyphen}-*" -printf "%P\n" | sort | tail -n1) # when empty, set to "newdate", so that the -d test below will turn out negative => testrunseq="0001" lastrundir=${lastrundir:-"newdate"} if [ -d "${TESTRUNDIRBASE}/${lastrundir}" ] then # create a new dir with testrun sequence one up oldtestrunseq=${lastrundir/"${datenohyphen}-"/} # remove leading zeros and add 1 with bc, then add leading zeros testrunseq=$(printf "%04d" $(echo "$oldtestrunseq+1" | bc)) else testrunseq="0001" fi TESTRUNDIR="${TESTRUNDIRBASE}/${datenohyphen}-${testrunseq}" mkdir -p "${TESTRUNDIR}" reportwrite() { case "$1" in 'checking') echo "$2" >> "$REPORTFILE" ;; 'remote') echo "$2" >> "$REPORTFILE" echo "[remote]" > "${TESTDIR}/cmdline" echo "$2" >> "${TESTDIR}/cmdline" ;; 'host') echo "$2" >> "$REPORTFILE" echo "[host]" > "${TESTDIR}/cmdline" echo "$2" >> "${TESTDIR}/cmdline" ;; 'compare') echo "$2" >> "$REPORTFILE" ;; 'boolresult') if [ "$2" = "true" ]; then echo "${OKSTRING}" >> "$REPORTFILE" echo "${OKSTRING}" > "${TESTDIR}/result" fi if [ "$2" = "false" ]; then echo "${FAILSTRING}" >> "$REPORTFILE" echo "${FAILSTRING}" > "${TESTDIR}/result" fi ;; 'stdout') echo "" >> "$REPORTFILE" echo "$2" >> "$REPORTFILE" echo "$2" > "${TESTDIR}/stdout" echo "" >> "$REPORTFILE" ;; 'exitstatus') echo "$2" >> "$REPORTFILE" echo "$2" > "${TESTDIR}/exitstatus" ;; 'time') if [ $2 = "begin" ] then echo "$(date -u +%FT%T.%3NZ)" >> "$REPORTFILE" echo "$(date -u +%FT%T.%3NZ)" > "${TESTDIR}/starttime" fi if [ $2 = "end" ] then echo "$(date -u +%FT%T.%3NZ)" >> "$REPORTFILE" echo "$(date -u +%FT%T.%3NZ)" > "${TESTDIR}/endtime" fi ;; *) echo "Error: No or wrong action given in reportwrite call in $0" >> "$LOGFILE" false esac } report_begin() { echo "" > "$REPORTFILE" } report_end() { echo "" >> "$REPORTFILE" cp "$REPORTFILE" "$TESTRUNDIRBASE/test${PTXDIST_PLATFORMSUFFIX}-${datenohyphen}-${testrunseq}.report" } test_begin() { (( testseq++ )) local testname=${FUNCNAME[1]/"acctest_"} local testseqstring=$(printf "%04d" $testseq) echo "" >> "$REPORTFILE" TESTDIR="${TESTRUNDIR}/${testseqstring}-$testname" if [ ! -e "${TESTDIR}" ] then mkdir -p "${TESTDIR}" else echo "Directory \"${TESTDIR}\" already exists. Something is going wrong." >&2 fi reportwrite time begin } test_end() { local ret="$?" reportwrite time end echo "" >> "$REPORTFILE" if [ "$exit_now" = "1" ]; then exit 1; fi return "${ret}" } checking() { printf "%-71s" "checking $1" >&2 reportwrite checking "$1" } result_ok() { printf "%8b" "[${GREEN} OK ${NC}]\n" >&2 reportwrite boolresult true (( ok_count++ )) } result_fail() { printf "%8b" "[${RED}FAILED${NC}]\n" >&2 reportwrite boolresult false (( fail_count++ )) } result() { if [ "$?" = "0" ]; then result_ok return 0 else result_fail if [ "$1" = "fatal" ]; then printf "%8b" "${RED}Fatal. Cannot continue.${NC}\n" >&2 exit_now="1" # actually exiting is done in test_end fi return 1 fi } # # functions acting on target # remote() { case "$SSH_COMMAND" in 'ssh') echo "ssh -q -o StrictHostKeyChecking=no -l root ${PTXCONF_BOARDSETUP_TARGETIP} \"$1\"" >> "$LOGFILE" local stdoutret=$(ssh -q -o StrictHostKeyChecking=no -l root ${PTXCONF_BOARDSETUP_TARGETIP} "$1"'; echo ret=$?') 2>> "$LOGFILE" ;; 'rsh') echo "rsh -l root ${PTXCONF_BOARDSETUP_TARGETIP} \"$1\"" >> "$LOGFILE" local stdoutret=$(rsh -l root ${PTXCONF_BOARDSETUP_TARGETIP} "$1"'; echo ret=$?') 2>> "$LOGFILE" ;; *) echo "Error: No or wrong remote-shell command defined in test script $0" >> "$LOGFILE" false esac reportwrite remote "$1" local stdout=$(echo "$stdoutret" | head -n-1) local retvalline=$(echo "$stdoutret" | tail -n1) if [ "${retvalline:0:4}" = "ret=" ] then # The "ret=" is on a line of its own local retvallinestdoutpart="" local retvallineretpart="" else # There was no newline before "ret=" local retvallineretpart=$(expr "$retvalline" : '.*\(ret=.*\)') local retvallinestdoutpart="${retvalline%$retvallineretpart}" retvalline="$retvallineretpart" fi echo "$stdout" echo -n "$retvallinestdoutpart" reportwrite stdout "${stdout}${retvallinestdoutpart}" reportwrite exitstatus ${retvalline:4} return ${retvalline:4} } host() { local stdout echo "${1}" >> "$LOGFILE" reportwrite host "${1}" stdout=$(eval ${1}; exit ${?}) 2>>"$LOGFILE" local retval=${?} reportwrite stdout "${stdout}" reportwrite exitstatus ${retval} echo "$stdout" return ${retval} } remote_compare() { echo "test \"\$\(remote \"$1\"\)\" = \"$2\"" >> "$LOGFILE" local ret=$(remote "$1") 2>> "$LOGFILE" reportwrite compare "$2" test "$ret" = "$2" 2>> "$LOGFILE" } remote_assure_module() { # This should not be used as an indicator for functionality: # Don't just check on loaded modules; rather check their indirect signs of operationality. echo "remote \"lsmod | grep \\\"^$1 \\\"\"" >> "$LOGFILE" local ret=$(remote "lsmod | grep \"^$1 \"") 2>> "$LOGFILE" test "${ret:0:${#1}}" = "$1" 2>> "$LOGFILE" } remote_busyboxps() { if [ -z $BUSYBOX ] then local bbtest=$(remote "ps --help 2>&1 | grep ^BusyBox") 2>> "$LOGFILE" test "${bbtest:0:7}" = "BusyBox" BUSYBOX=$? fi return $BUSYBOX } remote_assure_process() { if remote_busyboxps then #put brackets around the first char of search string, so grep won't hit its own pid local lookfor="[${1:0:1}]${1:1}" echo "remote \"ps | grep $lookfor\"" >> "$LOGFILE" local ret=$(remote "ps | grep $lookfor") 2>> "$LOGFILE" echo "$ret" | grep "$1[$ ]" 2>> "$LOGFILE" else echo "remote \"ps axo s,comm | grep \\\"^S $1\\\"\"" >> "$LOGFILE" local ret=$(remote "ps axo s,comm | grep \"^S $1\"") 2>> "$LOGFILE" test "${ret:2:${#1}}" = "$1" 2>> "$LOGFILE" fi } remote_file() { case "$2" in 'block') echo "remote \"test -b $1\"" >> "$LOGFILE" remote "test -b \"$1\"" 2>> "$LOGFILE" ;; 'character') echo "remote \"test -c $1\"" >> "$LOGFILE" remote "test -c \"$1\"" 2>> "$LOGFILE" ;; 'exists') echo "remote \"test -e $1\"" >> "$LOGFILE" remote "test -e \"$1\"" 2>> "$LOGFILE" ;; 'executable') echo "remote \"test -x $1\"" >> "$LOGFILE" remote "test -x \"$1\"" 2>> "$LOGFILE" ;; *) echo "Syntax error in test script $0" >> "$LOGFILE" false esac } all_on_board() { if test "$SSH_COMMAND" = "rsh" then test_begin checking "for local real rsh availability" # not all 'rsh' of this world starting a sentence with lower case rsh 2>&1 | grep -q "sage: rsh" result fatal test_end fi if test "$SSH_COMMAND" = "ssh" then test_begin checking "for local ssh availability" ssh 2>&1 | grep -q "usage: ssh" result fatal test_end fi test_begin checking "for grep on target" remote_file "/bin/grep" executable 2>> "$LOGFILE" result fatal test_end test_begin checking "for regular ps on target" remote 'ps --help all | grep -q -e "-o"' 2>> "$LOGFILE" result fatal test_end } write_to_log() { echo "$1" >> "$LOGFILE" }