Skip to content

Commit

Permalink
test
Browse files Browse the repository at this point in the history
  • Loading branch information
andreacorbellini committed Apr 19, 2024
1 parent 20be0a0 commit 3144488
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 0 deletions.
29 changes: 29 additions & 0 deletions .github/workflows/kernel-panic.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Kernel Panic

on:
push:
pull_request:
workflow_dispatch:

env:
CARGO_TERM_COLOR: always

jobs:
kernel-panic:
name: Kernel Panic
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Install qemu
run: |
sudo apt-get install -y qemu-system-x86
- name: Copy current kernel
run: |
sudo cp "/boot/vmlinuz-$(uname -r)" .
sudo chmod a+r "vmlinuz-$(uname -r)"
- name: Run virtual machine
run: |
tests/linux-kernel-panic/run-test.sh
9 changes: 9 additions & 0 deletions tests/linux-kernel-panic/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "atomic-write-file-test"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
atomic-write-file = { path = "../.." }
13 changes: 13 additions & 0 deletions tests/linux-kernel-panic/init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/sh -e

echo 'Mounting /proc'
mount -t proc none /proc
echo 'Mounting /sys'
mount -t sysfs none /sys
echo 'Mounting /test'
mount -t ext4 /dev/sdb /test

echo 'Running test binary'
atomic-write-file-test

echo 'Done'
144 changes: 144 additions & 0 deletions tests/linux-kernel-panic/run-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
#!/bin/bash

set -o errexit
set -o nounset
set -o pipefail

if [[ -t 1 ]]; then
highlight=$'\e[1;32m'
reset=$'\e[0m'
else
highlight=''
reset=''
fi

cd "$(dirname "$(readlink -f "$0")")"

qemu=qemu-system-$(uname -m)
kernel=/boot/vmlinuz-$(uname -r)
modules=/usr/lib/modules/$(uname -r)

busybox=$(which busybox)
init_script=init.sh
test_bin=target/release/atomic-write-file-test

filesystem_type=ext4

build_dir=build
initramfs_build_dir=$build_dir/rootfs
initramfs=$build_dir/rootfs.img
testfs=$build_dir/testfs.img

options=$(getopt --name "$0" --options k:m:f: --long kernel:,modules:,filesystem-type: -- "$@")

eval set -- "$options"

while true; do
case "$1" in
-k|--kernel)
kernel="$2"
shift 2
;;
-m|--modules)
modules="$2"
shift 2
;;
-f|--filesystem-type)
filesystem_type="$2"
shift 2
;;
--)
shift
break
;;
esac
done

if [[ $# -ne 0 ]]; then
echo "$0: extra arguments: $*" >&2
exit 1
fi

#
# Compile the test binary running atomic-write-file
#
# This needs to be a statically-linked binary because the root filesystem won't
# ship with libc
#

echo "${highlight}Compiling${reset} static binary at $test_bin"
RUSTFLAGS='-C target-feature=+crt-static' cargo build --release

#
# Create the root filesystem and put it into an initramfs
#
# The root filesystem contains:
# - busybox (to provide /bin/sh and other basic tools)
# - the test binary
# - an init script
# - kernel modules (to support uncommon filesystems like btrfs)
#

echo "${highlight}Building${reset} initramfs at $initramfs"
echo " Using busybox at $busybox"
echo " Using modules at $modules"
echo " Using $init_script as /sbin/init"

rm -rf "$initramfs" "$initramfs_build_dir"

echo " ${highlight}Creating${reset} filesystem"

mkdir -p \
"$initramfs_build_dir/bin" \
"$initramfs_build_dir/dev" \
"$initramfs_build_dir/lib" \
"$initramfs_build_dir/proc" \
"$initramfs_build_dir/sbin" \
"$initramfs_build_dir/sys" \
"$initramfs_build_dir/test" \
"$initramfs_build_dir/usr"

ln -s ../bin "$initramfs_build_dir/usr/bin"
ln -s ../lib "$initramfs_build_dir/usr/lib"

cp "$init_script" -T "$initramfs_build_dir/sbin/init"
cp "$test_bin" -t "$initramfs_build_dir/bin"
cp "$busybox" -t "$initramfs_build_dir/bin"
"$busybox" --install -s "$initramfs_build_dir/bin"

mkdir -p "$initramfs_build_dir/lib/modules"
cp -a "$modules" -t "$initramfs_build_dir/lib/modules"

echo " ${highlight}Creating${reset} squashfs file"

mksquashfs "$initramfs_build_dir" "$initramfs"

#
# Create the filesystem used for testing
#

echo "${highlight}Creating${reset} test filesystem at $testfs"
echo " Using: $filesystem_type"

dd if=/dev/zero of="$testfs" bs=1M count=200
"mkfs.$filesystem_type" "$testfs"

#
# Run the virtual machine
#
# This will create a file with atomic-write-file and then trigger a kernel
# panic
#

echo "${highlight}Running${reset} virtual machine"
echo " Using qemu at $qemu"
echo " Using kernel at $kernel"
echo " Using initramfs at $initramfs"

"$qemu" \
-kernel "$kernel" \
-append 'console=ttyS0 root=/dev/sda rw panic=-1' \
-drive 'index=0,media=disk,format=raw,file=rootfs.img' \
-drive 'index=1,media=disk,format=raw,file=testfs.img' \
-no-reboot \
-nographic
8 changes: 8 additions & 0 deletions tests/linux-kernel-panic/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use atomic_write_file::AtomicWriteFile;
use std::io::Write;

fn main() {
let mut file = AtomicWriteFile::open("/test/file").expect("open failed");
file.write_all(b"hello\n").expect("write failed");
file.commit().expect("commit failed");
}

0 comments on commit 3144488

Please sign in to comment.