Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An update to vmtest #2918

Merged
merged 14 commits into from
Feb 17, 2024
Prev Previous commit
Next Next commit
Convert kexec test
Signed-off-by: Chris Koch <[email protected]>
  • Loading branch information
hugelgupf committed Feb 16, 2024
commit f922c7370d10ac33d5cf81dbb7f439beaf33dab8
174 changes: 84 additions & 90 deletions integration/generic-tests/kexec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,54 +11,51 @@ import (
"fmt"
"os"
"os/exec"
"path/filepath"
"testing"
"time"

"github.com/hugelgupf/vmtest"
"github.com/hugelgupf/vmtest/qemu"
"github.com/hugelgupf/vmtest/scriptvm"
"github.com/hugelgupf/vmtest/testtmp"
"github.com/u-root/gobusybox/src/pkg/golang"
"github.com/u-root/mkuimage/uimage"
)

// TestMountKexec tests that kexec occurs correctly by checking the kernel cmdline.
// This is possible because the generic initramfs ensures that we mount the
// testdata directory containing the initramfs and kernel used in the VM.
func TestMountKexec(t *testing.T) {
vmtest.SkipIfNotArch(t, qemu.ArchAMD64, qemu.ArchArm64)
qemu.SkipIfNotArch(t, qemu.ArchAMD64, qemu.ArchArm64)

script := `
CMDLINE=$(cat /proc/cmdline)
SUFFIX=${CMDLINE:(-7)}
echo SAW $SUFFIX
kexec -l -i /testdata/initramfs.cpio -c "${CMDLINE} KEXEC=Y" /kernel
kexec -l -i /mount/9p/initramfs/initramfs.cpio -c "${CMDLINE} KEXEC=Y" /kernel
sync
kexec -e
`

vm := vmtest.StartVMAndRunCmds(t, script,
vmtest.WithBusyboxCommands(
"github.com/u-root/u-root/cmds/core/cat",
"github.com/u-root/u-root/cmds/core/sync",
initrd := filepath.Join(testtmp.TempDir(t), "initramfs.cpio")
vm := scriptvm.Start(t, "vm", script,
scriptvm.WithUimage(
uimage.WithBusyboxCommands(
"github.com/u-root/u-root/cmds/core/cat",
"github.com/u-root/u-root/cmds/core/sync",
),
// Build kexec as a binary command to get accurate GOCOVERDIR
// integration coverage data (busybox rewrites command code).
uimage.WithCoveredCommands("github.com/u-root/u-root/cmds/core/kexec"),
uimage.WithFiles(fmt.Sprintf("%s:kernel", os.Getenv("VMTEST_KERNEL"))),
uimage.WithCPIOOutput(initrd),
),
// Build kexec as a binary command to get accurate GOCOVERDIR
// integration coverage data (busybox rewrites command code).
vmtest.WithBinaryCommands(
"github.com/u-root/u-root/cmds/core/kexec",
),
vmtest.WithInitramfsFiles(
fmt.Sprintf("%s:kernel", os.Getenv("VMTEST_KERNEL")),
),
vmtest.WithQEMUFn(
scriptvm.WithQEMUFn(
qemu.WithVMTimeout(time.Minute),
qemu.ArbitraryArgs("-m", "8192"),
qemu.WithInitramfs(initrd),
// Initramfs available at /mount/9p/initramfs/initramfs.cpio.
qemu.P9Directory(filepath.Dir(initrd), "initramfs"),
),
// The initramfs will be placed in shared dir, so in the VM
// it's available at /testdata/initramfs.cpio.
vmtest.WithSharedDir(testtmp.TempDir(t)),
// Build kexec (and all other initramfs commands) with coverage enabled.
vmtest.WithGoBuildOpts(&golang.BuildOpts{
ExtraArgs: []string{"-cover", "-coverpkg=github.com/u-root/u-root/...", "-covermode=atomic"},
}),
)

if _, err := vm.Console.ExpectString("SAW KEXEC=Y"); err != nil {
Expand All @@ -73,7 +70,7 @@ func TestMountKexec(t *testing.T) {
// TestMountKexecLoad is same as TestMountKexec except it test calling
// kexec_load syscall than file load.
func TestMountKexecLoad(t *testing.T) {
vmtest.SkipIfNotArch(t, qemu.ArchAMD64, qemu.ArchArm64)
qemu.SkipIfNotArch(t, qemu.ArchAMD64, qemu.ArchArm64)

gzipP, err := exec.LookPath("gzip")
if err != nil {
Expand All @@ -84,37 +81,35 @@ func TestMountKexecLoad(t *testing.T) {
CMDLINE=$(cat /proc/cmdline)
SUFFIX=${CMDLINE:(-7)}
echo SAW $SUFFIX
kexec -l -d -i /testdata/initramfs.cpio --loadsyscall -c "${CMDLINE} KEXEC=Y" /kernel
kexec -l -d -i /mount/9p/initramfs/initramfs.cpio --loadsyscall -c "${CMDLINE} KEXEC=Y" /kernel
sync
kexec -e
`
vm := vmtest.StartVMAndRunCmds(t, script,
vmtest.WithBusyboxCommands(
"github.com/u-root/u-root/cmds/core/cat",
"github.com/u-root/u-root/cmds/core/sync",
),
// Build kexec as a binary command to get accurate GOCOVERDIR
// integration coverage data (busybox rewrites command code).
vmtest.WithBinaryCommands(
"github.com/u-root/u-root/cmds/core/kexec",
),
vmtest.WithInitramfsFiles(
fmt.Sprintf("%s:kernel", os.Getenv("VMTEST_KERNEL")),
gzipP,

initrd := filepath.Join(testtmp.TempDir(t), "initramfs.cpio")
vm := scriptvm.Start(t, "vm", script,
scriptvm.WithUimage(
uimage.WithBusyboxCommands(
"github.com/u-root/u-root/cmds/core/cat",
"github.com/u-root/u-root/cmds/core/sync",
),
// Build kexec as a binary command to get accurate GOCOVERDIR
// integration coverage data (busybox rewrites command code).
uimage.WithCoveredCommands("github.com/u-root/u-root/cmds/core/kexec"),
uimage.WithFiles(
fmt.Sprintf("%s:kernel", os.Getenv("VMTEST_KERNEL")),
gzipP,
),
uimage.WithCPIOOutput(initrd),
),
vmtest.WithQEMUFn(
scriptvm.WithQEMUFn(
qemu.WithVMTimeout(time.Minute),
qemu.ArbitraryArgs("-m", "8192"),
qemu.WithInitramfs(initrd),
// Initramfs available at /mount/9p/initramfs/initramfs.cpio.
qemu.P9Directory(filepath.Dir(initrd), "initramfs"),
),
// The initramfs will be placed in shared dir, so in the VM
// it's available at /testdata/initramfs.cpio.
vmtest.WithSharedDir(testtmp.TempDir(t)),
// Build kexec (and all other initramfs commands) with coverage enabled.
vmtest.WithGoBuildOpts(&golang.BuildOpts{
ExtraArgs: []string{"-cover", "-coverpkg=github.com/u-root/u-root/...", "-covermode=atomic"},
}),
)

if _, err := vm.Console.ExpectString("SAW KEXEC=Y"); err != nil {
t.Error(err)
}
Expand All @@ -126,7 +121,7 @@ func TestMountKexecLoad(t *testing.T) {

// TestMountKexecLoadOnly test kexec loads without a kexec reboot.
func TestMountKexecLoadOnly(t *testing.T) {
vmtest.SkipIfNotArch(t, qemu.ArchAMD64, qemu.ArchArm64)
qemu.SkipIfNotArch(t, qemu.ArchAMD64, qemu.ArchArm64)

gzipP, err := exec.LookPath("gzip")
if err != nil {
Expand All @@ -135,33 +130,32 @@ func TestMountKexecLoadOnly(t *testing.T) {

script := `
CMDLINE=$(cat /proc/cmdline)
kexec -d -l -i /testdata/initramfs.cpio --loadsyscall -c "${CMDLINE}" /kernel
kexec -d -l -i /mount/9p/initramfs/initramfs.cpio --loadsyscall -c "${CMDLINE}" /kernel
echo kexecloadresult $?
`
vm := vmtest.StartVMAndRunCmds(t, script,
vmtest.WithBusyboxCommands(
"github.com/u-root/u-root/cmds/core/cat",
),
// Build kexec as a binary command to get accurate GOCOVERDIR
// integration coverage data (busybox rewrites command code).
vmtest.WithBinaryCommands(
"github.com/u-root/u-root/cmds/core/kexec",
),
vmtest.WithInitramfsFiles(
fmt.Sprintf("%s:kernel", os.Getenv("VMTEST_KERNEL")),
gzipP,

initrd := filepath.Join(testtmp.TempDir(t), "initramfs.cpio")
vm := scriptvm.Start(t, "vm", script,
scriptvm.WithUimage(
uimage.WithBusyboxCommands(
"github.com/u-root/u-root/cmds/core/cat",
),
// Build kexec as a binary command to get accurate GOCOVERDIR
// integration coverage data (busybox rewrites command code).
uimage.WithCoveredCommands("github.com/u-root/u-root/cmds/core/kexec"),
uimage.WithFiles(
fmt.Sprintf("%s:kernel", os.Getenv("VMTEST_KERNEL")),
gzipP,
),
uimage.WithCPIOOutput(initrd),
),
vmtest.WithQEMUFn(
scriptvm.WithQEMUFn(
qemu.WithVMTimeout(time.Minute),
qemu.ArbitraryArgs("-m", "8192"),
qemu.WithInitramfs(initrd),
// Initramfs available at /mount/9p/initramfs/initramfs.cpio.
qemu.P9Directory(filepath.Dir(initrd), "initramfs"),
),
// The initramfs will be placed in shared dir, so in the VM
// it's available at /testdata/initramfs.cpio.
vmtest.WithSharedDir(testtmp.TempDir(t)),
// Build kexec (and all other initramfs commands) with coverage enabled.
vmtest.WithGoBuildOpts(&golang.BuildOpts{
ExtraArgs: []string{"-cover", "-coverpkg=github.com/u-root/u-root/...", "-covermode=atomic"},
}),
)

if _, err := vm.Console.ExpectString("kexecloadresult 0"); err != nil {
Expand All @@ -174,37 +168,37 @@ func TestMountKexecLoadOnly(t *testing.T) {

// TestMountKexecLoadCustomDTB test kexec_load a Arm64 Image with a user provided dtb.
func TestMountKexecLoadCustomDTB(t *testing.T) {
vmtest.SkipIfNotArch(t, qemu.ArchArm64)
qemu.SkipIfNotArch(t, qemu.ArchArm64)

script := `
CMDLINE=$(cat /proc/cmdline)
SUFFIX=${CMDLINE:(-7)}
echo SAW $SUFFIX
cp /sys/firmware/fdt /tmp/userfdt
kexec -d --dtb /tmp/userfdt -i /testdata/initramfs.cpio --loadsyscall -c "${CMDLINE} KEXEC=Y" /kernel
kexec -d --dtb /tmp/userfdt -i /mount/9p/initramfs/initramfs.cpio --loadsyscall -c "${CMDLINE} KEXEC=Y" /kernel
`
vm := vmtest.StartVMAndRunCmds(t, script,
vmtest.WithBusyboxCommands(
"github.com/u-root/u-root/cmds/core/cat",
"github.com/u-root/u-root/cmds/core/cp",
),
// Build kexec as a binary command to get accurate GOCOVERDIR
// integration coverage data (busybox rewrites command code).
vmtest.WithBinaryCommands(
"github.com/u-root/u-root/cmds/core/kexec",
initrd := filepath.Join(testtmp.TempDir(t), "initramfs.cpio")
vm := scriptvm.Start(t, "vm", script,
scriptvm.WithUimage(
uimage.WithBusyboxCommands(
"github.com/u-root/u-root/cmds/core/cat",
"github.com/u-root/u-root/cmds/core/cp",
),
// Build kexec as a binary command to get accurate GOCOVERDIR
// integration coverage data (busybox rewrites command code).
uimage.WithCoveredCommands("github.com/u-root/u-root/cmds/core/kexec"),
uimage.WithFiles(
fmt.Sprintf("%s:kernel", os.Getenv("VMTEST_KERNEL")),
),
uimage.WithCPIOOutput(initrd),
),
vmtest.WithInitramfsFiles(fmt.Sprintf("%s:kernel", os.Getenv("VMTEST_KERNEL"))),
vmtest.WithQEMUFn(
scriptvm.WithQEMUFn(
qemu.WithVMTimeout(time.Minute),
qemu.ArbitraryArgs("-m", "8192"),
qemu.WithInitramfs(initrd),
// Initramfs available at /mount/9p/initramfs/initramfs.cpio.
qemu.P9Directory(filepath.Dir(initrd), "initramfs"),
),
// The initramfs will be placed in shared dir, so in the VM
// it's available at /testdata/initramfs.cpio.
vmtest.WithSharedDir(testtmp.TempDir(t)),
// Build kexec (and all other initramfs commands) with coverage enabled.
vmtest.WithGoBuildOpts(&golang.BuildOpts{
ExtraArgs: []string{"-cover", "-coverpkg=github.com/u-root/u-root/...", "-covermode=atomic"},
}),
)

if _, err := vm.Console.ExpectString("SAW KEXEC=Y"); err != nil {
Expand Down