Add a new test to exercise the virtionet driver in GRUB as well as some elements of the network stack. This uses Python3 on the host to run a local HTTP server on the host / Qemu virtual interface and GRUB will download a GRUB file over HTTP and the host and GRUB calculated hashes are then compared.
Signed-off-by: Andrew Hamilton <adham...@gmail.com> --- .gitignore | 2 + Makefile.util.def | 12 ++++ tests/net_http_transfer_test.in | 107 ++++++++++++++++++++++++++++++++ tests/util/grub-shell.in | 3 + tests/util/qemu-linkup.in | 21 +++++++ 5 files changed, 145 insertions(+) create mode 100755 tests/net_http_transfer_test.in create mode 100755 tests/util/qemu-linkup.in diff --git a/.gitignore b/.gitignore index 4c1f91db8..0a8b588e4 100644 --- a/.gitignore +++ b/.gitignore @@ -237,6 +237,7 @@ widthspec.bin /m4/ /minixfs_test /missing +/net_http_transfer_test /netboot_test /nilfs2_test /ntfs_test @@ -260,6 +261,7 @@ widthspec.bin /printf_test /priority_queue_unit_test /pseries_test +/qemu-linkup /reiserfs_test /romfs_test /squashfs_test diff --git a/Makefile.util.def b/Makefile.util.def index 0f74a1680..c754d2b61 100644 --- a/Makefile.util.def +++ b/Makefile.util.def @@ -764,6 +764,18 @@ script = { dependencies = 'garbage-gen$(BUILD_EXEEXT)'; }; +script = { + name = qemu-linkup; + common = tests/util/qemu-linkup.in; + installdir = noinst; +}; + +script = { + testcase = nonnative; + name = net_http_transfer_test; + common = tests/net_http_transfer_test.in; +}; + script = { testcase = native; name = erofs_test; diff --git a/tests/net_http_transfer_test.in b/tests/net_http_transfer_test.in new file mode 100755 index 000000000..796621bcd --- /dev/null +++ b/tests/net_http_transfer_test.in @@ -0,0 +1,107 @@ +#! @BUILD_SHEBANG@ +# Copyright (C) 2024 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see <http://www.gnu.org/licenses/>. + +# Test purpose: +# This test will test the ability of GRUB to transfer a file +# from the host to GRUB memory using HTTP. This will exercise +# the virtionet driver, network stack (Net layer, ARP, Ethernet, IP, +# TCP), and HTTP code. + +set -e +grubshell=@builddir@/grub-shell + +. "@builddir@/grub-core/modinfo.sh" + +# This is required to run as root to support the "tap" interface +# in Qemu. +if [ "$EUID" = "" ] ; then + EUID=$(id -u) +fi + +if [ "$EUID" != 0 ] ; then + echo "Skipping, not run as root!" + exit 99 +fi + +# @TODO: figure out the correct targets here +case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in + # PLATFORM: emu is different + *-emu) + exit 77;; + # PLATFORM: Flash targets + mips-qemu_mips | mipsel-qemu_mips) + exit 77;; + # FIXME: currently grub-shell uses only -kernel for loongson + mipsel-loongson) + exit 77;; + # FIXME: We don't fully support netboot on ARC + *-arc) + exit 77;; + # FIXME: Many QEMU firmware have no netboot capability + powerpc-ieee1275 | sparc64-ieee1275) + exit 77;; +esac + +TEST_HOST_IP="169.254.67.38" +TEST_HOST_PORT="8080" +HTTP_SERVER_CMD="python3 -m http.server -b $TEST_HOST_IP $TEST_HOST_PORT" + +# Ensure any old server is stopped before starting the new one +pkill -9 -f "$HTTP_SERVER_CMD" 2>>/dev/null || true + +# Start another shell process to keep trying to start the http server on the qemu / host +# specific IP address / interface using a link-local address. Do this in a loop since +# Qemu (started after this) will create the interface and bind to the IP the below +# command will list on. +eval "for n in \"$(seq 1 20)\"; do sleep 0.5; $HTTP_SERVER_CMD 2>>/dev/null; done" & + +# Run GRUB in Qemu and direct output to a temp file +outfile1="$(mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")" || exit 99 +${grubshell} > "$outfile1" <<EOF +insmod hashsum +insmod http +insmod virtionet +net_add_addr virt0 virtionet 169.254.67.39 +md5sum (http,$TEST_HOST_IP:$TEST_HOST_PORT)/unicode/UnicodeData.txt +EOF + +# Stop the http server on the host, loop a few times to ensure +# we catch the child process in the event it's running a sleep +# statement the first time, +for _ in $(seq 1 5) +do + sleep 0.1 + pkill -9 -f "$HTTP_SERVER_CMD" 2>>/dev/null || true +done + +# Wait for children to exit +wait + +# Capture the expected hash of the file on the host +outfile2="$(mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")" || exit 99 +md5sum unicode/UnicodeData.txt > "${outfile2}" + +MD5SUM1=$(tr -d '\n' < "$outfile1" | cut -f1 -d" ") +MD5SUM2=$(tr -d '\n' < "$outfile2" | cut -f1 -d" ") +rm "${outfile1}" "${outfile2}" +if test "$MD5SUM1" = "$MD5SUM2" ; then + exit 0 +else + echo "Actual: $MD5SUM1" + echo "Expected: $MD5SUM2" + exit 1 +fi + diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index ae5f711fe..286d1b028 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -22,6 +22,7 @@ prefix="@prefix@" exec_prefix="@exec_prefix@" datarootdir="@datarootdir@" builddir="@builddir@" +abs_top_builddir="@abs_top_builddir@" srcdir="@srcdir@" PACKAGE_NAME=@PACKAGE_NAME@ PACKAGE_TARNAME=@PACKAGE_TARNAME@ @@ -172,6 +173,7 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in i386-pc) boot=cd qemu=qemu-system-i386 + qemuopts="$qemuopts -netdev tap,id=hostnet0,ifname=tap0,script=${abs_top_builddir}/qemu-linkup,downscript=no -device virtio-net-pci,netdev=hostnet0" console=console netbootext=0 ;; @@ -236,6 +238,7 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in exit 1 fi fi + qemuopts="$qemuopts -netdev tap,id=hostnet0,ifname=tap0,script=${abs_top_builddir}/qemu-linkup,downscript=no -device virtio-net-pci,netdev=hostnet0" ;; arm64-efi) qemu=qemu-system-aarch64 diff --git a/tests/util/qemu-linkup.in b/tests/util/qemu-linkup.in new file mode 100755 index 000000000..1dc020c50 --- /dev/null +++ b/tests/util/qemu-linkup.in @@ -0,0 +1,21 @@ +#! @BUILD_SHEBANG@ +set -e + +# Qemu network bringup script to assign an IP to an interface. +# Copyright (C) 2024 Free Software Foundation, Inc. +# +# GRUB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# GRUB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GRUB. If not, see <http://www.gnu.org/licenses/>. + +ip link set "$1" up +ip address add 169.254.67.38/24 dev "$1" -- 2.39.5 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel