Commit 458f647d authored by Martin Peres's avatar Martin Peres
Browse files

Add the first tests \o/

The only untested code-path should be the module loading, but I am
unsatisfied by it and will be replaced soon anyway :)
parent 6ed953b0
......@@ -26,8 +26,9 @@ SHELL := /bin/bash
DOCKER ?= docker
# TODO: Replace with a public registry address
IMAGE_LABEL ?= registry.freedesktop.org/mupuf/boot2container
TEST_IMAGE_LABEL = registry.freedesktop.org/mupuf/boot2container/test
CONTAINER_LABEL ?= boot2container
# TODO: Collect all wanted modules and load them
......@@ -45,9 +46,16 @@ out/initramfs.linux_amd64.cpio.xz: out/initramfs.linux_amd64.cpio
rebuild_container:
$(DOCKER) build -t $(IMAGE_LABEL) .
test: out/initramfs.linux_amd64.cpio
out/disk.img:
fallocate -l 128M out/disk.img
test: out/initramfs.linux_amd64.cpio out/disk.img
[ -f "$(KERNEL)" ] || (echo "ERROR: Set the KERNEL parameter, pointing to linux kernel with modules compiled in"; exit 1)
$(DOCKER) build -t $(TEST_IMAGE_LABEL) -f tests/Dockerfile .
$(DOCKER) run --rm -ti --device=/dev/kvm -v $(PWD)/out/initramfs.linux_amd64.cpio:/initramfs.linux_amd64.cpio -v $(KERNEL):/kernel -v $(PWD)/tests/tests.sh:/entrypoint $(TEST_IMAGE_LABEL) /entrypoint
manual_test: out/initramfs.linux_amd64.cpio out/disk.img
[ -f "$(KERNEL)" ] || (echo "ERROR: Set the KERNEL parameter, pointing to linux kernel with modules compiled in"; exit 1)
[ -f out/disk.img ] || fallocate -l 128M out/disk.img
qemu-system-x86_64 -drive file=out/disk.img,format=raw,if=virtio -nic user,model=virtio-net-pci -kernel $(KERNEL) -initrd out/initramfs.linux_amd64.cpio -nographic -m 256M -enable-kvm -append 'console=ttyS0 b2c.container=docker://registry.hub.docker.com/library/hello-world b2c.container="-ti docker://registry.hub.docker.com/library/alpine:latest" b2c.cache_device=auto'
clean:
......
......@@ -302,7 +302,7 @@ function create_container {
--runtime /bin/crun-no-pivot -e B2C_PIPELINE_STATUS=$B2C_PIPELINE_STATUS \
-e B2C_PIPELINE_FAILED_BY=\"$B2C_PIPELINE_FAILED_BY\" \
-e B2C_PIPELINE_PREV_CONTAINER=\"$B2C_PIPELINE_PREV_CONTAINER\" \
-e B2C_PIPELINE_PREV_CONTAINER_EXIT_CODE=\"$B2C_PIPELINE_PREV_CONTAINER_EXIT_CODE\""
-e B2C_PIPELINE_PREV_CONTAINER_EXIT_CODE=$B2C_PIPELINE_PREV_CONTAINER_EXIT_CODE"
# Set up the wanted container
container_id=`eval "$cmdline $@"` && podman init "$container_id" && return 0
......
# Copyright (c) 2021 Valve Corporation
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# Author: Martin Peres <martin.peres@mupuf.org>
#
FROM alpine
RUN apk add --no-cache qemu-system-x86_64 outils-md5 && \
wget -O /usr/bin/shunit2 https://raw.githubusercontent.com/kward/shunit2/v2.1.8/shunit2
#!/bin/sh
QEMU_NO_NIC="-nic none"
QEMU_NIC="-nic user,model=virtio-net-pci"
QEMU_DISK="-drive file=/disk.img,format=raw,if=virtio"
DISK_PATH=/disk.img
reset_disk() {
rm "$DISK_PATH" 2> /dev/null
fallocate -l 128M "$DISK_PATH"
}
run_test() {
tmpfile=$(mktemp /tmp/qemu_exec.XXXXXX)
cmdline="qemu-system-x86_64 -kernel /kernel -initrd /initramfs.linux_amd64.cpio \
-nographic -m 256M -enable-kvm $qemu_params \
-append 'console=ttyS0 $kernel_cmdline'"
eval "timeout 30 $cmdline" | tee "$tmpfile"
stdout=$(cat "$tmpfile")
rm "$tmpfile"
}
testBootingWithNoNICNoDisk() {
qemu_params="$QEMU_NO_NIC"
kernel_cmdline="b2c.container=docker://registry.hub.docker.com/library/hello-world"
run_test
assertContains "$stdout" "ERROR: Could not connect to the network, shutting down!"
}
testBootingWithDefault() {
qemu_params="$QEMU_NIC $QEMU_DISK"
kernel_cmdline="b2c.container=docker://registry.hub.docker.com/library/hello-world"
reset_disk; disk_hash=`md5sum "/disk.img"`
run_test
assertContains "$stdout" "Do not use a partition cache"
assertContains "$stdout" "WARNING: Did not reset the time, use b2c.ntp_peer=auto to set it on boot"
assertContains "$stdout" "Hello from Docker!"
assertEquals "The disk content has been modified" "$disk_hash" "`md5sum "/disk.img"`"
}
testBootingWithCacheDevice() {
# Check that a cache drive gets formated and mounted
qemu_params="$QEMU_NIC $QEMU_DISK"
kernel_cmdline="b2c.cache_device=auto"
reset_disk; disk_hash=`md5sum "/disk.img"`
run_test
assertContains "$stdout" "No existing cache partition found on this machine, create one from the disk /dev/vda"
assertContains "$stdout" "mkfs.ext4 -F -L B2C_CACHE /dev/vda1"
assertContains "$stdout" "Selected the partition /dev/vda1 as a cache"
assertContains "$stdout" "Mounting the partition /dev/vda1 to /container: DONE"
assertNotEquals "Disk_1's content has not been modified" "$disk_hash" "`md5sum "/disk.img"`"
# Check that if we add a new disk, the one already formated is used preferably
fallocate -l 128M "/disk2.img"
disk2_hash=`md5sum "/disk2.img"`
qemu_params="$QEMU_NIC -drive file=/disk2.img,format=raw,if=virtio $QEMU_DISK"
kernel_cmdline="b2c.cache_device=auto"
run_test
assertNotContains "$stdout" "mkfs.ext4 -F -L B2C_CACHE /dev/vda"
assertContains "$stdout" "Selected the partition /dev/vdb1 as a cache"
assertEquals "The disk_2 content has been modified" "$disk2_hash" "`md5sum "/disk2.img"`"
# Force-use the second disk, and make sure the original cache disk isn't being touched
kernel_cmdline="b2c.cache_device=/dev/vda"
disk_hash=`md5sum "/disk.img"`
disk2_hash=`md5sum "/disk2.img"`
run_test
assertContains "$stdout" "No existing cache partition on the drive /dev/vda, recreate the partition table and format a partition"
assertContains "$stdout" "mkfs.ext4 -F -L B2C_CACHE /dev/vda1"
assertContains "$stdout" "Selected the partition /dev/vda1 as a cache"
assertContains "$stdout" "Mounting the partition /dev/vda1 to /container: DONE"
assertEquals "Disk_1's content has been modified" "$disk_hash" "`md5sum "/disk.img"`"
assertNotEquals "The disk_2 content has not been modified" "$disk2_hash" "`md5sum "/disk.img"`"
}
testNTP() {
# Check that 'auto' defaults to pool.ntp.org
qemu_params="$QEMU_NIC"
kernel_cmdline="b2c.ntp_peer=auto"
run_test
assertContains "$stdout" "Getting the time from the NTP server pool.ntp.org: DONE"
# TODO: Check that the time was indeed updated
# Check overriding the ntp peer works
qemu_params="$QEMU_NIC"
kernel_cmdline="b2c.ntp_peer=wrong_server.com"
run_test
assertContains "$stdout" "Getting the time from the NTP server wrong_server.com: FAILED"
}
testDefaultContainerPipeline() {
qemu_params="$QEMU_NIC $QEMU_DISK"
kernel_cmdline='b2c.container="-e EXIT_CODE=42 docker://stakater/exit-container" \
b2c.container="-e EXIT_CODE=43 docker://stakater/exit-container" \
b2c.post_container="-e EXIT_CODE=44 docker://stakater/exit-container" \
b2c.post_container="-e EXIT_CODE=45 docker://stakater/exit-container"'
reset_disk
run_test
# First container
assertContains "$stdout" '-e B2C_PIPELINE_STATUS=0'
assertContains "$stdout" '-e B2C_PIPELINE_FAILED_BY=""'
assertContains "$stdout" '-e B2C_PIPELINE_PREV_CONTAINER=""'
assertContains "$stdout" '-e B2C_PIPELINE_PREV_CONTAINER_EXIT_CODE='
assertContains "$stdout" "Exiting with code: 42"
assertContains "$stdout" "The container exited with error code 42, continuing..."
# Second container, executed despite the previous one failing
assertContains "$stdout" '-e B2C_PIPELINE_STATUS=42'
assertContains "$stdout" '-e B2C_PIPELINE_FAILED_BY="-e EXIT_CODE=42 docker://stakater/exit-container"'
assertContains "$stdout" '-e B2C_PIPELINE_PREV_CONTAINER="-e EXIT_CODE=42 docker://stakater/exit-container"'
assertContains "$stdout" '-e B2C_PIPELINE_PREV_CONTAINER_EXIT_CODE=42'
assertContains "$stdout" "Exiting with code: 43"
assertContains "$stdout" "The container exited with error code 43, continuing..."
# First post-container, executed despite the pipeline failing
assertContains "$stdout" '-e B2C_PIPELINE_STATUS=42'
assertContains "$stdout" '-e B2C_PIPELINE_FAILED_BY="-e EXIT_CODE=42 docker://stakater/exit-container"'
assertContains "$stdout" '-e B2C_PIPELINE_PREV_CONTAINER="-e EXIT_CODE=43 docker://stakater/exit-container"'
assertContains "$stdout" '-e B2C_PIPELINE_PREV_CONTAINER_EXIT_CODE=43'
assertContains "$stdout" "Exiting with code: 44"
# Second post-container, executed despite the previous post container failing
assertContains "$stdout" '-e B2C_PIPELINE_STATUS=42'
assertContains "$stdout" '-e B2C_PIPELINE_FAILED_BY="-e EXIT_CODE=42 docker://stakater/exit-container"'
assertContains "$stdout" '-e B2C_PIPELINE_PREV_CONTAINER="-e EXIT_CODE=44 docker://stakater/exit-container"'
assertContains "$stdout" '-e B2C_PIPELINE_PREV_CONTAINER_EXIT_CODE=44'
assertContains "$stdout" "Exiting with code: 45"
}
testContainerPipelineWithPipeFail() {
qemu_params="$QEMU_NIC $QEMU_DISK"
kernel_cmdline='b2c.container="docker://stakater/exit-container" \
b2c.container="-e EXIT_CODE=42 docker://stakater/exit-container" \
b2c.container="-e EXIT_CODE=43 docker://stakater/exit-container" \
b2c.post_container="-e EXIT_CODE=44 docker://stakater/exit-container" \
b2c.post_container="-e EXIT_CODE=45 docker://stakater/exit-container" \
b2c.pipefail'
reset_disk
run_test
# Successful container, so we can run the next one
assertContains "$stdout" '-e B2C_PIPELINE_STATUS=0'
assertContains "$stdout" '-e B2C_PIPELINE_FAILED_BY=""'
assertContains "$stdout" '-e B2C_PIPELINE_PREV_CONTAINER=""'
assertContains "$stdout" '-e B2C_PIPELINE_PREV_CONTAINER_EXIT_CODE='
assertContains "$stdout" "Exiting with code: 0"
assertContains "$stdout" "The container run successfully, load the next one!"
# First failing container
assertContains "$stdout" '-e B2C_PIPELINE_PREV_CONTAINER=""'
assertContains "$stdout" '-e B2C_PIPELINE_PREV_CONTAINER_EXIT_CODE='
assertContains "$stdout" "Exiting with code: 42"
assertContains "$stdout" "The container exited with error code 42, aborting the pipeline..."
# Second failing container (should not have been executed)
assertNotContains "$stdout" "Exiting with code: 43"
# First post-container, executed right after the first failing container
assertContains "$stdout" '-e B2C_PIPELINE_STATUS=42'
assertContains "$stdout" '-e B2C_PIPELINE_FAILED_BY="-e EXIT_CODE=42 docker://stakater/exit-container"'
assertContains "$stdout" '-e B2C_PIPELINE_PREV_CONTAINER="-e EXIT_CODE=42 docker://stakater/exit-container"'
assertContains "$stdout" '-e B2C_PIPELINE_PREV_CONTAINER_EXIT_CODE=42'
assertContains "$stdout" "Exiting with code: 44"
# Second post-container, executed despite the previous post container failing
assertContains "$stdout" '-e B2C_PIPELINE_STATUS=42'
assertContains "$stdout" '-e B2C_PIPELINE_FAILED_BY="-e EXIT_CODE=42 docker://stakater/exit-container"'
assertContains "$stdout" '-e B2C_PIPELINE_PREV_CONTAINER="-e EXIT_CODE=44 docker://stakater/exit-container"'
assertContains "$stdout" '-e B2C_PIPELINE_PREV_CONTAINER_EXIT_CODE=44'
assertContains "$stdout" "Exiting with code: 45"
}
testShutdownCmdOverride() {
# Use printf to concatenate the strings, so we don't accidentally find the
# the parameter from the kernel command line and think it actually got executed!
qemu_params="$QEMU_NO_NIC"
kernel_cmdline='b2c.shutdown_cmd="printf %s%s%s\\n SHUT ME DOWN; poweroff -f"'
run_test
assertContains "$stdout" "SHUTMEDOWN"
}
# Load shUnit2.
stdout=""
cmdline=""
. /usr/bin/shunit2
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment