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	     umid=hwsim-$DATE \
172	     time-travel=inf-cpu \
173	     $A \
174	     root=none hostfs=/ rootfstype=hostfs rootflags=/ \
175	     ssl0=fd:0,fd:1 \
176	     ssl1=fd:100 \
177	     ssl-non-raw"
178
179	if [ "$GDB" = "1" ] ; then
180		export KERNELDIR=$KERNELDIR
181		export MODULEDIR=$MODULEDIR
182		gdb -ex "source linux.gdb" --args $KERNEL $UML_ARGS 100<>$LOGDIR/console
183	else
184		$KERNEL $UML_ARGS 100<>$LOGDIR/console 2>&1 | sed -u '0,/VM has started up/d'
185	fi
186else
187	$KVM \
188	    -kernel $KERNEL \
189	    -smp 4 \
190	    $KVMARGS \
191	    -m $MEMORY \
192	    -nographic \
193	    -fsdev local,security_model=none,id=fsdev-root,path=/$ROTAG \
194	    -device virtio-9p-pci,id=fs-root,fsdev=fsdev-root,mount_tag=/dev/root \
195	    -fsdev local,security_model=none,id=fsdev-logs,path="$LOGDIR",writeout=immediate \
196	    -device virtio-9p-pci,id=fs-logs,fsdev=fsdev-logs,mount_tag=logshare \
197	    -monitor null \
198	    -serial stdio \
199	    -serial file:$LOGDIR/console \
200	    $TELNET_QEMU \
201	    -append "$A root=/dev/root rootflags=trans=virtio,version=9p2000.u rootfstype=9p" | \
202	    sed -u '0,/VM has started up/d'
203fi
204
205if [ $CODECOV = "yes" ]; then
206    echo "Preparing code coverage reports"
207    ./process-codecov.sh $LOGDIR "" restore
208    ./combine-codecov.sh $LOGDIR lcov
209fi
210
211echo
212echo "Test run completed"
213echo "Logfiles are at $LOGDIR ($LOGS/latest)"
214if [ $CODECOV = "yes" ]; then
215    echo "Code coverage report:"
216    echo "file://$LOGDIR/lcov/index.html"
217fi
218