qemuimage-testlib 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428
  1. #!/bin/bash
  2. # Common function for test
  3. # Expect should be installed for SSH Testing
  4. # To execute `runqemu`, NOPASSWD needs to be set in /etc/sudoers for user
  5. # For example, for user "builder", /etc/sudoers can be like following:
  6. # #########
  7. # #Members of the admin group may gain root privileges
  8. # %builder ALL=(ALL) NOPASSWD: NOPASSWD: ALL
  9. # #########
  10. #
  11. # Author: Jiajun Xu <jiajun.xu@intel.com>
  12. #
  13. # This file is licensed under the GNU General Public License,
  14. # Version 2.
  15. #
  16. TYPE="ext3"
  17. # The folder to hold all scripts running on targets
  18. TOOLS="$POKYBASE/scripts/qemuimage-tests/tools"
  19. # Test Directory on target for testing
  20. TARGET_TEST_DIR="/opt/test"
  21. # Global variable for process id
  22. PID=0
  23. # Global variable for target ip address
  24. TARGET_IPADDR=0
  25. # common function for information print
  26. Test_Error()
  27. {
  28. echo -e "\tTest_Error: $*"
  29. }
  30. Test_Info()
  31. {
  32. echo -e "\tTest_Info: $*"
  33. }
  34. # function to copy files from host into target
  35. # $1 is the ip address of target
  36. # $2 is the files, which need to be copied into target
  37. # $3 is the path on target, where files are copied into
  38. Test_SCP()
  39. {
  40. local ip_addr=$1
  41. local src=$2
  42. local des=$3
  43. local tmpfile=`mktemp`
  44. local timeout=60
  45. local ret=0
  46. # We use expect to interactive with target by ssh
  47. local exp_cmd=`cat << EOF
  48. eval spawn scp -o UserKnownHostsFile=$tmpfile "$src" root@$ip_addr:"$des"
  49. set timeout $time_out
  50. expect {
  51. "*assword:" { send "\r"; exp_continue}
  52. "*(yes/no)?" { send "yes\r"; exp_continue }
  53. eof { exit [ lindex [wait] 3 ] }
  54. }
  55. EOF`
  56. expect -c "$exp_cmd"
  57. ret=$?
  58. rm -rf $tmpfile
  59. return $ret
  60. }
  61. # function to run command in $ip_addr via ssh
  62. Test_SSH()
  63. {
  64. local ip_addr=$1
  65. shift
  66. local command=$@
  67. local tmpfile=`mktemp`
  68. local timeout=60
  69. local ret=0
  70. local exp_cmd=`cat << EOF
  71. eval spawn ssh -o UserKnownHostsFile=$tmpfile root@$ip_addr "$command"
  72. set timeout $time_out
  73. expect {
  74. "*assword:" { send "\r"; exp_continue}
  75. "*(yes/no)?" { send "yes\r"; exp_continue }
  76. eof { exit [ lindex [wait] 3 ] }
  77. }
  78. EOF`
  79. expect -c "$exp_cmd"
  80. ret=$?
  81. rm -rf $tmpfile
  82. return $ret
  83. }
  84. # function to check if ssh is up in $ip_addr
  85. Test_SSH_UP()
  86. {
  87. local ip_addr=$1
  88. local timeout=$2
  89. local interval=0
  90. while [ ${interval} -lt ${timeout} ]
  91. do
  92. Test_SSH ${ip_addr} "hostname"
  93. if [ $? -ne 0 ]; then
  94. interval=`expr $interval + 10`
  95. sleep 10
  96. else
  97. Test_Info "We can ssh on ${ip_addr} now"
  98. return 0
  99. fi
  100. done
  101. Test_Info "We can not ssh on ${ip_addr} in ${timeout}"
  102. return 1
  103. }
  104. # function to prepare target test environment
  105. # $1 is the ip address of target system
  106. # $2 is the files, which needs to be copied into target
  107. Test_Target_Pre()
  108. {
  109. local ip_addr=$1
  110. local testscript=$2
  111. # Create a pre-defined folder for test scripts
  112. Test_SSH $ip_addr "mkdir -p $TARGET_TEST_DIR"
  113. if [ $? -eq 0 ]; then
  114. # Copy test scripts into target
  115. Test_SCP $ip_addr $testscript $TARGET_TEST_DIR && return 0
  116. else
  117. Test_Error "Fail to create $TARGET_TEST_DIR on target"
  118. return 1
  119. fi
  120. return 1
  121. }
  122. # function to record test result in $TEST_RESULT/testresult.log
  123. Test_Print_Result()
  124. {
  125. local PASS=0
  126. local FAIL=0
  127. local NORESULT=0
  128. if [ $2 -eq 0 ]; then
  129. PASS=1
  130. elif [ $2 -eq 1 ]; then
  131. FAIL=1
  132. else
  133. NORESULT=1
  134. fi
  135. # Format the output of the test result
  136. echo -e "$1 $PASS $FAIL $NORESULT" | awk '{printf("\t"); for(i=1;i<=NF;i++) printf("%-15s",$i); printf("\n");}' >> $TEST_RESULT/testresult.log
  137. }
  138. # Test_Kill_Qemu to kill child pid with parent pid given
  139. # $1 is qemu process id, which needs to be killed
  140. Test_Kill_Qemu()
  141. {
  142. local ret=0
  143. local ppid=0
  144. local i=0
  145. declare local pid
  146. # Check if $1 pid exists and is a qemu process
  147. ps -fp $PID | grep -iq "qemu"
  148. # Find all children pid of the pid $1
  149. if [ $? -eq 0 ]; then
  150. # Check if there is any child pid of the pid $PID
  151. ppid=$PID
  152. ps -f --ppid $ppid
  153. ret=$?
  154. while [ $ret -eq 0 ]
  155. do
  156. # If yes, get the child pid and check if the child pid has other child pid
  157. # Continue the while loop until there is no child pid found
  158. pid[$i]=`ps -f --ppid $ppid | awk '{if ($2 != "PID") print $2}'`
  159. ppid=${pid[$i]}
  160. i=$((i+1))
  161. ps -f --ppid $ppid
  162. ret=$?
  163. done
  164. # Kill these children pids from the last one
  165. while [ $i -ne 0 ]
  166. do
  167. i=$((i-1))
  168. kill ${pid[$i]}
  169. sleep 2
  170. done
  171. # Kill the parent id
  172. kill $PID
  173. fi
  174. return
  175. }
  176. # function to check if there is any qemu process
  177. Test_Check_Qemu_UP()
  178. {
  179. local count=`ps -ef | grep -c qemu`
  180. if [ ${count} -lt 2 ]; then
  181. Test_Info "There is no Qemu process"
  182. return 1
  183. else
  184. Test_Info "There is at least Qemu process running"
  185. return 0
  186. fi
  187. }
  188. # function to check if network is up
  189. Test_Check_IP_UP()
  190. {
  191. ping -c1 $1
  192. if [ $? -ne 0 ]; then
  193. Test_Info "IP $1 is not up"
  194. return 1
  195. else
  196. Test_Info "IP $1 is up"
  197. return 0
  198. fi
  199. }
  200. # function to find kernel/rootfs image
  201. Test_Find_Image()
  202. {
  203. where=""
  204. kernel=""
  205. arch=""
  206. target=""
  207. extension=""
  208. rootfs=""
  209. while getopts "l:k:a:t:" Option
  210. do
  211. case $Option in
  212. l) where="$OPTARG"
  213. ;;
  214. k) kernel="$OPTARG"
  215. extension="bin"
  216. ;;
  217. a) arch="$OPTARG"
  218. ;;
  219. t) target="$OPTARG"
  220. extension="ext3"
  221. ;;
  222. *) echo "invalid option: -$Option" && return 1
  223. ;;
  224. esac
  225. done
  226. if [ ! -z $kernel ]; then
  227. if [ -L ${where}/${kernel}-${arch}.${extension} ]; then
  228. echo ${where}/${kernel}-${arch}.${extension}
  229. return 0
  230. else
  231. for i in `dir ${where}`
  232. do
  233. echo $i | grep -q "${kernel}.*${arch}.*\.${extension}"
  234. if [ $? -eq 0 ]; then
  235. echo ${where}/${i}
  236. return 0
  237. fi
  238. done
  239. return 1
  240. fi
  241. fi
  242. if [ ! -z $target ]; then
  243. if [ -L ${where}/${target}-${arch}.${extension} ]; then
  244. rootfs=`readlink -f ${where}/${target}-${arch}.${extension}`
  245. echo ${rootfs}
  246. return 0
  247. else
  248. for i in `dir ${where}`
  249. do
  250. echo $i | grep -q "${target}-${arch}.*\.${extension}"
  251. if [ $? -eq 0 ]; then
  252. echo ${where}/${i}
  253. return 0
  254. fi
  255. done
  256. return 1
  257. fi
  258. fi
  259. return 1
  260. }
  261. # function to parse IP address of target
  262. # $1 is the pid of qemu startup process
  263. Test_Fetch_Target_IP()
  264. {
  265. local opid=$1
  266. local ppid=0
  267. local ip_addr=0
  268. local i=0
  269. declare local pid
  270. # Check if $1 pid exists and contains ipaddr of target
  271. ps -fp $opid | grep -oq "192\.168\.7\.[0-9]*::"
  272. # Find all children pid of the pid $1
  273. # and check if they contain ipaddr of target
  274. if [ $? -ne 0 ]; then
  275. # Check if there is any child pid of the pid $1
  276. ppid=$opid
  277. ps -f --ppid $ppid > /dev/zero
  278. ret=$?
  279. while [ $ret -eq 0 ]
  280. do
  281. # If yes, get the child pid and check if the child pid has other child pid
  282. # Continue the while loop until there is no child pid found
  283. pid[$i]=`ps -f --ppid $ppid | awk '{if ($2 != "PID") print $2}'`
  284. ppid=${pid[$i]}
  285. i=$((i+1))
  286. ps -f --ppid $ppid > /dev/zero
  287. ret=$?
  288. done
  289. # Check these children pids, if they have ipaddr included in command line
  290. while [ $i -ne 0 ]
  291. do
  292. i=$((i-1))
  293. ps -fp ${pid[$i]} | grep -oq "192\.168\.7\.[0-9]*::"
  294. if [ $? -eq 0 ]; then
  295. ip_addr=`ps -fp ${pid[$i]} | grep -o "192\.168\.7\.[0-9]*::" | awk -F":" '{print $1}'`
  296. fi
  297. sleep 1
  298. done
  299. else
  300. ip_addr=`ps -fp $opid | grep -o "192\.168\.7\.[0-9]*::" | awk -F":" '{print $1}'`
  301. fi
  302. echo $ip_addr
  303. return
  304. }
  305. # function to check if qemu and its network
  306. Test_Create_Qemu()
  307. {
  308. local timeout=$1
  309. local ret=1
  310. local up_time=0
  311. which poky-qemu
  312. if [ $? -eq 0 ]; then
  313. RUNQEMU=`which poky-qemu`
  314. else
  315. Test_Error "Can not find poky-qemu in \$PATH, return fail"
  316. exit 1
  317. fi
  318. if [ "$QEMUARCH" = "qemux86" -o "$QEMUARCH" = "qemux86-64" ]; then
  319. KERNEL=$(Test_Find_Image -l ${DEPLOY_DIR}/images -k bzImage -a ${QEMUARCH})
  320. elif [ "$QEMUARCH" = "qemuarm" -o "$QEMUARCH" = "spitz" -o "$QEMUARCH" = "borzoi" -o "$QEMUARCH" = "akita" -o "$QEMUARCH" = "nokia800" -o "$QEMUARCH" = "qemuppc" ]; then
  321. KERNEL=$(Test_Find_Image -l ${DEPLOY_DIR}/images -k zImage -a ${QEMUARCH})
  322. elif [ "$QEMUARCH" = "qemumips" ]; then
  323. KERNEL=$(Test_Find_Image -l ${DEPLOY_DIR}/images -k vmlinux -a ${QEMUARCH})
  324. fi
  325. ROOTFS_IMAGE=$(Test_Find_Image -l ${DEPLOY_DIR}/images -t ${QEMUTARGET} -a ${QEMUARCH})
  326. TEST_ROOTFS_IMAGE="${TEST_TMP}/${QEMUTARGET}-${QEMUARCH}-test.ext3"
  327. CP=`which cp`
  328. if [ -e "$TEST_ROOTFS_IMAGE" ]; then
  329. rm -rf $TEST_ROOTFS_IMAGE
  330. fi
  331. $CP $ROOTFS_IMAGE $TEST_ROOTFS_IMAGE
  332. export MACHINE=$QEMUARCH
  333. # Create Qemu in localhost VNC Port 1
  334. xterm -display ${DISPLAY} -e "${RUNQEMU} ${KERNEL} ${TEST_ROOTFS_IMAGE}" &
  335. # Get the pid of the xterm processor, which will be used in Test_Kill_Qemu
  336. PID=$!
  337. sleep 5
  338. while [ ${up_time} -lt ${timeout} ]
  339. do
  340. Test_Check_Qemu_UP
  341. if [ $? -ne 0 ]; then
  342. Test_Info "Wait for qemu up..."
  343. up_time=`expr $up_time + 5`
  344. sleep 5
  345. else
  346. Test_Info "Begin to check if qemu network is up"
  347. break
  348. fi
  349. done
  350. # Parse IP address of target from the qemu command line
  351. if [ ${up_time} -lt ${timeout} ]; then
  352. sleep 5
  353. TARGET_IPADDR=`Test_Fetch_Target_IP $PID`
  354. fi
  355. while [ ${up_time} -lt ${timeout} ]
  356. do
  357. Test_Check_IP_UP ${TARGET_IPADDR}
  358. if [ $? -eq 0 ]; then
  359. Test_Info "Qemu Network is up, ping with ${TARGET_IPADDR} is OK"
  360. ret=0
  361. break
  362. else
  363. Test_Info "Wait for Qemu Network up"
  364. up_time=`expr $up_time + 5`
  365. sleep 5
  366. fi
  367. done
  368. if [ $ret -eq 0 ]; then
  369. Test_Info "Qemu and its network is up"
  370. return $ret
  371. else
  372. Test_Info "Qemu or its network is not up in ${timeout}"
  373. return $ret
  374. fi
  375. }