]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core.git/blob - scripts/qemuimage-testlib
qemuimage-testlib: Add delay to work around races in qemu startup
[thirdparty/openembedded/openembedded-core.git] / scripts / qemuimage-testlib
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
17 TYPE="ext3"
18
19 # The folder to hold all scripts running on targets
20 TOOLS="$COREBASE/scripts/qemuimage-tests/tools"
21
22 # The folder to hold all projects for toolchain testing
23 TOOLCHAIN_PROJECTS="$COREBASE/scripts/qemuimage-tests/toolchain_projects"
24
25 # Test Directory on target for testing
26 TARGET_TEST_DIR="/opt/test"
27
28 # Global variables for process id
29 XTERMPID=0
30 QEMUPID=0
31
32 # Global variable for target ip address
33 TARGET_IPADDR=0
34
35 # Global variable for test project version during toolchain test
36 # Version of cvs is 1.12.13
37 # Version of iptables is 1.4.11
38 # Version of sudoku-savant is 1.3
39 PROJECT_PV=0
40
41 # Global variable for test project download URL during toolchain test
42 # URL of cvs is http://ftp.gnu.org/non-gnu/cvs/source/feature/1.12.13/cvs-1.12.13.tar.bz2
43 # URL of iptables is http://netfilter.org/projects/iptables/files/iptables-1.4.11.tar.bz2
44 # URL of sudoku-savant is http://downloads.sourceforge.net/project/sudoku-savant/sudoku-savant/sudoku-savant-1.3/sudoku-savant-1.3.tar.bz2
45 PROJECT_DOWNLOAD_URL=0
46
47 # SDK folder to hold toolchain tarball
48 TOOLCHAIN_DIR="${DEPLOY_DIR}/sdk"
49
50 # Toolchain test folder to hold extracted toolchain tarball
51 TOOLCHAIN_TEST="/opt"
52
53 # common function for information print
54 Test_Error()
55 {
56 echo -e "\tTest_Error: $*"
57 }
58
59 Test_Info()
60 {
61 echo -e "\tTest_Info: $*"
62 }
63
64 # function to update target ip address
65 # $1 is the process id of the process, which starts the qemu target
66 # $2 is the ip address of the target
67 Test_Update_IPSAVE()
68 {
69 local pid=$1
70 local ip_addr=$2
71
72 if [ "$TEST_SERIALIZE" -eq 1 ]; then
73 echo "Saving $pid $ip_addr to $TARGET_IPSAVE"
74 echo "$pid $ip_addr" > $TARGET_IPSAVE
75 fi
76 }
77
78 # function to copy files from host into target
79 # $1 is the ip address of target
80 # $2 is the files, which need to be copied into target
81 # $3 is the path on target, where files are copied into
82 Test_SCP()
83 {
84 local ip_addr=$1
85 local src=$2
86 local des=$3
87 local tmpfile=`mktemp`
88 local time_out=60
89 local ret=0
90
91 # We use expect to interactive with target by ssh
92 local exp_cmd=`cat << EOF
93 eval spawn scp -o UserKnownHostsFile=$tmpfile "$src" root@$ip_addr:"$des"
94 set timeout $time_out
95 expect {
96 "*assword:" { send "\r"; exp_continue}
97 "*(yes/no)?" { send "yes\r"; exp_continue }
98 eof { exit [ lindex [wait] 3 ] }
99 }
100 EOF`
101
102 expect=`which expect`
103 if [ ! -x "$expect" ]; then
104 Test_Error "ERROR: Please install expect"
105 return 1
106 fi
107
108 expect -c "$exp_cmd"
109 ret=$?
110 rm -rf $tmpfile
111 return $ret
112 }
113
114 # function to run command in $ip_addr via ssh
115 Test_SSH()
116 {
117 local ip_addr=$1
118 shift
119 local command=$@
120 local tmpfile=`mktemp`
121 local time_out=60
122 local ret=0
123 local exp_cmd=`cat << EOF
124 eval spawn ssh -o UserKnownHostsFile=$tmpfile root@$ip_addr "$command"
125 set timeout $time_out
126 expect {
127 "*assword:" { send "\r"; exp_continue}
128 "*(yes/no)?" { send "yes\r"; exp_continue }
129 eof { exit [ lindex [wait] 3 ] }
130 }
131 EOF`
132
133 expect=`which expect`
134 if [ ! -x "$expect" ]; then
135 Test_Error "ERROR: Please install expect"
136 return 1
137 fi
138
139 expect -c "$exp_cmd"
140 ret=$?
141 rm -rf $tmpfile
142 return $ret
143 }
144
145 # function to check if ssh is up in $ip_addr
146 Test_SSH_UP()
147 {
148 local ip_addr=$1
149 local timeout=$2
150 local interval=0
151
152 # If TEST_SERIALIZE is set, use existing running qemu for testing
153 if [ ${TEST_SERIALIZE} -eq 1 -a -e ${TARGET_IPSAVE} ]; then
154 timeout=50
155 fi
156
157 while [ ${interval} -lt ${timeout} ]
158 do
159 Test_SSH ${ip_addr} "hostname"
160 if [ $? -ne 0 ]; then
161 interval=`expr $interval + 10`
162 sleep 10
163 else
164 Test_Info "We can ssh on ${ip_addr} within ${interval} seconds"
165 return 0
166 fi
167
168 done
169
170 Test_Info "We can not ssh on ${ip_addr} in ${timeout} seconds"
171 return 1
172 }
173
174 # function to prepare target test environment
175 # $1 is the ip address of target system
176 # $2 is the files, which needs to be copied into target
177 Test_Target_Pre()
178 {
179 local ip_addr=$1
180 local testscript=$2
181
182 # Create a pre-defined folder for test scripts
183 Test_SSH $ip_addr "mkdir -p $TARGET_TEST_DIR"
184 if [ $? -eq 0 ]; then
185 # Copy test scripts into target
186 Test_SCP $ip_addr $testscript $TARGET_TEST_DIR && return 0
187 else
188 Test_Error "Fail to create $TARGET_TEST_DIR on target"
189 return 1
190 fi
191
192 return 1
193 }
194
195 # function to record test result in $TEST_RESULT/testresult.log
196 Test_Print_Result()
197 {
198 local PASS=0
199 local FAIL=0
200 local NORESULT=0
201 if [ $2 -eq 0 ]; then
202 PASS=1
203 elif [ $2 -eq 1 ]; then
204 FAIL=1
205 else
206 NORESULT=1
207 fi
208
209 # Format the output of the test result
210 echo -e "$1 $PASS $FAIL $NORESULT" | awk '{printf("\t"); for(i=1;i<=NF;i++) printf("%-15s",$i); printf("\n");}' >> $TEST_RESULT/testresult.log
211 }
212
213 # Test_Kill_Qemu to kill child pid with parent pid given
214 # $1 is qemu process id, which needs to be killed
215 Test_Kill_Qemu()
216 {
217 local index=0
218 local total=0
219 local k=0
220
221 # When TEST_SERIALIZE is set, qemu process will not be
222 # killed until all the cases are finished
223 if [ ${TEST_SERIALIZE} -eq 1 -a -e ${TEST_STATUS} ]; then
224 index=`sed -n 2p ${TEST_STATUS} | awk '{print $3}'`
225 total=`sed -n 2p ${TEST_STATUS} | awk '{print $4}'`
226 if [ ${index} != ${total} ]; then
227 Test_Info "Do not kill the qemu process and use it for later testing (step $index of $total)"
228 Test_Update_IPSAVE $XTERMPID $TARGET_IPADDR
229 else
230 k=1
231 fi
232 else
233 k=1
234 fi
235
236 if [ $k -eq 1 ]; then
237 running=`ps -wwfp $QEMUPID`
238 if [ $? -eq 0 ]; then
239 echo "killing $QEMUPID"
240 kill $QEMUPID
241 fi
242 running=`ps -wwfp $XTERMPID`
243 if [ $? -eq 0 ]; then
244 echo "killing $XTERMPID"
245 kill $XTERMPID
246 fi
247 fi
248
249 return
250 }
251
252 # function to check if network is up
253 Test_Check_IP_UP()
254 {
255 ping -c1 $1 1> /dev/null
256 if [ $? -ne 0 ]; then
257 Test_Info "IP $1 is not up"
258 return 1
259 else
260 Test_Info "IP $1 is up"
261 return 0
262 fi
263 }
264
265 # function to find kernel/rootfs image
266 Test_Find_Image()
267 {
268 where=""
269 kernel=""
270 arch=""
271 target=""
272 extension=""
273 rootfs=""
274
275 while getopts "l:k:a:t:" Option
276 do
277 case $Option in
278 l) where="$OPTARG"
279 ;;
280 k) kernel="$OPTARG"
281 extension="bin"
282 ;;
283 a) arch="$OPTARG"
284 ;;
285 t) target="$OPTARG"
286 extension="ext3"
287 ;;
288 *) echo "invalid option: -$Option" && return 1
289 ;;
290 esac
291 done
292
293 if [ ! -z $kernel ]; then
294 if [ -L ${where}/${kernel}-${arch}.${extension} ]; then
295 echo ${where}/${kernel}-${arch}.${extension}
296 return 0
297 else
298 for i in `dir ${where}`
299 do
300 # Exclude qemux86-64 when target is qemux86
301 echo $i | grep "${kernel}.*${arch}.*\.${extension}" | grep -qv "${kernel}.*${arch}-64.*\.${extension}"
302 if [ $? -eq 0 ]; then
303 echo ${where}/${i}
304 return 0
305 fi
306 done
307 return 1
308 fi
309 fi
310
311 if [ ! -z $target ]; then
312 if [ -L ${where}/${target}-${arch}.${extension} ]; then
313 rootfs=`readlink -f ${where}/${target}-${arch}.${extension}`
314 echo ${rootfs}
315 return 0
316 else
317 for i in `dir ${where}`
318 do
319 # Exclude qemux86-64 when target is qemux86
320 echo $i | grep "${target}-${arch}.*\.${extension}" | grep -qv "${target}-${arch}-64.*\.${extension}"
321 if [ $? -eq 0 ]; then
322 echo ${where}/${i}
323 return 0
324 fi
325 done
326 return 1
327 fi
328 fi
329 return 1
330 }
331
332 # function to parse IP address of target
333 # $1 is the pid of qemu startup process
334 Test_Fetch_Target_IP()
335 {
336 local opid=$1
337 local ip_addr=0
338
339 # Check if $1 pid exists and contains ipaddr of target
340 ip_addr=`ps -wwfp $opid | grep -o "192\.168\.7\.[0-9]*::" | awk -F":" '{print $1}'`
341
342 echo $ip_addr
343
344 return
345 }
346
347 # function to check if qemu and its network
348 Test_Create_Qemu()
349 {
350 local timeout=$1
351 local up_time=0
352
353 RUNQEMU=`which runqemu`
354 if [ $? -ne 0 ]; then
355 Test_Error "Can not find runqemu in \$PATH, return fail"
356 return 1
357 fi
358
359 if [ "$QEMUARCH" = "qemux86" -o "$QEMUARCH" = "qemux86-64" ]; then
360 KERNEL=$(Test_Find_Image -l ${DEPLOY_DIR}/images -k bzImage -a ${QEMUARCH})
361 elif [ "$QEMUARCH" = "qemuarm" -o "$QEMUARCH" = "spitz" -o "$QEMUARCH" = "borzoi" -o "$QEMUARCH" = "akita" -o "$QEMUARCH" = "nokia800" ]; then
362 KERNEL=$(Test_Find_Image -l ${DEPLOY_DIR}/images -k zImage -a ${QEMUARCH})
363 elif [ "$QEMUARCH" = "qemumips" -o "$QEMUARCH" = "qemuppc" ]; then
364 KERNEL=$(Test_Find_Image -l ${DEPLOY_DIR}/images -k vmlinux -a ${QEMUARCH})
365 fi
366
367 # If there is no kernel image found, return failed directly
368 if [ $? -eq 1 ]; then
369 Test_Info "No kernel image file found under ${DEPLOY_DIR}/images for ${QEMUARCH}, pls. have a check"
370 return 1
371 fi
372
373 ROOTFS_IMAGE=$(Test_Find_Image -l ${DEPLOY_DIR}/images -t ${QEMUTARGET} -a ${QEMUARCH})
374
375 # If there is no rootfs image found, return failed directly
376 if [ $? -eq 1 ]; then
377 Test_Info "No ${QEMUTARGET} rootfs image file found under ${DEPLOY_DIR}/images for ${QEMUARCH}, pls. have a check"
378 return 1
379 fi
380
381 TEST_ROOTFS_IMAGE="${TEST_TMP}/${QEMUTARGET}-${QEMUARCH}-test.ext3"
382
383 CP=`which cp`
384
385 # When TEST_SERIALIZE is set, we use the existing image under tmp folder
386 if [ ${TEST_SERIALIZE} -eq 1 -a -e "$TARGET_IPSAVE" ]; then
387 # If TARGET_IPSAVE exists, check PID of the qemu process from it
388 XTERMPID=`awk '{print $1}' $TARGET_IPSAVE`
389 timeout=50
390 else
391 rm -rf $TEST_ROOTFS_IMAGE
392 echo "Copying rootfs $ROOTFS_IMAGE to $TEST_ROOTFS_IMAGE"
393 $CP $ROOTFS_IMAGE $TEST_ROOTFS_IMAGE
394 if [ $? -ne 0 ]; then
395 Test_Info "Image ${ROOTFS_IMAGE} copy to ${TEST_ROOTFS_IMAGE} failed, return fail"
396 return 1
397 fi
398
399 export MACHINE=$QEMUARCH
400
401 # Create Qemu in localhost VNC Port 1
402 echo "Running xterm -display ${DISPLAY} -e 'OE_TMPDIR=${OE_TMPDIR} ${RUNQEMU} ${KERNEL} ${TEST_ROOTFS_IMAGE} || /bin/sleep 60' &"
403 xterm -display ${DISPLAY} -e "OE_TMPDIR=${OE_TMPDIR} ${RUNQEMU} ${KERNEL} ${TEST_ROOTFS_IMAGE} || /bin/sleep 60" &
404
405 # Get the pid of the xterm processor, which will be used in Test_Kill_Qemu
406 XTERMPID=$!
407 echo "XTERMPID is $XTERMPID"
408 # When starting, qemu can reexecute itself and change PID so wait a short while for things to settle
409 sleep 5
410 fi
411
412 while [ ${up_time} -lt 10 ]
413 do
414 QEMUPID=`qemuimage-testlib-pythonhelper --findqemu $XTERMPID`
415 if [ $? -ne 0 ]; then
416 Test_Info "Wait for qemu up..."
417 up_time=`expr $up_time + 5`
418 sleep 5
419 else
420 Test_Info "Begin to check if qemu network is up"
421 echo "QEMUPID is $QEMUPID"
422 break
423 fi
424 done
425
426 if [ ${up_time} == 10 ]; then
427 Test_Info "No qemu process appeared to start, exiting"
428 return 1
429 fi
430
431 # Parse IP address of target from the qemu command line
432 TARGET_IPADDR=`Test_Fetch_Target_IP $QEMUPID`
433 echo "Target IP is ${TARGET_IPADDR}"
434 if [ -z ${TARGET_IPADDR} ]; then
435 Test_Info "There is no qemu process or qemu ip address found, return failed"
436 return 1
437 fi
438
439 while [ ${up_time} -lt ${timeout} ]
440 do
441 Test_Check_IP_UP ${TARGET_IPADDR}
442 if [ $? -eq 0 ]; then
443 Test_Info "Qemu Network is up, ping with ${TARGET_IPADDR} is OK within ${up_time} seconds"
444 return 0
445 else
446 Test_Info "Wait for Qemu Network up"
447 up_time=`expr $up_time + 5`
448 sleep 5
449 fi
450 done
451
452 Test_Info "Qemu or its network is not up in ${timeout} seconds"
453 Test_Update_IPSAVE $XTERMPID $TARGET_IPADDR
454 return 1
455 }
456
457 # Function to prepare test project for toolchain test
458 # $1 is the folder holding test project file
459 # $2 is the test project name
460 Test_Project_Prepare()
461 {
462 local toolchain_dir=$1
463
464 if [ ! -d ${toolchain_dir} ]; then
465 mkdir -p ${toolchain_dir}
466 if [ $? -ne 0 ]; then
467 ret=$?
468 Test_Info "Create ${toolchain_dir} fail, return"
469 return $ret
470 fi
471 fi
472
473 # Download test project tarball if it does not exist
474 if [ ! -f ${toolchain_dir}/${2}-${PROJECT_PV}.${suffix} ]; then
475 wget -c -t 5 $PROJECT_DOWNLOAD_URL -O ${toolchain_dir}/${2}-${PROJECT_PV}.${suffix}
476 if [ $? -ne 0 ]; then
477 ret=$?
478 Test_Info "Fail to download ${2}-${PROJECT_PV}.${suffix} from $PROJECT_DOWNLOAD_URL"
479 rm -rf ${toolchain_dir}/${2}-${PROJECT_PV}.${suffix}
480 return $ret
481 fi
482 fi
483
484 # Extract the test project into ${TEST_TMP}
485 tar jxf ${toolchain_dir}/${2}-${PROJECT_PV}.${suffix} -C ${TEST_TMP}
486 if [ $? -ne 0 ]; then
487 ret=$?
488 Test_Info "Fail to extract ${2}-${PROJECT_PV}.${suffix} into ${TEST_TMP}"
489 return $ret
490 fi
491 Test_Info "Extract ${2}-${PROJECT_PV}.${suffix} into ${TEST_TMP} successfully"
492 return 0
493 }
494
495 # Function to prepare toolchain environment
496 # $1 is toolchain directory to hold toolchain tarball
497 # $2 is prefix name for toolchain tarball
498 Test_Toolchain_Prepare()
499 {
500 local toolchain_dir=$1
501 local sdk_name=$2
502 local ret=1
503
504 if [ ! -d ${toolchain_dir} ]; then
505 Test_Info "No directory ${toolchain_dir}, which holds toolchain tarballs"
506 return 1
507 fi
508
509 # Check if there is any toolchain tarball under $toolchain_dir with prefix $sdk_name
510 for i in `dir ${toolchain_dir}`
511 do
512 echo $i | grep "${sdk_name}-toolchain-gmae"
513 if [ $? -eq 0 ]; then
514 rm -rf ${TEST_TMP}/opt
515 tar jxf ${toolchain_dir}/${i} -C ${TEST_TMP}
516 ret=$?
517 break
518 fi
519 done
520
521 if [ $ret -eq 0 ]; then
522 Test_Info "Check if /opt is accessible for non-root user"
523
524 # Check if the non-root test user has write access of $TOOLCHAIN_TEST
525 if [ -d ${TOOLCHAIN_TEST} ]; then
526 touch ${TOOLCHAIN_TEST}
527 if [ $? -ne 0 ]; then
528 Test_Info "Has no right to modify folder $TOOLCHAIN_TEST, pls. chown it to test user"
529 return 2
530 fi
531 else
532 mkdir -p ${TOOLCHAIN_TEST}
533 if [ $? -ne 0 ]; then
534 Test_Info "Has no right to create folder $TOOLCHAIN_TEST, pls. create it and chown it to test user"
535 return 2
536 fi
537 fi
538
539 # If there is a toolchain folder under $TOOLCHAIN_TEST, let's remove it
540 if [ -d ${TOOLCHAIN_TEST}/poky ]; then
541 rm -rf ${TOOLCHAIN_TEST}/poky
542 fi
543
544 # Copy toolchain into $TOOLCHAIN_TEST
545 cp -r ${TEST_TMP}/opt/poky ${TOOLCHAIN_TEST}
546 ret=$?
547
548 if [ $ret -eq 0 ]; then
549 Test_Info "Successfully copy toolchain into $TOOLCHAIN_TEST"
550 return $ret
551 else
552 Test_Info "Meet error when copy toolchain into $TOOLCHAIN_TEST"
553 return $ret
554 fi
555 else
556 Test_Info "No tarball named ${sdk_name}-toolchain-gmae under ${toolchain_dir}"
557 return $ret
558 fi
559 }
560
561 # Function to execute command and exit if run out of time
562 # $1 is timeout value
563 # $2 is the command to be executed
564 Test_Time_Out()
565 {
566 local timeout=$1
567 shift
568 local command=$*
569 local date=0
570 local tmp=`mktemp`
571 local ret=1
572 local pid=0
573 local ppid=0
574 local i=0
575 declare local pid_l
576
577 # Run command in background
578 ($command; echo $? > $tmp) &
579 pid=$!
580 while ps -e -o pid | grep -qw $pid; do
581 if [ $date -ge $timeout ]; then
582 Test_Info "$timeout Timeout when running command $command"
583 rm -rf $tmp
584
585 # Find all child processes of pid and kill them
586 ppid=$pid
587 ps -f --ppid $ppid
588 ret=$?
589
590 while [ $ret -eq 0 ]
591 do
592 # If yes, get the child pid and check if the child pid has other child pid
593 # Continue the while loop until there is no child pid found
594 pid_l[$i]=`ps -f --ppid $ppid | awk '{if ($2 != "PID") print $2}'`
595 ppid=${pid_l[$i]}
596 i=$((i+1))
597 ps -f --ppid $ppid
598 ret=$?
599 done
600
601 # Kill these children pids from the last one
602 while [ $i -ne 0 ]
603 do
604 i=$((i-1))
605 kill ${pid_l[$i]}
606 sleep 2
607 done
608
609 # Kill the parent id
610 kill $pid
611 return 1
612 fi
613 sleep 5
614 date=`expr $date + 5`
615 done
616 ret=`cat $tmp`
617 rm -rf $tmp
618 return $ret
619 }
620
621 # Function to test toolchain
622 # $1 is test project name
623 # $2 is the timeout value
624 Test_Toolchain()
625 {
626 local test_project=$1
627 local timeout=$2
628 local ret=1
629 local suffix="tar.bz2"
630 local env_setup=""
631 local pro_install="${TEST_TMP}/pro_install"
632
633 # Set value for PROJECT_PV and PROJECT_DOWNLOAD_URL accordingly
634 if [ $test_project == "cvs" ]; then
635 PROJECT_PV=1.12.13
636 PROJECT_DOWNLOAD_URL="http://ftp.gnu.org/non-gnu/cvs/source/feature/1.12.13/cvs-1.12.13.tar.bz2"
637 elif [ $test_project == "iptables" ]; then
638 PROJECT_PV=1.4.11
639 PROJECT_DOWNLOAD_URL="http://netfilter.org/projects/iptables/files/iptables-1.4.11.tar.bz2"
640 elif [ $test_project == "sudoku-savant" ]; then
641 PROJECT_PV=1.3
642 PROJECT_DOWNLOAD_URL="http://downloads.sourceforge.net/project/sudoku-savant/sudoku-savant/sudoku-savant-1.3/sudoku-savant-1.3.tar.bz2"
643 else
644 Test_Info "Unknown test project name $test_project"
645 return 1
646 fi
647
648 # Download test project and extract it
649 Test_Project_Prepare $TOOLCHAIN_PROJECTS $test_project
650 if [ $? -ne 0 ]; then
651 Test_Info "Prepare test project file failed"
652 return 1
653 fi
654
655 # Extract toolchain tarball into ${TEST_TMP}
656 Test_Toolchain_Prepare $TOOLCHAIN_DIR $SDK_NAME
657 ret=$?
658 if [ $ret -ne 0 ]; then
659 Test_Info "Prepare toolchain test environment failed"
660 return $ret
661 fi
662
663 if [ ! -d ${pro_install} ]; then
664 mkdir -p ${pro_install}
665 fi
666
667 # Begin to build test project in toolchain environment
668 env_setup=`find ${TOOLCHAIN_TEST}/poky -name "environment-setup*"`
669
670 source $env_setup
671
672 if [ $test_project == "cvs" -o $test_project == "iptables" ]; then
673 cd ${TEST_TMP}/${test_project}-${PROJECT_PV}
674 Test_Time_Out $timeout ./configure ${CONFIGURE_FLAGS} || { Test_Info "configure failed with $test_project"; return 1; }
675 Test_Time_Out $timeout make -j4 || { Test_Info "make failed with $test_project"; return 1; }
676 Test_Time_Out $timeout make install DESTDIR=${pro_install} || { Test_Info "make failed with $test_project"; return 1; }
677 cd -
678 ret=0
679 elif [ $test_project == "sudoku-savant" ]; then
680 cd ${TEST_TMP}/${test_project}-${PROJECT_PV}
681 Test_Time_Out $timeout ./configure ${CONFIGURE_FLAGS} || { Test_Info "configure failed with $test_project"; return 1; }
682 Test_Time_Out $timeout make -j4 || { Test_Info "make failed with $test_project"; return 1; }
683 cd -
684 ret=0
685 else
686 Test_Info "Unknown test project $test_project"
687 ret=1
688 fi
689
690 return $ret
691 }