mirror of
git://git.yoctoproject.org/poky.git
synced 2025-07-19 21:09:03 +02:00

To reduce the time on sanity testing, we remove variable SHARE_IMAGE and use a new variable TEST_SERIALIZE in local.conf. It is by default set to 1. Poky will copy and boot the to-be tested image for only once. It will not remove or kill the image and test cases will be serialized executed against the same image. If it is set to 0, image is always be copied for each cases, which takes much time. I had a experiment that latest qemuppc sato only takes 7 minutes to finish 9 sanity test cases, which takes more than 20 minutes before. I also removed sanity case "boot" from sato/sdk/lsb because the other cases for these targets already cover the check point of "boot". Signed-off-by Jiajun Xu <jiajun.xu@intel.com>
500 lines
11 KiB
Bash
500 lines
11 KiB
Bash
#!/bin/bash
|
|
# Common function for test
|
|
# Expect should be installed for SSH Testing
|
|
# To execute `runqemu`, NOPASSWD needs to be set in /etc/sudoers for user
|
|
# For example, for user "builder", /etc/sudoers can be like following:
|
|
# #########
|
|
# #Members of the admin group may gain root privileges
|
|
# %builder ALL=(ALL) NOPASSWD: NOPASSWD: ALL
|
|
# #########
|
|
#
|
|
# Author: Jiajun Xu <jiajun.xu@intel.com>
|
|
#
|
|
# This file is licensed under the GNU General Public License,
|
|
# Version 2.
|
|
#
|
|
|
|
TYPE="ext3"
|
|
|
|
# The folder to hold all scripts running on targets
|
|
TOOLS="$POKYBASE/scripts/qemuimage-tests/tools"
|
|
|
|
# Test Directory on target for testing
|
|
TARGET_TEST_DIR="/opt/test"
|
|
|
|
# Global variable for process id
|
|
PID=0
|
|
|
|
# Global variable for target ip address
|
|
TARGET_IPADDR=0
|
|
|
|
# common function for information print
|
|
Test_Error()
|
|
{
|
|
echo -e "\tTest_Error: $*"
|
|
}
|
|
|
|
Test_Info()
|
|
{
|
|
echo -e "\tTest_Info: $*"
|
|
}
|
|
|
|
# function to update target ip address
|
|
# $1 is the process id of the process, which starts the qemu target
|
|
# $2 is the ip address of the target
|
|
Test_Update_IPSAVE()
|
|
{
|
|
local pid=$1
|
|
local ip_addr=$2
|
|
|
|
if [ "$TEST_SERIALIZE" -eq 1 ]; then
|
|
echo "$pid $ip_addr" > $TARGET_IPSAVE
|
|
fi
|
|
}
|
|
|
|
# function to copy files from host into target
|
|
# $1 is the ip address of target
|
|
# $2 is the files, which need to be copied into target
|
|
# $3 is the path on target, where files are copied into
|
|
Test_SCP()
|
|
{
|
|
local ip_addr=$1
|
|
local src=$2
|
|
local des=$3
|
|
local tmpfile=`mktemp`
|
|
local timeout=60
|
|
local ret=0
|
|
|
|
# We use expect to interactive with target by ssh
|
|
local exp_cmd=`cat << EOF
|
|
eval spawn scp -o UserKnownHostsFile=$tmpfile "$src" root@$ip_addr:"$des"
|
|
set timeout $time_out
|
|
expect {
|
|
"*assword:" { send "\r"; exp_continue}
|
|
"*(yes/no)?" { send "yes\r"; exp_continue }
|
|
eof { exit [ lindex [wait] 3 ] }
|
|
}
|
|
EOF`
|
|
expect -c "$exp_cmd"
|
|
ret=$?
|
|
rm -rf $tmpfile
|
|
return $ret
|
|
}
|
|
|
|
# function to run command in $ip_addr via ssh
|
|
Test_SSH()
|
|
{
|
|
local ip_addr=$1
|
|
shift
|
|
local command=$@
|
|
local tmpfile=`mktemp`
|
|
local timeout=60
|
|
local ret=0
|
|
local exp_cmd=`cat << EOF
|
|
eval spawn ssh -o UserKnownHostsFile=$tmpfile root@$ip_addr "$command"
|
|
set timeout $time_out
|
|
expect {
|
|
"*assword:" { send "\r"; exp_continue}
|
|
"*(yes/no)?" { send "yes\r"; exp_continue }
|
|
eof { exit [ lindex [wait] 3 ] }
|
|
}
|
|
EOF`
|
|
expect -c "$exp_cmd"
|
|
ret=$?
|
|
rm -rf $tmpfile
|
|
return $ret
|
|
}
|
|
|
|
# function to check if ssh is up in $ip_addr
|
|
Test_SSH_UP()
|
|
{
|
|
local ip_addr=$1
|
|
local timeout=$2
|
|
local interval=0
|
|
|
|
# If TEST_SERIALIZE is set, use existing running qemu for testing
|
|
if [ ${TEST_SERIALIZE} -eq 1 -a -e ${TARGET_IPSAVE} ]; then
|
|
timeout=50
|
|
fi
|
|
|
|
while [ ${interval} -lt ${timeout} ]
|
|
do
|
|
Test_SSH ${ip_addr} "hostname"
|
|
if [ $? -ne 0 ]; then
|
|
interval=`expr $interval + 10`
|
|
sleep 10
|
|
else
|
|
Test_Info "We can ssh on ${ip_addr} within ${interval} seconds"
|
|
return 0
|
|
fi
|
|
|
|
done
|
|
|
|
Test_Info "We can not ssh on ${ip_addr} in ${timeout} seconds"
|
|
return 1
|
|
}
|
|
|
|
# function to prepare target test environment
|
|
# $1 is the ip address of target system
|
|
# $2 is the files, which needs to be copied into target
|
|
Test_Target_Pre()
|
|
{
|
|
local ip_addr=$1
|
|
local testscript=$2
|
|
|
|
# Create a pre-defined folder for test scripts
|
|
Test_SSH $ip_addr "mkdir -p $TARGET_TEST_DIR"
|
|
if [ $? -eq 0 ]; then
|
|
# Copy test scripts into target
|
|
Test_SCP $ip_addr $testscript $TARGET_TEST_DIR && return 0
|
|
else
|
|
Test_Error "Fail to create $TARGET_TEST_DIR on target"
|
|
return 1
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
# function to record test result in $TEST_RESULT/testresult.log
|
|
Test_Print_Result()
|
|
{
|
|
local PASS=0
|
|
local FAIL=0
|
|
local NORESULT=0
|
|
if [ $2 -eq 0 ]; then
|
|
PASS=1
|
|
elif [ $2 -eq 1 ]; then
|
|
FAIL=1
|
|
else
|
|
NORESULT=1
|
|
fi
|
|
|
|
# Format the output of the test result
|
|
echo -e "$1 $PASS $FAIL $NORESULT" | awk '{printf("\t"); for(i=1;i<=NF;i++) printf("%-15s",$i); printf("\n");}' >> $TEST_RESULT/testresult.log
|
|
}
|
|
|
|
# Test_Kill_Qemu to kill child pid with parent pid given
|
|
# $1 is qemu process id, which needs to be killed
|
|
Test_Kill_Qemu()
|
|
{
|
|
local ret=0
|
|
local ppid=0
|
|
local i=0
|
|
local index=0
|
|
local total=0
|
|
declare local pid
|
|
|
|
# Check if $1 pid exists and is a qemu process
|
|
ps -fp $PID | grep -iq "qemu"
|
|
|
|
# Find all children pid of the pid $1
|
|
if [ $? -eq 0 ]; then
|
|
|
|
# Check if there is any child pid of the pid $PID
|
|
ppid=$PID
|
|
ps -f --ppid $ppid
|
|
ret=$?
|
|
|
|
while [ $ret -eq 0 ]
|
|
do
|
|
# If yes, get the child pid and check if the child pid has other child pid
|
|
# Continue the while loop until there is no child pid found
|
|
pid[$i]=`ps -f --ppid $ppid | awk '{if ($2 != "PID") print $2}'`
|
|
ppid=${pid[$i]}
|
|
i=$((i+1))
|
|
ps -f --ppid $ppid
|
|
ret=$?
|
|
done
|
|
|
|
# When TEST_SERIALIZE is set, qemu process will not be
|
|
# killed until all the cases are finished
|
|
if [ ${TEST_SERIALIZE} -eq 1 -a -e ${TEST_STATUS} ]; then
|
|
index=`sed -n 2p ${TEST_STATUS} | awk '{print $3}'`
|
|
total=`sed -n 2p ${TEST_STATUS} | awk '{print $4}'`
|
|
if [ ${index} != ${total} ]; then
|
|
Test_Info "Do not kill the qemu process and use it for later testing"
|
|
Test_Update_IPSAVE $PID $TARGET_IPADDR
|
|
else
|
|
# If it is the last case, let's kill it
|
|
while [ $i -ne 0 ]
|
|
do
|
|
i=$((i-1))
|
|
kill ${pid[$i]}
|
|
sleep 2
|
|
done
|
|
|
|
# Kill the parent id
|
|
kill $PID
|
|
fi
|
|
|
|
else
|
|
# Kill these children pids from the last one
|
|
while [ $i -ne 0 ]
|
|
do
|
|
i=$((i-1))
|
|
kill ${pid[$i]}
|
|
sleep 2
|
|
done
|
|
|
|
# Kill the parent id
|
|
kill $PID
|
|
fi
|
|
fi
|
|
|
|
return
|
|
}
|
|
|
|
# function to check if there is any qemu process
|
|
Test_Check_Qemu_UP()
|
|
{
|
|
local count=`ps -eo command | cut -d " " -f 1 | grep -c "\(^qemu\|.*/qemu\)"`
|
|
if [ ${count} -lt 1 ]; then
|
|
Test_Info "There is no Qemu process"
|
|
return 1
|
|
else
|
|
Test_Info "There is at least one Qemu process running"
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
# function to check if network is up
|
|
Test_Check_IP_UP()
|
|
{
|
|
ping -c1 $1
|
|
if [ $? -ne 0 ]; then
|
|
Test_Info "IP $1 is not up"
|
|
return 1
|
|
else
|
|
Test_Info "IP $1 is up"
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
# function to find kernel/rootfs image
|
|
Test_Find_Image()
|
|
{
|
|
where=""
|
|
kernel=""
|
|
arch=""
|
|
target=""
|
|
extension=""
|
|
rootfs=""
|
|
|
|
while getopts "l:k:a:t:" Option
|
|
do
|
|
case $Option in
|
|
l) where="$OPTARG"
|
|
;;
|
|
k) kernel="$OPTARG"
|
|
extension="bin"
|
|
;;
|
|
a) arch="$OPTARG"
|
|
;;
|
|
t) target="$OPTARG"
|
|
extension="ext3"
|
|
;;
|
|
*) echo "invalid option: -$Option" && return 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ ! -z $kernel ]; then
|
|
if [ -L ${where}/${kernel}-${arch}.${extension} ]; then
|
|
echo ${where}/${kernel}-${arch}.${extension}
|
|
return 0
|
|
else
|
|
for i in `dir ${where}`
|
|
do
|
|
echo $i | grep -q "${kernel}.*${arch}.*\.${extension}"
|
|
if [ $? -eq 0 ]; then
|
|
echo ${where}/${i}
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
if [ ! -z $target ]; then
|
|
if [ -L ${where}/${target}-${arch}.${extension} ]; then
|
|
rootfs=`readlink -f ${where}/${target}-${arch}.${extension}`
|
|
echo ${rootfs}
|
|
return 0
|
|
else
|
|
for i in `dir ${where}`
|
|
do
|
|
echo $i | grep -q "${target}-${arch}.*\.${extension}"
|
|
if [ $? -eq 0 ]; then
|
|
echo ${where}/${i}
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
fi
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
# function to parse IP address of target
|
|
# $1 is the pid of qemu startup process
|
|
Test_Fetch_Target_IP()
|
|
{
|
|
local opid=$1
|
|
local ppid=0
|
|
local ip_addr=0
|
|
local i=0
|
|
declare local pid
|
|
|
|
# Check if $1 pid exists and contains ipaddr of target
|
|
ps -fp $opid | grep -oq "192\.168\.7\.[0-9]*::"
|
|
|
|
# Find all children pid of the pid $1
|
|
# and check if they contain ipaddr of target
|
|
if [ $? -ne 0 ]; then
|
|
# Check if there is any child pid of the pid $1
|
|
ppid=$opid
|
|
ps -f --ppid $ppid > /dev/zero
|
|
ret=$?
|
|
|
|
while [ $ret -eq 0 ]
|
|
do
|
|
# If yes, get the child pid and check if the child pid has other child pid
|
|
# Continue the while loop until there is no child pid found
|
|
pid[$i]=`ps -f --ppid $ppid | awk '{if ($2 != "PID") print $2}'`
|
|
ppid=${pid[$i]}
|
|
i=$((i+1))
|
|
ps -f --ppid $ppid > /dev/zero
|
|
ret=$?
|
|
done
|
|
|
|
# Check these children pids, if they have ipaddr included in command line
|
|
while [ $i -ne 0 ]
|
|
do
|
|
i=$((i-1))
|
|
ps -fp ${pid[$i]} | grep -oq "192\.168\.7\.[0-9]*::"
|
|
if [ $? -eq 0 ]; then
|
|
ip_addr=`ps -fp ${pid[$i]} | grep -o "192\.168\.7\.[0-9]*::" | awk -F":" '{print $1}'`
|
|
fi
|
|
sleep 1
|
|
done
|
|
else
|
|
ip_addr=`ps -fp $opid | grep -o "192\.168\.7\.[0-9]*::" | awk -F":" '{print $1}'`
|
|
fi
|
|
|
|
echo $ip_addr
|
|
|
|
return
|
|
}
|
|
|
|
# function to check if qemu and its network
|
|
Test_Create_Qemu()
|
|
{
|
|
local timeout=$1
|
|
local ret=1
|
|
local up_time=0
|
|
|
|
which poky-qemu
|
|
if [ $? -eq 0 ]; then
|
|
RUNQEMU=`which poky-qemu`
|
|
else
|
|
Test_Error "Can not find poky-qemu in \$PATH, return fail"
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$QEMUARCH" = "qemux86" -o "$QEMUARCH" = "qemux86-64" ]; then
|
|
KERNEL=$(Test_Find_Image -l ${DEPLOY_DIR}/images -k bzImage -a ${QEMUARCH})
|
|
elif [ "$QEMUARCH" = "qemuarm" -o "$QEMUARCH" = "spitz" -o "$QEMUARCH" = "borzoi" -o "$QEMUARCH" = "akita" -o "$QEMUARCH" = "nokia800" -o "$QEMUARCH" = "qemuppc" ]; then
|
|
KERNEL=$(Test_Find_Image -l ${DEPLOY_DIR}/images -k zImage -a ${QEMUARCH})
|
|
elif [ "$QEMUARCH" = "qemumips" ]; then
|
|
KERNEL=$(Test_Find_Image -l ${DEPLOY_DIR}/images -k vmlinux -a ${QEMUARCH})
|
|
fi
|
|
|
|
# If there is no kernel image found, return failed directly
|
|
if [ $? -eq 1 ]; then
|
|
Test_Info "No kernel image file found under ${DEPLOY_DIR}/images for ${QEMUARCH}, pls. have a check"
|
|
return $ret
|
|
fi
|
|
|
|
ROOTFS_IMAGE=$(Test_Find_Image -l ${DEPLOY_DIR}/images -t ${QEMUTARGET} -a ${QEMUARCH})
|
|
|
|
# If there is no rootfs image found, return failed directly
|
|
if [ $? -eq 1 ]; then
|
|
Test_Info "No ${QEMUTARGET} rootfs image file found under ${DEPLOY_DIR}/images for ${QEMUARCH}, pls. have a check"
|
|
return $ret
|
|
fi
|
|
|
|
TEST_ROOTFS_IMAGE="${TEST_TMP}/${QEMUTARGET}-${QEMUARCH}-test.ext3"
|
|
|
|
CP=`which cp`
|
|
|
|
# When TEST_SERIALIZE is set, we use the existing image under tmp folder
|
|
if [ ${TEST_SERIALIZE} -eq 1 -a -e "$TARGET_IPSAVE" ]; then
|
|
# If TARGET_IPSAVE exists, check PID of the qemu process from it
|
|
PID=`awk '{print $1}' $TARGET_IPSAVE`
|
|
timeout=50
|
|
else
|
|
rm -rf $TEST_ROOTFS_IMAGE
|
|
$CP $ROOTFS_IMAGE $TEST_ROOTFS_IMAGE
|
|
if [ $? -ne 0 ]; then
|
|
Test_Info "Image ${ROOTFS_IMAGE} copy to ${TEST_ROOTFS_IMAGE} failed, return fail"
|
|
return $ret
|
|
fi
|
|
|
|
export MACHINE=$QEMUARCH
|
|
|
|
# Create Qemu in localhost VNC Port 1
|
|
echo "Running xterm -display ${DISPLAY} -e 'BUILDDIR=${TOPDIR} ${RUNQEMU} ${KERNEL} ${TEST_ROOTFS_IMAGE}' &"
|
|
xterm -display ${DISPLAY} -e "BUILDDIR=${TOPDIR} ${RUNQEMU} ${KERNEL} ${TEST_ROOTFS_IMAGE}" &
|
|
|
|
# Get the pid of the xterm processor, which will be used in Test_Kill_Qemu
|
|
PID=$!
|
|
fi
|
|
|
|
while [ ${up_time} -lt 10 ]
|
|
do
|
|
Test_Check_Qemu_UP
|
|
if [ $? -ne 0 ]; then
|
|
Test_Info "Wait for qemu up..."
|
|
up_time=`expr $up_time + 5`
|
|
sleep 5
|
|
else
|
|
Test_Info "Begin to check if qemu network is up"
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Parse IP address of target from the qemu command line
|
|
if [ ${up_time} -lt ${timeout} ]; then
|
|
sleep 5
|
|
TARGET_IPADDR=`Test_Fetch_Target_IP $PID`
|
|
# If IP address is 0, means there is no qemu process found
|
|
if [ ${TARGET_IPADDR} == "0" ]; then
|
|
Test_Info "There is no qemu process or qemu ip address found, return failed"
|
|
return $ret
|
|
fi
|
|
fi
|
|
|
|
while [ ${up_time} -lt ${timeout} ]
|
|
do
|
|
Test_Check_IP_UP ${TARGET_IPADDR}
|
|
if [ $? -eq 0 ]; then
|
|
Test_Info "Qemu Network is up, ping with ${TARGET_IPADDR} is OK within ${up_time} seconds"
|
|
ret=0
|
|
break
|
|
else
|
|
Test_Info "Wait for Qemu Network up"
|
|
up_time=`expr $up_time + 5`
|
|
sleep 5
|
|
fi
|
|
done
|
|
|
|
if [ $ret -eq 0 ]; then
|
|
Test_Info "Qemu and its network is up"
|
|
return $ret
|
|
else
|
|
Test_Info "Qemu or its network is not up in ${timeout} seconds"
|
|
Test_Update_IPSAVE $PID $TARGET_IPADDR
|
|
return $ret
|
|
fi
|
|
}
|