1#!/bin/bash
2
3cd "$(dirname $0)"
4
5if [ -z "$TESTDIR" ] ; then
6	TESTDIR=$(pwd)/../
7fi
8
9if [ -n "$HWSIM_TEST_LOG_DIR" ] ; then
10	LOGS="$HWSIM_TEST_LOG_DIR"
11else
12	LOGS=/tmp/hwsim-test-logs
13fi
14
15# increase the memory size if you want to run with valgrind, 512 MB works
16MEMORY=256
17
18# Some ubuntu systems (notably 12.04) have issues with this - since the guest
19# mounts as read-only it should be safe to not specify ,readonly. Override in
20# vm-config if needed (see below)
21ROTAG=,readonly
22
23# set this to ttyS0 to see kvm messages (if something doesn't work)
24KVMOUT=ttyS1
25
26# you can set EPATH if you need anything extra in $PATH inside the VM
27#EPATH=/some/dir
28
29# extra KVM arguments, e.g., -s for gdbserver
30#KVMARGS=-s
31
32# number of channels each hwsim device supports
33CHANNELS=1
34
35test -f vm-config && . vm-config
36test -f ~/.wpas-vm-config && . ~/.wpas-vm-config
37
38if [ -z "$KERNEL" ] && [ -z "$KERNELDIR" ] ; then
39	echo "You need to set a KERNEL or KERNELDIR (in the environment or vm-config)"
40	exit 2
41fi
42if [ -z "$KERNEL" ] ; then
43	if [ -e $KERNELDIR/arch/x86_64/boot/bzImage ]; then
44		KERNEL=$KERNELDIR/arch/x86_64/boot/bzImage
45	elif [ -e $KERNELDIR/linux ]; then
46		KERNEL=$KERNELDIR/linux
47	else
48		echo "No suitable kernel image found from KERNELDIR"
49		exit 2
50	fi
51fi
52if [ ! -e $KERNEL ]; then
53	echo "Kernel image not found: $KERNEL"
54	exit 2
55fi
56
57
58CMD=$TESTDIR/vm/inside.sh
59
60unset RUN_TEST_ARGS
61TIMESTAMP=$(date +%s)
62DATE=$TIMESTAMP
63CODECOV=no
64TIMEWARP=0
65GDB=0
66TELNET_QEMU=
67TELNET_ARG=0
68CODECOV_DIR=
69while [ "$1" != "" ]; do
70	case $1 in
71		--timestamp ) shift
72			TIMESTAMP=$1
73			shift
74			;;
75		--ext ) shift
76			DATE=$TIMESTAMP.$1
77			shift
78			;;
79		--codecov ) shift
80			CODECOV=yes
81			;;
82		--codecov_dir ) shift
83			CODECOV_DIR=$1
84			shift
85			;;
86		--timewrap ) shift
87			TIMEWARP=1
88			;;
89		--gdb ) shift
90			GDB=1
91			;;
92		--telnet ) shift
93			TELNET_ARG=1
94			TELNET_QEMU="-net nic,model=virtio -net user,id=telnet,restrict=on,net=172.16.0.0/24,hostfwd=tcp:127.0.0.1:$1-:23"
95			shift
96			;;
97		* )
98			RUN_TEST_ARGS="$RUN_TEST_ARGS$1 "
99			shift
100			;;
101	esac
102done
103
104LOGDIR=$LOGS/$DATE
105mkdir -p $LOGDIR
106rm -f $LOGS/latest
107ln -s $LOGDIR $LOGS/latest
108
109if [ -n "$CODECOV_DIR" ]; then
110    cp -a $CODECOV_DIR/alt-wpa_supplicant $LOGDIR
111    cp -a $CODECOV_DIR/alt-hostapd $LOGDIR
112    cp -a $CODECOV_DIR/alt-hostapd-as $LOGDIR
113    cp -a $CODECOV_DIR/alt-hlr_auc_gw $LOGDIR
114elif [ $CODECOV = "yes" ]; then
115    ./build-codecov.sh $LOGDIR || exit 1
116else
117    CODECOV=no
118fi
119
120echo "Starting test run in a virtual machine"
121
122if [ -x $KERNEL ]; then
123	unset KVM
124else
125	KVM=kvm
126	for kvmprog in kvm qemu-kvm; do
127		if $kvmprog --version &> /dev/null; then
128			KVM=$kvmprog
129			break
130		fi
131	done
132fi
133
134argsfile=$(mktemp)
135if [ $? -ne 0 ] ; then
136	exit 2
137fi
138function finish {
139	rm -f $argsfile
140}
141trap finish EXIT
142
143if [ -z $KVM ]; then
144	RUN_TEST_ARGS="--long $RUN_TEST_ARGS"
145fi
146echo "$RUN_TEST_ARGS" > $argsfile
147
148A="mac80211_hwsim.support_p2p_device=0 "
149A+="mac80211_hwsim.channels=$CHANNELS "
150A+="mac80211_hwsim.radios=7 "
151A+="cfg80211.dyndbg=+p "
152A+="mac80211.dyndbg=+p "
153A+="mac80211_hwsim.dyndbg=+p "
154A+="init=$CMD "
155A+="TESTDIR=$TESTDIR "
156A+="TIMEWARP=$TIMEWARP "
157A+="MODULEDIR=$MODULEDIR "
158A+="TELNET=$TELNET_ARG "
159A+="EPATH=$EPATH "
160A+="ARGS=$argsfile "
161A+="console=$KVMOUT "
162COMMITID="$(git rev-parse HEAD)"
163if [ -n "$COMMITID" ]; then
164    A+="COMMITID=$COMMITID "
165fi
166A+="ro"
167
168if [ -z $KVM ]; then
169	UML_ARGS="mem=${MEMORY}M \
170	     LOGDIR=$LOGDIR \
171	     time-travel=inf-cpu \
172	     $A \
173	     root=none hostfs=/ rootfstype=hostfs rootflags=/ \
174	     ssl0=fd:0,fd:1 \
175	     ssl1=fd:100 \
176	     ssl-non-raw"
177
178	if [ "$GDB" = "1" ] ; then
179		export KERNELDIR=$KERNELDIR
180		export MODULEDIR=$MODULEDIR
181		gdb -ex "source linux.gdb" --args $KERNEL $UML_ARGS 100<>$LOGDIR/console
182	else
183		$KERNEL $UML_ARGS 100<>$LOGDIR/console 2>&1 | sed -u '0,/VM has started up/d'
184	fi
185else
186	$KVM \
187	    -kernel $KERNEL \
188	    -smp 4 \
189	    $KVMARGS \
190	    -m $MEMORY \
191	    -nographic \
192	    -fsdev local,security_model=none,id=fsdev-root,path=/$ROTAG \
193	    -device virtio-9p-pci,id=fs-root,fsdev=fsdev-root,mount_tag=/dev/root \
194	    -fsdev local,security_model=none,id=fsdev-logs,path="$LOGDIR",writeout=immediate \
195	    -device virtio-9p-pci,id=fs-logs,fsdev=fsdev-logs,mount_tag=logshare \
196	    -monitor null \
197	    -serial stdio \
198	    -serial file:$LOGDIR/console \
199	    $TELNET_QEMU \
200	    -append "$A root=/dev/root rootflags=trans=virtio,version=9p2000.u rootfstype=9p" | \
201	    sed -u '0,/VM has started up/d'
202fi
203
204if [ $CODECOV = "yes" ]; then
205    echo "Preparing code coverage reports"
206    ./process-codecov.sh $LOGDIR "" restore
207    ./combine-codecov.sh $LOGDIR lcov
208fi
209
210echo
211echo "Test run completed"
212echo "Logfiles are at $LOGDIR ($LOGS/latest)"
213if [ $CODECOV = "yes" ]; then
214    echo "Code coverage report:"
215    echo "file://$LOGDIR/lcov/index.html"
216fi
217