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