1
0
mirror of https://git.yoctoproject.org/poky synced 2026-05-31 12:49:46 +00:00

qemu-testlib: Add python helper and simplify shell

The current code has a race since it greps for *any* qemu process
running, even if it isn't the one we started. This leads to some sanity
tests potentially failing on machines where multiple sets of sanity tests
are running.

To resovle this and some other ugly code issues, add a python script
to accurately walk the process tree and find the qemu process. We can
then replace all the shell functions attempting this which happen to
work in many cases but not all.

Also clean up some of the error handling so its more legible.

(From OE-Core rev: a62263761fc77c139d418236cc52b04bed629229)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Richard Purdie
2013-03-19 11:44:27 +00:00
parent 24023149cc
commit ebf1f6dacf
3 changed files with 117 additions and 158 deletions
+55 -157
View File
@@ -25,8 +25,9 @@ TOOLCHAIN_PROJECTS="$COREBASE/scripts/qemuimage-tests/toolchain_projects"
# Test Directory on target for testing # Test Directory on target for testing
TARGET_TEST_DIR="/opt/test" TARGET_TEST_DIR="/opt/test"
# Global variable for process id # Global variables for process id
PID=0 XTERMPID=0
QEMUPID=0
# Global variable for target ip address # Global variable for target ip address
TARGET_IPADDR=0 TARGET_IPADDR=0
@@ -212,90 +213,33 @@ Test_Print_Result()
# $1 is qemu process id, which needs to be killed # $1 is qemu process id, which needs to be killed
Test_Kill_Qemu() Test_Kill_Qemu()
{ {
local ret=0
local ppid=0
local i=0
local index=0 local index=0
local total=0 local total=0
declare local pid
# Check if $1 pid exists and is a qemu process
ps -wwfp $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
# 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 $XTERMPID $TARGET_IPADDR
else else
# Kill these children pids from the last one kill -$QEMUPID
while [ $i -ne 0 ] kill -$XTERMPID
do
i=$((i-1))
kill ${pid[$i]}
sleep 2
done
# Kill the parent id
kill $PID
fi fi
else
kill -$QEMUPID
kill -$XTERMPID
fi fi
return 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 # function to check if network is up
Test_Check_IP_UP() Test_Check_IP_UP()
{ {
ping -c1 $1 ping -c1 $1 1> /dev/null
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Test_Info "IP $1 is not up" Test_Info "IP $1 is not up"
return 1 return 1
@@ -377,46 +321,12 @@ Test_Find_Image()
Test_Fetch_Target_IP() Test_Fetch_Target_IP()
{ {
local opid=$1 local opid=$1
local ppid=0
local ip_addr=0 local ip_addr=0
local i=0
declare local pid
# Check if $1 pid exists and contains ipaddr of target # Check if $1 pid exists and contains ipaddr of target
ps -wwfp $opid | grep -oq "192\.168\.7\.[0-9]*::" ps -wwfp $opid | grep -oq "192\.168\.7\.[0-9]*::"
# Find all children pid of the pid $1 ip_addr=`ps -wwfp $opid | grep -o "192\.168\.7\.[0-9]*::" | awk -F":" '{print $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 -wwfp ${pid[$i]} | grep -oq "192\.168\.7\.[0-9]*::"
if [ $? -eq 0 ]; then
ip_addr=`ps -wwfp ${pid[$i]} | grep -o "192\.168\.7\.[0-9]*::" | awk -F":" '{print $1}'`
fi
sleep 1
done
else
ip_addr=`ps -wwfp $opid | grep -o "192\.168\.7\.[0-9]*::" | awk -F":" '{print $1}'`
fi
echo $ip_addr echo $ip_addr
@@ -427,13 +337,10 @@ Test_Fetch_Target_IP()
Test_Create_Qemu() Test_Create_Qemu()
{ {
local timeout=$1 local timeout=$1
local ret=1
local up_time=0 local up_time=0
which runqemu RUNQEMU=`which runqemu`
if [ $? -eq 0 ]; then if [ $? -ne 0 ]; then
RUNQEMU=`which runqemu`
else
Test_Error "Can not find runqemu in \$PATH, return fail" Test_Error "Can not find runqemu in \$PATH, return fail"
return 1 return 1
fi fi
@@ -449,7 +356,7 @@ Test_Create_Qemu()
# If there is no kernel image found, return failed directly # If there is no kernel image found, return failed directly
if [ $? -eq 1 ]; then if [ $? -eq 1 ]; then
Test_Info "No kernel image file found under ${DEPLOY_DIR}/images for ${QEMUARCH}, pls. have a check" Test_Info "No kernel image file found under ${DEPLOY_DIR}/images for ${QEMUARCH}, pls. have a check"
return $ret return 1
fi fi
ROOTFS_IMAGE=$(Test_Find_Image -l ${DEPLOY_DIR}/images -t ${QEMUTARGET} -a ${QEMUARCH}) ROOTFS_IMAGE=$(Test_Find_Image -l ${DEPLOY_DIR}/images -t ${QEMUTARGET} -a ${QEMUARCH})
@@ -457,7 +364,7 @@ Test_Create_Qemu()
# If there is no rootfs image found, return failed directly # If there is no rootfs image found, return failed directly
if [ $? -eq 1 ]; then if [ $? -eq 1 ]; then
Test_Info "No ${QEMUTARGET} rootfs image file found under ${DEPLOY_DIR}/images for ${QEMUARCH}, pls. have a check" Test_Info "No ${QEMUTARGET} rootfs image file found under ${DEPLOY_DIR}/images for ${QEMUARCH}, pls. have a check"
return $ret return 1
fi fi
TEST_ROOTFS_IMAGE="${TEST_TMP}/${QEMUTARGET}-${QEMUARCH}-test.ext3" TEST_ROOTFS_IMAGE="${TEST_TMP}/${QEMUTARGET}-${QEMUARCH}-test.ext3"
@@ -467,7 +374,7 @@ Test_Create_Qemu()
# When TEST_SERIALIZE is set, we use the existing image under tmp folder # When TEST_SERIALIZE is set, we use the existing image under tmp folder
if [ ${TEST_SERIALIZE} -eq 1 -a -e "$TARGET_IPSAVE" ]; then if [ ${TEST_SERIALIZE} -eq 1 -a -e "$TARGET_IPSAVE" ]; then
# If TARGET_IPSAVE exists, check PID of the qemu process from it # If TARGET_IPSAVE exists, check PID of the qemu process from it
PID=`awk '{print $1}' $TARGET_IPSAVE` XTERMPID=`awk '{print $1}' $TARGET_IPSAVE`
timeout=50 timeout=50
else else
rm -rf $TEST_ROOTFS_IMAGE rm -rf $TEST_ROOTFS_IMAGE
@@ -475,22 +382,22 @@ Test_Create_Qemu()
$CP $ROOTFS_IMAGE $TEST_ROOTFS_IMAGE $CP $ROOTFS_IMAGE $TEST_ROOTFS_IMAGE
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Test_Info "Image ${ROOTFS_IMAGE} copy to ${TEST_ROOTFS_IMAGE} failed, return fail" Test_Info "Image ${ROOTFS_IMAGE} copy to ${TEST_ROOTFS_IMAGE} failed, return fail"
return $ret return 1
fi fi
export MACHINE=$QEMUARCH export MACHINE=$QEMUARCH
# Create Qemu in localhost VNC Port 1 # Create Qemu in localhost VNC Port 1
echo "Running xterm -display ${DISPLAY} -e 'OE_TMPDIR=${OE_TMPDIR} ${RUNQEMU} ${KERNEL} ${TEST_ROOTFS_IMAGE} && /bin/sleep 60' &" echo "Running xterm -display ${DISPLAY} -e 'OE_TMPDIR=${OE_TMPDIR} ${RUNQEMU} ${KERNEL} ${TEST_ROOTFS_IMAGE} || /bin/sleep 60' &"
xterm -display ${DISPLAY} -e "OE_TMPDIR=${OE_TMPDIR} ${RUNQEMU} ${KERNEL} ${TEST_ROOTFS_IMAGE} && /bin/sleep 60" & xterm -display ${DISPLAY} -e "OE_TMPDIR=${OE_TMPDIR} ${RUNQEMU} ${KERNEL} ${TEST_ROOTFS_IMAGE} || /bin/sleep 60" &
# Get the pid of the xterm processor, which will be used in Test_Kill_Qemu # Get the pid of the xterm processor, which will be used in Test_Kill_Qemu
PID=$! XTERMPID=$!
fi fi
while [ ${up_time} -lt 10 ] while [ ${up_time} -lt 10 ]
do do
Test_Check_Qemu_UP QEMUPID=`qemuimage-testlib-pythonhelper --findqemu $XTERMPID`
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
Test_Info "Wait for qemu up..." Test_Info "Wait for qemu up..."
up_time=`expr $up_time + 5` up_time=`expr $up_time + 5`
@@ -501,15 +408,17 @@ Test_Create_Qemu()
fi fi
done done
if [ ${up_time} == 10 ]; then
Test_Info "No qemu process appeared to start, exiting"
return 1
fi
# Parse IP address of target from the qemu command line # Parse IP address of target from the qemu command line
if [ ${up_time} -lt ${timeout} ]; then TARGET_IPADDR=`Test_Fetch_Target_IP $QEMUPID`
sleep 5 # If IP address is 0, means there is no qemu process found
TARGET_IPADDR=`Test_Fetch_Target_IP $PID` if [ ${TARGET_IPADDR} == "0" ]; then
# If IP address is 0, means there is no qemu process found Test_Info "There is no qemu process or qemu ip address found, return failed"
if [ ${TARGET_IPADDR} == "0" ]; then return 1
Test_Info "There is no qemu process or qemu ip address found, return failed"
return $ret
fi
fi fi
while [ ${up_time} -lt ${timeout} ] while [ ${up_time} -lt ${timeout} ]
@@ -517,8 +426,7 @@ Test_Create_Qemu()
Test_Check_IP_UP ${TARGET_IPADDR} Test_Check_IP_UP ${TARGET_IPADDR}
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
Test_Info "Qemu Network is up, ping with ${TARGET_IPADDR} is OK within ${up_time} seconds" Test_Info "Qemu Network is up, ping with ${TARGET_IPADDR} is OK within ${up_time} seconds"
ret=0 return 0
break
else else
Test_Info "Wait for Qemu Network up" Test_Info "Wait for Qemu Network up"
up_time=`expr $up_time + 5` up_time=`expr $up_time + 5`
@@ -526,14 +434,9 @@ Test_Create_Qemu()
fi fi
done done
if [ $ret -eq 0 ]; then Test_Info "Qemu or its network is not up in ${timeout} seconds"
Test_Info "Qemu and its network is up" Test_Update_IPSAVE $XTERMPID $TARGET_IPADDR
return $ret return 1
else
Test_Info "Qemu or its network is not up in ${timeout} seconds"
Test_Update_IPSAVE $PID $TARGET_IPADDR
return $ret
fi
} }
# Function to prepare test project for toolchain test # Function to prepare test project for toolchain test
@@ -542,41 +445,36 @@ Test_Create_Qemu()
Test_Project_Prepare() Test_Project_Prepare()
{ {
local toolchain_dir=$1 local toolchain_dir=$1
local ret=1
if [ ! -d ${toolchain_dir} ]; then if [ ! -d ${toolchain_dir} ]; then
mkdir -p ${toolchain_dir} mkdir -p ${toolchain_dir}
ret=$? if [ $? -ne 0 ]; then
ret=$?
if [ $ret -ne 0 ]; then
Test_Info "Create ${toolchain_dir} fail, return" Test_Info "Create ${toolchain_dir} fail, return"
return $ret return $ret
fi fi
fi fi
ret=0
# Download test project tarball if it does not exist # Download test project tarball if it does not exist
if [ ! -f ${toolchain_dir}/${2}-${PROJECT_PV}.${suffix} ]; then if [ ! -f ${toolchain_dir}/${2}-${PROJECT_PV}.${suffix} ]; then
wget -c -t 5 $PROJECT_DOWNLOAD_URL -O ${toolchain_dir}/${2}-${PROJECT_PV}.${suffix} wget -c -t 5 $PROJECT_DOWNLOAD_URL -O ${toolchain_dir}/${2}-${PROJECT_PV}.${suffix}
ret=$? if [ $? -ne 0 ]; then
ret=$?
Test_Info "Fail to download ${2}-${PROJECT_PV}.${suffix} from $PROJECT_DOWNLOAD_URL"
rm -rf ${toolchain_dir}/${2}-${PROJECT_PV}.${suffix}
return $ret
fi
fi fi
# Extract the test project into ${TEST_TMP} # Extract the test project into ${TEST_TMP}
if [ $ret -eq 0 ]; then tar jxf ${toolchain_dir}/${2}-${PROJECT_PV}.${suffix} -C ${TEST_TMP}
tar jxf ${toolchain_dir}/${2}-${PROJECT_PV}.${suffix} -C ${TEST_TMP} if [ $? -ne 0 ]; then
ret=$? ret=$?
if [ $ret -eq 0 ]; then Test_Info "Fail to extract ${2}-${PROJECT_PV}.${suffix} into ${TEST_TMP}"
Test_Info "Extract ${2}-${PROJECT_PV}.${suffix} into ${TEST_TMP} successfully"
return $ret
else
Test_Info "Fail to extract ${2}-${PROJECT_PV}.${suffix} into ${TEST_TMP}"
return $ret
fi
else
Test_Info "Fail to download ${2}-${PROJECT_PV}.${suffix} from $PROJECT_DOWNLOAD_URL"
rm -rf ${toolchain_dir}/${2}-${PROJECT_PV}.${suffix}
return $ret return $ret
fi fi
Test_Info "Extract ${2}-${PROJECT_PV}.${suffix} into ${TEST_TMP} successfully"
return 0
} }
# Function to prepare toolchain environment # Function to prepare toolchain environment
+61
View File
@@ -0,0 +1,61 @@
#!/usr/bin/env python
import optparse
import subprocess
import sys
parser = optparse.OptionParser(
usage = """
%prog [options]
""")
parser.add_option("-q", "--findqemu",
help = "find a qemu beneath the process <pid>",
action="store", dest="findqemu")
options, args = parser.parse_args(sys.argv)
if options.findqemu:
#
# Walk the process tree from the process specified looking for a qemu-system. Return its pid.
#
ps = subprocess.Popen(['ps', 'ax', '-o', 'pid,ppid,command'], stdout=subprocess.PIPE).communicate()[0]
processes = ps.split('\n')
nfields = len(processes[0].split()) - 1
pids = {}
commands = {}
for row in processes[1:]:
data = row.split(None, nfields)
if len(data) != 3:
continue
if data[1] not in pids:
pids[data[1]] = []
pids[data[1]].append(data[0])
commands[data[0]] = data[2]
if options.findqemu not in pids:
print "No children found matching %s" % options.findqemu
sys.exit(1)
parents = []
newparents = pids[options.findqemu]
while newparents:
next = []
for p in newparents:
if p in pids:
for n in pids[p]:
if n not in parents and n not in next:
next.append(n)
if p not in parents:
parents.append(p)
newparents = next
#print "Children matching %s:" % str(parents)
for p in parents:
if "qemu-system" in commands[p]:
print p
sys.exit(0)
sys.exit(1)
else:
parser.print_help()
+1 -1
View File
@@ -45,7 +45,7 @@ if [ $RET -eq 0 ]; then
# If qemu start up process ends up, it means shutdown completes # If qemu start up process ends up, it means shutdown completes
while [ $i -lt $TIMEOUT ] while [ $i -lt $TIMEOUT ]
do do
ps -fp $PID > /dev/null ps -fp $QEMUPID > /dev/null 2> /dev/null
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
RET=0 RET=0
break break