aboutsummaryrefslogtreecommitdiff
path: root/tests/arch
diff options
context:
space:
mode:
Diffstat (limited to 'tests/arch')
-rw-r--r--tests/arch143
1 files changed, 143 insertions, 0 deletions
diff --git a/tests/arch b/tests/arch
new file mode 100644
index 0000000..2f60451
--- /dev/null
+++ b/tests/arch
@@ -0,0 +1,143 @@
+# ARCH picks the qemu binary, the machine type and the display device.
+# Nothing here needs /dev/kvm: another architecture is emulated.
+
+"$VMM" create ar1 64M >/dev/null 2>&1
+FW=/usr/share/qemu/edk2-aarch64-code.fd
+[ -f "$FW" ] || FW=/usr/share/AAVMF/AAVMF_CODE.fd
+
+cfg ar1 <<EOF
+ARCH=riscv64
+EOF
+refuses 'ARCH must be' "an unsupported ARCH is refused" dryrun ar1
+
+cfg ar1 <<EOF
+ARCH=aarch64
+EOF
+refuses 'requires FIRMWARE' "aarch64 without firmware is refused" dryrun ar1
+
+cfg ar1 <<EOF
+FIRMWARE=firmware.fd
+EOF
+refuses 'FIRMWARE must be an absolute path' "a relative FIRMWARE is refused" dryrun ar1
+
+# The host's own architecture is accelerated. -cpu host means nothing
+# anywhere else, and asking for it under emulation is an error.
+: > "$VMMDIR/ar1/config"
+outputs 'accel=kvm' "the host architecture gets kvm" dryrun ar1
+outputs "-cpu 'host'" "the host architecture gets the host cpu" dryrun ar1
+
+# A host with no /dev/kvm can still run its own architecture, slowly.
+cfg ar1 <<EOF
+HWACCEL=no
+EOF
+outputs 'accel=tcg' "HWACCEL=no emulates the host architecture" dryrun ar1
+outputs "-cpu 'max'" "HWACCEL=no drops -cpu host, which needs kvm" dryrun ar1
+
+cfg ar1 <<EOF
+HWACCEL=maybe
+EOF
+refuses 'HWACCEL must be' "HWACCEL takes yes or no" dryrun ar1
+
+cfg ar1 <<EOF
+ARCH=aarch64
+FIRMWARE="$FW"
+GRAPHICS=vnc
+EOF
+outputs 'qemu-system-aarch64' "ARCH picks the qemu binary" dryrun ar1
+outputs "machine 'virt" "aarch64 gets the virt machine" dryrun ar1
+outputs 'accel=tcg' "a foreign architecture is emulated" dryrun ar1
+outputs "-cpu 'max'" "an emulated guest does not ask for the host cpu" dryrun ar1
+outputs "bios '$FW'" "the firmware reaches the argv" dryrun ar1
+outputs 'virtio-gpu-pci' "aarch64 gets a display device that is not VGA" dryrun ar1
+
+# ARCH names a binary that may not be installed. Saying so is instant;
+# leaving it to setsid costs both monitor timeouts first.
+NOQEMU=$WORK/noqemu-bin
+mkdir -p "$NOQEMU"
+for b in flock uname od awk cat tr; do
+ ln -sf "$(command -v "$b")" "$NOQEMU/$b"
+done
+: > "$VMMDIR/ar1/config"
+out=$(PATH=$NOQEMU "$VMM" start ar1 2>&1) && got=0 || got=$?
+if [ "$got" != 0 ] && printf '%s' "$out" | grep -q 'qemu-system-.* is not on PATH'; then
+ ok "a qemu that is not installed is named at once"
+else
+ notok "a qemu that is not installed is named at once" "exit $got: $out"
+fi
+
+# Emulated end to end: the firmware really runs and really talks to the
+# serial console, which is the whole point of passing -bios.
+if [ -f "$FW" ] && command -v qemu-system-aarch64 >/dev/null 2>&1; then
+ cfg ar1 <<EOF
+ARCH=aarch64
+FIRMWARE="$FW"
+MEM=512
+CPUS=1
+EOF
+ exits 0 "an emulated aarch64 guest starts" start ar1
+ outputs 'running' "the emulated guest answers its monitor" \
+ monitor ar1 info status
+ sleep 2
+ holds "the emulated firmware writes to the serial console" \
+ test -s "$VMMDIR/ar1/console.log"
+ "$VMM" kill ar1 >/dev/null 2>&1 || :
+else
+ skip 3 "no qemu-system-aarch64 or no aarch64 firmware"
+fi
+
+# Failure after spawn must reap only that child and remove every runtime
+# object it may have created.
+if command -v "qemu-system-$(uname -m)" >/dev/null 2>&1; then
+ "$VMM" create ar2 64M >/dev/null 2>&1
+ printf 'not a qcow2 image\n' > "$VMMDIR/ar2/disk.qcow2"
+ cfg ar2 <<EOF
+HWACCEL=no
+MEM=256
+CPUS=1
+EOF
+ exits 1 "a qemu startup failure is reported" start ar2
+ holds "a failed start leaves no pidfile" test ! -e "$VMMDIR/ar2/pid"
+ holds "a failed start leaves no input FIFO" test ! -e "$VMMDIR/ar2/qmp.in"
+ holds "a failed start leaves no output FIFO" test ! -e "$VMMDIR/ar2/qmp.out"
+ holds "a failed start releases its lock" \
+ flock -n "$VMMDIR/ar2" true
+else
+ skip 5 "no qemu for the host architecture"
+fi
+
+# A qemu that never opens the monitor does not die of its own accord, and
+# it has written no pidfile to be found by. It is still vmm's own child.
+# The stand-in does not exec, so it keeps the argv this looks for.
+FAKEBIN=$WORK/fake-qemu-bin
+FAKE=$FAKEBIN/qemu-system-$(uname -m)
+mkdir -p "$FAKEBIN"
+cat > "$FAKE" <<'EOF'
+#!/bin/sh
+sleep 5
+EOF
+chmod +x "$FAKE"
+"$VMM" create ar3 64M >/dev/null 2>&1
+out=$(PATH=$FAKEBIN:$PATH MONITOR_TIMEOUT=1 "$VMM" start ar3 2>&1) && got=0 || got=$?
+if [ "$got" = 1 ]; then
+ ok "a start whose monitor never answers fails"
+else
+ notok "a start whose monitor never answers fails" "exit $got: $out"
+fi
+left=
+for cmdline in /proc/[0-9]*/cmdline; do
+ line=
+ IFS= read -r line 2>/dev/null < "$cmdline" || :
+ case $line in
+ *"-pidfile$VMMDIR/ar3/pid")
+ p=${cmdline#/proc/}
+ left="$left ${p%/cmdline}"
+ ;;
+ esac
+done
+if [ -z "$left" ]; then
+ ok "and kills the child it spawned"
+else
+ notok "and kills the child it spawned" "still running:$left"
+ # shellcheck disable=SC2086 # a list of pids this loop collected
+ kill -9 $left 2>/dev/null || :
+fi