Bumped the version of the ovirt-node-image project to 1.9.0 to match the
[ovirt-node-image.git] / autotest.sh
blob7503be0540a19ecb28fb3b0df3ff44e1c1d3b22a
1 #!/bin/bash
3 # oVirt node image autotest script
5 # Copyright (C) 2009 Red Hat, Inc.
6 # Written by Darryl L. Pierce <dpierce@redhat.com>
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; version 2 of the License.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 # MA 02110-1301, USA. A copy of the GNU General Public License is
21 # also available at http://www.gnu.org/copyleft/gpl.html.
23 # To include autotesting on the build system, you need to insert the
24 # following snippet *BEFORE* the text that reads "Output Stages":
25 # ---8<[begin]---
26 # # Integration test
27 # {
28 # name = integration
29 # label = Test group
30 # module = Test::AutoBuild::Stage::Test
31 # # Don't abort entire cycle if the module test fails
32 # critical = 0
33 # }
34 # ---8<[end]---
36 # This will, for each module whose autobuild.sh is run, to have a matching
37 # autotest.sh to run as well.
39 # To run these tests locally, you will need to open port 69 TCP and UDP and have
40 # an ISO file.
42 ME=$(basename "$0")
43 WORKDIR=$(mktemp -d)
44 warn() { printf '%s: %s\n' "$ME" "$*" >&2; }
45 die() { warn "$*"; exit 1; }
46 debug() { if $debugging; then log "[DEBUG] %s" "$*"; fi }
48 trap '__st=$?; cleanup_after_testing; exit $__st' 1 2 3 13 15
49 trap 'cleanup_after_testing' 0
51 # set -e
52 # set -u
54 log () {
55 date=$(date)
56 printf "${date} $*\n"
59 usage () {
60 cat <<EOF
61 Usage: $ME [-n test_name] [LOGFILE]
62 -i: set the ISO filename (defualt: ovirt-node-image.iso)
63 -n: the name of the specific autotest to run (default: run all autotests)
64 -d: enable more verbose output (default: disabled)
65 -t: change the timeout between markers (in ms, default: 120)
66 -v: enable tracing (default: disabled)
67 -w: launch virt-viewer for each VM (default: no window shown)
68 -h: display this help and exit
69 EOF
72 # $1 - the test function to call
73 execute_test () {
74 local testname=$1
76 if [ -z $testname ]; then die "Missing test name"; fi
78 log "Executing test: $testname"
80 eval $testname
82 rc=$?
83 log "Completed test: $testname [result=$rc]"
85 if [ $rc -ne 0 ]; then
86 log "Build fails smoke tests."
89 return $rc
92 # setup a node for pxeboot
93 # $1 - the working directory
94 # $2 - kernel arguments; if present then they replace all default flags
95 setup_pxeboot () {
96 local workdir=$1
97 local kernelargs=$2
98 local pxedefault=$workdir/tftpboot/pxelinux.cfg/default
100 debug "setup for pxeboot: isofile=${isofile} workdir=${workdir} kernelargs='${kernelargs}' pxedefault=${pxedefault}"
101 (cd $workdir && sudo livecd-iso-to-pxeboot $isofile) > /dev/null 2>&1
102 sudo chmod -R 777 $workdir
104 # set default kernel arguments if none were provided
105 # the defaults boot in standalone mode
106 if [ -z "$kernelargs" ]; then
107 kernelargs="standalone"
110 local definition="DEFAULT pxeboot"
111 definition="${definition}\nTIMEOUT 20"
112 definition="${definition}\nPROMPT 0"
113 definition="${definition}\nLABEL pxeboot"
114 definition="${definition}\n KERNEL vmlinuz0"
115 definition="${definition}\n IPAPPEND 2"
116 definition="${definition}\n APPEND rootflags=loop initrd=initrd0.img root=/${isoname} rootfstype=auto console=tty0 check console=ttyS0,115200n8 $kernelargs"
118 debug "pxeboot definition=\n${definition}"
119 sudo bash -c "printf \"${definition}\" > $pxedefault"
122 # Starts a simple instance of dnsmasq.
123 # $1 - the iface on which dnsmasq works
124 # $2 - the root for tftp files
125 # $3 - the mac address for the node (ignored if blank)
126 # $4 - the nodename
127 start_dnsmasq () {
128 local iface=$1
129 local tftproot=$2
130 local macaddress=$3
131 local nodename=$4
132 local pidfile=$2/dnsmasq.pid
134 stop_dnsmasq
135 debug "Starting dnsmasq"
136 dns_startup="sudo /usr/sbin/dnsmasq --read-ethers
137 --dhcp-range=${NETWORK}.100,${NETWORK}.254,255.255.255.0,24h
138 --conf-file=
139 --interface=${iface}
140 --bind-interfaces
141 --except-interface=lo
142 --dhcp-boot=tftpboot/pxelinux.0
143 --enable-tftp
144 --tftp-root=${tftproot}
145 --log-facility=$WORKDIR/dnsmasq-${nodename}.log
146 --log-queries
147 --log-dhcp
148 --pid-file=${pidfile}"
149 if [ -n "$macaddress" ]; then
150 dns_startup="${dns_startup} --dhcp-host=${macaddress},${NODE_ADDRESS}"
152 # start dnsmasq
153 eval $dns_startup
154 debug "pidfile=$pidfile"
155 DNSMASQ_PID=$(sudo cat $pidfile)
156 debug "DNSMASQ_PID=${DNSMASQ_PID}"
159 # Kills the running instance of dnsmasq.
160 stop_dnsmasq () {
161 if [ -n "${DNSMASQ_PID-}" -a "${DNSMASQ_PID-}" != "0" ]; then
162 local check=$(ps -ef | awk "/${DNSMASQ_PID}/"' { if ($2 ~ '"${DNSMASQ_PID}"') print $2 }')
164 if [[ "${check}" == "${DNSMASQ_PID}" ]]; then
165 sudo kill -9 $DNSMASQ_PID
166 return
169 DNSMASQ_PID="0"
172 # Creates a virt network.
173 # $1 - the node name
174 # $2 - the network interface name
175 # $3 - use DHCP (any value)
176 # $4 - start dnsmsq (def. false)
177 start_networking () {
178 local nodename=$1
179 local ifacename=$2
180 local use_dhcp=${3-false}
181 local start_dnsmasq=${4-false}
182 local workdir=$5
183 local definition=""
184 local network=$NETWORK
185 local xmlfile=$WORKDIR/$nodename-$ifacename.xml
187 debug "start_networking ()"
188 for var in nodename ifacename use_dhcp start_dnsmasq workdir network xmlfile; do
189 eval debug "::$var: \$$var"
190 done
192 definition="<network>\n<name>${ifacename}</name>\n<forward mode='nat' />\n<bridge name='${ifacename}' stp='on' forwardDelay='0' />"
193 definition="${definition}\n<ip address='${network}.1' netmask='255.255.255.0'>"
194 if $use_dhcp; then
195 definition="${definition}\n<dhcp>\n<range start='${network}.100' end='${network}.199' />\n</dhcp>"
197 definition="${definition}\n</ip>\n</network>"
199 debug "Saving network definition file to: ${xmlfile}\n"
200 sudo printf "${definition}" > $xmlfile
201 sudo virsh net-define $xmlfile > /dev/null 2>&1
202 debug "Starting network."
203 sudo virsh net-start $ifacename > /dev/null 2>&1
205 if [ "${use_dhcp}" == "false" ]; then
206 if $start_dnsmasq; then
207 start_dnsmasq $ifacename $workdir "" $nodename
212 # Destroys the test network interface
213 # $1 - the network name
214 # $2 - stop dnsmasq (def. false)
215 stop_networking () {
216 local networkname=${1-}
217 local stop_dnsmasq=${2-true}
219 # if no network was supplied, then check for the global network
220 if [ -z "$networkname" ]; then
221 networkname=${NETWORK_NAME-}
224 # exit if preserve was enabled
225 if $preserve_vm; then return; fi
227 if [ -n "${networkname}" ]; then
228 debug "Destroying network interface: ${networkname}"
229 check=$(sudo virsh net-list --all)
230 if [[ "${check}" =~ "${networkname}" ]]; then
231 if [[ "{$check}" =~ active ]]; then
232 sudo virsh net-destroy $networkname > /dev/null 2>&1
234 sudo virsh net-undefine $networkname > /dev/null 2>&1
238 if $stop_dnsmasq; then
239 stop_dnsmasq
243 # creates a HD disk file
244 # $1 - filename for disk file
245 # $2 - size (##M or ##G)
246 create_hard_disk () {
247 local filename=$1
248 local size=$2
250 debug "Creating hard disk: filename=${filename} size=${size}"
251 sudo qemu-img create -f raw $filename "${size}M" > /dev/null 2>&1
252 sudo chcon -t virt_image_t $filename > /dev/null 2>&1
255 # Creates the XML for a virtual machine.
256 # $1 - the file to write the xml
257 # $2 - the node name
258 # $3 - memory size (in kb)
259 # $4 - boot device
260 # $5 - the local hard disk (if blank then no disk is used)
261 # $6 - the cdrom disk (if blank then no cdrom is used)
262 # $7 - the network bridge (if blank then 'default' is used)
263 # $8 - optional arguments
264 define_node () {
265 local filename=$1
266 local nodename=$2
267 local memory=$3
268 local boot_device=$4
269 local harddrive=$5
270 local cddrive=$6
271 local bridge=${7-default}
272 local options=${8-}
273 local result=""
275 # flexible options
276 # define defaults, then allow the caller to override them as needed
277 local arch=$(uname -i)
278 local serial="true"
279 local vncport="-1"
280 local bootdev='hd'
282 # first destroy the node
283 destroy_node $nodename
285 if [ -n "$options" ]; then eval "$options"; fi
287 debug "define_node ()"
288 for var in filename nodename memory harddrive cddrive bridge options arch serial vncport bootdev; do
289 eval debug "::$var: \$$var"
290 done
292 result="<domain type='kvm'>\n<name>${nodename}</name>\n<memory>${memory}</memory>\n <vcpu>1</vcpu>"
294 # begin the os section
295 # inject the boot device
296 result="${result}\n<os>\n<type arch='${arch}' machine='pc'>hvm</type>"
297 result="${result}\n<boot dev='${boot_device}' />"
298 result="${result}\n</os>"
300 # virtual machine features
301 result="${result}\n<features>"
302 result="${result}\n<acpi />"
303 if [ -z "${noapic-}" ]; then result="${result}\n<apic />"; fi
304 result="${result}\n<pae /></features>"
305 result="${result}\n<clock offset='utc' />"
306 result="${result}\n<on_poweroff>destroy</on_poweroff>"
307 result="${result}\n<on_reboot>restart</on_reboot>"
308 result="${result}\n<on_crash>restart</on_crash>"
310 # add devices
311 result="${result}\n<devices>"
312 # inject the hard disk if defined
313 if [ -n "$harddrive" ]; then
314 debug "Adding a hard drive to the node"
315 result="${result}\n<disk type='file' device='disk'>"
316 result="${result}\n<source file='$harddrive' />"
317 result="${result}\n<target dev='vda' bus='virtio' />"
318 result="${result}\n</disk>"
320 # inject the cdrom drive if defined
321 if [ -n "$cddrive" ]; then
322 debug "Adding a CDROM drive to the node"
323 result="${result}\n<disk type='file' device='cdrom'>"
324 result="${result}\n<source file='${cddrive}' />"
325 result="${result}\n<target dev='hdc' bus='ide' />"
326 result="${result}\n</disk>"
328 # inject the bridge network
329 result="${result}\n<interface type='network'>"
330 result="${result}\n<source network='${bridge}' />"
331 result="${result}\n</interface>"
332 # inject the serial port
333 if [ -n "$serial" ]; then
334 result="${result}\n<serial type='pty' />"
336 # inject the vnc port
337 if [ -n "$vncport" ]; then
338 result="${result}\n<console type='pty' />"
339 result="${result}\n<graphics type='vnc' port='${vncport}' autoport='yes' keyman='en-us' />"
341 # finish the device section
342 result="${result}\n</devices>"
344 result="${result}\n</domain>"
346 debug "Node definition: ${filename}"
347 sudo printf "$result" > $filename
349 # now define the vm
350 sudo virsh define $filename > /dev/null 2>&1
352 if [ $? != 0 ]; then die "Unable to define virtual machine: $nodename"; fi
355 # $1 - the node name
356 # $2 - the boot device (def. "hd")
357 # $3 - the memory size in kb (def. 524288)
358 # $4 - hard disk size (if blank then no hard disk)
359 # $5 - the cd drive image file (if blank then no cd drive)
360 # $6 - option arguments
361 configure_node () {
362 local nodename=$1
363 local boot_device=$2
364 local memory=$3
365 local hdsize=$4
366 local hdfile=""
367 local cdfile=$5
368 local args=$6
369 local nodefile=$WORKDIR/$nodename.xml
371 if [ -z "${boot_device}" ]; then boot_device="hd"; fi
372 if [ -z "${memory}" ]; then memory="524288"; fi
374 debug "configure_node ()"
375 for var in nodename boot_device memory hdsize hdfile cdfile args nodefile; do
376 eval debug "::$var: \$$var"
377 done
379 # create the hard disk file
380 if [ -n "${hdsize}" ]; then
381 hdfile=$WORKDIR/$nodename-hd.img
382 create_hard_disk $hdfile $hdsize
385 define_node $nodefile $nodename "${memory}" "${boot_device}" "${hdfile}" "${cdfile}" $IFACE_NAME "${args}"
388 # $1 - the node name
389 # $2 - undefine the node (def. true)
390 destroy_node () {
391 local nodename=$1
392 local undefine=${2-true}
394 # if preserving nodes then exit
395 if $preserve_vm; then return; fi
397 if [ -n "${nodename}" ]; then
398 check=$(sudo virsh list --all)
399 if [[ "${check}" =~ "${nodename}" ]]; then
400 if [[ "${check}" =~ running ]]; then
401 sudo virsh destroy $nodename > /dev/null 2>&1
403 if $undefine; then
404 sudo virsh undefine $nodename > /dev/null 2>&1
410 # for each test created, add it to the follow array:
411 tests=''; testcount=0;
413 # $1 - test name
414 add_test () {
415 tests="${tests} $1"
418 # $1 - node name
419 start_virt_viewer () {
420 local nodename=$1
422 sudo virt-viewer $nodename > /dev/null 2>&1&
425 # $1 - the node's name
426 # $2 - kernel arguments
427 # $3 - working directory
428 boot_with_pxe () {
429 local nodename=$1
430 local kernel_args=$2
431 local workdir=$3
433 debug "boot_with_pxe ()"
434 debug "- workdir: ${workdir}"
435 debug "- nodename: ${nodename}"
436 debug "- kernel_args: ${kernel_args}"
438 setup_pxeboot $workdir "${kernel_args}"
440 sudo virsh start $nodename > /dev/null 2>&1
441 if $show_viewer; then
442 start_virt_viewer $nodename
446 # $1 - the node's name
447 boot_from_hd () {
448 local nodename=$1
450 debug "boot_from_hd ()"
451 debug "::nodename: ${nodename}"
453 sudo virsh start $nodename > /dev/null 2>&1
454 if $show_viewer; then
455 start_virt_viewer $nodename
459 # $1 - the node name
460 # $2 - the old boot device
461 # $3 - the new boot device
462 substitute_boot_device () {
463 local nodename=$1
464 local old_device=$2
465 local new_device=$3
466 local new_node_file=$WORKDIR/$nodename-new.xml
468 if [ -n "${nodename}" ]; then
469 local xml=$(sudo virsh dumpxml $nodename | sed "s/boot dev='"${old_device}"'/boot dev='"${new_device}"'/")
471 sudo printf "${xml}" > $new_node_file
473 sudo virsh define $new_node_file
477 add_test "test_stateless_pxe"
478 test_stateless_pxe () {
479 local nodename="${vm_prefix}-stateless-pxe"
480 local workdir=$WORKDIR
482 start_networking $nodename $IFACE_NAME false true $workdir
484 configure_node "${nodename}" "network" "" "10000" "" "local noapic=true"
485 boot_with_pxe "${nodename}" "standalone firstboot=no" "${workdir}"
487 expect -c '
488 set timeout '${timeout_period}'
490 log_file -noappend stateless-pxe.log
492 spawn sudo virsh console '"${nodename}"'
494 expect {
495 -exact "Linux version" { send_log "\n\nMarker 1\n\n"; exp_continue }
496 -exact "Starting ovirt-early:" { send_log "\n\nMarker 2\n\n"; exp_continue }
497 -exact "Starting ovirt:" { send_log "\n\nMarker 3\n\n"; exp_continue }
498 -exact "Starting ovirt-post:" { send_log "\n\nMarker 4\n\n"; exp_continue }
499 -re "localhost.*login:" { send_log "\n\nMarker 5\n\n"; exit }
500 timeout {
501 send_log "\nTimeout waiting for marker..\n\n"
502 exit 1
503 } eof {
504 send_log "Unexpected end of file."
505 exit 2
509 send_log "\n\nUnexpected end of interaction.\n\n"
510 exit 3'
511 result=$?
513 destroy_node $nodename
514 stop_networking $IFACE_NAME true
516 return $result
519 add_test "test_stateless_pxe_with_nohd"
520 test_stateless_pxe_with_nohd () {
521 local nodename="${vm_prefix}-stateless-pxe-nohd"
522 local workdir=$WORKDIR
524 start_networking $nodename $IFACE_NAME false true $workdir
526 configure_node "${nodename}" "network" "" "" "" "local noapic=true"
527 boot_with_pxe "${nodename}" "firstboot=no" "${workdir}"
529 expect -c '
530 set timeout '${timeout_period}'
532 log_file -noappend stateless-pxe.log
534 spawn sudo virsh console '"${nodename}"'
536 expect {
537 -exact "Linux version" { send_log "\n\nMarker 1\n\n"; exp_continue }
538 -exact "Starting ovirt-early:" { send_log "\n\nMarker 2\n\n"; exp_continue }
539 -exact "Starting ovirt:" { send_log "\n\nMarker 3\n\n"; exp_continue }
540 -exact "Starting ovirt-post:" { send_log "\n\nMarker 4\n\n"; exp_continue }
541 -re "localhost.*login:" { send_log "\n\nMarker 5\n\n"; exit }
542 timeout {
543 send_log "\nTimeout waiting for marker..\n\n"
544 exit 1
545 } eof {
546 send_log "Unexpected end of file."
547 exit 2
551 send_log "\n\nUnexpected end of interaction.\n\n"
552 exit 3'
554 result=$?
556 destroy_node $nodename
557 stop_networking $IFACE_NAME true
559 return $result
562 add_test "test_stateful_pxe"
563 test_stateful_pxe () {
564 local nodename="${vm_prefix}-stateful-pxe"
565 local workdir=$WORKDIR
566 local ipaddress=${NODE_ADDRESS}
568 for var in nodename workdir ipaddress; do
569 eval debug "::\$$var: $var"
570 done
572 start_networking $nodename $IFACE_NAME false true $workdir
574 configure_node "${nodename}" "network" "" "10000" "" "local noapic=true"
575 boot_with_pxe "${nodename}" "standalone storage_init=/dev/vda local_boot ip=${ipaddress}" ${workdir}
577 # verify the booting and installation
578 expect -c '
579 set timeout '${timeout_period}'
580 log_file -noappend stateful-pxe.log
582 spawn sudo virsh console '"${nodename}"'
584 expect {
585 -exact "Linux version" { send_log "\n\nMarker 1\n\n"; exp_continue }
586 -exact "Starting ovirt-early:" { send_log "\n\nMarker 2\n\n"; exp_continue }
587 -exact "Starting ovirt:" { send_log "\n\nMarker 3\n\n"; exp_continue }
588 -exact "Starting ovirt-post:" { send_log "\n\nMarker 4\n\n"; exp_continue }
589 -exact "Starting ovirt-firstpost:" { send_log "\n\nMarker 5\n\n"; exp_continue }
590 -exact "Starting partitioning of /dev/vda" { send_log "\n\nMarker 6\n\n"; exp_continue }
591 -exact "Restarting system" { send_log "\n\nMarker 7\n\n"; exit }
592 timeout {
593 send_log "\nTimeout waiting for marker..\n\n"
594 exit 1
595 } eof {
596 send_log "Unexpected end of file."
597 exit 2
601 send_log "\n\nUnexpected end of interaction.\n\n"
602 exit 3'
603 result=$?
605 # only continue if we're in a good state
606 if [ $result -eq 0 ]; then
607 destroy_node "${nodename}" false
608 substitute_boot_device "${nodename}" "network" "hd"
609 boot_from_hd "${nodename}"
611 expect -c '
612 set timeout '${timeout_period}'
613 log_file stateful-pxe.log
615 send_log "Restarted node, booting from hard disk.\n"
617 spawn sudo virsh console '"${nodename}"'
619 expect {
620 -re "localhost.*login:" { send_log "\n\nLogin marker found\n\n"; exit }
622 timeout {
623 send_log "\nMarker not found.\n\n"
624 exit 1
625 } eof {
626 send_log "Unexpected end of file."
627 exit 2
631 send_log "\n\nUnexpected end of interaction.\n\n"
633 exit 3
636 expect -c '
637 set timeout 3
638 log_file stateful-pxe.log
640 spawn ping -c 3 '"${ipaddress}"'
642 expect {
643 -exact "64 bytes from '"${ipaddress}"'" { send_log "\n\nGot ping response!\n"; send_log "\n\nNetworking verified!\n"; exit }
645 timeout {
646 send_log "\nMarker not found.\n\n"
647 exit 1
648 } eof {
649 send_log "Unexpected end of file."
650 exit 2
654 send_log "\n\nUnexpected end of interaction.\n\n"
656 exit 3'
658 result=$?
661 destroy_node $nodename
662 stop_networking $IFACE_NAME true
664 return $result
668 # configures the environment for testing
669 setup_for_testing () {
670 debug "WORKDIR=${WORKDIR}"
671 debug "isofile=${isofile}"
672 debug "isoname=${isoname}"
673 IFACE_NAME=testbr$$
674 debug "IFACE_NAME=${IFACE_NAME}"
675 NETWORK=192.168.$(echo "scale=0; print $$ % 255" | bc -l)
676 debug "NETWORK=${NETWORK}"
677 NODE_ADDRESS=$NETWORK.100
678 debug "NODE_ADDRESS=${NODE_ADDRESS}"
679 DNSMASQ_PID=0
680 debug "preserve_vm=${preserve_vm}"
683 # cleans up any loose ends
684 cleanup_after_testing () {
685 debug "Cleaning up"
686 stop_dnsmasq
687 stop_networking
688 # destroy any running vms
689 vm_list=$(sudo virsh list --all | awk '/'${vm_prefix}-'/ { print $2 }')
690 test -n "$vm_list" && for vm in $vm_list; do
691 destroy_node $vm
692 done
693 stop_networking
695 # do not delete the work directory if preserve was specified
696 if $preserve_vm; then return; fi
698 rm -rf $WORKDIR
701 # check commandline options
702 test=''
703 debugging=false
704 isofile="${PWD}/ovirt-node-image.iso"
705 show_viewer=false
706 vm_prefix="$$"
707 preserve_vm=false
708 timeout_period="120"
710 while getopts di:n:pt:vwh c; do
711 case $c in
712 d) debugging=true;;
713 i) isofile=($OPTARG);;
714 n) tests=($OPTARG);;
715 p) preserve_vm=true;;
716 t) timeout_period=($OPTARG);;
717 v) set -v;;
718 w) show_viewer=true;;
719 h) usage; exit 0;;
720 '?') die "invalid option \`-$OPTARG'";;
721 :) die "missing argument to \`-$OPTARG' option";;
722 *) die "internal error";;
723 esac
724 done
726 isoname=$(basename $isofile)
727 isofile="$(cd `dirname $isofile`; pwd)/${isoname}"
729 if ! [ -s "${isofile}" ]; then
730 die "Missing or invalid file: ${isofile}"
733 shift $(($OPTIND - 1))
735 set +u
736 if [ $# -gt 0 -a -n "$1" ]; then RESULTS=$1; else RESULTS=autotest.log; fi
737 set -u
739 result_file=$WORKDIR/results.log
740 debug "result_file=${result_file}"
742 log "Logging results to file: ${RESULTS}"
744 setup_for_testing
746 log "Begin Testing: ${isoname}"
747 log "Tests: ${tests}"
748 log "Timeout: ${timeout_period} ms"
750 for test in ${tests}; do
751 execute_test $test
752 result=$?
754 if [ $result != 0 ]; then
755 echo "${result}" > $result_file
756 break
758 done
760 log "End Testing: ${isoname}"
762 } | sudo tee --append $RESULTS
764 if [ -s "$result_file" ]; then
765 exit $(cat $result_file)