Split up qemu invocation and fix exit status
[qemu-test.git] / qemu-test
1 #!/bin/sh
2
3 if test -z "$1" -o -z "$2"; then
4     echo "Usage: $0 QEMU TEST1 [TEST2 ...]"
5     exit 1
6 fi
7
8 qemu=$1
9 shift
10
11 FREEZE_THRESHOLD=10
12 QMP_TIMEOUT=10
13
14 kernel=bin/vmlinuz-3.0
15 initrd=bin/initramfs-1.9.2.img.gz
16
17 if test -z $QEMU_SRC; then
18     QEMU_SRC=~/git/qemu
19 fi
20
21 qmp="${QEMU_SRC}/QMP/qmp"
22
23 if ! test -x "${qmp}"; then
24     echo "Please set QEMU_SRC to set to a recent qemu.git tree"
25     exit 1
26 fi
27
28 tmpdir=.tmp-$$
29 tmpinitrd=$tmpdir/initramfs-$$.img.gz
30 tmplog=$tmpdir/logfile-$$.log
31 tmppid=$tmpdir/pidfile-$$.pid
32 tmpqmp=$tmpdir/qmpsock-$$.sock
33 tmprc=$tmpdir/rc.out
34
35 if test "$QEMU_TEST_SEED"; then
36     seed=$QEMU_TEST_SEED
37 else
38     seed=`(dd if=/dev/urandom bs=2 count=1 | hexdump -e '/2 "%u\n"') 2>/dev/null`
39 fi
40
41 RANDOM=$seed
42
43 echo "Using RANDOM seed $seed"
44
45 mkdir -p $tmpdir
46 util/mktest-initramfs.sh $initrd "$@" > $tmpinitrd
47
48 checkpid() {
49     kill -0 $1 2>/dev/null
50 }
51
52 get_file_size() {
53     ls -al $1 | cut -f5 -d' ' 2>/dev/null
54     if test $? != 0; then
55         echo 0
56     fi
57 }
58
59 qmp() {
60     $qmp --path=$tmpqmp "$@" &
61     qmp_pid=$!
62     count=0
63     while checkpid $qmp_pid; do
64         sleep 1
65         count=$(($count + 1))
66         if test $count -gt $QMP_TIMEOUT; then
67             echo $count, $QMP_TIMEOUT
68             kill -9 $qmp_pid
69             return 1
70         fi
71     done
72     return 0
73 }
74
75 e() {
76     echo "$@"
77     "$@"
78     rc=$?
79     echo $rc > $tmprc
80     return $rc
81 }
82
83 choose() {
84     local count=0
85     local target=0
86
87     target=$(($RANDOM % $#))
88     count=0
89     for i in "$@"; do
90         if test $count = $target; then
91             echo $i
92             return 0
93         fi
94         count=$(($count + 1))
95     done
96
97     # not supposed to happen...
98     echo $1
99 }
100
101 start_qemu() {
102     e $qemu -kernel $kernel -initrd $tmpinitrd \
103             -append "console=ttyS0 seed=$seed" "$@" \
104             -pidfile $tmppid -qmp unix:$tmpqmp,server,nowait | tee $tmplog &
105     pid=$!
106
107     last_log_size=`get_file_size $tmplog`
108     freeze_count=0
109 }
110
111 qemu_is_okay() {
112     # it's stopped, that's not necessarly bad
113     if ! checkpid $pid; then
114         return 1
115     fi
116  
117     log_size=`get_file_size $tmplog`
118     if test $last_log_size = $log_size; then
119         freeze_count=$(($freeze_count + 1))
120     else
121         freeze_count=0
122         last_log_size=$log_size
123     fi
124     if test $freeze_count -gt $FREEZE_THRESHOLD && checkpid $pid; then
125         qemu_pid=`cat $tmppid`
126         kill -9 $qemu_pid
127         echo "Guest ($qemu_pid) has not had output in $FREEZE_THRESHOLD seconds!"
128         return 2
129     fi
130
131     if ! qmp query-status >/dev/null 2>/dev/null && checkpid $pid; then
132         qemu_pid=`cat $tmppid`
133         
134         kill -9 $qemu_pid
135         echo "QEMU is hung!"
136         return 3
137     fi
138
139     # it's stopped, that's not necessarly bad
140     if ! checkpid $pid; then
141         return 1
142     fi
143 }
144
145 get_qemu_status() {
146     wait $pid
147     rc=`cat $tmprc`
148     if test $(($rc & 1)) = 1; then
149         rc=$(($rc / 2))
150     fi
151     return $rc
152 }
153
154 qemu() {
155     start_qemu "$@"
156
157     while qemu_is_okay; do
158         sleep 1
159     done
160
161     get_qemu_status
162 }
163
164 QEMU_TEST=1
165
166 . "$1"
167 rc=$?
168
169 rm -f $tmplog $tmppid $tmpqmp $tmpinitrd
170 rm -rf $tmpdir $tmprc
171
172 exit $rc