1#!/bin/bash
2
3set -ex -o pipefail
4
5# One of:              dom0:   Testing:
6#  - dom0pv              PV      PVH domU
7#  - dom0pvh             PVH     PVH domU
8#  - dom0pvh-hvm         PVH     HVM domU
9#  - pci-hvm             PV      HVM domU + PCI Passthrough
10#  - pci-pv              PV      PV domU + PCI Passthrough
11#  - pvshim              PV      PVSHIM domU
12#  - s3                  PV      S3 suspend/resume
13#  - tools-tests-pv      PV      Run tests from tools/tests/*
14#  - tools-tests-pvh     PVH     Run tests from tools/tests/*
15test_variant=$1
16
17### defaults
18extra_xen_opts=
19wait_and_wakeup=
20timeout=120
21domU_type="pvh"
22domU_vif="'bridge=xenbr0',"
23domU_extra_config=
24retrieve_xml=
25dom0_rootfs_extra_comp=()
26dom0_rootfs_extra_uncomp=()
27
28case "${test_variant}" in
29    ### test: smoke test & smoke test PVH & smoke test HVM & smoke test PVSHIM
30    "dom0pv"|"dom0pvh"|"dom0pvh-hvm"|"pvshim")
31        passed="ping test passed"
32        domU_check="
33ifconfig eth0 192.168.0.2
34until ping -c 10 192.168.0.1; do
35    sleep 1
36done
37echo \"${passed}\"
38"
39        dom0_check="
40set +x
41until grep -q \"${passed}\" /var/log/xen/console/guest-domU.log; do
42    sleep 1
43done
44set -x
45echo \"${passed}\"
46"
47        if [ "${test_variant}" = "dom0pvh" ] || [ "${test_variant}" = "dom0pvh-hvm" ]; then
48            extra_xen_opts="dom0=pvh"
49        fi
50
51        if [ "${test_variant}" = "dom0pvh-hvm" ]; then
52            domU_type="hvm"
53        elif [ "${test_variant}" = "pvshim" ]; then
54            domU_type="pvh"
55            domU_extra_config='pvshim = 1'
56        fi
57        ;;
58
59    ### test: S3
60    "s3")
61        passed="suspend test passed"
62        wait_and_wakeup="started, suspending"
63        domU_check="
64ifconfig eth0 192.168.0.2
65echo domU started
66"
67        dom0_check="
68until grep 'domU started' /var/log/xen/console/guest-domU.log; do
69    sleep 1
70done
71echo \"${wait_and_wakeup}\"
72# let the above message flow to console, then suspend
73sync /dev/stdout
74sleep 5
75set -x
76echo deep > /sys/power/mem_sleep
77echo mem > /sys/power/state
78xl list
79xl dmesg | grep 'Finishing wakeup from ACPI S3 state' || exit 1
80# check if domU is still alive
81ping -c 10 192.168.0.2 || exit 1
82echo \"${passed}\"
83"
84        ;;
85
86    ### test: pci-pv, pci-hvm
87    "pci-pv"|"pci-hvm")
88
89        if [ -z "$PCIDEV" ]; then
90            echo "Please set 'PCIDEV' variable with BDF of test network adapter" >&2
91            echo "Optionally set also 'PCIDEV_INTR' to 'MSI' or 'MSI-X'" >&2
92            exit 1
93        fi
94
95        passed="pci test passed"
96
97        domU_type="${test_variant#pci-}"
98        domU_vif=""
99
100        domU_extra_config='
101extra = "earlyprintk=xen"
102pci = [ "'$PCIDEV',seize=1" ]
103on_reboot = "destroy"
104'
105
106        domU_check="
107set -x -e
108interface=eth0
109while ! [ -e \"/sys/class/net/\$interface\" ]; do sleep 1; done
110ip link set \"\$interface\" up
111timeout 30s udhcpc -i \"\$interface\"
112pingip=\$(ip -o -4 r show default|cut -f 3 -d ' ')
113ping -c 10 \"\$pingip\"
114echo domU started
115pcidevice=\$(realpath /sys/class/net/\$interface/device |
116             sed 's#.*pci0000:00/\\([^/]*\\).*#\\1#')
117lspci -vs \$pcidevice
118"
119        if [ -n "$PCIDEV_INTR" ]; then
120            domU_check="$domU_check
121lspci -vs \$pcidevice | fgrep '$PCIDEV_INTR: Enable+'
122"
123        fi
124        domU_check="$domU_check
125echo \"${passed}\"
126"
127
128        dom0_check="
129until grep -q \"^domU Welcome to Alpine Linux\" /var/log/xen/console/guest-domU.log; do
130    sleep 1
131done
132"
133        ;;
134
135    ### tests: tools-tests-pv, tools-tests-pvh
136    "tools-tests-pv"|"tools-tests-pvh")
137        retrieve_xml=1
138        passed="test passed"
139        domU_check=""
140        dom0_check="
141/root/run-tools-tests /usr/lib/xen/tests /tmp/tests-junit.xml && echo \"${passed}\"
142nc -l -p 8080 < /tmp/tests-junit.xml >/dev/null &
143"
144        if [ "${test_variant}" = "tools-tests-pvh" ]; then
145            extra_xen_opts="dom0=pvh"
146        fi
147
148        ;;
149
150    *)
151        echo "Unrecognised test_variant '${test_variant}'" >&2
152        exit 1
153        ;;
154esac
155
156domU_config="
157type = '${domU_type}'
158name = 'domU'
159kernel = '/boot/vmlinuz-domU'
160ramdisk = '/boot/initrd-domU'
161cmdline = 'root=/dev/ram0 console=hvc0'
162memory = 512
163vif = [ ${domU_vif} ]
164disk = [ ]
165${domU_extra_config}
166"
167
168if [ -n "$domU_check" ]; then
169    # DomU rootfs
170    cp binaries/rootfs.cpio.gz binaries/domU-rootfs.cpio.gz
171
172    # test-local configuration
173    mkdir -p rootfs
174    cd rootfs
175    mkdir -p etc/local.d
176    echo "#!/bin/sh
177
178echo 8 > /proc/sys/kernel/printk
179
180${domU_check}
181" > etc/local.d/xen.start
182    chmod +x etc/local.d/xen.start
183    echo "domU Welcome to Alpine Linux
184Kernel \r on an \m (\l)
185
186" > etc/issue
187    find . | cpio -H newc -o | gzip >> ../binaries/domU-rootfs.cpio.gz
188    cd ..
189    rm -rf rootfs
190
191    # Package domU kernel+rootfs in /boot for dom0 (uncompressed)
192    mkdir -p rootfs/boot
193    cd rootfs
194    cp ../binaries/bzImage boot/vmlinuz-domU
195    cp ../binaries/domU-rootfs.cpio.gz boot/initrd-domU
196    find . | cpio -H newc -o > ../binaries/domU-in-dom0.cpio
197    cd ..
198    rm -rf rootfs
199
200    dom0_rootfs_extra_uncomp+=(binaries/domU-in-dom0.cpio)
201fi
202
203# Dom0 rootfs.  The order of concatenation is important; ucode wants to come
204# first, and all uncompressed must be ahead of compressed.
205dom0_rootfs_parts=(
206    binaries/ucode.cpio
207    "${dom0_rootfs_extra_uncomp[@]}"
208    binaries/rootfs.cpio.gz
209    binaries/xen-tools.cpio.gz
210    "${dom0_rootfs_extra_comp[@]}"
211)
212cat "${dom0_rootfs_parts[@]}" > binaries/dom0-rootfs.cpio.gz
213
214# test-local configuration
215mkdir -p rootfs
216cd rootfs
217mkdir -p boot etc/local.d root
218cp -a ../automation/scripts/run-tools-tests root/
219
220echo "#!/bin/bash
221
222bash /etc/init.d/xencommons start
223
224brctl addbr xenbr0
225brctl addif xenbr0 eth0
226ifconfig eth0 up
227ifconfig xenbr0 up
228ifconfig xenbr0 192.168.0.1
229
230" > etc/local.d/xen.start
231
232if [ -n "$retrieve_xml" ]; then
233    echo "timeout 30s udhcpc -i xenbr0" >> etc/local.d/xen.start
234fi
235
236if [ -n "$domU_check" ]; then
237    echo "
238# get domU console content into test log
239tail -F /var/log/xen/console/guest-domU.log 2>/dev/null | sed -e \"s/^/(domU) /\" &
240tail -F /var/log/xen/qemu-dm-domU.log 2>/dev/null | sed -e \"s/^/(qemu-dm) /\" &
241xl -vvv create /etc/xen/domU.cfg
242" >> etc/local.d/xen.start
243fi
244
245echo "${dom0_check}" >> etc/local.d/xen.start
246
247chmod +x etc/local.d/xen.start
248mkdir -p etc/xen
249echo "$domU_config" > etc/xen/domU.cfg
250
251mkdir -p etc/default
252echo "XENCONSOLED_TRACE=all" >> etc/default/xencommons
253echo "QEMU_XEN=/bin/false" >> etc/default/xencommons
254mkdir -p var/log/xen/console
255find . | cpio -H newc -o | gzip >> ../binaries/dom0-rootfs.cpio.gz
256cd ..
257
258
259TFTP=/scratch/gitlab-runner/tftp
260CONTROLLER=control@thor.testnet
261
262echo "
263multiboot2 (http)/gitlab-ci/xen $CONSOLE_OPTS loglvl=all guest_loglvl=all dom0_mem=4G console_timestamps=boot $extra_xen_opts
264module2 (http)/gitlab-ci/vmlinuz console=hvc0 root=/dev/ram0 earlyprintk=xen
265module2 --nounzip (http)/gitlab-ci/initrd-dom0
266" > $TFTP/grub.cfg
267
268echo "#!ipxe
269
270kernel /gitlab-ci/xen $CONSOLE_OPTS loglvl=all guest_loglvl=all dom0_mem=4G console_timestamps=boot $extra_xen_opts || reboot
271module /gitlab-ci/vmlinuz console=hvc0 root=/dev/ram0 earlyprintk=xen || reboot
272module /gitlab-ci/initrd-dom0 || reboot
273boot
274" > $TFTP/boot.ipxe
275
276cp -f binaries/xen $TFTP/xen
277cp -f binaries/bzImage $TFTP/vmlinuz
278cp -f binaries/dom0-rootfs.cpio.gz $TFTP/initrd-dom0
279
280# start the system pointing at gitlab-ci predefined config
281ssh $CONTROLLER gitlabci poweron
282trap "ssh $CONTROLLER poweroff" EXIT
283
284if [ -n "$wait_and_wakeup" ]; then
285    export SUSPEND_MSG="$wait_and_wakeup"
286    export WAKEUP_CMD="ssh $CONTROLLER wake"
287fi
288
289export PASSED="${passed}"
290export BOOT_MSG="Latest ChangeSet: "
291export LOG_MSG="\nWelcome to Alpine Linux"
292export TEST_CMD="ssh $CONTROLLER console"
293export TEST_LOG="smoke.serial"
294export TEST_TIMEOUT="$timeout"
295./automation/scripts/console.exp | sed 's/\r\+$//'
296TEST_RESULT=$?
297
298if [ -n "$retrieve_xml" ]; then
299    nc -w 10 "$SUT_ADDR" 8080 > tests-junit.xml </dev/null
300fi
301
302exit "$TEST_RESULT"
303