qemu-test: add support for named choices
[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 named_choose() {
117     option="$QEMU_TEST_NAME"
118     if test "$QEMU_TEST_PROFILE"; then
119         option="$option.$QEMU_TEST_PROFILE"
120     fi
121     option="$option.$1"
122     shift
123
124     choices=`git config -f ~/.qemu-testrc $option`
125     if test "$choices"; then
126         # FIXME compute intersection of $choices and $@
127         choose $choices
128     else
129         choose "$@"
130     fi
131 }
132
133 named_choose_bool() {
134     if test `named_choose "$1" "yes" "no"` = "yes"; then
135         return 0
136     fi
137
138     return 1
139 }
140
141
142 start_qemu() {
143     e $qemu -kernel $kernel -initrd $tmpinitrd \
144             -append "console=ttyS0 seed=$seed" "$@" \
145             -pidfile $tmppid -qmp unix:$tmpqmp,server,nowait | tee $tmplog &
146     pid=$!
147
148     last_log_size=`get_file_size $tmplog`
149     freeze_count=0
150 }
151
152 qemu_is_okay() {
153     # it's stopped, that's not necessarly bad
154     if ! checkpid $pid; then
155         return 1
156     fi
157  
158     log_size=`get_file_size $tmplog`
159     if test $last_log_size = $log_size; then
160         freeze_count=$(($freeze_count + 1))
161     else
162         freeze_count=0
163         last_log_size=$log_size
164     fi
165     if test $freeze_count -gt $FREEZE_THRESHOLD && checkpid $pid; then
166         qemu_pid=`cat $tmppid`
167         kill -9 $qemu_pid
168         echo "Guest ($qemu_pid) has not had output in $FREEZE_THRESHOLD seconds!"
169         return 2
170     fi
171
172     if ! qmp query-status >/dev/null 2>/dev/null && checkpid $pid; then
173         qemu_pid=`cat $tmppid`
174         
175         kill -9 $qemu_pid
176         echo "QEMU is hung!"
177         return 3
178     fi
179
180     # it's stopped, that's not necessarly bad
181     if ! checkpid $pid; then
182         return 1
183     fi
184 }
185
186 get_qemu_status() {
187     wait $pid
188     rc=`cat $tmprc`
189     if test $(($rc & 1)) = 1; then
190         rc=$(($rc / 2))
191     fi
192     return $rc
193 }
194
195 qemu() {
196     start_qemu "$@"
197
198     while qemu_is_okay; do
199         sleep 1
200     done
201
202     get_qemu_status
203 }
204
205 QEMU_TEST=1
206
207 QEMU_TEST_NAME=$(basename $1 .sh)
208
209 . "$1"
210 rc=$?
211
212 rm -f $tmplog $tmppid $tmpqmp $tmpinitrd
213 rm -rf $tmpdir $tmprc
214
215 exit $rc