From 49600a6f46d99ff35d883381670548de1f01846e Mon Sep 17 00:00:00 2001 From: Ophestra Date: Sun, 31 Aug 2025 23:11:25 +0900 Subject: [PATCH] container/stub: export stub helpers These are very useful in many packages containing relatively large amount of code making calls to difficult or impossible to stub functions. Signed-off-by: Ophestra --- container/autoetc_test.go | 360 ++-- container/autoroot_test.go | 150 +- container/dispatcher_test.go | 601 +++--- container/errors_test.go | 11 +- container/init_test.go | 3481 +++++++++++++++++---------------- container/initbind_test.go | 132 +- container/initdev_test.go | 1214 ++++++------ container/initmkdir_test.go | 6 +- container/initoverlay_test.go | 180 +- container/initplace_test.go | 60 +- container/initproc_test.go | 14 +- container/initremount_test.go | 6 +- container/initsymlink_test.go | 30 +- container/inittmpfs_test.go | 6 +- container/mount_test.go | 233 +-- container/stub/call.go | 37 + container/stub/call_test.go | 23 + container/stub/errors.go | 25 + container/stub/errors_test.go | 35 + container/stub/exit.go | 15 + container/stub/exit_test.go | 30 + container/stub/stub.go | 141 ++ container/stub/stub_test.go | 265 +++ 23 files changed, 3808 insertions(+), 3247 deletions(-) create mode 100644 container/stub/call.go create mode 100644 container/stub/call_test.go create mode 100644 container/stub/errors.go create mode 100644 container/stub/errors_test.go create mode 100644 container/stub/exit.go create mode 100644 container/stub/exit_test.go create mode 100644 container/stub/stub.go create mode 100644 container/stub/stub_test.go diff --git a/container/autoetc_test.go b/container/autoetc_test.go index a892b59..f337f2f 100644 --- a/container/autoetc_test.go +++ b/container/autoetc_test.go @@ -4,6 +4,8 @@ import ( "errors" "os" "testing" + + "hakurei.app/container/stub" ) func TestAutoEtcOp(t *testing.T) { @@ -17,22 +19,22 @@ func TestAutoEtcOp(t *testing.T) { checkOpBehaviour(t, []opBehaviourTestCase{ {"mkdirAll", new(Params), &AutoEtcOp{ Prefix: "81ceabb30d37bbdb3868004629cb84e9", - }, nil, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/etc/", os.FileMode(0755)}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/etc/", os.FileMode(0755)}, nil, stub.UniqueError(3)}, + }, stub.UniqueError(3)}, {"readdir", new(Params), &AutoEtcOp{ Prefix: "81ceabb30d37bbdb3868004629cb84e9", - }, nil, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/etc/", os.FileMode(0755)}, nil, nil}, - {"readdir", expectArgs{"/sysroot/etc/.host/81ceabb30d37bbdb3868004629cb84e9"}, stubDir(), errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/etc/", os.FileMode(0755)}, nil, nil}, + {"readdir", stub.ExpectArgs{"/sysroot/etc/.host/81ceabb30d37bbdb3868004629cb84e9"}, stubDir(), stub.UniqueError(2)}, + }, stub.UniqueError(2)}, {"symlink", new(Params), &AutoEtcOp{ Prefix: "81ceabb30d37bbdb3868004629cb84e9", - }, nil, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/etc/", os.FileMode(0755)}, nil, nil}, - {"readdir", expectArgs{"/sysroot/etc/.host/81ceabb30d37bbdb3868004629cb84e9"}, stubDir(".host", + }, nil, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/etc/", os.FileMode(0755)}, nil, nil}, + {"readdir", stub.ExpectArgs{"/sysroot/etc/.host/81ceabb30d37bbdb3868004629cb84e9"}, stubDir(".host", "alsa", "bash_logout", "bashrc", "binfmt.d", "dbus-1", "default", "dhcpcd.exit-hook", "fonts", "fstab", "fuse.conf", "group", "host.conf", "hostname", "hosts", "hsurc", "inputrc", "issue", "kbd", "locale.conf", "login.defs", "lsb-release", "lvm", "machine-id", "man_db.conf", "mdadm.conf", @@ -41,14 +43,14 @@ func TestAutoEtcOp(t *testing.T) { "protocols", "resolv.conf", "resolvconf.conf", "rpc", "services", "set-environment", "shadow", "shells", "ssh", "ssl", "static", "subgid", "subuid", "sudoers", "sway", "sysctl.d", "systemd", "terminfo", "tmpfiles.d", "udev", "vconsole.conf", "X11", "xdg", "zoneinfo"), nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/alsa", "/sysroot/etc/alsa"}, nil, errUnique}, - }, errUnique}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/alsa", "/sysroot/etc/alsa"}, nil, stub.UniqueError(1)}, + }, stub.UniqueError(1)}, {"symlink mtab", new(Params), &AutoEtcOp{ Prefix: "81ceabb30d37bbdb3868004629cb84e9", - }, nil, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/etc/", os.FileMode(0755)}, nil, nil}, - {"readdir", expectArgs{"/sysroot/etc/.host/81ceabb30d37bbdb3868004629cb84e9"}, stubDir(".host", + }, nil, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/etc/", os.FileMode(0755)}, nil, nil}, + {"readdir", stub.ExpectArgs{"/sysroot/etc/.host/81ceabb30d37bbdb3868004629cb84e9"}, stubDir(".host", "alsa", "bash_logout", "bashrc", "binfmt.d", "dbus-1", "default", "dhcpcd.exit-hook", "fonts", "fstab", "fuse.conf", "group", "host.conf", "hostname", "hosts", "hsurc", "inputrc", "issue", "kbd", "locale.conf", "login.defs", "lsb-release", "lvm", "machine-id", "man_db.conf", "mdadm.conf", @@ -57,40 +59,40 @@ func TestAutoEtcOp(t *testing.T) { "protocols", "resolv.conf", "resolvconf.conf", "rpc", "services", "set-environment", "shadow", "shells", "ssh", "ssl", "static", "subgid", "subuid", "sudoers", "sway", "sysctl.d", "systemd", "terminfo", "tmpfiles.d", "udev", "vconsole.conf", "X11", "xdg", "zoneinfo"), nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/alsa", "/sysroot/etc/alsa"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/bash_logout", "/sysroot/etc/bash_logout"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/bashrc", "/sysroot/etc/bashrc"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/binfmt.d", "/sysroot/etc/binfmt.d"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/dbus-1", "/sysroot/etc/dbus-1"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/default", "/sysroot/etc/default"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/dhcpcd.exit-hook", "/sysroot/etc/dhcpcd.exit-hook"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fonts", "/sysroot/etc/fonts"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fstab", "/sysroot/etc/fstab"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fuse.conf", "/sysroot/etc/fuse.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/host.conf", "/sysroot/etc/host.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hostname", "/sysroot/etc/hostname"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hosts", "/sysroot/etc/hosts"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hsurc", "/sysroot/etc/hsurc"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/inputrc", "/sysroot/etc/inputrc"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/issue", "/sysroot/etc/issue"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/kbd", "/sysroot/etc/kbd"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/locale.conf", "/sysroot/etc/locale.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/login.defs", "/sysroot/etc/login.defs"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/lsb-release", "/sysroot/etc/lsb-release"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/lvm", "/sysroot/etc/lvm"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/machine-id", "/sysroot/etc/machine-id"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/man_db.conf", "/sysroot/etc/man_db.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/mdadm.conf", "/sysroot/etc/mdadm.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/modprobe.d", "/sysroot/etc/modprobe.d"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/modules-load.d", "/sysroot/etc/modules-load.d"}, nil, nil}, - {"symlink", expectArgs{"/proc/mounts", "/sysroot/etc/mtab"}, nil, errUnique}, - }, errUnique}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/alsa", "/sysroot/etc/alsa"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/bash_logout", "/sysroot/etc/bash_logout"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/bashrc", "/sysroot/etc/bashrc"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/binfmt.d", "/sysroot/etc/binfmt.d"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/dbus-1", "/sysroot/etc/dbus-1"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/default", "/sysroot/etc/default"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/dhcpcd.exit-hook", "/sysroot/etc/dhcpcd.exit-hook"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fonts", "/sysroot/etc/fonts"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fstab", "/sysroot/etc/fstab"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fuse.conf", "/sysroot/etc/fuse.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/host.conf", "/sysroot/etc/host.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hostname", "/sysroot/etc/hostname"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hosts", "/sysroot/etc/hosts"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hsurc", "/sysroot/etc/hsurc"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/inputrc", "/sysroot/etc/inputrc"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/issue", "/sysroot/etc/issue"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/kbd", "/sysroot/etc/kbd"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/locale.conf", "/sysroot/etc/locale.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/login.defs", "/sysroot/etc/login.defs"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/lsb-release", "/sysroot/etc/lsb-release"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/lvm", "/sysroot/etc/lvm"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/machine-id", "/sysroot/etc/machine-id"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/man_db.conf", "/sysroot/etc/man_db.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/mdadm.conf", "/sysroot/etc/mdadm.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/modprobe.d", "/sysroot/etc/modprobe.d"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/modules-load.d", "/sysroot/etc/modules-load.d"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/mounts", "/sysroot/etc/mtab"}, nil, stub.UniqueError(0)}, + }, stub.UniqueError(0)}, {"success nested", new(Params), &AutoEtcOp{ Prefix: "81ceabb30d37bbdb3868004629cb84e9", - }, nil, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/etc/", os.FileMode(0755)}, nil, nil}, - {"readdir", expectArgs{"/sysroot/etc/.host/81ceabb30d37bbdb3868004629cb84e9"}, stubDir(".host", + }, nil, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/etc/", os.FileMode(0755)}, nil, nil}, + {"readdir", stub.ExpectArgs{"/sysroot/etc/.host/81ceabb30d37bbdb3868004629cb84e9"}, stubDir(".host", "alsa", "bash_logout", "bashrc", "binfmt.d", "dbus-1", "default", "dhcpcd.exit-hook", "fonts", "fstab", "fuse.conf", "group", "host.conf", "hostname", "hosts", "hsurc", "inputrc", "issue", "kbd", "locale.conf", "login.defs", "lsb-release", "lvm", "machine-id", "man_db.conf", "mdadm.conf", @@ -99,78 +101,78 @@ func TestAutoEtcOp(t *testing.T) { "protocols", "resolv.conf", "resolvconf.conf", "rpc", "services", "set-environment", "shadow", "shells", "ssh", "ssl", "static", "subgid", "subuid", "sudoers", "sway", "sysctl.d", "systemd", "terminfo", "tmpfiles.d", "udev", "vconsole.conf", "X11", "xdg", "zoneinfo"), nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/alsa", "/sysroot/etc/alsa"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/bash_logout", "/sysroot/etc/bash_logout"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/bashrc", "/sysroot/etc/bashrc"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/binfmt.d", "/sysroot/etc/binfmt.d"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/dbus-1", "/sysroot/etc/dbus-1"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/default", "/sysroot/etc/default"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/dhcpcd.exit-hook", "/sysroot/etc/dhcpcd.exit-hook"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fonts", "/sysroot/etc/fonts"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fstab", "/sysroot/etc/fstab"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fuse.conf", "/sysroot/etc/fuse.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/host.conf", "/sysroot/etc/host.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hostname", "/sysroot/etc/hostname"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hosts", "/sysroot/etc/hosts"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hsurc", "/sysroot/etc/hsurc"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/inputrc", "/sysroot/etc/inputrc"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/issue", "/sysroot/etc/issue"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/kbd", "/sysroot/etc/kbd"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/locale.conf", "/sysroot/etc/locale.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/login.defs", "/sysroot/etc/login.defs"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/lsb-release", "/sysroot/etc/lsb-release"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/lvm", "/sysroot/etc/lvm"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/machine-id", "/sysroot/etc/machine-id"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/man_db.conf", "/sysroot/etc/man_db.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/mdadm.conf", "/sysroot/etc/mdadm.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/modprobe.d", "/sysroot/etc/modprobe.d"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/modules-load.d", "/sysroot/etc/modules-load.d"}, nil, nil}, - {"symlink", expectArgs{"/proc/mounts", "/sysroot/etc/mtab"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nanorc", "/sysroot/etc/nanorc"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/netgroup", "/sysroot/etc/netgroup"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nix", "/sysroot/etc/nix"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nixos", "/sysroot/etc/nixos"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/NIXOS", "/sysroot/etc/NIXOS"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nscd.conf", "/sysroot/etc/nscd.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nsswitch.conf", "/sysroot/etc/nsswitch.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/os-release", "/sysroot/etc/os-release"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/pam", "/sysroot/etc/pam"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/pam.d", "/sysroot/etc/pam.d"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/pipewire", "/sysroot/etc/pipewire"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/pki", "/sysroot/etc/pki"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/polkit-1", "/sysroot/etc/polkit-1"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/profile", "/sysroot/etc/profile"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/protocols", "/sysroot/etc/protocols"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/resolv.conf", "/sysroot/etc/resolv.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/resolvconf.conf", "/sysroot/etc/resolvconf.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/rpc", "/sysroot/etc/rpc"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/services", "/sysroot/etc/services"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/set-environment", "/sysroot/etc/set-environment"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/shadow", "/sysroot/etc/shadow"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/shells", "/sysroot/etc/shells"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/ssh", "/sysroot/etc/ssh"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/ssl", "/sysroot/etc/ssl"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/static", "/sysroot/etc/static"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/subgid", "/sysroot/etc/subgid"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/subuid", "/sysroot/etc/subuid"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/sudoers", "/sysroot/etc/sudoers"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/sway", "/sysroot/etc/sway"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/sysctl.d", "/sysroot/etc/sysctl.d"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/systemd", "/sysroot/etc/systemd"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/terminfo", "/sysroot/etc/terminfo"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/tmpfiles.d", "/sysroot/etc/tmpfiles.d"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/udev", "/sysroot/etc/udev"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/vconsole.conf", "/sysroot/etc/vconsole.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/X11", "/sysroot/etc/X11"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/xdg", "/sysroot/etc/xdg"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/zoneinfo", "/sysroot/etc/zoneinfo"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/alsa", "/sysroot/etc/alsa"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/bash_logout", "/sysroot/etc/bash_logout"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/bashrc", "/sysroot/etc/bashrc"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/binfmt.d", "/sysroot/etc/binfmt.d"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/dbus-1", "/sysroot/etc/dbus-1"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/default", "/sysroot/etc/default"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/dhcpcd.exit-hook", "/sysroot/etc/dhcpcd.exit-hook"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fonts", "/sysroot/etc/fonts"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fstab", "/sysroot/etc/fstab"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fuse.conf", "/sysroot/etc/fuse.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/host.conf", "/sysroot/etc/host.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hostname", "/sysroot/etc/hostname"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hosts", "/sysroot/etc/hosts"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hsurc", "/sysroot/etc/hsurc"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/inputrc", "/sysroot/etc/inputrc"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/issue", "/sysroot/etc/issue"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/kbd", "/sysroot/etc/kbd"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/locale.conf", "/sysroot/etc/locale.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/login.defs", "/sysroot/etc/login.defs"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/lsb-release", "/sysroot/etc/lsb-release"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/lvm", "/sysroot/etc/lvm"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/machine-id", "/sysroot/etc/machine-id"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/man_db.conf", "/sysroot/etc/man_db.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/mdadm.conf", "/sysroot/etc/mdadm.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/modprobe.d", "/sysroot/etc/modprobe.d"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/modules-load.d", "/sysroot/etc/modules-load.d"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/mounts", "/sysroot/etc/mtab"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nanorc", "/sysroot/etc/nanorc"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/netgroup", "/sysroot/etc/netgroup"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nix", "/sysroot/etc/nix"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nixos", "/sysroot/etc/nixos"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/NIXOS", "/sysroot/etc/NIXOS"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nscd.conf", "/sysroot/etc/nscd.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nsswitch.conf", "/sysroot/etc/nsswitch.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/os-release", "/sysroot/etc/os-release"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/pam", "/sysroot/etc/pam"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/pam.d", "/sysroot/etc/pam.d"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/pipewire", "/sysroot/etc/pipewire"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/pki", "/sysroot/etc/pki"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/polkit-1", "/sysroot/etc/polkit-1"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/profile", "/sysroot/etc/profile"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/protocols", "/sysroot/etc/protocols"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/resolv.conf", "/sysroot/etc/resolv.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/resolvconf.conf", "/sysroot/etc/resolvconf.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/rpc", "/sysroot/etc/rpc"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/services", "/sysroot/etc/services"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/set-environment", "/sysroot/etc/set-environment"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/shadow", "/sysroot/etc/shadow"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/shells", "/sysroot/etc/shells"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/ssh", "/sysroot/etc/ssh"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/ssl", "/sysroot/etc/ssl"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/static", "/sysroot/etc/static"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/subgid", "/sysroot/etc/subgid"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/subuid", "/sysroot/etc/subuid"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/sudoers", "/sysroot/etc/sudoers"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/sway", "/sysroot/etc/sway"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/sysctl.d", "/sysroot/etc/sysctl.d"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/systemd", "/sysroot/etc/systemd"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/terminfo", "/sysroot/etc/terminfo"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/tmpfiles.d", "/sysroot/etc/tmpfiles.d"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/udev", "/sysroot/etc/udev"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/vconsole.conf", "/sysroot/etc/vconsole.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/X11", "/sysroot/etc/X11"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/xdg", "/sysroot/etc/xdg"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/zoneinfo", "/sysroot/etc/zoneinfo"}, nil, nil}, }, nil}, {"success", new(Params), &AutoEtcOp{ Prefix: "81ceabb30d37bbdb3868004629cb84e9", - }, nil, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/etc/", os.FileMode(0755)}, nil, nil}, - {"readdir", expectArgs{"/sysroot/etc/.host/81ceabb30d37bbdb3868004629cb84e9"}, stubDir( + }, nil, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/etc/", os.FileMode(0755)}, nil, nil}, + {"readdir", stub.ExpectArgs{"/sysroot/etc/.host/81ceabb30d37bbdb3868004629cb84e9"}, stubDir( "alsa", "bash_logout", "bashrc", "binfmt.d", "dbus-1", "default", "dhcpcd.exit-hook", "fonts", "fstab", "fuse.conf", "group", "host.conf", "hostname", "hosts", "hsurc", "inputrc", "issue", "kbd", "locale.conf", "login.defs", "lsb-release", "lvm", "machine-id", "man_db.conf", "mdadm.conf", @@ -179,71 +181,71 @@ func TestAutoEtcOp(t *testing.T) { "protocols", "resolv.conf", "resolvconf.conf", "rpc", "services", "set-environment", "shadow", "shells", "ssh", "ssl", "static", "subgid", "subuid", "sudoers", "sway", "sysctl.d", "systemd", "terminfo", "tmpfiles.d", "udev", "vconsole.conf", "X11", "xdg", "zoneinfo"), nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/alsa", "/sysroot/etc/alsa"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/bash_logout", "/sysroot/etc/bash_logout"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/bashrc", "/sysroot/etc/bashrc"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/binfmt.d", "/sysroot/etc/binfmt.d"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/dbus-1", "/sysroot/etc/dbus-1"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/default", "/sysroot/etc/default"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/dhcpcd.exit-hook", "/sysroot/etc/dhcpcd.exit-hook"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fonts", "/sysroot/etc/fonts"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fstab", "/sysroot/etc/fstab"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fuse.conf", "/sysroot/etc/fuse.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/host.conf", "/sysroot/etc/host.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hostname", "/sysroot/etc/hostname"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hosts", "/sysroot/etc/hosts"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hsurc", "/sysroot/etc/hsurc"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/inputrc", "/sysroot/etc/inputrc"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/issue", "/sysroot/etc/issue"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/kbd", "/sysroot/etc/kbd"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/locale.conf", "/sysroot/etc/locale.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/login.defs", "/sysroot/etc/login.defs"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/lsb-release", "/sysroot/etc/lsb-release"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/lvm", "/sysroot/etc/lvm"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/machine-id", "/sysroot/etc/machine-id"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/man_db.conf", "/sysroot/etc/man_db.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/mdadm.conf", "/sysroot/etc/mdadm.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/modprobe.d", "/sysroot/etc/modprobe.d"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/modules-load.d", "/sysroot/etc/modules-load.d"}, nil, nil}, - {"symlink", expectArgs{"/proc/mounts", "/sysroot/etc/mtab"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nanorc", "/sysroot/etc/nanorc"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/netgroup", "/sysroot/etc/netgroup"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nix", "/sysroot/etc/nix"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nixos", "/sysroot/etc/nixos"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/NIXOS", "/sysroot/etc/NIXOS"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nscd.conf", "/sysroot/etc/nscd.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nsswitch.conf", "/sysroot/etc/nsswitch.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/os-release", "/sysroot/etc/os-release"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/pam", "/sysroot/etc/pam"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/pam.d", "/sysroot/etc/pam.d"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/pipewire", "/sysroot/etc/pipewire"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/pki", "/sysroot/etc/pki"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/polkit-1", "/sysroot/etc/polkit-1"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/profile", "/sysroot/etc/profile"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/protocols", "/sysroot/etc/protocols"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/resolv.conf", "/sysroot/etc/resolv.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/resolvconf.conf", "/sysroot/etc/resolvconf.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/rpc", "/sysroot/etc/rpc"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/services", "/sysroot/etc/services"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/set-environment", "/sysroot/etc/set-environment"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/shadow", "/sysroot/etc/shadow"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/shells", "/sysroot/etc/shells"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/ssh", "/sysroot/etc/ssh"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/ssl", "/sysroot/etc/ssl"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/static", "/sysroot/etc/static"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/subgid", "/sysroot/etc/subgid"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/subuid", "/sysroot/etc/subuid"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/sudoers", "/sysroot/etc/sudoers"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/sway", "/sysroot/etc/sway"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/sysctl.d", "/sysroot/etc/sysctl.d"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/systemd", "/sysroot/etc/systemd"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/terminfo", "/sysroot/etc/terminfo"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/tmpfiles.d", "/sysroot/etc/tmpfiles.d"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/udev", "/sysroot/etc/udev"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/vconsole.conf", "/sysroot/etc/vconsole.conf"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/X11", "/sysroot/etc/X11"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/xdg", "/sysroot/etc/xdg"}, nil, nil}, - {"symlink", expectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/zoneinfo", "/sysroot/etc/zoneinfo"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/alsa", "/sysroot/etc/alsa"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/bash_logout", "/sysroot/etc/bash_logout"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/bashrc", "/sysroot/etc/bashrc"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/binfmt.d", "/sysroot/etc/binfmt.d"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/dbus-1", "/sysroot/etc/dbus-1"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/default", "/sysroot/etc/default"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/dhcpcd.exit-hook", "/sysroot/etc/dhcpcd.exit-hook"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fonts", "/sysroot/etc/fonts"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fstab", "/sysroot/etc/fstab"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/fuse.conf", "/sysroot/etc/fuse.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/host.conf", "/sysroot/etc/host.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hostname", "/sysroot/etc/hostname"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hosts", "/sysroot/etc/hosts"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/hsurc", "/sysroot/etc/hsurc"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/inputrc", "/sysroot/etc/inputrc"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/issue", "/sysroot/etc/issue"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/kbd", "/sysroot/etc/kbd"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/locale.conf", "/sysroot/etc/locale.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/login.defs", "/sysroot/etc/login.defs"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/lsb-release", "/sysroot/etc/lsb-release"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/lvm", "/sysroot/etc/lvm"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/machine-id", "/sysroot/etc/machine-id"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/man_db.conf", "/sysroot/etc/man_db.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/mdadm.conf", "/sysroot/etc/mdadm.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/modprobe.d", "/sysroot/etc/modprobe.d"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/modules-load.d", "/sysroot/etc/modules-load.d"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/mounts", "/sysroot/etc/mtab"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nanorc", "/sysroot/etc/nanorc"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/netgroup", "/sysroot/etc/netgroup"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nix", "/sysroot/etc/nix"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nixos", "/sysroot/etc/nixos"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/NIXOS", "/sysroot/etc/NIXOS"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nscd.conf", "/sysroot/etc/nscd.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/nsswitch.conf", "/sysroot/etc/nsswitch.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/os-release", "/sysroot/etc/os-release"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/pam", "/sysroot/etc/pam"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/pam.d", "/sysroot/etc/pam.d"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/pipewire", "/sysroot/etc/pipewire"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/pki", "/sysroot/etc/pki"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/polkit-1", "/sysroot/etc/polkit-1"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/profile", "/sysroot/etc/profile"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/protocols", "/sysroot/etc/protocols"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/resolv.conf", "/sysroot/etc/resolv.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/resolvconf.conf", "/sysroot/etc/resolvconf.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/rpc", "/sysroot/etc/rpc"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/services", "/sysroot/etc/services"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/set-environment", "/sysroot/etc/set-environment"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/shadow", "/sysroot/etc/shadow"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/shells", "/sysroot/etc/shells"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/ssh", "/sysroot/etc/ssh"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/ssl", "/sysroot/etc/ssl"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/static", "/sysroot/etc/static"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/subgid", "/sysroot/etc/subgid"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/subuid", "/sysroot/etc/subuid"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/sudoers", "/sysroot/etc/sudoers"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/sway", "/sysroot/etc/sway"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/sysctl.d", "/sysroot/etc/sysctl.d"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/systemd", "/sysroot/etc/systemd"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/terminfo", "/sysroot/etc/terminfo"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/tmpfiles.d", "/sysroot/etc/tmpfiles.d"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/udev", "/sysroot/etc/udev"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/vconsole.conf", "/sysroot/etc/vconsole.conf"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/X11", "/sysroot/etc/X11"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/xdg", "/sysroot/etc/xdg"}, nil, nil}, + {"symlink", stub.ExpectArgs{".host/81ceabb30d37bbdb3868004629cb84e9/zoneinfo", "/sysroot/etc/zoneinfo"}, nil, nil}, }, nil}, }) diff --git a/container/autoroot_test.go b/container/autoroot_test.go index 3678725..29613f6 100644 --- a/container/autoroot_test.go +++ b/container/autoroot_test.go @@ -4,6 +4,8 @@ import ( "errors" "os" "testing" + + "hakurei.app/container/stub" ) func TestAutoRootOp(t *testing.T) { @@ -18,100 +20,100 @@ func TestAutoRootOp(t *testing.T) { {"readdir", &Params{ParentPerm: 0750}, &AutoRootOp{ Host: MustAbs("/"), Flags: BindWritable, - }, []kexpect{ - {"readdir", expectArgs{"/"}, stubDir(), errUnique}, - }, errUnique, nil, nil}, + }, []stub.Call{ + {"readdir", stub.ExpectArgs{"/"}, stubDir(), stub.UniqueError(2)}, + }, stub.UniqueError(2), nil, nil}, {"early", &Params{ParentPerm: 0750}, &AutoRootOp{ Host: MustAbs("/"), Flags: BindWritable, - }, []kexpect{ - {"readdir", expectArgs{"/"}, stubDir("bin", "dev", "etc", "home", "lib64", + }, []stub.Call{ + {"readdir", stub.ExpectArgs{"/"}, stubDir("bin", "dev", "etc", "home", "lib64", "lost+found", "mnt", "nix", "proc", "root", "run", "srv", "sys", "tmp", "usr", "var"), nil}, - {"evalSymlinks", expectArgs{"/bin"}, "", errUnique}, - }, errUnique, nil, nil}, + {"evalSymlinks", stub.ExpectArgs{"/bin"}, "", stub.UniqueError(1)}, + }, stub.UniqueError(1), nil, nil}, {"apply", &Params{ParentPerm: 0750}, &AutoRootOp{ Host: MustAbs("/"), Flags: BindWritable, - }, []kexpect{ - {"readdir", expectArgs{"/"}, stubDir("bin", "dev", "etc", "home", "lib64", + }, []stub.Call{ + {"readdir", stub.ExpectArgs{"/"}, stubDir("bin", "dev", "etc", "home", "lib64", "lost+found", "mnt", "nix", "proc", "root", "run", "srv", "sys", "tmp", "usr", "var"), nil}, - {"evalSymlinks", expectArgs{"/bin"}, "/usr/bin", nil}, - {"evalSymlinks", expectArgs{"/home"}, "/home", nil}, - {"evalSymlinks", expectArgs{"/lib64"}, "/lib64", nil}, - {"evalSymlinks", expectArgs{"/lost+found"}, "/lost+found", nil}, - {"evalSymlinks", expectArgs{"/nix"}, "/nix", nil}, - {"evalSymlinks", expectArgs{"/root"}, "/root", nil}, - {"evalSymlinks", expectArgs{"/run"}, "/run", nil}, - {"evalSymlinks", expectArgs{"/srv"}, "/srv", nil}, - {"evalSymlinks", expectArgs{"/sys"}, "/sys", nil}, - {"evalSymlinks", expectArgs{"/usr"}, "/usr", nil}, - {"evalSymlinks", expectArgs{"/var"}, "/var", nil}, - }, nil, []kexpect{ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/usr/bin"), MustAbs("/bin"), MustAbs("/bin"), BindWritable}}}, nil, nil}, - {"stat", expectArgs{"/host/usr/bin"}, isDirFi(false), errUnique}, - }, errUnique}, + {"evalSymlinks", stub.ExpectArgs{"/bin"}, "/usr/bin", nil}, + {"evalSymlinks", stub.ExpectArgs{"/home"}, "/home", nil}, + {"evalSymlinks", stub.ExpectArgs{"/lib64"}, "/lib64", nil}, + {"evalSymlinks", stub.ExpectArgs{"/lost+found"}, "/lost+found", nil}, + {"evalSymlinks", stub.ExpectArgs{"/nix"}, "/nix", nil}, + {"evalSymlinks", stub.ExpectArgs{"/root"}, "/root", nil}, + {"evalSymlinks", stub.ExpectArgs{"/run"}, "/run", nil}, + {"evalSymlinks", stub.ExpectArgs{"/srv"}, "/srv", nil}, + {"evalSymlinks", stub.ExpectArgs{"/sys"}, "/sys", nil}, + {"evalSymlinks", stub.ExpectArgs{"/usr"}, "/usr", nil}, + {"evalSymlinks", stub.ExpectArgs{"/var"}, "/var", nil}, + }, nil, []stub.Call{ + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/usr/bin"), MustAbs("/bin"), MustAbs("/bin"), BindWritable}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host/usr/bin"}, isDirFi(false), stub.UniqueError(0)}, + }, stub.UniqueError(0)}, {"success pd", &Params{ParentPerm: 0750}, &AutoRootOp{ Host: MustAbs("/"), Flags: BindWritable, - }, []kexpect{ - {"readdir", expectArgs{"/"}, stubDir("bin", "dev", "etc", "home", "lib64", + }, []stub.Call{ + {"readdir", stub.ExpectArgs{"/"}, stubDir("bin", "dev", "etc", "home", "lib64", "lost+found", "mnt", "nix", "proc", "root", "run", "srv", "sys", "tmp", "usr", "var"), nil}, - {"evalSymlinks", expectArgs{"/bin"}, "/usr/bin", nil}, - {"evalSymlinks", expectArgs{"/home"}, "/home", nil}, - {"evalSymlinks", expectArgs{"/lib64"}, "/lib64", nil}, - {"evalSymlinks", expectArgs{"/lost+found"}, "/lost+found", nil}, - {"evalSymlinks", expectArgs{"/nix"}, "/nix", nil}, - {"evalSymlinks", expectArgs{"/root"}, "/root", nil}, - {"evalSymlinks", expectArgs{"/run"}, "/run", nil}, - {"evalSymlinks", expectArgs{"/srv"}, "/srv", nil}, - {"evalSymlinks", expectArgs{"/sys"}, "/sys", nil}, - {"evalSymlinks", expectArgs{"/usr"}, "/usr", nil}, - {"evalSymlinks", expectArgs{"/var"}, "/var", nil}, - }, nil, []kexpect{ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/usr/bin"), MustAbs("/bin"), MustAbs("/bin"), BindWritable}}}, nil, nil}, {"stat", expectArgs{"/host/usr/bin"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/bin", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/usr/bin", "/sysroot/bin", uintptr(0x4004), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/home"), MustAbs("/home"), MustAbs("/home"), BindWritable}}}, nil, nil}, {"stat", expectArgs{"/host/home"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/home", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/home", "/sysroot/home", uintptr(0x4004), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/lib64"), MustAbs("/lib64"), MustAbs("/lib64"), BindWritable}}}, nil, nil}, {"stat", expectArgs{"/host/lib64"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/lib64", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/lib64", "/sysroot/lib64", uintptr(0x4004), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/lost+found"), MustAbs("/lost+found"), MustAbs("/lost+found"), BindWritable}}}, nil, nil}, {"stat", expectArgs{"/host/lost+found"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/lost+found", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/lost+found", "/sysroot/lost+found", uintptr(0x4004), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/nix"), MustAbs("/nix"), MustAbs("/nix"), BindWritable}}}, nil, nil}, {"stat", expectArgs{"/host/nix"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/nix", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/nix", "/sysroot/nix", uintptr(0x4004), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/root"), MustAbs("/root"), MustAbs("/root"), BindWritable}}}, nil, nil}, {"stat", expectArgs{"/host/root"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/root", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/root", "/sysroot/root", uintptr(0x4004), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/run"), MustAbs("/run"), MustAbs("/run"), BindWritable}}}, nil, nil}, {"stat", expectArgs{"/host/run"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/run", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/run", "/sysroot/run", uintptr(0x4004), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/srv"), MustAbs("/srv"), MustAbs("/srv"), BindWritable}}}, nil, nil}, {"stat", expectArgs{"/host/srv"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/srv", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/srv", "/sysroot/srv", uintptr(0x4004), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/sys"), MustAbs("/sys"), MustAbs("/sys"), BindWritable}}}, nil, nil}, {"stat", expectArgs{"/host/sys"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/sys", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/sys", "/sysroot/sys", uintptr(0x4004), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/usr"), MustAbs("/usr"), MustAbs("/usr"), BindWritable}}}, nil, nil}, {"stat", expectArgs{"/host/usr"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/usr", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/usr", "/sysroot/usr", uintptr(0x4004), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var"), MustAbs("/var"), MustAbs("/var"), BindWritable}}}, nil, nil}, {"stat", expectArgs{"/host/var"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/var", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/var", "/sysroot/var", uintptr(0x4004), false}, nil, nil}, + {"evalSymlinks", stub.ExpectArgs{"/bin"}, "/usr/bin", nil}, + {"evalSymlinks", stub.ExpectArgs{"/home"}, "/home", nil}, + {"evalSymlinks", stub.ExpectArgs{"/lib64"}, "/lib64", nil}, + {"evalSymlinks", stub.ExpectArgs{"/lost+found"}, "/lost+found", nil}, + {"evalSymlinks", stub.ExpectArgs{"/nix"}, "/nix", nil}, + {"evalSymlinks", stub.ExpectArgs{"/root"}, "/root", nil}, + {"evalSymlinks", stub.ExpectArgs{"/run"}, "/run", nil}, + {"evalSymlinks", stub.ExpectArgs{"/srv"}, "/srv", nil}, + {"evalSymlinks", stub.ExpectArgs{"/sys"}, "/sys", nil}, + {"evalSymlinks", stub.ExpectArgs{"/usr"}, "/usr", nil}, + {"evalSymlinks", stub.ExpectArgs{"/var"}, "/var", nil}, + }, nil, []stub.Call{ + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/usr/bin"), MustAbs("/bin"), MustAbs("/bin"), BindWritable}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/usr/bin"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/bin", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/usr/bin", "/sysroot/bin", uintptr(0x4004), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/home"), MustAbs("/home"), MustAbs("/home"), BindWritable}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/home"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/home", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/home", "/sysroot/home", uintptr(0x4004), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/lib64"), MustAbs("/lib64"), MustAbs("/lib64"), BindWritable}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/lib64"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/lib64", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/lib64", "/sysroot/lib64", uintptr(0x4004), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/lost+found"), MustAbs("/lost+found"), MustAbs("/lost+found"), BindWritable}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/lost+found"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/lost+found", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/lost+found", "/sysroot/lost+found", uintptr(0x4004), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/nix"), MustAbs("/nix"), MustAbs("/nix"), BindWritable}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/nix"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/nix", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/nix", "/sysroot/nix", uintptr(0x4004), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/root"), MustAbs("/root"), MustAbs("/root"), BindWritable}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/root"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/root", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/root", "/sysroot/root", uintptr(0x4004), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/run"), MustAbs("/run"), MustAbs("/run"), BindWritable}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/run"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/run", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/run", "/sysroot/run", uintptr(0x4004), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/srv"), MustAbs("/srv"), MustAbs("/srv"), BindWritable}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/srv"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/srv", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/srv", "/sysroot/srv", uintptr(0x4004), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/sys"), MustAbs("/sys"), MustAbs("/sys"), BindWritable}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/sys"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/sys", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/sys", "/sysroot/sys", uintptr(0x4004), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/usr"), MustAbs("/usr"), MustAbs("/usr"), BindWritable}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/usr"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/usr", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/usr", "/sysroot/usr", uintptr(0x4004), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var"), MustAbs("/var"), MustAbs("/var"), BindWritable}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/var"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/var", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/var", "/sysroot/var", uintptr(0x4004), false}, nil, nil}, }, nil}, {"success", &Params{ParentPerm: 0750}, &AutoRootOp{ Host: MustAbs("/var/lib/planterette/base/debian:f92c9052"), - }, []kexpect{ - {"readdir", expectArgs{"/var/lib/planterette/base/debian:f92c9052"}, stubDir("bin", "dev", "etc", "home", "lib64", + }, []stub.Call{ + {"readdir", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052"}, stubDir("bin", "dev", "etc", "home", "lib64", "lost+found", "mnt", "nix", "proc", "root", "run", "srv", "sys", "tmp", "usr", "var"), nil}, - {"evalSymlinks", expectArgs{"/var/lib/planterette/base/debian:f92c9052/bin"}, "/var/lib/planterette/base/debian:f92c9052/usr/bin", nil}, - {"evalSymlinks", expectArgs{"/var/lib/planterette/base/debian:f92c9052/home"}, "/var/lib/planterette/base/debian:f92c9052/home", nil}, - {"evalSymlinks", expectArgs{"/var/lib/planterette/base/debian:f92c9052/lib64"}, "/var/lib/planterette/base/debian:f92c9052/lib64", nil}, - {"evalSymlinks", expectArgs{"/var/lib/planterette/base/debian:f92c9052/lost+found"}, "/var/lib/planterette/base/debian:f92c9052/lost+found", nil}, - {"evalSymlinks", expectArgs{"/var/lib/planterette/base/debian:f92c9052/nix"}, "/var/lib/planterette/base/debian:f92c9052/nix", nil}, - {"evalSymlinks", expectArgs{"/var/lib/planterette/base/debian:f92c9052/root"}, "/var/lib/planterette/base/debian:f92c9052/root", nil}, - {"evalSymlinks", expectArgs{"/var/lib/planterette/base/debian:f92c9052/run"}, "/var/lib/planterette/base/debian:f92c9052/run", nil}, - {"evalSymlinks", expectArgs{"/var/lib/planterette/base/debian:f92c9052/srv"}, "/var/lib/planterette/base/debian:f92c9052/srv", nil}, - {"evalSymlinks", expectArgs{"/var/lib/planterette/base/debian:f92c9052/sys"}, "/var/lib/planterette/base/debian:f92c9052/sys", nil}, - {"evalSymlinks", expectArgs{"/var/lib/planterette/base/debian:f92c9052/usr"}, "/var/lib/planterette/base/debian:f92c9052/usr", nil}, - {"evalSymlinks", expectArgs{"/var/lib/planterette/base/debian:f92c9052/var"}, "/var/lib/planterette/base/debian:f92c9052/var", nil}, - }, nil, []kexpect{ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/usr/bin"), MustAbs("/var/lib/planterette/base/debian:f92c9052/bin"), MustAbs("/bin"), 0}}}, nil, nil}, {"stat", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/usr/bin"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/bin", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/usr/bin", "/sysroot/bin", uintptr(0x4005), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/home"), MustAbs("/var/lib/planterette/base/debian:f92c9052/home"), MustAbs("/home"), 0}}}, nil, nil}, {"stat", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/home"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/home", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/home", "/sysroot/home", uintptr(0x4005), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/lib64"), MustAbs("/var/lib/planterette/base/debian:f92c9052/lib64"), MustAbs("/lib64"), 0}}}, nil, nil}, {"stat", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/lib64"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/lib64", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/lib64", "/sysroot/lib64", uintptr(0x4005), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/lost+found"), MustAbs("/var/lib/planterette/base/debian:f92c9052/lost+found"), MustAbs("/lost+found"), 0}}}, nil, nil}, {"stat", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/lost+found"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/lost+found", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/lost+found", "/sysroot/lost+found", uintptr(0x4005), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/nix"), MustAbs("/var/lib/planterette/base/debian:f92c9052/nix"), MustAbs("/nix"), 0}}}, nil, nil}, {"stat", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/nix"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/nix", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/nix", "/sysroot/nix", uintptr(0x4005), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/root"), MustAbs("/var/lib/planterette/base/debian:f92c9052/root"), MustAbs("/root"), 0}}}, nil, nil}, {"stat", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/root"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/root", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/root", "/sysroot/root", uintptr(0x4005), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/run"), MustAbs("/var/lib/planterette/base/debian:f92c9052/run"), MustAbs("/run"), 0}}}, nil, nil}, {"stat", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/run"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/run", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/run", "/sysroot/run", uintptr(0x4005), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/srv"), MustAbs("/var/lib/planterette/base/debian:f92c9052/srv"), MustAbs("/srv"), 0}}}, nil, nil}, {"stat", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/srv"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/srv", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/srv", "/sysroot/srv", uintptr(0x4005), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/sys"), MustAbs("/var/lib/planterette/base/debian:f92c9052/sys"), MustAbs("/sys"), 0}}}, nil, nil}, {"stat", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/sys"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/sys", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/sys", "/sysroot/sys", uintptr(0x4005), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/usr"), MustAbs("/var/lib/planterette/base/debian:f92c9052/usr"), MustAbs("/usr"), 0}}}, nil, nil}, {"stat", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/usr"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/usr", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/usr", "/sysroot/usr", uintptr(0x4005), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/var"), MustAbs("/var/lib/planterette/base/debian:f92c9052/var"), MustAbs("/var"), 0}}}, nil, nil}, {"stat", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/var"}, isDirFi(true), nil}, {"mkdirAll", expectArgs{"/sysroot/var", os.FileMode(0700)}, nil, nil}, {"bindMount", expectArgs{"/host/var/lib/planterette/base/debian:f92c9052/var", "/sysroot/var", uintptr(0x4005), false}, nil, nil}, + {"evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052/bin"}, "/var/lib/planterette/base/debian:f92c9052/usr/bin", nil}, + {"evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052/home"}, "/var/lib/planterette/base/debian:f92c9052/home", nil}, + {"evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052/lib64"}, "/var/lib/planterette/base/debian:f92c9052/lib64", nil}, + {"evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052/lost+found"}, "/var/lib/planterette/base/debian:f92c9052/lost+found", nil}, + {"evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052/nix"}, "/var/lib/planterette/base/debian:f92c9052/nix", nil}, + {"evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052/root"}, "/var/lib/planterette/base/debian:f92c9052/root", nil}, + {"evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052/run"}, "/var/lib/planterette/base/debian:f92c9052/run", nil}, + {"evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052/srv"}, "/var/lib/planterette/base/debian:f92c9052/srv", nil}, + {"evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052/sys"}, "/var/lib/planterette/base/debian:f92c9052/sys", nil}, + {"evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052/usr"}, "/var/lib/planterette/base/debian:f92c9052/usr", nil}, + {"evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052/var"}, "/var/lib/planterette/base/debian:f92c9052/var", nil}, + }, nil, []stub.Call{ + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/usr/bin"), MustAbs("/var/lib/planterette/base/debian:f92c9052/bin"), MustAbs("/bin"), 0}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/usr/bin"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/bin", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/usr/bin", "/sysroot/bin", uintptr(0x4005), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/home"), MustAbs("/var/lib/planterette/base/debian:f92c9052/home"), MustAbs("/home"), 0}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/home"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/home", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/home", "/sysroot/home", uintptr(0x4005), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/lib64"), MustAbs("/var/lib/planterette/base/debian:f92c9052/lib64"), MustAbs("/lib64"), 0}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/lib64"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/lib64", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/lib64", "/sysroot/lib64", uintptr(0x4005), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/lost+found"), MustAbs("/var/lib/planterette/base/debian:f92c9052/lost+found"), MustAbs("/lost+found"), 0}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/lost+found"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/lost+found", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/lost+found", "/sysroot/lost+found", uintptr(0x4005), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/nix"), MustAbs("/var/lib/planterette/base/debian:f92c9052/nix"), MustAbs("/nix"), 0}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/nix"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/nix", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/nix", "/sysroot/nix", uintptr(0x4005), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/root"), MustAbs("/var/lib/planterette/base/debian:f92c9052/root"), MustAbs("/root"), 0}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/root"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/root", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/root", "/sysroot/root", uintptr(0x4005), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/run"), MustAbs("/var/lib/planterette/base/debian:f92c9052/run"), MustAbs("/run"), 0}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/run"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/run", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/run", "/sysroot/run", uintptr(0x4005), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/srv"), MustAbs("/var/lib/planterette/base/debian:f92c9052/srv"), MustAbs("/srv"), 0}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/srv"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/srv", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/srv", "/sysroot/srv", uintptr(0x4005), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/sys"), MustAbs("/var/lib/planterette/base/debian:f92c9052/sys"), MustAbs("/sys"), 0}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/sys"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/sys", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/sys", "/sysroot/sys", uintptr(0x4005), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/usr"), MustAbs("/var/lib/planterette/base/debian:f92c9052/usr"), MustAbs("/usr"), 0}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/usr"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/usr", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/usr", "/sysroot/usr", uintptr(0x4005), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{MustAbs("/var/lib/planterette/base/debian:f92c9052/var"), MustAbs("/var/lib/planterette/base/debian:f92c9052/var"), MustAbs("/var"), 0}}}, nil, nil}, {"stat", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/var"}, isDirFi(true), nil}, {"mkdirAll", stub.ExpectArgs{"/sysroot/var", os.FileMode(0700)}, nil, nil}, {"bindMount", stub.ExpectArgs{"/host/var/lib/planterette/base/debian:f92c9052/var", "/sysroot/var", uintptr(0x4005), false}, nil, nil}, }, nil}, }) diff --git a/container/dispatcher_test.go b/container/dispatcher_test.go index 69d698a..5b04ea7 100644 --- a/container/dispatcher_test.go +++ b/container/dispatcher_test.go @@ -2,7 +2,6 @@ package container import ( "bytes" - "errors" "io" "io/fs" "os" @@ -11,16 +10,14 @@ import ( "runtime" "slices" "strings" - "sync" "syscall" "testing" "time" "hakurei.app/container/seccomp" + "hakurei.app/container/stub" ) -var errUnique = errors.New("unique error injected by the test suite") - type opValidTestCase struct { name string op Op @@ -28,9 +25,15 @@ type opValidTestCase struct { } func checkOpsValid(t *testing.T, testCases []opValidTestCase) { + t.Helper() + t.Run("valid", func(t *testing.T) { + t.Helper() + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Helper() + if got := tc.op.Valid(); got != tc.want { t.Errorf("Valid: %v, want %v", got, tc.want) } @@ -46,9 +49,15 @@ type opsBuilderTestCase struct { } func checkOpsBuilder(t *testing.T, testCases []opsBuilderTestCase) { + t.Helper() + t.Run("build", func(t *testing.T) { + t.Helper() + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Helper() + if !slices.EqualFunc(*tc.ops, tc.want, func(op Op, v Op) bool { return op.Is(v) }) { t.Errorf("Ops: %#v, want %#v", tc.ops, tc.want) } @@ -64,9 +73,15 @@ type opIsTestCase struct { } func checkOpIs(t *testing.T, testCases []opIsTestCase) { + t.Helper() + t.Run("is", func(t *testing.T) { + t.Helper() + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Helper() + if got := tc.op.Is(tc.v); got != tc.want { t.Errorf("Is: %v, want %v", got, tc.want) } @@ -84,16 +99,26 @@ type opMetaTestCase struct { } func checkOpMeta(t *testing.T, testCases []opMetaTestCase) { + t.Helper() + t.Run("meta", func(t *testing.T) { + t.Helper() + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { + t.Helper() + t.Run("prefix", func(t *testing.T) { + t.Helper() + if got := tc.op.prefix(); got != tc.wantPrefix { t.Errorf("prefix: %q, want %q", got, tc.wantPrefix) } }) t.Run("string", func(t *testing.T) { + t.Helper() + if got := tc.op.String(); got != tc.wantString { t.Errorf("String: %s, want %s", got, tc.wantString) } @@ -106,20 +131,26 @@ func checkOpMeta(t *testing.T, testCases []opMetaTestCase) { type simpleTestCase struct { name string f func(k syscallDispatcher) error - want [][]kexpect + want stub.Expect wantErr error } func checkSimple(t *testing.T, fname string, testCases []simpleTestCase) { + t.Helper() + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - defer handleExitStub() - k := &kstub{t: t, want: tc.want, wg: new(sync.WaitGroup)} + t.Helper() + + defer stub.HandleExit() + k := &kstub{stub.New(t, func(s *stub.Stub[syscallDispatcher]) syscallDispatcher { return &kstub{s} }, tc.want)} if err := tc.f(k); !reflect.DeepEqual(err, tc.wantErr) { t.Errorf("%s: error = %v, want %v", fname, err, tc.wantErr) } - k.handleIncomplete(func(k *kstub) { - t.Errorf("%s: %d calls, want %d (track %d)", fname, k.pos, len(k.want[k.track]), k.track) + k.VisitIncomplete(func(s *stub.Stub[syscallDispatcher]) { + t.Helper() + + t.Errorf("%s: %d calls, want %d", fname, s.Pos(), s.Len()) }) }) } @@ -130,22 +161,31 @@ type opBehaviourTestCase struct { params *Params op Op - early []kexpect + early []stub.Call wantErrEarly error - apply []kexpect + apply []stub.Call wantErrApply error } func checkOpBehaviour(t *testing.T, testCases []opBehaviourTestCase) { + t.Helper() + t.Run("behaviour", func(t *testing.T) { + t.Helper() + for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - defer handleExitStub() + t.Helper() + + defer stub.HandleExit() state := &setupState{Params: tc.params} - k := &kstub{t: t, want: [][]kexpect{slices.Concat(tc.early, []kexpect{{name: "\x00"}}, tc.apply)}, wg: new(sync.WaitGroup)} + k := &kstub{stub.New(t, + func(s *stub.Stub[syscallDispatcher]) syscallDispatcher { return &kstub{s} }, + stub.Expect{Calls: slices.Concat(tc.early, []stub.Call{{Name: stub.CallSeparator}}, tc.apply)}, + )} errEarly := tc.op.early(state, k) - k.expect("\x00") + k.Expects(stub.CallSeparator) if !reflect.DeepEqual(errEarly, tc.wantErrEarly) { t.Errorf("early: error = %v, want %v", errEarly, tc.wantErrEarly) } @@ -158,8 +198,8 @@ func checkOpBehaviour(t *testing.T, testCases []opBehaviourTestCase) { } out: - k.handleIncomplete(func(k *kstub) { - count := k.pos - 1 // separator + k.VisitIncomplete(func(s *stub.Stub[syscallDispatcher]) { + count := k.Pos() - 1 // separator if count < len(tc.early) { t.Errorf("early: %d calls, want %d", count, len(tc.early)) } else { @@ -226,8 +266,6 @@ func (writeErrOsFile) Stat() (fs.FileInfo, error) { panic("unreachable") } func (writeErrOsFile) Read([]byte) (int, error) { panic("unreachable") } func (writeErrOsFile) Close() error { panic("unreachable") } -type expectArgs = [5]any - type isDirFi bool func (isDirFi) Name() string { panic("unreachable") } @@ -252,184 +290,83 @@ func (nameDentry) IsDir() bool { panic("unreachable") } func (nameDentry) Type() fs.FileMode { panic("unreachable") } func (nameDentry) Info() (fs.FileInfo, error) { panic("unreachable") } -type kexpect struct { - name string - args expectArgs - ret any - err error -} +type kstub struct{ *stub.Stub[syscallDispatcher] } -func (k *kexpect) error(ok ...bool) error { - if !slices.Contains(ok, false) { - return k.err - } - return syscall.ENOTRECOVERABLE -} +func (k *kstub) new(f func(k syscallDispatcher)) { k.Helper(); k.New(f) } -func handleExitStub() { - r := recover() - if r == 0xdeadbeef { - return - } - if r != nil { - panic(r) - } -} - -type kstub struct { - t *testing.T - - want [][]kexpect - // pos is the current position in want[track]. - pos int - // track is the current active want. - track int - // sub stores addresses of kstub created by new. - sub []*kstub - // wg waits for all descendants to complete. - wg *sync.WaitGroup -} - -// handleIncomplete calls f on an incomplete k and all its descendants. -func (k *kstub) handleIncomplete(f func(k *kstub)) { - k.wg.Wait() - - if k.want != nil && len(k.want[k.track]) != k.pos { - f(k) - } - for _, sk := range k.sub { - sk.handleIncomplete(f) - } -} - -// expect checks name and returns the current kexpect and advances pos. -func (k *kstub) expect(name string) (expect *kexpect) { - if len(k.want[k.track]) == k.pos { - k.t.Fatal("expect: want too short") - } - expect = &k.want[k.track][k.pos] - if name != expect.name { - if expect.name == "\x00" { - k.t.Fatalf("expect: func = %s, separator overrun", name) - } - if name == "\x00" { - k.t.Fatalf("expect: separator, want %s", expect.name) - } - k.t.Fatalf("expect: func = %s, want %s", name, expect.name) - } - k.pos++ - return -} - -// checkArg checks an argument comparable with the == operator. Avoid using this with pointers. -func checkArg[T comparable](k *kstub, arg string, got T, n int) bool { - if k.pos == 0 { - panic("invalid call to checkArg") - } - expect := k.want[k.track][k.pos-1] - want, ok := expect.args[n].(T) - if !ok || got != want { - k.t.Errorf("%s: %s = %#v, want %#v (%d)", expect.name, arg, got, want, k.pos-1) - return false - } - return true -} - -// checkArgReflect checks an argument of any type. -func checkArgReflect(k *kstub, arg string, got any, n int) bool { - if k.pos == 0 { - panic("invalid call to checkArgReflect") - } - expect := k.want[k.track][k.pos-1] - want := expect.args[n] - if !reflect.DeepEqual(got, want) { - k.t.Errorf("%s: %s = %#v, want %#v (%d)", expect.name, arg, got, want, k.pos-1) - return false - } - return true -} - -func (k *kstub) new(f func(k syscallDispatcher)) { - k.expect("new") - if len(k.want) <= k.track+1 { - k.t.Fatalf("new: track overrun") - } - sk := &kstub{t: k.t, want: k.want, track: len(k.sub) + 1, wg: k.wg} - k.sub = append(k.sub, sk) - k.wg.Add(1) - go func() { - defer k.wg.Done() - defer handleExitStub() - f(sk) - }() -} - -func (k *kstub) lockOSThread() { k.expect("lockOSThread") } +func (k *kstub) lockOSThread() { k.Helper(); k.Expects("lockOSThread") } func (k *kstub) setPtracer(pid uintptr) error { - return k.expect("setPtracer").error( - checkArg(k, "pid", pid, 0)) + k.Helper() + return k.Expects("setPtracer").Error( + stub.CheckArg(k.Stub, "pid", pid, 0)) } func (k *kstub) setDumpable(dumpable uintptr) error { - return k.expect("setDumpable").error( - checkArg(k, "dumpable", dumpable, 0)) + k.Helper() + return k.Expects("setDumpable").Error( + stub.CheckArg(k.Stub, "dumpable", dumpable, 0)) } -func (k *kstub) setNoNewPrivs() error { return k.expect("setNoNewPrivs").err } -func (k *kstub) lastcap() uintptr { return k.expect("lastcap").ret.(uintptr) } +func (k *kstub) setNoNewPrivs() error { k.Helper(); return k.Expects("setNoNewPrivs").Err } +func (k *kstub) lastcap() uintptr { k.Helper(); return k.Expects("lastcap").Ret.(uintptr) } func (k *kstub) capset(hdrp *capHeader, datap *[2]capData) error { - return k.expect("capset").error( - checkArgReflect(k, "hdrp", hdrp, 0), - checkArgReflect(k, "datap", datap, 1)) + k.Helper() + return k.Expects("capset").Error( + stub.CheckArgReflect(k.Stub, "hdrp", hdrp, 0), + stub.CheckArgReflect(k.Stub, "datap", datap, 1)) } func (k *kstub) capBoundingSetDrop(cap uintptr) error { - return k.expect("capBoundingSetDrop").error( - checkArg(k, "cap", cap, 0)) + k.Helper() + return k.Expects("capBoundingSetDrop").Error( + stub.CheckArg(k.Stub, "cap", cap, 0)) } -func (k *kstub) capAmbientClearAll() error { return k.expect("capAmbientClearAll").err } +func (k *kstub) capAmbientClearAll() error { k.Helper(); return k.Expects("capAmbientClearAll").Err } func (k *kstub) capAmbientRaise(cap uintptr) error { - return k.expect("capAmbientRaise").error( - checkArg(k, "cap", cap, 0)) + k.Helper() + return k.Expects("capAmbientRaise").Error( + stub.CheckArg(k.Stub, "cap", cap, 0)) } func (k *kstub) isatty(fd int) bool { - expect := k.expect("isatty") - if !checkArg(k, "fd", fd, 0) { - k.t.FailNow() + k.Helper() + expect := k.Expects("isatty") + if !stub.CheckArg(k.Stub, "fd", fd, 0) { + k.FailNow() } - return expect.ret.(bool) + return expect.Ret.(bool) } func (k *kstub) receive(key string, e any, fdp *uintptr) (closeFunc func() error, err error) { - expect := k.expect("receive") + k.Helper() + expect := k.Expects("receive") var closed bool closeFunc = func() error { if closed { - k.t.Error("closeFunc called more than once") + k.Error("closeFunc called more than once") return os.ErrClosed } closed = true - if expect.ret != nil { + if expect.Ret != nil { // use return stored in kexpect for closeFunc instead - return expect.ret.(error) + return expect.Ret.(error) } return nil } - err = expect.error( - checkArg(k, "key", key, 0), - checkArgReflect(k, "e", e, 1), - checkArgReflect(k, "fdp", fdp, 2)) + err = expect.Error( + stub.CheckArg(k.Stub, "key", key, 0), + stub.CheckArgReflect(k.Stub, "e", e, 1), + stub.CheckArgReflect(k.Stub, "fdp", fdp, 2)) // 3 is unused so stores params - if expect.args[3] != nil { - if v, ok := expect.args[3].(*initParams); ok && v != nil { + if expect.Args[3] != nil { + if v, ok := expect.Args[3].(*initParams); ok && v != nil { if p, ok0 := e.(*initParams); ok0 && p != nil { *p = *v } @@ -437,8 +374,8 @@ func (k *kstub) receive(key string, e any, fdp *uintptr) (closeFunc func() error } // 4 is unused so stores fd - if expect.args[4] != nil { - if v, ok := expect.args[4].(uintptr); ok && v >= 3 { + if expect.Args[4] != nil { + if v, ok := expect.Args[4].(uintptr); ok && v >= 3 { if fdp != nil { *fdp = v } @@ -449,246 +386,277 @@ func (k *kstub) receive(key string, e any, fdp *uintptr) (closeFunc func() error } func (k *kstub) bindMount(source, target string, flags uintptr, eq bool) error { - return k.expect("bindMount").error( - checkArg(k, "source", source, 0), - checkArg(k, "target", target, 1), - checkArg(k, "flags", flags, 2), - checkArg(k, "eq", eq, 3)) + k.Helper() + return k.Expects("bindMount").Error( + stub.CheckArg(k.Stub, "source", source, 0), + stub.CheckArg(k.Stub, "target", target, 1), + stub.CheckArg(k.Stub, "flags", flags, 2), + stub.CheckArg(k.Stub, "eq", eq, 3)) } func (k *kstub) remount(target string, flags uintptr) error { - return k.expect("remount").error( - checkArg(k, "target", target, 0), - checkArg(k, "flags", flags, 1)) + k.Helper() + return k.Expects("remount").Error( + stub.CheckArg(k.Stub, "target", target, 0), + stub.CheckArg(k.Stub, "flags", flags, 1)) } func (k *kstub) mountTmpfs(fsname, target string, flags uintptr, size int, perm os.FileMode) error { - return k.expect("mountTmpfs").error( - checkArg(k, "fsname", fsname, 0), - checkArg(k, "target", target, 1), - checkArg(k, "flags", flags, 2), - checkArg(k, "size", size, 3), - checkArg(k, "perm", perm, 4)) + k.Helper() + return k.Expects("mountTmpfs").Error( + stub.CheckArg(k.Stub, "fsname", fsname, 0), + stub.CheckArg(k.Stub, "target", target, 1), + stub.CheckArg(k.Stub, "flags", flags, 2), + stub.CheckArg(k.Stub, "size", size, 3), + stub.CheckArg(k.Stub, "perm", perm, 4)) } func (k *kstub) ensureFile(name string, perm, pperm os.FileMode) error { - - return k.expect("ensureFile").error( - checkArg(k, "name", name, 0), - checkArg(k, "perm", perm, 1), - checkArg(k, "pperm", pperm, 2)) + k.Helper() + return k.Expects("ensureFile").Error( + stub.CheckArg(k.Stub, "name", name, 0), + stub.CheckArg(k.Stub, "perm", perm, 1), + stub.CheckArg(k.Stub, "pperm", pperm, 2)) } func (k *kstub) seccompLoad(rules []seccomp.NativeRule, flags seccomp.ExportFlag) error { - return k.expect("seccompLoad").error( - checkArgReflect(k, "rules", rules, 0), - checkArg(k, "flags", flags, 1)) + k.Helper() + return k.Expects("seccompLoad").Error( + stub.CheckArgReflect(k.Stub, "rules", rules, 0), + stub.CheckArg(k.Stub, "flags", flags, 1)) } func (k *kstub) notify(c chan<- os.Signal, sig ...os.Signal) { - expect := k.expect("notify") - if c == nil || expect.error( - checkArgReflect(k, "sig", sig, 1)) != nil { - k.t.FailNow() + k.Helper() + expect := k.Expects("notify") + if c == nil || expect.Error( + stub.CheckArgReflect(k.Stub, "sig", sig, 1)) != nil { + k.FailNow() } // export channel for external instrumentation - if chanf, ok := expect.args[0].(func(c chan<- os.Signal)); ok && chanf != nil { + if chanf, ok := expect.Args[0].(func(c chan<- os.Signal)); ok && chanf != nil { chanf(c) } } func (k *kstub) start(c *exec.Cmd) error { - expect := k.expect("start") - err := expect.error( - checkArg(k, "c.Path", c.Path, 0), - checkArgReflect(k, "c.Args", c.Args, 1), - checkArgReflect(k, "c.Env", c.Env, 2), - checkArg(k, "c.Dir", c.Dir, 3)) + k.Helper() + expect := k.Expects("start") + err := expect.Error( + stub.CheckArg(k.Stub, "c.Path", c.Path, 0), + stub.CheckArgReflect(k.Stub, "c.Args", c.Args, 1), + stub.CheckArgReflect(k.Stub, "c.Env", c.Env, 2), + stub.CheckArg(k.Stub, "c.Dir", c.Dir, 3)) - if process, ok := expect.ret.(*os.Process); ok && process != nil { + if process, ok := expect.Ret.(*os.Process); ok && process != nil { c.Process = process } return err } func (k *kstub) signal(c *exec.Cmd, sig os.Signal) error { - return k.expect("signal").error( - checkArg(k, "c.Path", c.Path, 0), - checkArgReflect(k, "c.Args", c.Args, 1), - checkArgReflect(k, "c.Env", c.Env, 2), - checkArg(k, "c.Dir", c.Dir, 3), - checkArg(k, "sig", sig, 4)) + k.Helper() + return k.Expects("signal").Error( + stub.CheckArg(k.Stub, "c.Path", c.Path, 0), + stub.CheckArgReflect(k.Stub, "c.Args", c.Args, 1), + stub.CheckArgReflect(k.Stub, "c.Env", c.Env, 2), + stub.CheckArg(k.Stub, "c.Dir", c.Dir, 3), + stub.CheckArg(k.Stub, "sig", sig, 4)) } func (k *kstub) evalSymlinks(path string) (string, error) { - expect := k.expect("evalSymlinks") - return expect.ret.(string), expect.error( - checkArg(k, "path", path, 0)) + k.Helper() + expect := k.Expects("evalSymlinks") + return expect.Ret.(string), expect.Error( + stub.CheckArg(k.Stub, "path", path, 0)) } func (k *kstub) exit(code int) { - k.expect("exit") - if !checkArg(k, "code", code, 0) { - k.t.FailNow() + k.Helper() + k.Expects("exit") + if !stub.CheckArg(k.Stub, "code", code, 0) { + k.FailNow() } - panic(0xdeadbeef) + panic(stub.PanicExit) } -func (k *kstub) getpid() int { return k.expect("getpid").ret.(int) } +func (k *kstub) getpid() int { k.Helper(); return k.Expects("getpid").Ret.(int) } func (k *kstub) stat(name string) (os.FileInfo, error) { - expect := k.expect("stat") - return expect.ret.(os.FileInfo), expect.error( - checkArg(k, "name", name, 0)) + k.Helper() + expect := k.Expects("stat") + return expect.Ret.(os.FileInfo), expect.Error( + stub.CheckArg(k.Stub, "name", name, 0)) } func (k *kstub) mkdir(name string, perm os.FileMode) error { - return k.expect("mkdir").error( - checkArg(k, "name", name, 0), - checkArg(k, "perm", perm, 1)) + k.Helper() + return k.Expects("mkdir").Error( + stub.CheckArg(k.Stub, "name", name, 0), + stub.CheckArg(k.Stub, "perm", perm, 1)) } func (k *kstub) mkdirTemp(dir, pattern string) (string, error) { - expect := k.expect("mkdirTemp") - return expect.ret.(string), expect.error( - checkArg(k, "dir", dir, 0), - checkArg(k, "pattern", pattern, 1)) + k.Helper() + expect := k.Expects("mkdirTemp") + return expect.Ret.(string), expect.Error( + stub.CheckArg(k.Stub, "dir", dir, 0), + stub.CheckArg(k.Stub, "pattern", pattern, 1)) } func (k *kstub) mkdirAll(path string, perm os.FileMode) error { - return k.expect("mkdirAll").error( - checkArg(k, "path", path, 0), - checkArg(k, "perm", perm, 1)) + k.Helper() + return k.Expects("mkdirAll").Error( + stub.CheckArg(k.Stub, "path", path, 0), + stub.CheckArg(k.Stub, "perm", perm, 1)) } func (k *kstub) readdir(name string) ([]os.DirEntry, error) { - expect := k.expect("readdir") - return expect.ret.([]os.DirEntry), expect.error( - checkArg(k, "name", name, 0)) + k.Helper() + expect := k.Expects("readdir") + return expect.Ret.([]os.DirEntry), expect.Error( + stub.CheckArg(k.Stub, "name", name, 0)) } func (k *kstub) openNew(name string) (osFile, error) { - expect := k.expect("openNew") - return expect.ret.(osFile), expect.error( - checkArg(k, "name", name, 0)) + k.Helper() + expect := k.Expects("openNew") + return expect.Ret.(osFile), expect.Error( + stub.CheckArg(k.Stub, "name", name, 0)) } func (k *kstub) writeFile(name string, data []byte, perm os.FileMode) error { - return k.expect("writeFile").error( - checkArg(k, "name", name, 0), - checkArgReflect(k, "data", data, 1), - checkArg(k, "perm", perm, 2)) + k.Helper() + return k.Expects("writeFile").Error( + stub.CheckArg(k.Stub, "name", name, 0), + stub.CheckArgReflect(k.Stub, "data", data, 1), + stub.CheckArg(k.Stub, "perm", perm, 2)) } func (k *kstub) createTemp(dir, pattern string) (osFile, error) { - expect := k.expect("createTemp") - return expect.ret.(osFile), expect.error( - checkArg(k, "dir", dir, 0), - checkArg(k, "pattern", pattern, 1)) + k.Helper() + expect := k.Expects("createTemp") + return expect.Ret.(osFile), expect.Error( + stub.CheckArg(k.Stub, "dir", dir, 0), + stub.CheckArg(k.Stub, "pattern", pattern, 1)) } func (k *kstub) remove(name string) error { - return k.expect("remove").error( - checkArg(k, "name", name, 0)) + k.Helper() + return k.Expects("remove").Error( + stub.CheckArg(k.Stub, "name", name, 0)) } func (k *kstub) newFile(fd uintptr, name string) *os.File { - expect := k.expect("newFile") - if expect.error( - checkArg(k, "fd", fd, 0), - checkArg(k, "name", name, 1)) != nil { - k.t.FailNow() + k.Helper() + expect := k.Expects("newFile") + if expect.Error( + stub.CheckArg(k.Stub, "fd", fd, 0), + stub.CheckArg(k.Stub, "name", name, 1)) != nil { + k.FailNow() } - return expect.ret.(*os.File) + return expect.Ret.(*os.File) } func (k *kstub) symlink(oldname, newname string) error { - return k.expect("symlink").error( - checkArg(k, "oldname", oldname, 0), - checkArg(k, "newname", newname, 1)) + k.Helper() + return k.Expects("symlink").Error( + stub.CheckArg(k.Stub, "oldname", oldname, 0), + stub.CheckArg(k.Stub, "newname", newname, 1)) } func (k *kstub) readlink(name string) (string, error) { - expect := k.expect("readlink") - return expect.ret.(string), expect.error( - checkArg(k, "name", name, 0)) + k.Helper() + expect := k.Expects("readlink") + return expect.Ret.(string), expect.Error( + stub.CheckArg(k.Stub, "name", name, 0)) } func (k *kstub) umask(mask int) (oldmask int) { - expect := k.expect("umask") - if !checkArg(k, "mask", mask, 0) { - k.t.FailNow() + k.Helper() + expect := k.Expects("umask") + if !stub.CheckArg(k.Stub, "mask", mask, 0) { + k.FailNow() } - return expect.ret.(int) + return expect.Ret.(int) } func (k *kstub) sethostname(p []byte) (err error) { - return k.expect("sethostname").error( - checkArgReflect(k, "p", p, 0)) + k.Helper() + return k.Expects("sethostname").Error( + stub.CheckArgReflect(k.Stub, "p", p, 0)) } func (k *kstub) chdir(path string) (err error) { - return k.expect("chdir").error( - checkArg(k, "path", path, 0)) + k.Helper() + return k.Expects("chdir").Error( + stub.CheckArg(k.Stub, "path", path, 0)) } func (k *kstub) fchdir(fd int) (err error) { - return k.expect("fchdir").error( - checkArg(k, "fd", fd, 0)) + k.Helper() + return k.Expects("fchdir").Error( + stub.CheckArg(k.Stub, "fd", fd, 0)) } func (k *kstub) open(path string, mode int, perm uint32) (fd int, err error) { - expect := k.expect("open") - return expect.ret.(int), expect.error( - checkArg(k, "path", path, 0), - checkArg(k, "mode", mode, 1), - checkArg(k, "perm", perm, 2)) + k.Helper() + expect := k.Expects("open") + return expect.Ret.(int), expect.Error( + stub.CheckArg(k.Stub, "path", path, 0), + stub.CheckArg(k.Stub, "mode", mode, 1), + stub.CheckArg(k.Stub, "perm", perm, 2)) } func (k *kstub) close(fd int) (err error) { - return k.expect("close").error( - checkArg(k, "fd", fd, 0)) + k.Helper() + return k.Expects("close").Error( + stub.CheckArg(k.Stub, "fd", fd, 0)) } func (k *kstub) pivotRoot(newroot, putold string) (err error) { - return k.expect("pivotRoot").error( - checkArg(k, "newroot", newroot, 0), - checkArg(k, "putold", putold, 1)) + k.Helper() + return k.Expects("pivotRoot").Error( + stub.CheckArg(k.Stub, "newroot", newroot, 0), + stub.CheckArg(k.Stub, "putold", putold, 1)) } func (k *kstub) mount(source, target, fstype string, flags uintptr, data string) (err error) { - return k.expect("mount").error( - checkArg(k, "source", source, 0), - checkArg(k, "target", target, 1), - checkArg(k, "fstype", fstype, 2), - checkArg(k, "flags", flags, 3), - checkArg(k, "data", data, 4)) + k.Helper() + return k.Expects("mount").Error( + stub.CheckArg(k.Stub, "source", source, 0), + stub.CheckArg(k.Stub, "target", target, 1), + stub.CheckArg(k.Stub, "fstype", fstype, 2), + stub.CheckArg(k.Stub, "flags", flags, 3), + stub.CheckArg(k.Stub, "data", data, 4)) } func (k *kstub) unmount(target string, flags int) (err error) { - return k.expect("unmount").error( - checkArg(k, "target", target, 0), - checkArg(k, "flags", flags, 1)) + k.Helper() + return k.Expects("unmount").Error( + stub.CheckArg(k.Stub, "target", target, 0), + stub.CheckArg(k.Stub, "flags", flags, 1)) } func (k *kstub) wait4(pid int, wstatus *syscall.WaitStatus, options int, rusage *syscall.Rusage) (wpid int, err error) { - expect := k.expect("wait4") + k.Helper() + expect := k.Expects("wait4") // special case to prevent leaking the wait4 goroutine when testing initEntrypoint - if v, ok := expect.args[4].(int); ok && v == 0xdeadbeef { - k.t.Log("terminating current goroutine as requested by kexpect") - panic(0xdeadbeef) + if v, ok := expect.Args[4].(int); ok && v == stub.PanicExit { + k.Log("terminating current goroutine as requested by kexpect") + panic(stub.PanicExit) } - wpid = expect.ret.(int) - err = expect.error( - checkArg(k, "pid", pid, 0), - checkArg(k, "options", options, 2)) + wpid = expect.Ret.(int) + err = expect.Error( + stub.CheckArg(k.Stub, "pid", pid, 0), + stub.CheckArg(k.Stub, "options", options, 2)) - if wstatusV, ok := expect.args[1].(syscall.WaitStatus); wstatus != nil && ok { + if wstatusV, ok := expect.Args[1].(syscall.WaitStatus); wstatus != nil && ok { *wstatus = wstatusV } - if rusageV, ok := expect.args[3].(syscall.Rusage); rusage != nil && ok { + if rusageV, ok := expect.Args[3].(syscall.Rusage); rusage != nil && ok { *rusage = rusageV } @@ -696,53 +664,50 @@ func (k *kstub) wait4(pid int, wstatus *syscall.WaitStatus, options int, rusage } func (k *kstub) printf(format string, v ...any) { - if k.expect("printf").error( - checkArg(k, "format", format, 0), - checkArgReflect(k, "v", v, 1)) != nil { - k.t.FailNow() + k.Helper() + if k.Expects("printf").Error( + stub.CheckArg(k.Stub, "format", format, 0), + stub.CheckArgReflect(k.Stub, "v", v, 1)) != nil { + k.FailNow() } } func (k *kstub) fatal(v ...any) { - if k.expect("fatal").error( - checkArgReflect(k, "v", v, 0)) != nil { - k.t.FailNow() + k.Helper() + if k.Expects("fatal").Error( + stub.CheckArgReflect(k.Stub, "v", v, 0)) != nil { + k.FailNow() } - panic(0xdeadbeef) + panic(stub.PanicExit) } func (k *kstub) fatalf(format string, v ...any) { - if k.expect("fatalf").error( - checkArg(k, "format", format, 0), - checkArgReflect(k, "v", v, 1)) != nil { - k.t.FailNow() + k.Helper() + if k.Expects("fatalf").Error( + stub.CheckArg(k.Stub, "format", format, 0), + stub.CheckArgReflect(k.Stub, "v", v, 1)) != nil { + k.FailNow() } - panic(0xdeadbeef) + panic(stub.PanicExit) } func (k *kstub) verbose(v ...any) { - if k.expect("verbose").error( - checkArgReflect(k, "v", v, 0)) != nil { - k.t.FailNow() + k.Helper() + if k.Expects("verbose").Error( + stub.CheckArgReflect(k.Stub, "v", v, 0)) != nil { + k.FailNow() } } func (k *kstub) verbosef(format string, v ...any) { - if k.expect("verbosef").error( - checkArg(k, "format", format, 0), - checkArgReflect(k, "v", v, 1)) != nil { - k.t.FailNow() + k.Helper() + if k.Expects("verbosef").Error( + stub.CheckArg(k.Stub, "format", format, 0), + stub.CheckArgReflect(k.Stub, "v", v, 1)) != nil { + k.FailNow() } } -func (k *kstub) suspend() { k.expect("suspend") } -func (k *kstub) resume() bool { return k.expect("resume").ret.(bool) } -func (k *kstub) beforeExit() { k.expect("beforeExit") } - -func (k *kstub) printBaseErr(err error, fallback string) { - if k.expect("printBaseErr").error( - checkArgReflect(k, "err", err, 0), - checkArg(k, "fallback", fallback, 1)) != nil { - k.t.FailNow() - } -} +func (k *kstub) suspend() { k.Helper(); k.Expects("suspend") } +func (k *kstub) resume() bool { k.Helper(); return k.Expects("resume").Ret.(bool) } +func (k *kstub) beforeExit() { k.Helper(); k.Expects("beforeExit") } diff --git a/container/errors_test.go b/container/errors_test.go index 45a5fcd..fd774a4 100644 --- a/container/errors_test.go +++ b/container/errors_test.go @@ -8,6 +8,7 @@ import ( "syscall" "testing" + "hakurei.app/container/stub" "hakurei.app/container/vfs" ) @@ -30,8 +31,8 @@ func TestMessageFromError(t *testing.T) { {"path", &os.PathError{ Op: "mount", Path: "/sysroot", - Err: errUnique, - }, "cannot mount /sysroot: unique error injected by the test suite", true}, + Err: stub.UniqueError(0xdeadbeef), + }, "cannot mount /sysroot: unique error 3735928559 injected by the test suite", true}, {"absolute", &AbsoluteError{"etc/mtab"}, `path "etc/mtab" is not absolute`, true}, @@ -48,7 +49,7 @@ func TestMessageFromError(t *testing.T) { {"tmpfs", TmpfsSizeError(-1), "tmpfs size -1 out of bounds", true}, - {"unsupported", errUnique, zeroString, false}, + {"unsupported", stub.UniqueError(0xdeadbeef), zeroString, false}, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { @@ -144,10 +145,10 @@ func TestErrnoFallback(t *testing.T) { Err: syscall.ETIMEDOUT, }, syscall.ETIMEDOUT, nil}, - {"fallback", errUnique, 0, &os.PathError{ + {"fallback", stub.UniqueError(0xcafebabe), 0, &os.PathError{ Op: "fallback", Path: "/proc/nonexistent", - Err: errUnique, + Err: stub.UniqueError(0xcafebabe), }}, } for _, tc := range testCases { diff --git a/container/init_test.go b/container/init_test.go index f045293..e6a7511 100644 --- a/container/init_test.go +++ b/container/init_test.go @@ -7,6 +7,7 @@ import ( "time" "hakurei.app/container/seccomp" + "hakurei.app/container/stub" ) func TestInitEntrypoint(t *testing.T) { @@ -28,50 +29,50 @@ func TestInitEntrypoint(t *testing.T) { } checkSimple(t, "initEntrypoint", []simpleTestCase{ - {"getpid", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1 << 10, nil}, - {"fatal", expectArgs{[]any{"this process must run as pid 1"}}, nil, nil}, + {"getpid", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1 << 10, nil}, + {"fatal", stub.ExpectArgs{[]any{"this process must run as pid 1"}}, nil, nil}, }, }, nil}, - {"receive bad fd", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr)}, nil, syscall.EBADF}, - {"fatal", expectArgs{[]any{"invalid setup descriptor"}}, nil, nil}, + {"receive bad fd", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr)}, nil, syscall.EBADF}, + {"fatal", stub.ExpectArgs{[]any{"invalid setup descriptor"}}, nil, nil}, }, }, nil}, - {"receive not set", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr)}, nil, ErrReceiveEnv}, - {"fatal", expectArgs{[]any{"HAKUREI_SETUP not set"}}, nil, nil}, + {"receive not set", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr)}, nil, ErrReceiveEnv}, + {"fatal", stub.ExpectArgs{[]any{"HAKUREI_SETUP not set"}}, nil, nil}, }, }, nil}, - {"receive payload decode", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr)}, nil, errUnique}, - {"fatalf", expectArgs{"cannot decode init setup payload: %v", []any{errUnique}}, nil, nil}, + {"receive payload decode", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr)}, nil, stub.UniqueError(80)}, + {"fatalf", stub.ExpectArgs{"cannot decode init setup payload: %v", []any{stub.UniqueError(80)}}, nil, nil}, }, }, nil}, - {"receive invalid params", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"receive invalid params", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -85,17 +86,17 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"fatal", expectArgs{[]any{"invalid setup parameters"}}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(79), nil}, + {"fatal", stub.ExpectArgs{[]any{"invalid setup parameters"}}, nil, nil}, }, }, nil}, - {"setDumpable user", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"setDumpable user", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -110,19 +111,19 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, errUnique}, - {"fatalf", expectArgs{"cannot set SUID_DUMP_USER: %v", []any{errUnique}}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(78), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, stub.UniqueError(77)}, + {"fatalf", stub.ExpectArgs{"cannot set SUID_DUMP_USER: %v", []any{stub.UniqueError(77)}}, nil, nil}, }, }, nil}, - {"writeFile uid_map", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"writeFile uid_map", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -137,20 +138,20 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, errUnique}, - {"fatalf", expectArgs{"%v", []any{errUnique}}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(76), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, stub.UniqueError(75)}, + {"fatalf", stub.ExpectArgs{"%v", []any{stub.UniqueError(75)}}, nil, nil}, }, }, nil}, - {"writeFile setgroups", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"writeFile setgroups", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -165,21 +166,21 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, errUnique}, - {"fatalf", expectArgs{"%v", []any{errUnique}}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(74), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, stub.UniqueError(73)}, + {"fatalf", stub.ExpectArgs{"%v", []any{stub.UniqueError(73)}}, nil, nil}, }, }, nil}, - {"writeFile gid_map", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"writeFile gid_map", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -194,22 +195,22 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, errUnique}, - {"fatalf", expectArgs{"%v", []any{errUnique}}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(72), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, stub.UniqueError(71)}, + {"fatalf", stub.ExpectArgs{"%v", []any{stub.UniqueError(71)}}, nil, nil}, }, }, nil}, - {"setDumpable disable", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"setDumpable disable", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -224,23 +225,23 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, errUnique}, - {"fatalf", expectArgs{"cannot set SUID_DUMP_DISABLE: %v", []any{errUnique}}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(70), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, stub.UniqueError(69)}, + {"fatalf", stub.ExpectArgs{"cannot set SUID_DUMP_DISABLE: %v", []any{stub.UniqueError(69)}}, nil, nil}, }, }, nil}, - {"sethostname", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"sethostname", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -255,25 +256,25 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, errUnique}, - {"fatalf", expectArgs{"cannot set hostname: %v", []any{errUnique}}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(68), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, stub.UniqueError(67)}, + {"fatalf", stub.ExpectArgs{"cannot set hostname: %v", []any{stub.UniqueError(67)}}, nil, nil}, }, }, nil}, - {"mount rslave root", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"mount rslave root", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -288,27 +289,27 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, errUnique}, - {"fatalf", expectArgs{"cannot make / rslave: %v", []any{errUnique}}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(66), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, stub.UniqueError(65)}, + {"fatalf", stub.ExpectArgs{"cannot make / rslave: %v", []any{stub.UniqueError(65)}}, nil, nil}, }, }, nil}, - {"nil op", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"nil op", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -323,29 +324,29 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(64), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"fatalf", expectArgs{"invalid op at index %d", []any{0}}, nil, nil}, + {"fatalf", stub.ExpectArgs{"invalid op at index %d", []any{0}}, nil, nil}, /* end early */ }, }, nil}, - {"invalid op", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"invalid op", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -360,29 +361,29 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(63), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"fatalf", expectArgs{"invalid op at index %d", []any{0}}, nil, nil}, + {"fatalf", stub.ExpectArgs{"invalid op at index %d", []any{0}}, nil, nil}, /* end early */ }, }, nil}, - {"early unhandled error", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"early unhandled error", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -397,30 +398,30 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(62), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", errUnique}, - {"fatalf", expectArgs{"cannot prepare op at index %d: %v", []any{0, errUnique}}, nil, nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", stub.UniqueError(61)}, + {"fatalf", stub.ExpectArgs{"cannot prepare op at index %d: %v", []any{0, stub.UniqueError(61)}}, nil, nil}, /* end early */ }, }, nil}, - {"early", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"early", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -435,30 +436,30 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(60), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", &os.PathError{Op: "readlink", Path: "/", Err: errUnique}}, - {"fatal", expectArgs{[]any{"cannot readlink /: unique error injected by the test suite"}}, nil, nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", &os.PathError{Op: "readlink", Path: "/", Err: stub.UniqueError(60)}}, + {"fatal", stub.ExpectArgs{[]any{"cannot readlink /: unique error 60 injected by the test suite"}}, nil, nil}, /* end early */ }, }, nil}, - {"mount ih", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"mount ih", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -473,31 +474,31 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(59), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, errUnique}, - {"fatalf", expectArgs{"cannot mount intermediate root: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, stub.UniqueError(58)}, + {"fatalf", stub.ExpectArgs{"cannot mount intermediate root: %v", []any{stub.UniqueError(58)}}, nil, nil}, }, }, nil}, - {"chdir ih", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"chdir ih", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -512,32 +513,32 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(57), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, errUnique}, - {"fatalf", expectArgs{"cannot enter intermediate host path: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, stub.UniqueError(56)}, + {"fatalf", stub.ExpectArgs{"cannot enter intermediate host path: %v", []any{stub.UniqueError(56)}}, nil, nil}, }, }, nil}, - {"mkdir sysroot", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"mkdir sysroot", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -552,33 +553,33 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(55), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, errUnique}, - {"fatalf", expectArgs{"%v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, stub.UniqueError(54)}, + {"fatalf", stub.ExpectArgs{"%v", []any{stub.UniqueError(54)}}, nil, nil}, }, }, nil}, - {"mount bind sysroot", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"mount bind sysroot", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -593,34 +594,34 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(53), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, errUnique}, - {"fatalf", expectArgs{"cannot bind sysroot: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, stub.UniqueError(52)}, + {"fatalf", stub.ExpectArgs{"cannot bind sysroot: %v", []any{stub.UniqueError(52)}}, nil, nil}, }, }, nil}, - {"mkdir host", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"mkdir host", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -635,35 +636,35 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(51), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, errUnique}, - {"fatalf", expectArgs{"%v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, stub.UniqueError(50)}, + {"fatalf", stub.ExpectArgs{"%v", []any{stub.UniqueError(50)}}, nil, nil}, }, }, nil}, - {"pivotRoot ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"pivotRoot ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -678,36 +679,36 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(49), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, errUnique}, - {"fatalf", expectArgs{"cannot pivot into intermediate root: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, stub.UniqueError(48)}, + {"fatalf", stub.ExpectArgs{"cannot pivot into intermediate root: %v", []any{stub.UniqueError(48)}}, nil, nil}, }, }, nil}, - {"chdir ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"chdir ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -722,37 +723,37 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(47), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, errUnique}, - {"fatalf", expectArgs{"cannot enter intermediate root: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, stub.UniqueError(46)}, + {"fatalf", stub.ExpectArgs{"cannot enter intermediate root: %v", []any{stub.UniqueError(46)}}, nil, nil}, }, }, nil}, - {"apply unhandled error", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"apply unhandled error", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -767,46 +768,46 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(45), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, errUnique}, - {"fatalf", expectArgs{"cannot apply op at index %d: %v", []any{1, errUnique}}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, stub.UniqueError(44)}, + {"fatalf", stub.ExpectArgs{"cannot apply op at index %d: %v", []any{1, stub.UniqueError(44)}}, nil, nil}, /* end apply */ }, }, nil}, - {"apply", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"apply", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -821,46 +822,46 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(43), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, &MountError{"proc", "/sysroot/proc", "proc", uintptr(0xe), "", syscall.ENOTRECOVERABLE}}, - {"fatal", expectArgs{[]any{"cannot mount proc on /sysroot/proc: state not recoverable"}}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, &MountError{"proc", "/sysroot/proc", "proc", uintptr(0xe), "", syscall.ENOTRECOVERABLE}}, + {"fatal", stub.ExpectArgs{[]any{"cannot mount proc on /sysroot/proc: state not recoverable"}}, nil, nil}, /* end apply */ }, }, nil}, - {"mount rprivate host", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"mount rprivate host", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -875,47 +876,47 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(42), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, errUnique}, - {"fatalf", expectArgs{"cannot make host root rprivate: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, stub.UniqueError(41)}, + {"fatalf", stub.ExpectArgs{"cannot make host root rprivate: %v", []any{stub.UniqueError(41)}}, nil, nil}, }, }, nil}, - {"unmount host", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"unmount host", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -930,48 +931,48 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(40), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, errUnique}, - {"fatalf", expectArgs{"cannot unmount host root: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, stub.UniqueError(39)}, + {"fatalf", stub.ExpectArgs{"cannot unmount host root: %v", []any{stub.UniqueError(39)}}, nil, nil}, }, }, nil}, - {"open ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"open ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -986,50 +987,50 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(38), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, errUnique}, - {"fatalf", expectArgs{"cannot open intermediate root: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, stub.UniqueError(37)}, + {"fatalf", stub.ExpectArgs{"cannot open intermediate root: %v", []any{stub.UniqueError(37)}}, nil, nil}, }, }, nil}, - {"chdir sysroot", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"chdir sysroot", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -1044,51 +1045,51 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(36), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, errUnique}, - {"fatalf", expectArgs{"cannot enter sysroot: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, stub.UniqueError(35)}, + {"fatalf", stub.ExpectArgs{"cannot enter sysroot: %v", []any{stub.UniqueError(35)}}, nil, nil}, }, }, nil}, - {"pivotRoot sysroot", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"pivotRoot sysroot", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -1103,52 +1104,52 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(34), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, nil}, - {"pivotRoot", expectArgs{".", "."}, nil, errUnique}, - {"fatalf", expectArgs{"cannot pivot into sysroot: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{".", "."}, nil, stub.UniqueError(33)}, + {"fatalf", stub.ExpectArgs{"cannot pivot into sysroot: %v", []any{stub.UniqueError(33)}}, nil, nil}, }, }, nil}, - {"fchdir ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"fchdir ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -1163,53 +1164,53 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(32), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, nil}, - {"pivotRoot", expectArgs{".", "."}, nil, nil}, - {"fchdir", expectArgs{1 << 35}, nil, errUnique}, - {"fatalf", expectArgs{"cannot re-enter intermediate root: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{".", "."}, nil, nil}, + {"fchdir", stub.ExpectArgs{1 << 35}, nil, stub.UniqueError(31)}, + {"fatalf", stub.ExpectArgs{"cannot re-enter intermediate root: %v", []any{stub.UniqueError(31)}}, nil, nil}, }, }, nil}, - {"unmount ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"unmount ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -1224,54 +1225,54 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(30), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, nil}, - {"pivotRoot", expectArgs{".", "."}, nil, nil}, - {"fchdir", expectArgs{1 << 35}, nil, nil}, - {"unmount", expectArgs{".", 2}, nil, errUnique}, - {"fatalf", expectArgs{"cannot unmount intermediate root: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{".", "."}, nil, nil}, + {"fchdir", stub.ExpectArgs{1 << 35}, nil, nil}, + {"unmount", stub.ExpectArgs{".", 2}, nil, stub.UniqueError(29)}, + {"fatalf", stub.ExpectArgs{"cannot unmount intermediate root: %v", []any{stub.UniqueError(29)}}, nil, nil}, }, }, nil}, - {"chdir ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"chdir ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -1286,55 +1287,55 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(28), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, nil}, - {"pivotRoot", expectArgs{".", "."}, nil, nil}, - {"fchdir", expectArgs{1 << 35}, nil, nil}, - {"unmount", expectArgs{".", 2}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, errUnique}, - {"fatalf", expectArgs{"cannot enter root: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{".", "."}, nil, nil}, + {"fchdir", stub.ExpectArgs{1 << 35}, nil, nil}, + {"unmount", stub.ExpectArgs{".", 2}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, stub.UniqueError(27)}, + {"fatalf", stub.ExpectArgs{"cannot enter root: %v", []any{stub.UniqueError(27)}}, nil, nil}, }, }, nil}, - {"close ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"close ir", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -1349,56 +1350,56 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(26), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, nil}, - {"pivotRoot", expectArgs{".", "."}, nil, nil}, - {"fchdir", expectArgs{1 << 35}, nil, nil}, - {"unmount", expectArgs{".", 2}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, - {"close", expectArgs{1 << 35}, nil, errUnique}, - {"fatalf", expectArgs{"cannot close intermediate root: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{".", "."}, nil, nil}, + {"fchdir", stub.ExpectArgs{1 << 35}, nil, nil}, + {"unmount", stub.ExpectArgs{".", 2}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, + {"close", stub.ExpectArgs{1 << 35}, nil, stub.UniqueError(25)}, + {"fatalf", stub.ExpectArgs{"cannot close intermediate root: %v", []any{stub.UniqueError(25)}}, nil, nil}, }, }, nil}, - {"capAmbientClearAll", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"capAmbientClearAll", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -1413,57 +1414,57 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(24), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, nil}, - {"pivotRoot", expectArgs{".", "."}, nil, nil}, - {"fchdir", expectArgs{1 << 35}, nil, nil}, - {"unmount", expectArgs{".", 2}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, - {"close", expectArgs{1 << 35}, nil, nil}, - {"capAmbientClearAll", expectArgs{}, nil, errUnique}, - {"fatalf", expectArgs{"cannot clear the ambient capability set: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{".", "."}, nil, nil}, + {"fchdir", stub.ExpectArgs{1 << 35}, nil, nil}, + {"unmount", stub.ExpectArgs{".", 2}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, + {"close", stub.ExpectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", stub.ExpectArgs{}, nil, stub.UniqueError(23)}, + {"fatalf", stub.ExpectArgs{"cannot clear the ambient capability set: %v", []any{stub.UniqueError(23)}}, nil, nil}, }, }, nil}, - {"capBoundingSetDrop", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"capBoundingSetDrop", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -1478,65 +1479,65 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(22), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, nil}, - {"pivotRoot", expectArgs{".", "."}, nil, nil}, - {"fchdir", expectArgs{1 << 35}, nil, nil}, - {"unmount", expectArgs{".", 2}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, - {"close", expectArgs{1 << 35}, nil, nil}, - {"capAmbientClearAll", expectArgs{}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x5)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x6)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x7)}, nil, errUnique}, - {"fatalf", expectArgs{"cannot drop capability from bounding set: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{".", "."}, nil, nil}, + {"fchdir", stub.ExpectArgs{1 << 35}, nil, nil}, + {"unmount", stub.ExpectArgs{".", 2}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, + {"close", stub.ExpectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", stub.ExpectArgs{}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x4)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x5)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x6)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x7)}, nil, stub.UniqueError(21)}, + {"fatalf", stub.ExpectArgs{"cannot drop capability from bounding set: %v", []any{stub.UniqueError(21)}}, nil, nil}, }, }, nil}, - {"capAmbientRaise", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"capAmbientRaise", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -1551,98 +1552,98 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(20), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, nil}, - {"pivotRoot", expectArgs{".", "."}, nil, nil}, - {"fchdir", expectArgs{1 << 35}, nil, nil}, - {"unmount", expectArgs{".", 2}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, - {"close", expectArgs{1 << 35}, nil, nil}, - {"capAmbientClearAll", expectArgs{}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x5)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x6)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x7)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x8)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x9)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xa)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xb)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xc)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xd)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xe)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xf)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x10)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x11)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x12)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x13)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x14)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x16)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x17)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x18)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x19)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1a)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1b)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1c)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1d)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1e)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1f)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x20)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x21)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x22)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x23)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x24)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x25)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x26)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x27)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x28)}, nil, nil}, - {"capAmbientRaise", expectArgs{uintptr(0x15)}, nil, errUnique}, - {"fatalf", expectArgs{"cannot raise CAP_SYS_ADMIN: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{".", "."}, nil, nil}, + {"fchdir", stub.ExpectArgs{1 << 35}, nil, nil}, + {"unmount", stub.ExpectArgs{".", 2}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, + {"close", stub.ExpectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", stub.ExpectArgs{}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x4)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x5)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x6)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x7)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x8)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x9)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xa)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xb)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xc)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xd)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xe)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xf)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x10)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x11)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x12)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x13)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x14)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x16)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x17)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x18)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x19)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1a)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1b)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1c)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1d)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1e)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1f)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x20)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x21)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x22)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x23)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x24)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x25)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x26)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x27)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x28)}, nil, nil}, + {"capAmbientRaise", stub.ExpectArgs{uintptr(0x15)}, nil, stub.UniqueError(19)}, + {"fatalf", stub.ExpectArgs{"cannot raise CAP_SYS_ADMIN: %v", []any{stub.UniqueError(19)}}, nil, nil}, }, }, nil}, - {"capset", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"capset", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -1657,99 +1658,99 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(18), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, nil}, - {"pivotRoot", expectArgs{".", "."}, nil, nil}, - {"fchdir", expectArgs{1 << 35}, nil, nil}, - {"unmount", expectArgs{".", 2}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, - {"close", expectArgs{1 << 35}, nil, nil}, - {"capAmbientClearAll", expectArgs{}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x5)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x6)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x7)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x8)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x9)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xa)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xb)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xc)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xd)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xe)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xf)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x10)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x11)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x12)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x13)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x14)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x16)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x17)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x18)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x19)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1a)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1b)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1c)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1d)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1e)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1f)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x20)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x21)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x22)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x23)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x24)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x25)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x26)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x27)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x28)}, nil, nil}, - {"capAmbientRaise", expectArgs{uintptr(0x15)}, nil, nil}, - {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, &[2]capData{{0, 0x200000, 0x200000}, {0, 0, 0}}}, nil, errUnique}, - {"fatalf", expectArgs{"cannot capset: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{".", "."}, nil, nil}, + {"fchdir", stub.ExpectArgs{1 << 35}, nil, nil}, + {"unmount", stub.ExpectArgs{".", 2}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, + {"close", stub.ExpectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", stub.ExpectArgs{}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x4)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x5)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x6)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x7)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x8)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x9)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xa)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xb)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xc)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xd)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xe)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xf)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x10)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x11)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x12)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x13)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x14)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x16)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x17)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x18)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x19)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1a)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1b)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1c)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1d)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1e)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1f)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x20)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x21)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x22)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x23)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x24)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x25)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x26)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x27)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x28)}, nil, nil}, + {"capAmbientRaise", stub.ExpectArgs{uintptr(0x15)}, nil, nil}, + {"capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, &[2]capData{{0, 0x200000, 0x200000}, {0, 0, 0}}}, nil, stub.UniqueError(17)}, + {"fatalf", stub.ExpectArgs{"cannot capset: %v", []any{stub.UniqueError(17)}}, nil, nil}, }, }, nil}, - {"seccompLoad", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"seccompLoad", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -1764,102 +1765,102 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(16), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, nil}, - {"pivotRoot", expectArgs{".", "."}, nil, nil}, - {"fchdir", expectArgs{1 << 35}, nil, nil}, - {"unmount", expectArgs{".", 2}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, - {"close", expectArgs{1 << 35}, nil, nil}, - {"capAmbientClearAll", expectArgs{}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x5)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x6)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x7)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x8)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x9)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xa)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xb)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xc)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xd)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xe)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xf)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x10)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x11)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x12)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x13)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x14)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x16)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x17)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x18)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x19)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1a)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1b)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1c)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1d)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1e)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1f)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x20)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x21)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x22)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x23)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x24)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x25)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x26)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x27)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x28)}, nil, nil}, - {"capAmbientRaise", expectArgs{uintptr(0x15)}, nil, nil}, - {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, &[2]capData{{0, 0x200000, 0x200000}, {0, 0, 0}}}, nil, nil}, - {"verbosef", expectArgs{"resolving presets %#x", []any{seccomp.FilterPreset(0xf)}}, nil, nil}, - {"seccompLoad", expectArgs{seccomp.Preset(0xf, 0), seccomp.ExportFlag(0)}, nil, errUnique}, - {"fatalf", expectArgs{"cannot load syscall filter: %v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{".", "."}, nil, nil}, + {"fchdir", stub.ExpectArgs{1 << 35}, nil, nil}, + {"unmount", stub.ExpectArgs{".", 2}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, + {"close", stub.ExpectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", stub.ExpectArgs{}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x4)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x5)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x6)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x7)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x8)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x9)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xa)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xb)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xc)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xd)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xe)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xf)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x10)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x11)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x12)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x13)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x14)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x16)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x17)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x18)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x19)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1a)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1b)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1c)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1d)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1e)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1f)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x20)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x21)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x22)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x23)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x24)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x25)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x26)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x27)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x28)}, nil, nil}, + {"capAmbientRaise", stub.ExpectArgs{uintptr(0x15)}, nil, nil}, + {"capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, &[2]capData{{0, 0x200000, 0x200000}, {0, 0, 0}}}, nil, nil}, + {"verbosef", stub.ExpectArgs{"resolving presets %#x", []any{seccomp.FilterPreset(0xf)}}, nil, nil}, + {"seccompLoad", stub.ExpectArgs{seccomp.Preset(0xf, 0), seccomp.ExportFlag(0)}, nil, stub.UniqueError(15)}, + {"fatalf", stub.ExpectArgs{"cannot load syscall filter: %v", []any{stub.UniqueError(15)}}, nil, nil}, }, }, nil}, - {"start", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, [][]kexpect{ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, 0, errUnique}, - {"verbosef", expectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{errUnique}}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + {"start", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, stub.Expect{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(14)}, + {"verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(14)}}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei/nonexistent"), Path: MustAbs("/run/current-system/sw/bin/bash"), Args: []string{"bash", "-c", "false"}, @@ -1872,107 +1873,107 @@ func TestInitEntrypoint(t *testing.T) { SeccompRules: make([]seccomp.NativeRule, 0), SeccompDisable: true, ParentPerm: 0750, - }, 1971, 127, 2, false}, uintptr(0x39)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1971, 127, 2, false}, uintptr(0x39)}, stub.UniqueError(13), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, nil}, - {"pivotRoot", expectArgs{".", "."}, nil, nil}, - {"fchdir", expectArgs{1 << 35}, nil, nil}, - {"unmount", expectArgs{".", 2}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, - {"close", expectArgs{1 << 35}, nil, nil}, - {"capAmbientClearAll", expectArgs{}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x5)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x6)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x7)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x8)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x9)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xa)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xb)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xc)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xd)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xe)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xf)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x10)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x11)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x12)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x13)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x14)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x15)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x16)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x17)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x18)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x19)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1a)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1b)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1c)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1d)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1e)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1f)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x20)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x21)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x22)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x23)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x24)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x25)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x26)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x27)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x28)}, nil, nil}, - {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, - {"verbose", expectArgs{[]any{"syscall filter not configured"}}, nil, nil}, - {"newFile", expectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, - {"newFile", expectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, - {"umask", expectArgs{022}, 0, nil}, - {"verbosef", expectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, - {"start", expectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, nil, errUnique}, - {"fatalf", expectArgs{"%v", []any{errUnique}}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{".", "."}, nil, nil}, + {"fchdir", stub.ExpectArgs{1 << 35}, nil, nil}, + {"unmount", stub.ExpectArgs{".", 2}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, + {"close", stub.ExpectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", stub.ExpectArgs{}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x4)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x5)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x6)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x7)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x8)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x9)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xa)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xb)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xc)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xd)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xe)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xf)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x10)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x11)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x12)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x13)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x14)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x15)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x16)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x17)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x18)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x19)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1a)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1b)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1c)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1d)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1e)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1f)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x20)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x21)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x22)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x23)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x24)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x25)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x26)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x27)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x28)}, nil, nil}, + {"capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, + {"verbose", stub.ExpectArgs{[]any{"syscall filter not configured"}}, nil, nil}, + {"newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, + {"newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, + {"umask", stub.ExpectArgs{022}, 0, nil}, + {"verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, + {"start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, nil, stub.UniqueError(12)}, + {"fatalf", stub.ExpectArgs{"%v", []any{stub.UniqueError(12)}}, nil, nil}, }, }, nil}, - {"lowlastcap signaled cancel forward error", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, [][]kexpect{ + {"lowlastcap signaled cancel forward error", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, stub.Expect{ /* entrypoint */ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, 0, errUnique}, - {"verbosef", expectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{errUnique}}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(11)}, + {"verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(11)}}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei/nonexistent"), Path: MustAbs("/run/current-system/sw/bin/bash"), Args: []string{"bash", "-c", "false"}, @@ -1985,91 +1986,91 @@ func TestInitEntrypoint(t *testing.T) { SeccompRules: make([]seccomp.NativeRule, 0), SeccompDisable: true, ParentPerm: 0750, - }, 1971, 127, 2, false}, uintptr(0x39)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(4), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1971, 127, 2, false}, uintptr(0x39)}, stub.UniqueError(10), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(4), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, nil}, - {"pivotRoot", expectArgs{".", "."}, nil, nil}, - {"fchdir", expectArgs{1 << 35}, nil, nil}, - {"unmount", expectArgs{".", 2}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, - {"close", expectArgs{1 << 35}, nil, nil}, - {"capAmbientClearAll", expectArgs{}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, - {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, - {"verbose", expectArgs{[]any{"syscall filter not configured"}}, nil, nil}, - {"newFile", expectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, - {"newFile", expectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, - {"umask", expectArgs{022}, 0, nil}, - {"verbosef", expectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, - {"start", expectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil}, - {"suspend", expectArgs{}, nil, nil}, - {"printf", expectArgs{"cannot close setup pipe: %v", []any{errUnique}}, nil, nil}, - {"new", expectArgs{}, nil, nil}, - {"notify", expectArgs{func(c chan<- os.Signal) { c <- CancelSignal }, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, - {"resume", expectArgs{}, true, nil}, - {"verbosef", expectArgs{"%s after process start", []any{"terminated"}}, nil, nil}, - {"verbose", expectArgs{[]any{"forwarding context cancellation"}}, nil, nil}, - {"signal", expectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent", os.Interrupt}, nil, errUnique}, - {"printf", expectArgs{"cannot forward cancellation: %v", []any{errUnique}}, nil, nil}, - {"resume", expectArgs{}, false, nil}, - {"verbosef", expectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil}, - {"printf", expectArgs{"timeout exceeded waiting for lingering processes", ([]any)(nil)}, nil, nil}, - {"beforeExit", expectArgs{}, nil, nil}, - {"exit", expectArgs{0xce}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{".", "."}, nil, nil}, + {"fchdir", stub.ExpectArgs{1 << 35}, nil, nil}, + {"unmount", stub.ExpectArgs{".", 2}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, + {"close", stub.ExpectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", stub.ExpectArgs{}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x4)}, nil, nil}, + {"capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, + {"verbose", stub.ExpectArgs{[]any{"syscall filter not configured"}}, nil, nil}, + {"newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, + {"newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, + {"umask", stub.ExpectArgs{022}, 0, nil}, + {"verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, + {"start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil}, + {"suspend", stub.ExpectArgs{}, nil, nil}, + {"printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(10)}}, nil, nil}, + {"New", stub.ExpectArgs{}, nil, nil}, + {"notify", stub.ExpectArgs{func(c chan<- os.Signal) { c <- CancelSignal }, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, + {"resume", stub.ExpectArgs{}, true, nil}, + {"verbosef", stub.ExpectArgs{"%s after process start", []any{"terminated"}}, nil, nil}, + {"verbose", stub.ExpectArgs{[]any{"forwarding context cancellation"}}, nil, nil}, + {"signal", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent", os.Interrupt}, nil, stub.UniqueError(9)}, + {"printf", stub.ExpectArgs{"cannot forward cancellation: %v", []any{stub.UniqueError(9)}}, nil, nil}, + {"resume", stub.ExpectArgs{}, false, nil}, + {"verbosef", stub.ExpectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil}, + {"printf", stub.ExpectArgs{"timeout exceeded waiting for lingering processes", ([]any)(nil)}, nil, nil}, + {"beforeExit", stub.ExpectArgs{}, nil, nil}, + {"exit", stub.ExpectArgs{0xce}, nil, nil}, }, /* wait4 */ - { - {"wait4", expectArgs{-1, syscall.WaitStatus(0xfade01ce), 0, nil}, 0xbad, nil}, + Tracks: []stub.Expect{{Calls: []stub.Call{ + {"wait4", stub.ExpectArgs{-1, syscall.WaitStatus(0xfade01ce), 0, nil}, 0xbad, nil}, // this terminates the goroutine at the call, preventing it from leaking while preserving behaviour - {"wait4", expectArgs{-1, nil, 0, nil, 0xdeadbeef}, 0, syscall.ECHILD}, - }, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil, 0xdeadbeef}, 0, syscall.ECHILD}, + }}}, }, nil}, - {"lowlastcap signaled cancel", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, [][]kexpect{ + {"lowlastcap signaled cancel", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, stub.Expect{ /* entrypoint */ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, 0, errUnique}, - {"verbosef", expectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{errUnique}}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(8)}, + {"verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(8)}}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei/nonexistent"), Path: MustAbs("/run/current-system/sw/bin/bash"), Args: []string{"bash", "-c", "false"}, @@ -2082,84 +2083,84 @@ func TestInitEntrypoint(t *testing.T) { SeccompRules: make([]seccomp.NativeRule, 0), SeccompDisable: true, ParentPerm: 0750, - }, 1971, 127, 2, false}, uintptr(0x39)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(4), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1971, 127, 2, false}, uintptr(0x39)}, stub.UniqueError(7), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(4), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, nil}, - {"pivotRoot", expectArgs{".", "."}, nil, nil}, - {"fchdir", expectArgs{1 << 35}, nil, nil}, - {"unmount", expectArgs{".", 2}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, - {"close", expectArgs{1 << 35}, nil, nil}, - {"capAmbientClearAll", expectArgs{}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, - {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, - {"verbose", expectArgs{[]any{"syscall filter not configured"}}, nil, nil}, - {"newFile", expectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, - {"newFile", expectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, - {"umask", expectArgs{022}, 0, nil}, - {"verbosef", expectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, - {"start", expectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil}, - {"suspend", expectArgs{}, nil, nil}, - {"printf", expectArgs{"cannot close setup pipe: %v", []any{errUnique}}, nil, nil}, - {"new", expectArgs{}, nil, nil}, - {"notify", expectArgs{func(c chan<- os.Signal) { c <- os.Interrupt }, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, - {"resume", expectArgs{}, false, nil}, - {"verbosef", expectArgs{"got %s", []any{"interrupt"}}, nil, nil}, - {"beforeExit", expectArgs{}, nil, nil}, - {"exit", expectArgs{0}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{".", "."}, nil, nil}, + {"fchdir", stub.ExpectArgs{1 << 35}, nil, nil}, + {"unmount", stub.ExpectArgs{".", 2}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, + {"close", stub.ExpectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", stub.ExpectArgs{}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x4)}, nil, nil}, + {"capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, + {"verbose", stub.ExpectArgs{[]any{"syscall filter not configured"}}, nil, nil}, + {"newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, + {"newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, + {"umask", stub.ExpectArgs{022}, 0, nil}, + {"verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, + {"start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil}, + {"suspend", stub.ExpectArgs{}, nil, nil}, + {"printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(7)}}, nil, nil}, + {"New", stub.ExpectArgs{}, nil, nil}, + {"notify", stub.ExpectArgs{func(c chan<- os.Signal) { c <- os.Interrupt }, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, + {"resume", stub.ExpectArgs{}, false, nil}, + {"verbosef", stub.ExpectArgs{"got %s", []any{"interrupt"}}, nil, nil}, + {"beforeExit", stub.ExpectArgs{}, nil, nil}, + {"exit", stub.ExpectArgs{0}, nil, nil}, }, /* wait4 */ - { + Tracks: []stub.Expect{{Calls: []stub.Call{ // this terminates the goroutine at the call, preventing it from leaking while preserving behaviour - {"wait4", expectArgs{-1, nil, 0, nil, 0xdeadbeef}, 0, syscall.ECHILD}, - }, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil, 0xdeadbeef}, 0, syscall.ECHILD}, + }}}, }, nil}, - {"lowlastcap signaled timeout", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, [][]kexpect{ + {"lowlastcap signaled timeout", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, stub.Expect{ /* entrypoint */ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, 0, errUnique}, - {"verbosef", expectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{errUnique}}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(6)}, + {"verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(6)}}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei/nonexistent"), Path: MustAbs("/run/current-system/sw/bin/bash"), Args: []string{"bash", "-c", "false"}, @@ -2172,86 +2173,86 @@ func TestInitEntrypoint(t *testing.T) { SeccompRules: make([]seccomp.NativeRule, 0), SeccompDisable: true, ParentPerm: 0750, - }, 1971, 127, 2, false}, uintptr(0x39)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(4), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1971, 127, 2, false}, uintptr(0x39)}, stub.UniqueError(5), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(4), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, nil}, - {"pivotRoot", expectArgs{".", "."}, nil, nil}, - {"fchdir", expectArgs{1 << 35}, nil, nil}, - {"unmount", expectArgs{".", 2}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, - {"close", expectArgs{1 << 35}, nil, nil}, - {"capAmbientClearAll", expectArgs{}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, - {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, - {"verbose", expectArgs{[]any{"syscall filter not configured"}}, nil, nil}, - {"newFile", expectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, - {"newFile", expectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, - {"umask", expectArgs{022}, 0, nil}, - {"verbosef", expectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, - {"start", expectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil}, - {"suspend", expectArgs{}, nil, nil}, - {"printf", expectArgs{"cannot close setup pipe: %v", []any{errUnique}}, nil, nil}, - {"new", expectArgs{}, nil, nil}, - {"notify", expectArgs{nil, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, - {"resume", expectArgs{}, true, nil}, - {"verbosef", expectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil}, - {"printf", expectArgs{"timeout exceeded waiting for lingering processes", ([]any)(nil)}, nil, nil}, - {"beforeExit", expectArgs{}, nil, nil}, - {"exit", expectArgs{0xce}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{".", "."}, nil, nil}, + {"fchdir", stub.ExpectArgs{1 << 35}, nil, nil}, + {"unmount", stub.ExpectArgs{".", 2}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, + {"close", stub.ExpectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", stub.ExpectArgs{}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x4)}, nil, nil}, + {"capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, + {"verbose", stub.ExpectArgs{[]any{"syscall filter not configured"}}, nil, nil}, + {"newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, + {"newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, + {"umask", stub.ExpectArgs{022}, 0, nil}, + {"verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, + {"start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil}, + {"suspend", stub.ExpectArgs{}, nil, nil}, + {"printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(5)}}, nil, nil}, + {"New", stub.ExpectArgs{}, nil, nil}, + {"notify", stub.ExpectArgs{nil, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, + {"resume", stub.ExpectArgs{}, true, nil}, + {"verbosef", stub.ExpectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil}, + {"printf", stub.ExpectArgs{"timeout exceeded waiting for lingering processes", ([]any)(nil)}, nil, nil}, + {"beforeExit", stub.ExpectArgs{}, nil, nil}, + {"exit", stub.ExpectArgs{0xce}, nil, nil}, }, /* wait4 */ - { - {"wait4", expectArgs{-1, syscall.WaitStatus(0xfade01ce), 0, nil}, 0xbad, nil}, + Tracks: []stub.Expect{{Calls: []stub.Call{ + {"wait4", stub.ExpectArgs{-1, syscall.WaitStatus(0xfade01ce), 0, nil}, 0xbad, nil}, // this terminates the goroutine at the call, preventing it from leaking while preserving behaviour - {"wait4", expectArgs{-1, nil, 0, nil, 0xdeadbeef}, 0, syscall.ECHILD}, - }, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil, 0xdeadbeef}, 0, syscall.ECHILD}, + }}}, }, nil}, - {"lowlastcap signaled", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, [][]kexpect{ + {"lowlastcap signaled", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, stub.Expect{ /* entrypoint */ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, 0, errUnique}, - {"verbosef", expectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{errUnique}}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(4)}, + {"verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(4)}}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei/nonexistent"), Path: MustAbs("/run/current-system/sw/bin/bash"), Args: []string{"bash", "-c", "false"}, @@ -2264,93 +2265,93 @@ func TestInitEntrypoint(t *testing.T) { SeccompRules: make([]seccomp.NativeRule, 0), SeccompDisable: true, ParentPerm: 0750, - }, 1971, 127, 2, false}, uintptr(0x39)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(4), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1971, 127, 2, false}, uintptr(0x39)}, stub.UniqueError(3), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(4), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, nil}, - {"pivotRoot", expectArgs{".", "."}, nil, nil}, - {"fchdir", expectArgs{1 << 35}, nil, nil}, - {"unmount", expectArgs{".", 2}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, - {"close", expectArgs{1 << 35}, nil, nil}, - {"capAmbientClearAll", expectArgs{}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, - {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, - {"verbose", expectArgs{[]any{"syscall filter not configured"}}, nil, nil}, - {"newFile", expectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, - {"newFile", expectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, - {"umask", expectArgs{022}, 0, nil}, - {"verbosef", expectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, - {"start", expectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil}, - {"suspend", expectArgs{}, nil, nil}, - {"printf", expectArgs{"cannot close setup pipe: %v", []any{errUnique}}, nil, nil}, - {"new", expectArgs{}, nil, nil}, - {"notify", expectArgs{nil, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, - {"resume", expectArgs{}, true, nil}, - {"verbosef", expectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil}, - {"beforeExit", expectArgs{}, nil, nil}, - {"exit", expectArgs{0xce}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{".", "."}, nil, nil}, + {"fchdir", stub.ExpectArgs{1 << 35}, nil, nil}, + {"unmount", stub.ExpectArgs{".", 2}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, + {"close", stub.ExpectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", stub.ExpectArgs{}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x4)}, nil, nil}, + {"capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, + {"verbose", stub.ExpectArgs{[]any{"syscall filter not configured"}}, nil, nil}, + {"newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, + {"newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, + {"umask", stub.ExpectArgs{022}, 0, nil}, + {"verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, + {"start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil}, + {"suspend", stub.ExpectArgs{}, nil, nil}, + {"printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(3)}}, nil, nil}, + {"New", stub.ExpectArgs{}, nil, nil}, + {"notify", stub.ExpectArgs{nil, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, + {"resume", stub.ExpectArgs{}, true, nil}, + {"verbosef", stub.ExpectArgs{"initial process exited with signal %s", []any{syscall.Signal(0x4e)}}, nil, nil}, + {"beforeExit", stub.ExpectArgs{}, nil, nil}, + {"exit", stub.ExpectArgs{0xce}, nil, nil}, }, /* wait4 */ - { - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, syscall.WaitStatus(0xfade01ce), 0, nil}, 0xbad, nil}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.ENOMEM}, - {"printf", expectArgs{"unexpected wait4 response: %v", []any{syscall.ENOMEM}}, nil, nil}, - }, + Tracks: []stub.Expect{{Calls: []stub.Call{ + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, syscall.WaitStatus(0xfade01ce), 0, nil}, 0xbad, nil}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.ENOMEM}, + {"printf", stub.ExpectArgs{"unexpected wait4 response: %v", []any{syscall.ENOMEM}}, nil, nil}, + }}}, }, nil}, - {"strangewait nopriv notty noseccomp yamafault", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, [][]kexpect{ + {"strangewait nopriv notty noseccomp yamafault", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseFalse); return nil }, stub.Expect{ /* entrypoint */ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, 0, errUnique}, - {"verbosef", expectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{errUnique}}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, 0, stub.UniqueError(2)}, + {"verbosef", stub.ExpectArgs{"cannot enable ptrace protection via Yama LSM: %v", []any{stub.UniqueError(2)}}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei/nonexistent"), Path: MustAbs("/run/current-system/sw/bin/bash"), Args: []string{"bash", "-c", "false"}, @@ -2363,128 +2364,128 @@ func TestInitEntrypoint(t *testing.T) { SeccompRules: make([]seccomp.NativeRule, 0), SeccompDisable: true, ParentPerm: 0750, - }, 1971, 127, 2, false}, uintptr(0x39)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1971, 127, 2, false}, uintptr(0x39)}, stub.UniqueError(1), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("16777216 1971 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("140737488355328 127 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, nil}, - {"pivotRoot", expectArgs{".", "."}, nil, nil}, - {"fchdir", expectArgs{1 << 35}, nil, nil}, - {"unmount", expectArgs{".", 2}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, - {"close", expectArgs{1 << 35}, nil, nil}, - {"capAmbientClearAll", expectArgs{}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x5)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x6)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x7)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x8)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x9)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xa)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xb)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xc)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xd)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xe)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xf)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x10)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x11)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x12)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x13)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x14)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x15)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x16)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x17)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x18)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x19)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1a)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1b)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1c)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1d)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1e)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1f)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x20)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x21)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x22)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x23)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x24)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x25)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x26)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x27)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x28)}, nil, nil}, - {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, - {"verbose", expectArgs{[]any{"syscall filter not configured"}}, nil, nil}, - {"newFile", expectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, - {"newFile", expectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, - {"umask", expectArgs{022}, 0, nil}, - {"verbosef", expectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, - {"start", expectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil}, - {"suspend", expectArgs{}, nil, nil}, - {"printf", expectArgs{"cannot close setup pipe: %v", []any{errUnique}}, nil, nil}, - {"new", expectArgs{}, nil, nil}, - {"notify", expectArgs{nil, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, - {"resume", expectArgs{}, true, nil}, - {"verbosef", expectArgs{"initial process exited with code %d", []any{1}}, nil, nil}, - {"beforeExit", expectArgs{}, nil, nil}, - {"exit", expectArgs{1}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{".", "."}, nil, nil}, + {"fchdir", stub.ExpectArgs{1 << 35}, nil, nil}, + {"unmount", stub.ExpectArgs{".", 2}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, + {"close", stub.ExpectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", stub.ExpectArgs{}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x4)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x5)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x6)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x7)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x8)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x9)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xa)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xb)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xc)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xd)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xe)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xf)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x10)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x11)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x12)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x13)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x14)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x15)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x16)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x17)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x18)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x19)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1a)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1b)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1c)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1d)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1e)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1f)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x20)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x21)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x22)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x23)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x24)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x25)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x26)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x27)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x28)}, nil, nil}, + {"capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, new([2]capData)}, nil, nil}, + {"verbose", stub.ExpectArgs{[]any{"syscall filter not configured"}}, nil, nil}, + {"newFile", stub.ExpectArgs{uintptr(0x3a), "extra file 0"}, (*os.File)(nil), nil}, + {"newFile", stub.ExpectArgs{uintptr(0x3b), "extra file 1"}, (*os.File)(nil), nil}, + {"umask", stub.ExpectArgs{022}, 0, nil}, + {"verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/run/current-system/sw/bin/bash")}}, nil, nil}, + {"start", stub.ExpectArgs{"/run/current-system/sw/bin/bash", []string{"bash", "-c", "false"}, ([]string)(nil), "/.hakurei/nonexistent"}, &os.Process{Pid: 0xbad}, nil}, + {"suspend", stub.ExpectArgs{}, nil, nil}, + {"printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(1)}}, nil, nil}, + {"New", stub.ExpectArgs{}, nil, nil}, + {"notify", stub.ExpectArgs{nil, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, + {"resume", stub.ExpectArgs{}, true, nil}, + {"verbosef", stub.ExpectArgs{"initial process exited with code %d", []any{1}}, nil, nil}, + {"beforeExit", stub.ExpectArgs{}, nil, nil}, + {"exit", stub.ExpectArgs{1}, nil, nil}, }, /* wait4 */ - { - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, syscall.WaitStatus(0xfade0100), 0, nil}, 0xbad, nil}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.ENOMEM}, - {"printf", expectArgs{"unexpected wait4 response: %v", []any{syscall.ENOMEM}}, nil, nil}, - }, + Tracks: []stub.Expect{{Calls: []stub.Call{ + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, syscall.WaitStatus(0xfade0100), 0, nil}, 0xbad, nil}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.ENOMEM}, + {"printf", stub.ExpectArgs{"unexpected wait4 response: %v", []any{syscall.ENOMEM}}, nil, nil}, + }}}, }, nil}, - {"success", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, [][]kexpect{ + {"success", func(k syscallDispatcher) error { initEntrypoint(k, assertPrefix, assertVerboseTrue); return nil }, stub.Expect{ /* entrypoint */ - { - {"lockOSThread", expectArgs{}, nil, nil}, - {"getpid", expectArgs{}, 1, nil}, - {"setPtracer", expectArgs{uintptr(0)}, nil, nil}, - {"receive", expectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ + Calls: []stub.Call{ + {"lockOSThread", stub.ExpectArgs{}, nil, nil}, + {"getpid", stub.ExpectArgs{}, 1, nil}, + {"setPtracer", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"receive", stub.ExpectArgs{"HAKUREI_SETUP", new(initParams), new(uintptr), &initParams{Params{ Dir: MustAbs("/.hakurei"), Env: []string{"DISPLAY=:0"}, Path: MustAbs("/bin/zsh"), @@ -2499,121 +2500,121 @@ func TestInitEntrypoint(t *testing.T) { SeccompPresets: seccomp.PresetStrict, RetainSession: true, Privileged: true, - }, 1000, 100, 3, true}, uintptr(9)}, errUnique, nil}, - {"verbose", expectArgs{[]any{"received setup parameters"}}, nil, nil}, - {"setDumpable", expectArgs{uintptr(1)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, - {"writeFile", expectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, - {"setDumpable", expectArgs{uintptr(0)}, nil, nil}, - {"umask", expectArgs{0}, 022, nil}, - {"sethostname", expectArgs{[]byte("hakurei-check")}, nil, nil}, - {"lastcap", expectArgs{}, uintptr(40), nil}, - {"mount", expectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, + }, 1000, 100, 3, true}, uintptr(9)}, stub.UniqueError(0), nil}, + {"verbose", stub.ExpectArgs{[]any{"received setup parameters"}}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(1)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/uid_map", []byte("4294967296 1000 1\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/setgroups", []byte("deny\n"), os.FileMode(0)}, nil, nil}, + {"writeFile", stub.ExpectArgs{"/proc/self/gid_map", []byte("2147483648 100 1\n"), os.FileMode(0)}, nil, nil}, + {"setDumpable", stub.ExpectArgs{uintptr(0)}, nil, nil}, + {"umask", stub.ExpectArgs{0}, 022, nil}, + {"sethostname", stub.ExpectArgs{[]byte("hakurei-check")}, nil, nil}, + {"lastcap", stub.ExpectArgs{}, uintptr(40), nil}, + {"mount", stub.ExpectArgs{"", "/", "", uintptr(0x8c000), ""}, nil, nil}, /* begin early */ - {"evalSymlinks", expectArgs{"/"}, "/", nil}, + {"evalSymlinks", stub.ExpectArgs{"/"}, "/", nil}, /* end early */ - {"mount", expectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, - {"chdir", expectArgs{"/proc/self/fd"}, nil, nil}, - {"mkdir", expectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, - {"mkdir", expectArgs{"host", os.FileMode(0755)}, nil, nil}, - {"pivotRoot", expectArgs{"/proc/self/fd", "host"}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, + {"mount", stub.ExpectArgs{"rootfs", "/proc/self/fd", "tmpfs", uintptr(6), ""}, nil, nil}, + {"chdir", stub.ExpectArgs{"/proc/self/fd"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"sysroot", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"sysroot", "sysroot", "", uintptr(0xd000), ""}, nil, nil}, + {"mkdir", stub.ExpectArgs{"host", os.FileMode(0755)}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{"/proc/self/fd", "host"}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, /* begin apply */ - {"verbosef", expectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, - {"stat", expectArgs{"/host"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, - {"verbosef", expectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &BindMountOp{sourceFinal: MustAbs("/"), Source: MustAbs("/"), Target: MustAbs("/"), Flags: BindDevice}}}, nil, nil}, + {"stat", stub.ExpectArgs{"/host"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host", "/sysroot", uintptr(0x4001), false}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%s %s", []any{"mounting", &MountProcOp{Target: MustAbs("/proc/")}}}, nil, nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, /* end apply */ - {"mount", expectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, - {"unmount", expectArgs{"host", 2}, nil, nil}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, - {"open", expectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, - {"chdir", expectArgs{"/sysroot"}, nil, nil}, - {"pivotRoot", expectArgs{".", "."}, nil, nil}, - {"fchdir", expectArgs{1 << 35}, nil, nil}, - {"unmount", expectArgs{".", 2}, nil, nil}, - {"chdir", expectArgs{"/"}, nil, nil}, - {"close", expectArgs{1 << 35}, nil, nil}, - {"capAmbientClearAll", expectArgs{}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x0)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x2)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x3)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x4)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x5)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x6)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x7)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x8)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x9)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xa)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xb)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xc)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xd)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xe)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0xf)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x10)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x11)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x12)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x13)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x14)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x16)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x17)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x18)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x19)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1a)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1b)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1c)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1d)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1e)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x1f)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x20)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x21)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x22)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x23)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x24)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x25)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x26)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x27)}, nil, nil}, - {"capBoundingSetDrop", expectArgs{uintptr(0x28)}, nil, nil}, - {"capAmbientRaise", expectArgs{uintptr(0x15)}, nil, nil}, - {"capset", expectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, &[2]capData{{0, 0x200000, 0x200000}, {0, 0, 0}}}, nil, nil}, - {"verbosef", expectArgs{"resolving presets %#x", []any{seccomp.FilterPreset(0xf)}}, nil, nil}, - {"seccompLoad", expectArgs{seccomp.Preset(0xf, 0), seccomp.ExportFlag(0)}, nil, nil}, - {"verbosef", expectArgs{"%d filter rules loaded", []any{73}}, nil, nil}, - {"newFile", expectArgs{uintptr(10), "extra file 0"}, (*os.File)(nil), nil}, - {"newFile", expectArgs{uintptr(11), "extra file 1"}, (*os.File)(nil), nil}, - {"newFile", expectArgs{uintptr(12), "extra file 2"}, (*os.File)(nil), nil}, - {"umask", expectArgs{022}, 0, nil}, - {"verbosef", expectArgs{"starting initial program %s", []any{MustAbs("/bin/zsh")}}, nil, nil}, - {"start", expectArgs{"/bin/zsh", []string{"zsh", "-c", "exec vim"}, []string{"DISPLAY=:0"}, "/.hakurei"}, &os.Process{Pid: 0xcafe}, nil}, - {"suspend", expectArgs{}, nil, nil}, - {"printf", expectArgs{"cannot close setup pipe: %v", []any{errUnique}}, nil, nil}, - {"new", expectArgs{}, nil, nil}, - {"notify", expectArgs{nil, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, - {"resume", expectArgs{}, true, nil}, - {"verbosef", expectArgs{"initial process exited with status %#x", []any{syscall.WaitStatus(0xfade007f)}}, nil, nil}, - {"beforeExit", expectArgs{}, nil, nil}, - {"exit", expectArgs{0xff}, nil, nil}, + {"mount", stub.ExpectArgs{"host", "host", "", uintptr(0x4c000), ""}, nil, nil}, + {"unmount", stub.ExpectArgs{"host", 2}, nil, nil}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, syscall.EINTR}, + {"open", stub.ExpectArgs{"/", 0x10000, uint32(0)}, 1 << 35, nil}, + {"chdir", stub.ExpectArgs{"/sysroot"}, nil, nil}, + {"pivotRoot", stub.ExpectArgs{".", "."}, nil, nil}, + {"fchdir", stub.ExpectArgs{1 << 35}, nil, nil}, + {"unmount", stub.ExpectArgs{".", 2}, nil, nil}, + {"chdir", stub.ExpectArgs{"/"}, nil, nil}, + {"close", stub.ExpectArgs{1 << 35}, nil, nil}, + {"capAmbientClearAll", stub.ExpectArgs{}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x0)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x2)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x3)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x4)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x5)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x6)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x7)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x8)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x9)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xa)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xb)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xc)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xd)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xe)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0xf)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x10)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x11)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x12)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x13)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x14)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x16)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x17)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x18)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x19)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1a)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1b)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1c)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1d)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1e)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x1f)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x20)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x21)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x22)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x23)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x24)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x25)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x26)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x27)}, nil, nil}, + {"capBoundingSetDrop", stub.ExpectArgs{uintptr(0x28)}, nil, nil}, + {"capAmbientRaise", stub.ExpectArgs{uintptr(0x15)}, nil, nil}, + {"capset", stub.ExpectArgs{&capHeader{_LINUX_CAPABILITY_VERSION_3, 0}, &[2]capData{{0, 0x200000, 0x200000}, {0, 0, 0}}}, nil, nil}, + {"verbosef", stub.ExpectArgs{"resolving presets %#x", []any{seccomp.FilterPreset(0xf)}}, nil, nil}, + {"seccompLoad", stub.ExpectArgs{seccomp.Preset(0xf, 0), seccomp.ExportFlag(0)}, nil, nil}, + {"verbosef", stub.ExpectArgs{"%d filter rules loaded", []any{73}}, nil, nil}, + {"newFile", stub.ExpectArgs{uintptr(10), "extra file 0"}, (*os.File)(nil), nil}, + {"newFile", stub.ExpectArgs{uintptr(11), "extra file 1"}, (*os.File)(nil), nil}, + {"newFile", stub.ExpectArgs{uintptr(12), "extra file 2"}, (*os.File)(nil), nil}, + {"umask", stub.ExpectArgs{022}, 0, nil}, + {"verbosef", stub.ExpectArgs{"starting initial program %s", []any{MustAbs("/bin/zsh")}}, nil, nil}, + {"start", stub.ExpectArgs{"/bin/zsh", []string{"zsh", "-c", "exec vim"}, []string{"DISPLAY=:0"}, "/.hakurei"}, &os.Process{Pid: 0xcafe}, nil}, + {"suspend", stub.ExpectArgs{}, nil, nil}, + {"printf", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(0)}}, nil, nil}, + {"New", stub.ExpectArgs{}, nil, nil}, + {"notify", stub.ExpectArgs{nil, []os.Signal{syscall.SIGINT, syscall.SIGTERM}}, nil, nil}, + {"resume", stub.ExpectArgs{}, true, nil}, + {"verbosef", stub.ExpectArgs{"initial process exited with status %#x", []any{syscall.WaitStatus(0xfade007f)}}, nil, nil}, + {"beforeExit", stub.ExpectArgs{}, nil, nil}, + {"exit", stub.ExpectArgs{0xff}, nil, nil}, }, /* wait4 */ - { - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, syscall.WaitStatus(0xfade007f), 0, nil}, 0xcafe, nil}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, - {"wait4", expectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, - {"wait4", expectArgs{-1, nil, 0, nil}, 0, syscall.ECHILD}, - }, + Tracks: []stub.Expect{{Calls: []stub.Call{ + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, syscall.WaitStatus(0xfade007f), 0, nil}, 0xcafe, nil}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.EINTR}, + {"wait4", stub.ExpectArgs{-1, syscall.WaitStatus(0xdeaf), 0, nil}, 0xbabe, nil}, + {"wait4", stub.ExpectArgs{-1, nil, 0, nil}, 0, syscall.ECHILD}, + }}}, }, nil}, }) } diff --git a/container/initbind_test.go b/container/initbind_test.go index 3c91c61..93e880c 100644 --- a/container/initbind_test.go +++ b/container/initbind_test.go @@ -5,6 +5,8 @@ import ( "os" "syscall" "testing" + + "hakurei.app/container/stub" ) func TestBindMountOp(t *testing.T) { @@ -12,132 +14,132 @@ func TestBindMountOp(t *testing.T) { {"ENOENT not optional", new(Params), &BindMountOp{ Source: MustAbs("/bin/"), Target: MustAbs("/bin/"), - }, []kexpect{ - {"evalSymlinks", expectArgs{"/bin/"}, "", syscall.ENOENT}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/bin/"}, "", syscall.ENOENT}, }, syscall.ENOENT, nil, nil}, {"skip optional", new(Params), &BindMountOp{ Source: MustAbs("/bin/"), Target: MustAbs("/bin/"), Flags: BindOptional, - }, []kexpect{ - {"evalSymlinks", expectArgs{"/bin/"}, "", syscall.ENOENT}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/bin/"}, "", syscall.ENOENT}, }, nil, nil, nil}, {"success optional", new(Params), &BindMountOp{ Source: MustAbs("/bin/"), Target: MustAbs("/bin/"), Flags: BindOptional, - }, []kexpect{ - {"evalSymlinks", expectArgs{"/bin/"}, "/usr/bin", nil}, - }, nil, []kexpect{ - {"stat", expectArgs{"/host/usr/bin"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot/bin", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host/usr/bin", "/sysroot/bin", uintptr(0x4005), false}, nil, nil}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil}, + }, nil, []stub.Call{ + {"stat", stub.ExpectArgs{"/host/usr/bin"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/bin", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/usr/bin", "/sysroot/bin", uintptr(0x4005), false}, nil, nil}, }, nil}, {"ensureFile device", new(Params), &BindMountOp{ Source: MustAbs("/dev/null"), Target: MustAbs("/dev/null"), Flags: BindWritable | BindDevice, - }, []kexpect{ - {"evalSymlinks", expectArgs{"/dev/null"}, "/dev/null", nil}, - }, nil, []kexpect{ - {"stat", expectArgs{"/host/dev/null"}, isDirFi(false), nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0700)}, nil, errUnique}, - }, errUnique}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/dev/null"}, "/dev/null", nil}, + }, nil, []stub.Call{ + {"stat", stub.ExpectArgs{"/host/dev/null"}, isDirFi(false), nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0700)}, nil, stub.UniqueError(5)}, + }, stub.UniqueError(5)}, {"mkdirAll ensure", new(Params), &BindMountOp{ Source: MustAbs("/bin/"), Target: MustAbs("/bin/"), Flags: BindEnsure, - }, []kexpect{ - {"mkdirAll", expectArgs{"/bin/", os.FileMode(0700)}, nil, errUnique}, - }, errUnique, nil, nil}, + }, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/bin/", os.FileMode(0700)}, nil, stub.UniqueError(4)}, + }, stub.UniqueError(4), nil, nil}, {"success ensure", new(Params), &BindMountOp{ Source: MustAbs("/bin/"), Target: MustAbs("/usr/bin/"), Flags: BindEnsure, - }, []kexpect{ - {"mkdirAll", expectArgs{"/bin/", os.FileMode(0700)}, nil, nil}, - {"evalSymlinks", expectArgs{"/bin/"}, "/usr/bin", nil}, - }, nil, []kexpect{ - {"stat", expectArgs{"/host/usr/bin"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot/usr/bin", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host/usr/bin", "/sysroot/usr/bin", uintptr(0x4005), false}, nil, nil}, + }, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/bin/", os.FileMode(0700)}, nil, nil}, + {"evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil}, + }, nil, []stub.Call{ + {"stat", stub.ExpectArgs{"/host/usr/bin"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/usr/bin", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/usr/bin", "/sysroot/usr/bin", uintptr(0x4005), false}, nil, nil}, }, nil}, {"success device ro", new(Params), &BindMountOp{ Source: MustAbs("/dev/null"), Target: MustAbs("/dev/null"), Flags: BindDevice, - }, []kexpect{ - {"evalSymlinks", expectArgs{"/dev/null"}, "/dev/null", nil}, - }, nil, []kexpect{ - {"stat", expectArgs{"/host/dev/null"}, isDirFi(false), nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0x4001), false}, nil, nil}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/dev/null"}, "/dev/null", nil}, + }, nil, []stub.Call{ + {"stat", stub.ExpectArgs{"/host/dev/null"}, isDirFi(false), nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0x4001), false}, nil, nil}, }, nil}, {"success device", new(Params), &BindMountOp{ Source: MustAbs("/dev/null"), Target: MustAbs("/dev/null"), Flags: BindWritable | BindDevice, - }, []kexpect{ - {"evalSymlinks", expectArgs{"/dev/null"}, "/dev/null", nil}, - }, nil, []kexpect{ - {"stat", expectArgs{"/host/dev/null"}, isDirFi(false), nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0x4000), false}, nil, nil}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/dev/null"}, "/dev/null", nil}, + }, nil, []stub.Call{ + {"stat", stub.ExpectArgs{"/host/dev/null"}, isDirFi(false), nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0x4000), false}, nil, nil}, }, nil}, {"evalSymlinks", new(Params), &BindMountOp{ Source: MustAbs("/bin/"), Target: MustAbs("/bin/"), - }, []kexpect{ - {"evalSymlinks", expectArgs{"/bin/"}, "/usr/bin", errUnique}, - }, errUnique, nil, nil}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", stub.UniqueError(3)}, + }, stub.UniqueError(3), nil, nil}, {"stat", new(Params), &BindMountOp{ Source: MustAbs("/bin/"), Target: MustAbs("/bin/"), - }, []kexpect{ - {"evalSymlinks", expectArgs{"/bin/"}, "/usr/bin", nil}, - }, nil, []kexpect{ - {"stat", expectArgs{"/host/usr/bin"}, isDirFi(true), errUnique}, - }, errUnique}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil}, + }, nil, []stub.Call{ + {"stat", stub.ExpectArgs{"/host/usr/bin"}, isDirFi(true), stub.UniqueError(2)}, + }, stub.UniqueError(2)}, {"mkdirAll", new(Params), &BindMountOp{ Source: MustAbs("/bin/"), Target: MustAbs("/bin/"), - }, []kexpect{ - {"evalSymlinks", expectArgs{"/bin/"}, "/usr/bin", nil}, - }, nil, []kexpect{ - {"stat", expectArgs{"/host/usr/bin"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot/bin", os.FileMode(0700)}, nil, errUnique}, - }, errUnique}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil}, + }, nil, []stub.Call{ + {"stat", stub.ExpectArgs{"/host/usr/bin"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/bin", os.FileMode(0700)}, nil, stub.UniqueError(1)}, + }, stub.UniqueError(1)}, {"bindMount", new(Params), &BindMountOp{ Source: MustAbs("/bin/"), Target: MustAbs("/bin/"), - }, []kexpect{ - {"evalSymlinks", expectArgs{"/bin/"}, "/usr/bin", nil}, - }, nil, []kexpect{ - {"stat", expectArgs{"/host/usr/bin"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot/bin", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host/usr/bin", "/sysroot/bin", uintptr(0x4005), false}, nil, errUnique}, - }, errUnique}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil}, + }, nil, []stub.Call{ + {"stat", stub.ExpectArgs{"/host/usr/bin"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/bin", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/usr/bin", "/sysroot/bin", uintptr(0x4005), false}, nil, stub.UniqueError(0)}, + }, stub.UniqueError(0)}, {"success", new(Params), &BindMountOp{ Source: MustAbs("/bin/"), Target: MustAbs("/bin/"), - }, []kexpect{ - {"evalSymlinks", expectArgs{"/bin/"}, "/usr/bin", nil}, - }, nil, []kexpect{ - {"stat", expectArgs{"/host/usr/bin"}, isDirFi(true), nil}, - {"mkdirAll", expectArgs{"/sysroot/bin", os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"/host/usr/bin", "/sysroot/bin", uintptr(0x4005), false}, nil, nil}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/bin/"}, "/usr/bin", nil}, + }, nil, []stub.Call{ + {"stat", stub.ExpectArgs{"/host/usr/bin"}, isDirFi(true), nil}, + {"mkdirAll", stub.ExpectArgs{"/sysroot/bin", os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/usr/bin", "/sysroot/bin", uintptr(0x4005), false}, nil, nil}, }, nil}, }) diff --git a/container/initdev_test.go b/container/initdev_test.go index 3293161..e3cc9d5 100644 --- a/container/initdev_test.go +++ b/container/initdev_test.go @@ -3,6 +3,8 @@ package container import ( "os" "testing" + + "hakurei.app/container/stub" ) func TestMountDevOp(t *testing.T) { @@ -10,745 +12,745 @@ func TestMountDevOp(t *testing.T) { {"mountTmpfs", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, stub.UniqueError(27)}, + }, stub.UniqueError(27)}, {"ensureFile null", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, stub.UniqueError(26)}, + }, stub.UniqueError(26)}, {"bindMount null", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, stub.UniqueError(25)}, + }, stub.UniqueError(25)}, {"ensureFile zero", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, stub.UniqueError(24)}, + }, stub.UniqueError(24)}, {"bindMount zero", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, stub.UniqueError(23)}, + }, stub.UniqueError(23)}, {"ensureFile full", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, stub.UniqueError(22)}, + }, stub.UniqueError(22)}, {"bindMount full", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, stub.UniqueError(21)}, + }, stub.UniqueError(21)}, {"ensureFile random", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, stub.UniqueError(20)}, + }, stub.UniqueError(20)}, {"bindMount random", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, stub.UniqueError(19)}, + }, stub.UniqueError(19)}, {"ensureFile urandom", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, stub.UniqueError(18)}, + }, stub.UniqueError(18)}, {"bindMount urandom", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, stub.UniqueError(17)}, + }, stub.UniqueError(17)}, {"ensureFile tty", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, stub.UniqueError(16)}, + }, stub.UniqueError(16)}, {"bindMount tty", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, stub.UniqueError(15)}, + }, stub.UniqueError(15)}, {"symlink stdin", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, stub.UniqueError(14)}, + }, stub.UniqueError(14)}, {"symlink stdout", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, stub.UniqueError(13)}, + }, stub.UniqueError(13)}, {"symlink stderr", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, stub.UniqueError(12)}, + }, stub.UniqueError(12)}, {"symlink fd", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, stub.UniqueError(11)}, + }, stub.UniqueError(11)}, {"symlink kcore", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, - {"symlink", expectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, stub.UniqueError(10)}, + }, stub.UniqueError(10)}, {"symlink ptmx", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, - {"symlink", expectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, - {"symlink", expectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, + {"symlink", stub.ExpectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, stub.UniqueError(9)}, + }, stub.UniqueError(9)}, {"mkdir shm", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, - {"symlink", expectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, - {"symlink", expectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, + {"symlink", stub.ExpectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, stub.UniqueError(8)}, + }, stub.UniqueError(8)}, {"mkdir devpts", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, - {"symlink", expectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, - {"symlink", expectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, + {"symlink", stub.ExpectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, stub.UniqueError(7)}, + }, stub.UniqueError(7)}, {"mount devpts", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, - {"symlink", expectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, - {"symlink", expectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, + {"symlink", stub.ExpectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, stub.UniqueError(6)}, + }, stub.UniqueError(6)}, {"ensureFile stdout", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, - {"symlink", expectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, - {"symlink", expectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, - {"isatty", expectArgs{1}, true, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, + {"symlink", stub.ExpectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, + {"isatty", stub.ExpectArgs{1}, true, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, stub.UniqueError(5)}, + }, stub.UniqueError(5)}, {"readlink stdout", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, - {"symlink", expectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, - {"symlink", expectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, - {"isatty", expectArgs{1}, true, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/1"}, "", errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, + {"symlink", stub.ExpectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, + {"isatty", stub.ExpectArgs{1}, true, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/1"}, "", stub.UniqueError(4)}, + }, stub.UniqueError(4)}, {"bindMount stdout", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, - {"symlink", expectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, - {"symlink", expectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, - {"isatty", expectArgs{1}, true, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/1"}, "/dev/pts/2", nil}, - {"bindMount", expectArgs{"/host/dev/pts/2", "/sysroot/dev/console", uintptr(0), false}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, + {"symlink", stub.ExpectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, + {"isatty", stub.ExpectArgs{1}, true, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/1"}, "/dev/pts/2", nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/pts/2", "/sysroot/dev/console", uintptr(0), false}, nil, stub.UniqueError(3)}, + }, stub.UniqueError(3)}, {"mkdir mqueue", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, - {"symlink", expectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, - {"symlink", expectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, - {"isatty", expectArgs{1}, true, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/1"}, "/dev/pts/2", nil}, - {"bindMount", expectArgs{"/host/dev/pts/2", "/sysroot/dev/console", uintptr(0), false}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/mqueue", os.FileMode(0750)}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, + {"symlink", stub.ExpectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, + {"isatty", stub.ExpectArgs{1}, true, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/1"}, "/dev/pts/2", nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/pts/2", "/sysroot/dev/console", uintptr(0), false}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/mqueue", os.FileMode(0750)}, nil, stub.UniqueError(2)}, + }, stub.UniqueError(2)}, {"mount mqueue", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, - {"symlink", expectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, - {"symlink", expectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, - {"isatty", expectArgs{1}, true, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/1"}, "/dev/pts/2", nil}, - {"bindMount", expectArgs{"/host/dev/pts/2", "/sysroot/dev/console", uintptr(0), false}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/mqueue", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"mqueue", "/sysroot/dev/mqueue", "mqueue", uintptr(0xe), ""}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, + {"symlink", stub.ExpectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, + {"isatty", stub.ExpectArgs{1}, true, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/1"}, "/dev/pts/2", nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/pts/2", "/sysroot/dev/console", uintptr(0), false}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/mqueue", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"mqueue", "/sysroot/dev/mqueue", "mqueue", uintptr(0xe), ""}, nil, stub.UniqueError(1)}, + }, stub.UniqueError(1)}, {"success no session", &Params{ParentPerm: 0755}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, Write: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0755)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0755)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0755)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0755)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0755)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0755)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0755)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, - {"symlink", expectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, - {"symlink", expectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/shm", os.FileMode(0755)}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/pts", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/mqueue", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"mqueue", "/sysroot/dev/mqueue", "mqueue", uintptr(0xe), ""}, nil, nil}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0755)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0755)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0755)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0755)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0755)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0755)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0755)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, + {"symlink", stub.ExpectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/shm", os.FileMode(0755)}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/pts", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/mqueue", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"mqueue", "/sysroot/dev/mqueue", "mqueue", uintptr(0xe), ""}, nil, nil}, }, nil}, {"success no tty", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, Write: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, - {"symlink", expectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, - {"symlink", expectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, - {"isatty", expectArgs{1}, false, nil}, - {"mkdir", expectArgs{"/sysroot/dev/mqueue", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"mqueue", "/sysroot/dev/mqueue", "mqueue", uintptr(0xe), ""}, nil, nil}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, + {"symlink", stub.ExpectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, + {"isatty", stub.ExpectArgs{1}, false, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/mqueue", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"mqueue", "/sysroot/dev/mqueue", "mqueue", uintptr(0xe), ""}, nil, nil}, }, nil}, {"remount", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, - {"symlink", expectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, - {"symlink", expectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, - {"isatty", expectArgs{1}, true, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/1"}, "/dev/pts/2", nil}, - {"bindMount", expectArgs{"/host/dev/pts/2", "/sysroot/dev/console", uintptr(0), false}, nil, nil}, - {"remount", expectArgs{"/sysroot/dev", uintptr(1)}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, + {"symlink", stub.ExpectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, + {"isatty", stub.ExpectArgs{1}, true, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/1"}, "/dev/pts/2", nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/pts/2", "/sysroot/dev/console", uintptr(0), false}, nil, nil}, + {"remount", stub.ExpectArgs{"/sysroot/dev", uintptr(1)}, nil, stub.UniqueError(0)}, + }, stub.UniqueError(0)}, {"success no mqueue", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, - {"symlink", expectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, - {"symlink", expectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, - {"isatty", expectArgs{1}, true, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/1"}, "/dev/pts/2", nil}, - {"bindMount", expectArgs{"/host/dev/pts/2", "/sysroot/dev/console", uintptr(0), false}, nil, nil}, - {"remount", expectArgs{"/sysroot/dev", uintptr(1)}, nil, nil}, - {"mountTmpfs", expectArgs{"tmpfs", "/sysroot/dev/shm", uintptr(0x6), 0, os.FileMode(01777)}, nil, nil}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, + {"symlink", stub.ExpectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, + {"isatty", stub.ExpectArgs{1}, true, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/1"}, "/dev/pts/2", nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/pts/2", "/sysroot/dev/console", uintptr(0), false}, nil, nil}, + {"remount", stub.ExpectArgs{"/sysroot/dev", uintptr(1)}, nil, nil}, + {"mountTmpfs", stub.ExpectArgs{"tmpfs", "/sysroot/dev/shm", uintptr(0x6), 0, os.FileMode(01777)}, nil, nil}, }, nil}, {"success rw", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, Write: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, - {"symlink", expectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, - {"symlink", expectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, - {"isatty", expectArgs{1}, true, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/1"}, "/dev/pts/2", nil}, - {"bindMount", expectArgs{"/host/dev/pts/2", "/sysroot/dev/console", uintptr(0), false}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/mqueue", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"mqueue", "/sysroot/dev/mqueue", "mqueue", uintptr(0xe), ""}, nil, nil}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, + {"symlink", stub.ExpectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, + {"isatty", stub.ExpectArgs{1}, true, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/1"}, "/dev/pts/2", nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/pts/2", "/sysroot/dev/console", uintptr(0), false}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/mqueue", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"mqueue", "/sysroot/dev/mqueue", "mqueue", uintptr(0xe), ""}, nil, nil}, }, nil}, {"success", &Params{ParentPerm: 0750, RetainSession: true}, &MountDevOp{ Target: MustAbs("/dev/"), Mqueue: true, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"bindMount", expectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, - {"symlink", expectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, - {"symlink", expectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, - {"symlink", expectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, - {"isatty", expectArgs{1}, true, nil}, - {"ensureFile", expectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/1"}, "/dev/pts/2", nil}, - {"bindMount", expectArgs{"/host/dev/pts/2", "/sysroot/dev/console", uintptr(0), false}, nil, nil}, - {"mkdir", expectArgs{"/sysroot/dev/mqueue", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"mqueue", "/sysroot/dev/mqueue", "mqueue", uintptr(0xe), ""}, nil, nil}, - {"remount", expectArgs{"/sysroot/dev", uintptr(1)}, nil, nil}, - {"mountTmpfs", expectArgs{"tmpfs", "/sysroot/dev/shm", uintptr(0x6), 0, os.FileMode(01777)}, nil, nil}, + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{"devtmpfs", "/sysroot/dev", uintptr(0x6), 0, os.FileMode(0750)}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/null", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/null", "/sysroot/dev/null", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/zero", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/zero", "/sysroot/dev/zero", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/full", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/full", "/sysroot/dev/full", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/random", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/random", "/sysroot/dev/random", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/urandom", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/urandom", "/sysroot/dev/urandom", uintptr(0), true}, nil, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/tty", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/tty", "/sysroot/dev/tty", uintptr(0), true}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/0", "/sysroot/dev/stdin"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/1", "/sysroot/dev/stdout"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd/2", "/sysroot/dev/stderr"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/self/fd", "/sysroot/dev/fd"}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/kcore", "/sysroot/dev/core"}, nil, nil}, + {"symlink", stub.ExpectArgs{"pts/ptmx", "/sysroot/dev/ptmx"}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/shm", os.FileMode(0750)}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/pts", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"devpts", "/sysroot/dev/pts", "devpts", uintptr(0xa), "newinstance,ptmxmode=0666,mode=620"}, nil, nil}, + {"isatty", stub.ExpectArgs{1}, true, nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/dev/console", os.FileMode(0444), os.FileMode(0750)}, nil, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/1"}, "/dev/pts/2", nil}, + {"bindMount", stub.ExpectArgs{"/host/dev/pts/2", "/sysroot/dev/console", uintptr(0), false}, nil, nil}, + {"mkdir", stub.ExpectArgs{"/sysroot/dev/mqueue", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"mqueue", "/sysroot/dev/mqueue", "mqueue", uintptr(0xe), ""}, nil, nil}, + {"remount", stub.ExpectArgs{"/sysroot/dev", uintptr(1)}, nil, nil}, + {"mountTmpfs", stub.ExpectArgs{"tmpfs", "/sysroot/dev/shm", uintptr(0x6), 0, os.FileMode(01777)}, nil, nil}, }, nil}, }) diff --git a/container/initmkdir_test.go b/container/initmkdir_test.go index 1f54e74..1a8a8f1 100644 --- a/container/initmkdir_test.go +++ b/container/initmkdir_test.go @@ -3,6 +3,8 @@ package container import ( "os" "testing" + + "hakurei.app/container/stub" ) func TestMkdirOp(t *testing.T) { @@ -10,8 +12,8 @@ func TestMkdirOp(t *testing.T) { {"success", new(Params), &MkdirOp{ Path: MustAbs("/.hakurei"), Perm: 0500, - }, nil, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/.hakurei", os.FileMode(0500)}, nil, nil}, + }, nil, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/.hakurei", os.FileMode(0500)}, nil, nil}, }, nil}, }) diff --git a/container/initoverlay_test.go b/container/initoverlay_test.go index 9dae211..4306099 100644 --- a/container/initoverlay_test.go +++ b/container/initoverlay_test.go @@ -4,6 +4,8 @@ import ( "errors" "os" "testing" + + "hakurei.app/container/stub" ) func TestMountOverlayOp(t *testing.T) { @@ -51,13 +53,13 @@ func TestMountOverlayOp(t *testing.T) { MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"), }, Upper: MustAbs("/"), - }, []kexpect{ - {"evalSymlinks", expectArgs{"/var/lib/planterette/base/debian:f92c9052"}, "/var/lib/planterette/base/debian:f92c9052", nil}, - {"evalSymlinks", expectArgs{"/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"}, "/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052", nil}, - }, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0705)}, nil, nil}, - {"mkdirTemp", expectArgs{"/", "overlay.upper.*"}, "overlay.upper.32768", errUnique}, - }, errUnique}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052"}, "/var/lib/planterette/base/debian:f92c9052", nil}, + {"evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"}, "/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052", nil}, + }, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0705)}, nil, nil}, + {"mkdirTemp", stub.ExpectArgs{"/", "overlay.upper.*"}, "overlay.upper.32768", stub.UniqueError(6)}, + }, stub.UniqueError(6)}, {"mkdirTemp work ephemeral", &Params{ParentPerm: 0705}, &MountOverlayOp{ Target: MustAbs("/"), @@ -66,14 +68,14 @@ func TestMountOverlayOp(t *testing.T) { MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"), }, Upper: MustAbs("/"), - }, []kexpect{ - {"evalSymlinks", expectArgs{"/var/lib/planterette/base/debian:f92c9052"}, "/var/lib/planterette/base/debian:f92c9052", nil}, - {"evalSymlinks", expectArgs{"/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"}, "/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052", nil}, - }, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0705)}, nil, nil}, - {"mkdirTemp", expectArgs{"/", "overlay.upper.*"}, "overlay.upper.32768", nil}, - {"mkdirTemp", expectArgs{"/", "overlay.work.*"}, "overlay.work.32768", errUnique}, - }, errUnique}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052"}, "/var/lib/planterette/base/debian:f92c9052", nil}, + {"evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"}, "/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052", nil}, + }, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0705)}, nil, nil}, + {"mkdirTemp", stub.ExpectArgs{"/", "overlay.upper.*"}, "overlay.upper.32768", nil}, + {"mkdirTemp", stub.ExpectArgs{"/", "overlay.work.*"}, "overlay.work.32768", stub.UniqueError(5)}, + }, stub.UniqueError(5)}, {"success ephemeral", &Params{ParentPerm: 0705}, &MountOverlayOp{ Target: MustAbs("/"), @@ -82,14 +84,14 @@ func TestMountOverlayOp(t *testing.T) { MustAbs("/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"), }, Upper: MustAbs("/"), - }, []kexpect{ - {"evalSymlinks", expectArgs{"/var/lib/planterette/base/debian:f92c9052"}, "/var/lib/planterette/base/debian:f92c9052", nil}, - {"evalSymlinks", expectArgs{"/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"}, "/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052", nil}, - }, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot", os.FileMode(0705)}, nil, nil}, - {"mkdirTemp", expectArgs{"/", "overlay.upper.*"}, "overlay.upper.32768", nil}, - {"mkdirTemp", expectArgs{"/", "overlay.work.*"}, "overlay.work.32768", nil}, - {"mount", expectArgs{"overlay", "/sysroot", "overlay", uintptr(0), "" + + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/base/debian:f92c9052"}, "/var/lib/planterette/base/debian:f92c9052", nil}, + {"evalSymlinks", stub.ExpectArgs{"/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052"}, "/var/lib/planterette/app/org.chromium.Chromium@debian:f92c9052", nil}, + }, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot", os.FileMode(0705)}, nil, nil}, + {"mkdirTemp", stub.ExpectArgs{"/", "overlay.upper.*"}, "overlay.upper.32768", nil}, + {"mkdirTemp", stub.ExpectArgs{"/", "overlay.work.*"}, "overlay.work.32768", nil}, + {"mount", stub.ExpectArgs{"overlay", "/sysroot", "overlay", uintptr(0), "" + "upperdir=overlay.upper.32768," + "workdir=overlay.work.32768," + "lowerdir=" + @@ -103,10 +105,10 @@ func TestMountOverlayOp(t *testing.T) { Lower: []*Absolute{ MustAbs("/mnt-root/nix/.ro-store"), }, - }, []kexpect{ - {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/.ro-store", nil}, - }, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/nix/store", os.FileMode(0755)}, nil, nil}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/.ro-store", nil}, + }, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/nix/store", os.FileMode(0755)}, nil, nil}, }, &OverlayArgumentError{OverlayReadonlyLower, zeroString}}, {"success ro noPrefix", &Params{ParentPerm: 0755}, &MountOverlayOp{ @@ -116,12 +118,12 @@ func TestMountOverlayOp(t *testing.T) { MustAbs("/mnt-root/nix/.ro-store0"), }, noPrefix: true, - }, []kexpect{ - {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/.ro-store", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store0"}, "/mnt-root/nix/.ro-store0", nil}, - }, nil, []kexpect{ - {"mkdirAll", expectArgs{"/nix/store", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"overlay", "/nix/store", "overlay", uintptr(0), "" + + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/.ro-store", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store0"}, "/mnt-root/nix/.ro-store0", nil}, + }, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/nix/store", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"overlay", "/nix/store", "overlay", uintptr(0), "" + "lowerdir=" + "/host/mnt-root/nix/.ro-store:" + "/host/mnt-root/nix/.ro-store0," + @@ -134,12 +136,12 @@ func TestMountOverlayOp(t *testing.T) { MustAbs("/mnt-root/nix/.ro-store"), MustAbs("/mnt-root/nix/.ro-store0"), }, - }, []kexpect{ - {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/.ro-store", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store0"}, "/mnt-root/nix/.ro-store0", nil}, - }, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/nix/store", os.FileMode(0755)}, nil, nil}, - {"mount", expectArgs{"overlay", "/sysroot/nix/store", "overlay", uintptr(0), "" + + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/.ro-store", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store0"}, "/mnt-root/nix/.ro-store0", nil}, + }, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/nix/store", os.FileMode(0755)}, nil, nil}, + {"mount", stub.ExpectArgs{"overlay", "/sysroot/nix/store", "overlay", uintptr(0), "" + "lowerdir=" + "/host/mnt-root/nix/.ro-store:" + "/host/mnt-root/nix/.ro-store0," + @@ -150,11 +152,11 @@ func TestMountOverlayOp(t *testing.T) { Target: MustAbs("/nix/store"), Upper: MustAbs("/mnt-root/nix/.rw-store/upper"), Work: MustAbs("/mnt-root/nix/.rw-store/work"), - }, []kexpect{ - {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil}, - }, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil}, + }, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil}, }, &OverlayArgumentError{OverlayEmptyLower, zeroString}}, {"evalSymlinks upper", &Params{ParentPerm: 0700}, &MountOverlayOp{ @@ -162,70 +164,70 @@ func TestMountOverlayOp(t *testing.T) { Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")}, Upper: MustAbs("/mnt-root/nix/.rw-store/upper"), Work: MustAbs("/mnt-root/nix/.rw-store/work"), - }, []kexpect{ - {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", errUnique}, - }, errUnique, nil, nil}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", stub.UniqueError(4)}, + }, stub.UniqueError(4), nil, nil}, {"evalSymlinks work", &Params{ParentPerm: 0700}, &MountOverlayOp{ Target: MustAbs("/nix/store"), Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")}, Upper: MustAbs("/mnt-root/nix/.rw-store/upper"), Work: MustAbs("/mnt-root/nix/.rw-store/work"), - }, []kexpect{ - {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", errUnique}, - }, errUnique, nil, nil}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", stub.UniqueError(3)}, + }, stub.UniqueError(3), nil, nil}, {"evalSymlinks lower", &Params{ParentPerm: 0700}, &MountOverlayOp{ Target: MustAbs("/nix/store"), Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")}, Upper: MustAbs("/mnt-root/nix/.rw-store/upper"), Work: MustAbs("/mnt-root/nix/.rw-store/work"), - }, []kexpect{ - {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", errUnique}, - }, errUnique, nil, nil}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", stub.UniqueError(2)}, + }, stub.UniqueError(2), nil, nil}, {"mkdirAll", &Params{ParentPerm: 0700}, &MountOverlayOp{ Target: MustAbs("/nix/store"), Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")}, Upper: MustAbs("/mnt-root/nix/.rw-store/upper"), Work: MustAbs("/mnt-root/nix/.rw-store/work"), - }, []kexpect{ - {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", nil}, - }, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, errUnique}, - }, errUnique}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", nil}, + }, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, stub.UniqueError(1)}, + }, stub.UniqueError(1)}, {"mount", &Params{ParentPerm: 0700}, &MountOverlayOp{ Target: MustAbs("/nix/store"), Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")}, Upper: MustAbs("/mnt-root/nix/.rw-store/upper"), Work: MustAbs("/mnt-root/nix/.rw-store/work"), - }, []kexpect{ - {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", nil}, - }, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil}, - {"mount", expectArgs{"overlay", "/sysroot/nix/store", "overlay", uintptr(0), "upperdir=/host/mnt-root/nix/.rw-store/.upper,workdir=/host/mnt-root/nix/.rw-store/.work,lowerdir=/host/mnt-root/nix/ro-store,userxattr"}, nil, errUnique}, - }, errUnique}, + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", nil}, + }, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil}, + {"mount", stub.ExpectArgs{"overlay", "/sysroot/nix/store", "overlay", uintptr(0), "upperdir=/host/mnt-root/nix/.rw-store/.upper,workdir=/host/mnt-root/nix/.rw-store/.work,lowerdir=/host/mnt-root/nix/ro-store,userxattr"}, nil, stub.UniqueError(0)}, + }, stub.UniqueError(0)}, {"success single layer", &Params{ParentPerm: 0700}, &MountOverlayOp{ Target: MustAbs("/nix/store"), Lower: []*Absolute{MustAbs("/mnt-root/nix/.ro-store")}, Upper: MustAbs("/mnt-root/nix/.rw-store/upper"), Work: MustAbs("/mnt-root/nix/.rw-store/work"), - }, []kexpect{ - {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", nil}, - }, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil}, - {"mount", expectArgs{"overlay", "/sysroot/nix/store", "overlay", uintptr(0), "" + + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", nil}, + }, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil}, + {"mount", stub.ExpectArgs{"overlay", "/sysroot/nix/store", "overlay", uintptr(0), "" + "upperdir=/host/mnt-root/nix/.rw-store/.upper," + "workdir=/host/mnt-root/nix/.rw-store/.work," + "lowerdir=/host/mnt-root/nix/ro-store," + @@ -243,17 +245,17 @@ func TestMountOverlayOp(t *testing.T) { }, Upper: MustAbs("/mnt-root/nix/.rw-store/upper"), Work: MustAbs("/mnt-root/nix/.rw-store/work"), - }, []kexpect{ - {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store0"}, "/mnt-root/nix/ro-store0", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store1"}, "/mnt-root/nix/ro-store1", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store2"}, "/mnt-root/nix/ro-store2", nil}, - {"evalSymlinks", expectArgs{"/mnt-root/nix/.ro-store3"}, "/mnt-root/nix/ro-store3", nil}, - }, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil}, - {"mount", expectArgs{"overlay", "/sysroot/nix/store", "overlay", uintptr(0), "" + + }, []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/upper"}, "/mnt-root/nix/.rw-store/.upper", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.rw-store/work"}, "/mnt-root/nix/.rw-store/.work", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store"}, "/mnt-root/nix/ro-store", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store0"}, "/mnt-root/nix/ro-store0", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store1"}, "/mnt-root/nix/ro-store1", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store2"}, "/mnt-root/nix/ro-store2", nil}, + {"evalSymlinks", stub.ExpectArgs{"/mnt-root/nix/.ro-store3"}, "/mnt-root/nix/ro-store3", nil}, + }, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/nix/store", os.FileMode(0700)}, nil, nil}, + {"mount", stub.ExpectArgs{"overlay", "/sysroot/nix/store", "overlay", uintptr(0), "" + "upperdir=/host/mnt-root/nix/.rw-store/.upper," + "workdir=/host/mnt-root/nix/.rw-store/.work," + "lowerdir=" + diff --git a/container/initplace_test.go b/container/initplace_test.go index 07402de..9970352 100644 --- a/container/initplace_test.go +++ b/container/initplace_test.go @@ -3,6 +3,8 @@ package container import ( "os" "testing" + + "hakurei.app/container/stub" ) func TestTmpfileOp(t *testing.T) { @@ -16,59 +18,59 @@ func TestTmpfileOp(t *testing.T) { {"createTemp", &Params{ParentPerm: 0700}, &TmpfileOp{ Path: samplePath, Data: sampleData, - }, nil, nil, []kexpect{ - {"createTemp", expectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), stub.UniqueError(5)}, + }, stub.UniqueError(5)}, {"Write", &Params{ParentPerm: 0700}, &TmpfileOp{ Path: samplePath, Data: sampleData, - }, nil, nil, []kexpect{ - {"createTemp", expectArgs{"/", "tmp.*"}, writeErrOsFile{errUnique}, nil}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"createTemp", stub.ExpectArgs{"/", "tmp.*"}, writeErrOsFile{stub.UniqueError(4)}, nil}, + }, stub.UniqueError(4)}, {"Close", &Params{ParentPerm: 0700}, &TmpfileOp{ Path: samplePath, Data: sampleData, - }, nil, nil, []kexpect{ - {"createTemp", expectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, errUnique), nil}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, stub.UniqueError(3)), nil}, + }, stub.UniqueError(3)}, {"ensureFile", &Params{ParentPerm: 0700}, &TmpfileOp{ Path: samplePath, Data: sampleData, - }, nil, nil, []kexpect{ - {"createTemp", expectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), nil}, - {"ensureFile", expectArgs{"/sysroot/etc/passwd", os.FileMode(0444), os.FileMode(0700)}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/etc/passwd", os.FileMode(0444), os.FileMode(0700)}, nil, stub.UniqueError(2)}, + }, stub.UniqueError(2)}, {"bindMount", &Params{ParentPerm: 0700}, &TmpfileOp{ Path: samplePath, Data: sampleData, - }, nil, nil, []kexpect{ - {"createTemp", expectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), nil}, - {"ensureFile", expectArgs{"/sysroot/etc/passwd", os.FileMode(0444), os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"tmp.32768", "/sysroot/etc/passwd", uintptr(0x5), false}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/etc/passwd", os.FileMode(0444), os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"tmp.32768", "/sysroot/etc/passwd", uintptr(0x5), false}, nil, stub.UniqueError(1)}, + }, stub.UniqueError(1)}, {"remove", &Params{ParentPerm: 0700}, &TmpfileOp{ Path: samplePath, Data: sampleData, - }, nil, nil, []kexpect{ - {"createTemp", expectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), nil}, - {"ensureFile", expectArgs{"/sysroot/etc/passwd", os.FileMode(0444), os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"tmp.32768", "/sysroot/etc/passwd", uintptr(0x5), false}, nil, nil}, - {"remove", expectArgs{"tmp.32768"}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/etc/passwd", os.FileMode(0444), os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"tmp.32768", "/sysroot/etc/passwd", uintptr(0x5), false}, nil, nil}, + {"remove", stub.ExpectArgs{"tmp.32768"}, nil, stub.UniqueError(0)}, + }, stub.UniqueError(0)}, {"success", &Params{ParentPerm: 0700}, &TmpfileOp{ Path: samplePath, Data: sampleData, - }, nil, nil, []kexpect{ - {"createTemp", expectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), nil}, - {"ensureFile", expectArgs{"/sysroot/etc/passwd", os.FileMode(0444), os.FileMode(0700)}, nil, nil}, - {"bindMount", expectArgs{"tmp.32768", "/sysroot/etc/passwd", uintptr(0x5), false}, nil, nil}, - {"remove", expectArgs{"tmp.32768"}, nil, nil}, + }, nil, nil, []stub.Call{ + {"createTemp", stub.ExpectArgs{"/", "tmp.*"}, newCheckedFile(t, "tmp.32768", sampleDataString, nil), nil}, + {"ensureFile", stub.ExpectArgs{"/sysroot/etc/passwd", os.FileMode(0444), os.FileMode(0700)}, nil, nil}, + {"bindMount", stub.ExpectArgs{"tmp.32768", "/sysroot/etc/passwd", uintptr(0x5), false}, nil, nil}, + {"remove", stub.ExpectArgs{"tmp.32768"}, nil, nil}, }, nil}, }) diff --git a/container/initproc_test.go b/container/initproc_test.go index ca90178..ee48e61 100644 --- a/container/initproc_test.go +++ b/container/initproc_test.go @@ -3,6 +3,8 @@ package container import ( "os" "testing" + + "hakurei.app/container/stub" ) func TestMountProcOp(t *testing.T) { @@ -10,16 +12,16 @@ func TestMountProcOp(t *testing.T) { {"mkdir", &Params{ParentPerm: 0755}, &MountProcOp{ Target: MustAbs("/proc/"), - }, nil, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0755)}, nil, stub.UniqueError(0)}, + }, stub.UniqueError(0)}, {"success", &Params{ParentPerm: 0700}, &MountProcOp{ Target: MustAbs("/proc/"), - }, nil, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/proc", os.FileMode(0700)}, nil, nil}, - {"mount", expectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, + }, nil, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/proc", os.FileMode(0700)}, nil, nil}, + {"mount", stub.ExpectArgs{"proc", "/sysroot/proc", "proc", uintptr(0xe), ""}, nil, nil}, }, nil}, }) diff --git a/container/initremount_test.go b/container/initremount_test.go index 22c978f..4fb60e1 100644 --- a/container/initremount_test.go +++ b/container/initremount_test.go @@ -3,6 +3,8 @@ package container import ( "syscall" "testing" + + "hakurei.app/container/stub" ) func TestRemountOp(t *testing.T) { @@ -10,8 +12,8 @@ func TestRemountOp(t *testing.T) { {"success", new(Params), &RemountOp{ Target: MustAbs("/"), Flags: syscall.MS_RDONLY, - }, nil, nil, []kexpect{ - {"remount", expectArgs{"/sysroot", uintptr(1)}, nil, nil}, + }, nil, nil, []stub.Call{ + {"remount", stub.ExpectArgs{"/sysroot", uintptr(1)}, nil, nil}, }, nil}, }) diff --git a/container/initsymlink_test.go b/container/initsymlink_test.go index db1c1a5..8e94ead 100644 --- a/container/initsymlink_test.go +++ b/container/initsymlink_test.go @@ -3,6 +3,8 @@ package container import ( "os" "testing" + + "hakurei.app/container/stub" ) func TestSymlinkOp(t *testing.T) { @@ -10,9 +12,9 @@ func TestSymlinkOp(t *testing.T) { {"mkdir", &Params{ParentPerm: 0700}, &SymlinkOp{ Target: MustAbs("/etc/nixos"), LinkName: "/etc/static/nixos", - }, nil, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/etc", os.FileMode(0700)}, nil, errUnique}, - }, errUnique}, + }, nil, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/etc", os.FileMode(0700)}, nil, stub.UniqueError(1)}, + }, stub.UniqueError(1)}, {"abs", &Params{ParentPerm: 0755}, &SymlinkOp{ Target: MustAbs("/etc/mtab"), @@ -24,27 +26,27 @@ func TestSymlinkOp(t *testing.T) { Target: MustAbs("/etc/mtab"), LinkName: "/etc/mtab", Dereference: true, - }, []kexpect{ - {"readlink", expectArgs{"/etc/mtab"}, "/proc/mounts", errUnique}, - }, errUnique, nil, nil}, + }, []stub.Call{ + {"readlink", stub.ExpectArgs{"/etc/mtab"}, "/proc/mounts", stub.UniqueError(0)}, + }, stub.UniqueError(0), nil, nil}, {"success noderef", &Params{ParentPerm: 0700}, &SymlinkOp{ Target: MustAbs("/etc/nixos"), LinkName: "/etc/static/nixos", - }, nil, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/etc", os.FileMode(0700)}, nil, nil}, - {"symlink", expectArgs{"/etc/static/nixos", "/sysroot/etc/nixos"}, nil, nil}, + }, nil, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/etc", os.FileMode(0700)}, nil, nil}, + {"symlink", stub.ExpectArgs{"/etc/static/nixos", "/sysroot/etc/nixos"}, nil, nil}, }, nil}, {"success", &Params{ParentPerm: 0755}, &SymlinkOp{ Target: MustAbs("/etc/mtab"), LinkName: "/etc/mtab", Dereference: true, - }, []kexpect{ - {"readlink", expectArgs{"/etc/mtab"}, "/proc/mounts", nil}, - }, nil, []kexpect{ - {"mkdirAll", expectArgs{"/sysroot/etc", os.FileMode(0755)}, nil, nil}, - {"symlink", expectArgs{"/proc/mounts", "/sysroot/etc/mtab"}, nil, nil}, + }, []stub.Call{ + {"readlink", stub.ExpectArgs{"/etc/mtab"}, "/proc/mounts", nil}, + }, nil, []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/etc", os.FileMode(0755)}, nil, nil}, + {"symlink", stub.ExpectArgs{"/proc/mounts", "/sysroot/etc/mtab"}, nil, nil}, }, nil}, }) diff --git a/container/inittmpfs_test.go b/container/inittmpfs_test.go index 97a591f..cbe7605 100644 --- a/container/inittmpfs_test.go +++ b/container/inittmpfs_test.go @@ -4,6 +4,8 @@ import ( "os" "syscall" "testing" + + "hakurei.app/container/stub" ) func TestMountTmpfsOp(t *testing.T) { @@ -25,8 +27,8 @@ func TestMountTmpfsOp(t *testing.T) { Path: MustAbs("/run/user/1000/"), Size: 1 << 10, Perm: 0700, - }, nil, nil, []kexpect{ - {"mountTmpfs", expectArgs{ + }, nil, nil, []stub.Call{ + {"mountTmpfs", stub.ExpectArgs{ "ephemeral", // fsname "/sysroot/run/user/1000", // target uintptr(0), // flags diff --git a/container/mount_test.go b/container/mount_test.go index 1d401d9..76eaad3 100644 --- a/container/mount_test.go +++ b/container/mount_test.go @@ -5,6 +5,7 @@ import ( "syscall" "testing" + "hakurei.app/container/stub" "hakurei.app/container/vfs" ) @@ -12,25 +13,25 @@ func TestBindMount(t *testing.T) { checkSimple(t, "bindMount", []simpleTestCase{ {"mount", func(k syscallDispatcher) error { return newProcPaths(k, hostPath).bindMount("/host/nix", "/sysroot/nix", syscall.MS_RDONLY, true) - }, [][]kexpect{{ - {"verbosef", expectArgs{"resolved %q flags %#x", []any{"/sysroot/nix", uintptr(1)}}, nil, nil}, - {"mount", expectArgs{"/host/nix", "/sysroot/nix", "", uintptr(0x9000), ""}, nil, errUnique}, - }}, errUnique}, + }, stub.Expect{Calls: []stub.Call{ + {"verbosef", stub.ExpectArgs{"resolved %q flags %#x", []any{"/sysroot/nix", uintptr(1)}}, nil, nil}, + {"mount", stub.ExpectArgs{"/host/nix", "/sysroot/nix", "", uintptr(0x9000), ""}, nil, stub.UniqueError(0xbad)}, + }}, stub.UniqueError(0xbad)}, {"success ne", func(k syscallDispatcher) error { return newProcPaths(k, hostPath).bindMount("/host/nix", "/sysroot/.host-nix", syscall.MS_RDONLY, false) - }, [][]kexpect{{ - {"verbosef", expectArgs{"resolved %q on %q flags %#x", []any{"/host/nix", "/sysroot/.host-nix", uintptr(1)}}, nil, nil}, - {"mount", expectArgs{"/host/nix", "/sysroot/.host-nix", "", uintptr(0x9000), ""}, nil, nil}, - {"remount", expectArgs{"/sysroot/.host-nix", uintptr(1)}, nil, nil}, + }, stub.Expect{Calls: []stub.Call{ + {"verbosef", stub.ExpectArgs{"resolved %q on %q flags %#x", []any{"/host/nix", "/sysroot/.host-nix", uintptr(1)}}, nil, nil}, + {"mount", stub.ExpectArgs{"/host/nix", "/sysroot/.host-nix", "", uintptr(0x9000), ""}, nil, nil}, + {"remount", stub.ExpectArgs{"/sysroot/.host-nix", uintptr(1)}, nil, nil}, }}, nil}, {"success", func(k syscallDispatcher) error { return newProcPaths(k, hostPath).bindMount("/host/nix", "/sysroot/nix", syscall.MS_RDONLY, true) - }, [][]kexpect{{ - {"verbosef", expectArgs{"resolved %q flags %#x", []any{"/sysroot/nix", uintptr(1)}}, nil, nil}, - {"mount", expectArgs{"/host/nix", "/sysroot/nix", "", uintptr(0x9000), ""}, nil, nil}, - {"remount", expectArgs{"/sysroot/nix", uintptr(1)}, nil, nil}, + }, stub.Expect{Calls: []stub.Call{ + {"verbosef", stub.ExpectArgs{"resolved %q flags %#x", []any{"/sysroot/nix", uintptr(1)}}, nil, nil}, + {"mount", stub.ExpectArgs{"/host/nix", "/sysroot/nix", "", uintptr(0x9000), ""}, nil, nil}, + {"remount", stub.ExpectArgs{"/sysroot/nix", uintptr(1)}, nil, nil}, }}, nil}, }) } @@ -81,138 +82,138 @@ func TestRemount(t *testing.T) { checkSimple(t, "remount", []simpleTestCase{ {"evalSymlinks", func(k syscallDispatcher) error { return newProcPaths(k, hostPath).remount("/sysroot/nix", syscall.MS_REC|syscall.MS_RDONLY|syscall.MS_NODEV) - }, [][]kexpect{{ - {"evalSymlinks", expectArgs{"/sysroot/nix"}, "/sysroot/nix", errUnique}, - }}, errUnique}, + }, stub.Expect{Calls: []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/sysroot/nix"}, "/sysroot/nix", stub.UniqueError(6)}, + }}, stub.UniqueError(6)}, {"open", func(k syscallDispatcher) error { return newProcPaths(k, hostPath).remount("/sysroot/nix", syscall.MS_REC|syscall.MS_RDONLY|syscall.MS_NODEV) - }, [][]kexpect{{ - {"evalSymlinks", expectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, - {"open", expectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, errUnique}, - }}, &os.PathError{Op: "open", Path: "/sysroot/nix", Err: errUnique}}, + }, stub.Expect{Calls: []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, + {"open", stub.ExpectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, stub.UniqueError(5)}, + }}, &os.PathError{Op: "open", Path: "/sysroot/nix", Err: stub.UniqueError(5)}}, {"readlink", func(k syscallDispatcher) error { return newProcPaths(k, hostPath).remount("/sysroot/nix", syscall.MS_REC|syscall.MS_RDONLY|syscall.MS_NODEV) - }, [][]kexpect{{ - {"evalSymlinks", expectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, - {"open", expectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", errUnique}, - }}, errUnique}, + }, stub.Expect{Calls: []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, + {"open", stub.ExpectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", stub.UniqueError(4)}, + }}, stub.UniqueError(4)}, {"close", func(k syscallDispatcher) error { return newProcPaths(k, hostPath).remount("/sysroot/nix", syscall.MS_REC|syscall.MS_RDONLY|syscall.MS_NODEV) - }, [][]kexpect{{ - {"evalSymlinks", expectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, - {"open", expectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", nil}, - {"close", expectArgs{0xdeadbeef}, nil, errUnique}, - }}, &os.PathError{Op: "close", Path: "/sysroot/nix", Err: errUnique}}, + }, stub.Expect{Calls: []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, + {"open", stub.ExpectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", nil}, + {"close", stub.ExpectArgs{0xdeadbeef}, nil, stub.UniqueError(3)}, + }}, &os.PathError{Op: "close", Path: "/sysroot/nix", Err: stub.UniqueError(3)}}, {"mountinfo no match", func(k syscallDispatcher) error { return newProcPaths(k, hostPath).remount("/sysroot/nix", syscall.MS_REC|syscall.MS_RDONLY|syscall.MS_NODEV) - }, [][]kexpect{{ - {"evalSymlinks", expectArgs{"/sysroot/nix"}, "/sysroot/.hakurei", nil}, - {"verbosef", expectArgs{"target resolves to %q", []any{"/sysroot/.hakurei"}}, nil, nil}, - {"open", expectArgs{"/sysroot/.hakurei", 0x280000, uint32(0)}, 0xdeadbeef, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/.hakurei", nil}, - {"close", expectArgs{0xdeadbeef}, nil, nil}, - {"openNew", expectArgs{"/host/proc/self/mountinfo"}, newConstFile(sampleMountinfoNix), nil}, + }, stub.Expect{Calls: []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/sysroot/nix"}, "/sysroot/.hakurei", nil}, + {"verbosef", stub.ExpectArgs{"target resolves to %q", []any{"/sysroot/.hakurei"}}, nil, nil}, + {"open", stub.ExpectArgs{"/sysroot/.hakurei", 0x280000, uint32(0)}, 0xdeadbeef, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/.hakurei", nil}, + {"close", stub.ExpectArgs{0xdeadbeef}, nil, nil}, + {"openNew", stub.ExpectArgs{"/host/proc/self/mountinfo"}, newConstFile(sampleMountinfoNix), nil}, }}, &vfs.DecoderError{Op: "unfold", Line: -1, Err: vfs.UnfoldTargetError("/sysroot/.hakurei")}}, {"mountinfo", func(k syscallDispatcher) error { return newProcPaths(k, hostPath).remount("/sysroot/nix", syscall.MS_REC|syscall.MS_RDONLY|syscall.MS_NODEV) - }, [][]kexpect{{ - {"evalSymlinks", expectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, - {"open", expectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", nil}, - {"close", expectArgs{0xdeadbeef}, nil, nil}, - {"openNew", expectArgs{"/host/proc/self/mountinfo"}, newConstFile("\x00"), nil}, + }, stub.Expect{Calls: []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, + {"open", stub.ExpectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", nil}, + {"close", stub.ExpectArgs{0xdeadbeef}, nil, nil}, + {"openNew", stub.ExpectArgs{"/host/proc/self/mountinfo"}, newConstFile("\x00"), nil}, }}, &vfs.DecoderError{Op: "parse", Line: 0, Err: vfs.ErrMountInfoFields}}, {"mount", func(k syscallDispatcher) error { return newProcPaths(k, hostPath).remount("/sysroot/nix", syscall.MS_REC|syscall.MS_RDONLY|syscall.MS_NODEV) - }, [][]kexpect{{ - {"evalSymlinks", expectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, - {"open", expectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", nil}, - {"close", expectArgs{0xdeadbeef}, nil, nil}, - {"openNew", expectArgs{"/host/proc/self/mountinfo"}, newConstFile(sampleMountinfoNix), nil}, - {"mount", expectArgs{"none", "/sysroot/nix", "", uintptr(0x209027), ""}, nil, errUnique}, - }}, errUnique}, + }, stub.Expect{Calls: []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, + {"open", stub.ExpectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", nil}, + {"close", stub.ExpectArgs{0xdeadbeef}, nil, nil}, + {"openNew", stub.ExpectArgs{"/host/proc/self/mountinfo"}, newConstFile(sampleMountinfoNix), nil}, + {"mount", stub.ExpectArgs{"none", "/sysroot/nix", "", uintptr(0x209027), ""}, nil, stub.UniqueError(2)}, + }}, stub.UniqueError(2)}, {"mount propagate", func(k syscallDispatcher) error { return newProcPaths(k, hostPath).remount("/sysroot/nix", syscall.MS_REC|syscall.MS_RDONLY|syscall.MS_NODEV) - }, [][]kexpect{{ - {"evalSymlinks", expectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, - {"open", expectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", nil}, - {"close", expectArgs{0xdeadbeef}, nil, nil}, - {"openNew", expectArgs{"/host/proc/self/mountinfo"}, newConstFile(sampleMountinfoNix), nil}, - {"mount", expectArgs{"none", "/sysroot/nix", "", uintptr(0x209027), ""}, nil, nil}, - {"mount", expectArgs{"none", "/sysroot/nix/.ro-store", "", uintptr(0x209027), ""}, nil, errUnique}, - }}, errUnique}, + }, stub.Expect{Calls: []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, + {"open", stub.ExpectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", nil}, + {"close", stub.ExpectArgs{0xdeadbeef}, nil, nil}, + {"openNew", stub.ExpectArgs{"/host/proc/self/mountinfo"}, newConstFile(sampleMountinfoNix), nil}, + {"mount", stub.ExpectArgs{"none", "/sysroot/nix", "", uintptr(0x209027), ""}, nil, nil}, + {"mount", stub.ExpectArgs{"none", "/sysroot/nix/.ro-store", "", uintptr(0x209027), ""}, nil, stub.UniqueError(1)}, + }}, stub.UniqueError(1)}, {"success toplevel", func(k syscallDispatcher) error { return newProcPaths(k, hostPath).remount("/sysroot/bin", syscall.MS_REC|syscall.MS_RDONLY|syscall.MS_NODEV) - }, [][]kexpect{{ - {"evalSymlinks", expectArgs{"/sysroot/bin"}, "/sysroot/bin", nil}, - {"open", expectArgs{"/sysroot/bin", 0x280000, uint32(0)}, 0xbabe, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/47806"}, "/sysroot/bin", nil}, - {"close", expectArgs{0xbabe}, nil, nil}, - {"openNew", expectArgs{"/host/proc/self/mountinfo"}, newConstFile(sampleMountinfoNix), nil}, - {"mount", expectArgs{"none", "/sysroot/bin", "", uintptr(0x209027), ""}, nil, nil}, + }, stub.Expect{Calls: []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/sysroot/bin"}, "/sysroot/bin", nil}, + {"open", stub.ExpectArgs{"/sysroot/bin", 0x280000, uint32(0)}, 0xbabe, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/47806"}, "/sysroot/bin", nil}, + {"close", stub.ExpectArgs{0xbabe}, nil, nil}, + {"openNew", stub.ExpectArgs{"/host/proc/self/mountinfo"}, newConstFile(sampleMountinfoNix), nil}, + {"mount", stub.ExpectArgs{"none", "/sysroot/bin", "", uintptr(0x209027), ""}, nil, nil}, }}, nil}, {"success EACCES", func(k syscallDispatcher) error { return newProcPaths(k, hostPath).remount("/sysroot/nix", syscall.MS_REC|syscall.MS_RDONLY|syscall.MS_NODEV) - }, [][]kexpect{{ - {"evalSymlinks", expectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, - {"open", expectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", nil}, - {"close", expectArgs{0xdeadbeef}, nil, nil}, - {"openNew", expectArgs{"/host/proc/self/mountinfo"}, newConstFile(sampleMountinfoNix), nil}, - {"mount", expectArgs{"none", "/sysroot/nix", "", uintptr(0x209027), ""}, nil, nil}, - {"mount", expectArgs{"none", "/sysroot/nix/.ro-store", "", uintptr(0x209027), ""}, nil, syscall.EACCES}, - {"mount", expectArgs{"none", "/sysroot/nix/store", "", uintptr(0x209027), ""}, nil, nil}, + }, stub.Expect{Calls: []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, + {"open", stub.ExpectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", nil}, + {"close", stub.ExpectArgs{0xdeadbeef}, nil, nil}, + {"openNew", stub.ExpectArgs{"/host/proc/self/mountinfo"}, newConstFile(sampleMountinfoNix), nil}, + {"mount", stub.ExpectArgs{"none", "/sysroot/nix", "", uintptr(0x209027), ""}, nil, nil}, + {"mount", stub.ExpectArgs{"none", "/sysroot/nix/.ro-store", "", uintptr(0x209027), ""}, nil, syscall.EACCES}, + {"mount", stub.ExpectArgs{"none", "/sysroot/nix/store", "", uintptr(0x209027), ""}, nil, nil}, }}, nil}, {"success no propagate", func(k syscallDispatcher) error { return newProcPaths(k, hostPath).remount("/sysroot/nix", syscall.MS_RDONLY|syscall.MS_NODEV) - }, [][]kexpect{{ - {"evalSymlinks", expectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, - {"open", expectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", nil}, - {"close", expectArgs{0xdeadbeef}, nil, nil}, - {"openNew", expectArgs{"/host/proc/self/mountinfo"}, newConstFile(sampleMountinfoNix), nil}, - {"mount", expectArgs{"none", "/sysroot/nix", "", uintptr(0x209027), ""}, nil, nil}, + }, stub.Expect{Calls: []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, + {"open", stub.ExpectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", nil}, + {"close", stub.ExpectArgs{0xdeadbeef}, nil, nil}, + {"openNew", stub.ExpectArgs{"/host/proc/self/mountinfo"}, newConstFile(sampleMountinfoNix), nil}, + {"mount", stub.ExpectArgs{"none", "/sysroot/nix", "", uintptr(0x209027), ""}, nil, nil}, }}, nil}, {"success case sensitive", func(k syscallDispatcher) error { return newProcPaths(k, hostPath).remount("/sysroot/nix", syscall.MS_REC|syscall.MS_RDONLY|syscall.MS_NODEV) - }, [][]kexpect{{ - {"evalSymlinks", expectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, - {"open", expectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", nil}, - {"close", expectArgs{0xdeadbeef}, nil, nil}, - {"openNew", expectArgs{"/host/proc/self/mountinfo"}, newConstFile(sampleMountinfoNix), nil}, - {"mount", expectArgs{"none", "/sysroot/nix", "", uintptr(0x209027), ""}, nil, nil}, - {"mount", expectArgs{"none", "/sysroot/nix/.ro-store", "", uintptr(0x209027), ""}, nil, nil}, - {"mount", expectArgs{"none", "/sysroot/nix/store", "", uintptr(0x209027), ""}, nil, nil}, + }, stub.Expect{Calls: []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/sysroot/nix"}, "/sysroot/nix", nil}, + {"open", stub.ExpectArgs{"/sysroot/nix", 0x280000, uint32(0)}, 0xdeadbeef, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", nil}, + {"close", stub.ExpectArgs{0xdeadbeef}, nil, nil}, + {"openNew", stub.ExpectArgs{"/host/proc/self/mountinfo"}, newConstFile(sampleMountinfoNix), nil}, + {"mount", stub.ExpectArgs{"none", "/sysroot/nix", "", uintptr(0x209027), ""}, nil, nil}, + {"mount", stub.ExpectArgs{"none", "/sysroot/nix/.ro-store", "", uintptr(0x209027), ""}, nil, nil}, + {"mount", stub.ExpectArgs{"none", "/sysroot/nix/store", "", uintptr(0x209027), ""}, nil, nil}, }}, nil}, {"success", func(k syscallDispatcher) error { return newProcPaths(k, hostPath).remount("/sysroot/.nix", syscall.MS_REC|syscall.MS_RDONLY|syscall.MS_NODEV) - }, [][]kexpect{{ - {"evalSymlinks", expectArgs{"/sysroot/.nix"}, "/sysroot/NIX", nil}, - {"verbosef", expectArgs{"target resolves to %q", []any{"/sysroot/NIX"}}, nil, nil}, - {"open", expectArgs{"/sysroot/NIX", 0x280000, uint32(0)}, 0xdeadbeef, nil}, - {"readlink", expectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", nil}, - {"close", expectArgs{0xdeadbeef}, nil, nil}, - {"openNew", expectArgs{"/host/proc/self/mountinfo"}, newConstFile(sampleMountinfoNix), nil}, - {"mount", expectArgs{"none", "/sysroot/nix", "", uintptr(0x209027), ""}, nil, nil}, - {"mount", expectArgs{"none", "/sysroot/nix/.ro-store", "", uintptr(0x209027), ""}, nil, nil}, - {"mount", expectArgs{"none", "/sysroot/nix/store", "", uintptr(0x209027), ""}, nil, nil}, + }, stub.Expect{Calls: []stub.Call{ + {"evalSymlinks", stub.ExpectArgs{"/sysroot/.nix"}, "/sysroot/NIX", nil}, + {"verbosef", stub.ExpectArgs{"target resolves to %q", []any{"/sysroot/NIX"}}, nil, nil}, + {"open", stub.ExpectArgs{"/sysroot/NIX", 0x280000, uint32(0)}, 0xdeadbeef, nil}, + {"readlink", stub.ExpectArgs{"/host/proc/self/fd/3735928559"}, "/sysroot/nix", nil}, + {"close", stub.ExpectArgs{0xdeadbeef}, nil, nil}, + {"openNew", stub.ExpectArgs{"/host/proc/self/mountinfo"}, newConstFile(sampleMountinfoNix), nil}, + {"mount", stub.ExpectArgs{"none", "/sysroot/nix", "", uintptr(0x209027), ""}, nil, nil}, + {"mount", stub.ExpectArgs{"none", "/sysroot/nix/.ro-store", "", uintptr(0x209027), ""}, nil, nil}, + {"mount", stub.ExpectArgs{"none", "/sysroot/nix/store", "", uintptr(0x209027), ""}, nil, nil}, }}, nil}, }) } @@ -221,18 +222,18 @@ func TestRemountWithFlags(t *testing.T) { checkSimple(t, "remountWithFlags", []simpleTestCase{ {"noop unmatched", func(k syscallDispatcher) error { return remountWithFlags(k, &vfs.MountInfoNode{MountInfoEntry: &vfs.MountInfoEntry{VfsOptstr: "rw,relatime,cat"}}, 0) - }, [][]kexpect{{ - {"verbosef", expectArgs{"unmatched vfs options: %q", []any{[]string{"cat"}}}, nil, nil}, + }, stub.Expect{Calls: []stub.Call{ + {"verbosef", stub.ExpectArgs{"unmatched vfs options: %q", []any{[]string{"cat"}}}, nil, nil}, }}, nil}, {"noop", func(k syscallDispatcher) error { return remountWithFlags(k, &vfs.MountInfoNode{MountInfoEntry: &vfs.MountInfoEntry{VfsOptstr: "rw,relatime"}}, 0) - }, nil, nil}, + }, stub.Expect{}, nil}, {"success", func(k syscallDispatcher) error { return remountWithFlags(k, &vfs.MountInfoNode{MountInfoEntry: &vfs.MountInfoEntry{VfsOptstr: "rw,relatime"}}, syscall.MS_RDONLY) - }, [][]kexpect{{ - {"mount", expectArgs{"none", "", "", uintptr(0x209021), ""}, nil, nil}, + }, stub.Expect{Calls: []stub.Call{ + {"mount", stub.ExpectArgs{"none", "", "", uintptr(0x209021), ""}, nil, nil}, }}, nil}, }) } @@ -241,22 +242,22 @@ func TestMountTmpfs(t *testing.T) { checkSimple(t, "mountTmpfs", []simpleTestCase{ {"mkdirAll", func(k syscallDispatcher) error { return mountTmpfs(k, "ephemeral", "/sysroot/run/user/1000", 0, 1<<10, 0700) - }, [][]kexpect{{ - {"mkdirAll", expectArgs{"/sysroot/run/user/1000", os.FileMode(0700)}, nil, errUnique}, - }}, errUnique}, + }, stub.Expect{Calls: []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/run/user/1000", os.FileMode(0700)}, nil, stub.UniqueError(0)}, + }}, stub.UniqueError(0)}, {"success no size", func(k syscallDispatcher) error { return mountTmpfs(k, "ephemeral", "/sysroot/run/user/1000", 0, 0, 0710) - }, [][]kexpect{{ - {"mkdirAll", expectArgs{"/sysroot/run/user/1000", os.FileMode(0750)}, nil, nil}, - {"mount", expectArgs{"ephemeral", "/sysroot/run/user/1000", "tmpfs", uintptr(0), "mode=0710"}, nil, nil}, + }, stub.Expect{Calls: []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/run/user/1000", os.FileMode(0750)}, nil, nil}, + {"mount", stub.ExpectArgs{"ephemeral", "/sysroot/run/user/1000", "tmpfs", uintptr(0), "mode=0710"}, nil, nil}, }}, nil}, {"success", func(k syscallDispatcher) error { return mountTmpfs(k, "ephemeral", "/sysroot/run/user/1000", 0, 1<<10, 0700) - }, [][]kexpect{{ - {"mkdirAll", expectArgs{"/sysroot/run/user/1000", os.FileMode(0700)}, nil, nil}, - {"mount", expectArgs{"ephemeral", "/sysroot/run/user/1000", "tmpfs", uintptr(0), "mode=0700,size=1024"}, nil, nil}, + }, stub.Expect{Calls: []stub.Call{ + {"mkdirAll", stub.ExpectArgs{"/sysroot/run/user/1000", os.FileMode(0700)}, nil, nil}, + {"mount", stub.ExpectArgs{"ephemeral", "/sysroot/run/user/1000", "tmpfs", uintptr(0), "mode=0700,size=1024"}, nil, nil}, }}, nil}, }) } diff --git a/container/stub/call.go b/container/stub/call.go new file mode 100644 index 0000000..585a69e --- /dev/null +++ b/container/stub/call.go @@ -0,0 +1,37 @@ +package stub + +import ( + "slices" +) + +// ExpectArgs is an array primarily for storing expected function arguments. +// Its actual use is defined by the implementation. +type ExpectArgs = [5]any + +// An Expect stores expected calls of a goroutine. +type Expect struct { + Calls []Call + + // Tracks are handed out to descendant goroutines in order. + Tracks []Expect +} + +// A Call holds expected arguments of a function call and its outcome. +type Call struct { + // Name is the function Name of this call. Must be unique. + Name string + // Args are the expected arguments of this Call. + Args ExpectArgs + // Ret is the return value of this Call. + Ret any + // Err is the returned error of this Call. + Err error +} + +// Error returns [Call.Err] if all arguments are true, or [ErrCheck] otherwise. +func (k *Call) Error(ok ...bool) error { + if !slices.Contains(ok, false) { + return k.Err + } + return ErrCheck +} diff --git a/container/stub/call_test.go b/container/stub/call_test.go new file mode 100644 index 0000000..6718798 --- /dev/null +++ b/container/stub/call_test.go @@ -0,0 +1,23 @@ +package stub_test + +import ( + "reflect" + "testing" + + "hakurei.app/container/stub" +) + +func TestCallError(t *testing.T) { + t.Run("contains false", func(t *testing.T) { + if err := new(stub.Call).Error(true, false, true); !reflect.DeepEqual(err, stub.ErrCheck) { + t.Errorf("Error: %#v, want %#v", err, stub.ErrCheck) + } + }) + + t.Run("passthrough", func(t *testing.T) { + wantErr := stub.UniqueError(0xbabe) + if err := (&stub.Call{Err: wantErr}).Error(true); !reflect.DeepEqual(err, wantErr) { + t.Errorf("Error: %#v, want %#v", err, wantErr) + } + }) +} diff --git a/container/stub/errors.go b/container/stub/errors.go new file mode 100644 index 0000000..4d13a67 --- /dev/null +++ b/container/stub/errors.go @@ -0,0 +1,25 @@ +package stub + +import ( + "errors" + "strconv" +) + +var ( + ErrCheck = errors.New("one or more arguments did not match") +) + +// UniqueError is an error that only equivalates to other [UniqueError] with the same magic value. +type UniqueError uintptr + +func (e UniqueError) Error() string { + return "unique error " + strconv.Itoa(int(e)) + " injected by the test suite" +} + +func (e UniqueError) Is(target error) bool { + var u UniqueError + if !errors.As(target, &u) { + return false + } + return e == u +} diff --git a/container/stub/errors_test.go b/container/stub/errors_test.go new file mode 100644 index 0000000..4d9252d --- /dev/null +++ b/container/stub/errors_test.go @@ -0,0 +1,35 @@ +package stub_test + +import ( + "errors" + "syscall" + "testing" + + "hakurei.app/container/stub" +) + +func TestUniqueError(t *testing.T) { + t.Run("format", func(t *testing.T) { + want := "unique error 2989 injected by the test suite" + if got := stub.UniqueError(0xbad).Error(); got != want { + t.Errorf("Error: %q, want %q", got, want) + } + }) + + t.Run("is", func(t *testing.T) { + t.Run("type", func(t *testing.T) { + if errors.Is(stub.UniqueError(0), syscall.ENOTRECOVERABLE) { + t.Error("Is: unexpected true") + } + }) + + t.Run("val", func(t *testing.T) { + if errors.Is(stub.UniqueError(0), stub.UniqueError(1)) { + t.Error("Is: unexpected true") + } + if !errors.Is(stub.UniqueError(0xbad), stub.UniqueError(0xbad)) { + t.Error("Is: unexpected false") + } + }) + }) +} diff --git a/container/stub/exit.go b/container/stub/exit.go new file mode 100644 index 0000000..8d85946 --- /dev/null +++ b/container/stub/exit.go @@ -0,0 +1,15 @@ +package stub + +// PanicExit is a magic panic value treated as a simulated exit. +const PanicExit = 0xdeadbeef + +// HandleExit must be deferred before calling with the stub. +func HandleExit() { + r := recover() + if r == PanicExit { + return + } + if r != nil { + panic(r) + } +} diff --git a/container/stub/exit_test.go b/container/stub/exit_test.go new file mode 100644 index 0000000..5021971 --- /dev/null +++ b/container/stub/exit_test.go @@ -0,0 +1,30 @@ +package stub_test + +import ( + "testing" + + "hakurei.app/container/stub" +) + +func TestHandleExit(t *testing.T) { + t.Run("exit", func(t *testing.T) { + defer stub.HandleExit() + panic(stub.PanicExit) + }) + + t.Run("nil", func(t *testing.T) { + defer stub.HandleExit() + }) + + t.Run("passthrough", func(t *testing.T) { + defer func() { + want := 0xcafebabe + if r := recover(); r != want { + t.Errorf("recover: %v, want %v", r, want) + } + + }() + defer stub.HandleExit() + panic(0xcafebabe) + }) +} diff --git a/container/stub/stub.go b/container/stub/stub.go new file mode 100644 index 0000000..942a339 --- /dev/null +++ b/container/stub/stub.go @@ -0,0 +1,141 @@ +// Package stub provides function call level stubbing and validation +// for library functions that are impossible to check otherwise. +package stub + +import ( + "reflect" + "sync" + "testing" +) + +// this should prevent stub from being inadvertently imported outside tests +var _ = func() { + if !testing.Testing() { + panic("stub imported while not in a test") + } +} + +const ( + // A CallSeparator denotes an injected separation between two groups of calls. + CallSeparator = "\x00" +) + +// A Stub is a collection of tracks of expected calls. +type Stub[K any] struct { + testing.TB + + // makeK creates a new K for a descendant [Stub]. + // This function may be called concurrently. + makeK func(s *Stub[K]) K + + // want is a hierarchy of expected calls. + want Expect + // pos is the current position in [Expect.Calls]. + pos int + // goroutine counts the number of goroutines created by this [Stub]. + goroutine int + // sub stores the addresses of descendant [Stub] created by New. + sub []*Stub[K] + // wg waits for all descendants to complete. + wg *sync.WaitGroup +} + +// New creates a root [Stub]. +func New[K any](tb testing.TB, makeK func(s *Stub[K]) K, want Expect) *Stub[K] { + return &Stub[K]{TB: tb, makeK: makeK, want: want, wg: new(sync.WaitGroup)} +} + +// New calls f in a new goroutine +func (s *Stub[K]) New(f func(k K)) { + s.Helper() + + s.Expects("New") + if len(s.want.Tracks) <= s.goroutine { + s.Fatal("New: track overrun") + } + ds := &Stub[K]{TB: s.TB, makeK: s.makeK, want: s.want.Tracks[s.goroutine], wg: s.wg} + s.goroutine++ + s.sub = append(s.sub, ds) + s.wg.Add(1) + go func() { + s.Helper() + + defer s.wg.Done() + defer HandleExit() + f(s.makeK(ds)) + }() +} + +// Pos returns the current position of [Stub] in its [Expect.Calls] +func (s *Stub[K]) Pos() int { return s.pos } + +// Len returns the length of [Expect.Calls]. +func (s *Stub[K]) Len() int { return len(s.want.Calls) } + +// VisitIncomplete calls f on an incomplete s and all its descendants. +func (s *Stub[K]) VisitIncomplete(f func(s *Stub[K])) { + s.Helper() + s.wg.Wait() + + if s.want.Calls != nil && len(s.want.Calls) != s.pos { + f(s) + } + for _, ds := range s.sub { + ds.VisitIncomplete(f) + } +} + +// Expects checks the name of and returns the current [Call] and advances pos. +func (s *Stub[K]) Expects(name string) (expect *Call) { + s.Helper() + + if len(s.want.Calls) == s.pos { + s.Fatal("Expects: advancing beyond expected calls") + } + expect = &s.want.Calls[s.pos] + if name != expect.Name { + if expect.Name == CallSeparator { + s.Fatalf("Expects: func = %s, separator overrun", name) + } + if name == CallSeparator { + s.Fatalf("Expects: separator, want %s", expect.Name) + } + s.Fatalf("Expects: func = %s, want %s", name, expect.Name) + } + s.pos++ + return +} + +// CheckArg checks an argument comparable with the == operator. Avoid using this with pointers. +func CheckArg[T comparable, K any](s *Stub[K], arg string, got T, n int) bool { + s.Helper() + + pos := s.pos - 1 + if pos < 0 || pos >= len(s.want.Calls) { + panic("invalid call to CheckArg") + } + expect := s.want.Calls[pos] + want, ok := expect.Args[n].(T) + if !ok || got != want { + s.Errorf("%s: %s = %#v, want %#v (%d)", expect.Name, arg, got, want, pos) + return false + } + return true +} + +// CheckArgReflect checks an argument of any type. +func CheckArgReflect[K any](s *Stub[K], arg string, got any, n int) bool { + s.Helper() + + pos := s.pos - 1 + if pos < 0 || pos >= len(s.want.Calls) { + panic("invalid call to CheckArgReflect") + } + expect := s.want.Calls[pos] + want := expect.Args[n] + if !reflect.DeepEqual(got, want) { + s.Errorf("%s: %s = %#v, want %#v (%d)", expect.Name, arg, got, want, pos) + return false + } + return true +} diff --git a/container/stub/stub_test.go b/container/stub/stub_test.go new file mode 100644 index 0000000..3333ce7 --- /dev/null +++ b/container/stub/stub_test.go @@ -0,0 +1,265 @@ +package stub + +import ( + "reflect" + "sync/atomic" + "testing" +) + +// stubHolder embeds [Stub]. +type stubHolder struct{ *Stub[stubHolder] } + +// overrideT allows some methods of [testing.T] to be overridden. +type overrideT struct { + *testing.T + + fatal atomic.Pointer[func(args ...any)] + fatalf atomic.Pointer[func(format string, args ...any)] + errorf atomic.Pointer[func(format string, args ...any)] +} + +func (t *overrideT) Fatal(args ...any) { + fp := t.fatal.Load() + if fp == nil || *fp == nil { + t.T.Fatal(args...) + return + } + (*fp)(args...) +} + +func (t *overrideT) Fatalf(format string, args ...any) { + fp := t.fatalf.Load() + if fp == nil || *fp == nil { + t.T.Fatalf(format, args...) + return + } + (*fp)(format, args...) +} + +func (t *overrideT) Errorf(format string, args ...any) { + fp := t.errorf.Load() + if fp == nil || *fp == nil { + t.T.Errorf(format, args...) + return + } + (*fp)(format, args...) +} + +func TestStub(t *testing.T) { + t.Run("new", func(t *testing.T) { + t.Run("success", func(t *testing.T) { + s := New(t, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{ + {"New", ExpectArgs{}, nil, nil}, + }, Tracks: []Expect{{Calls: []Call{ + {"done", ExpectArgs{0xbabe}, nil, nil}, + }}}}) + + s.New(func(k stubHolder) { + expect := k.Expects("done") + if expect.Name != "done" { + t.Errorf("New: Name = %s, want done", expect.Name) + } + if expect.Args != (ExpectArgs{0xbabe}) { + t.Errorf("New: Args = %#v", expect.Args) + } + if expect.Ret != nil { + t.Errorf("New: Ret = %#v", expect.Ret) + } + if expect.Err != nil { + t.Errorf("New: Err = %#v", expect.Err) + } + }) + + if pos := s.Pos(); pos != 1 { + t.Errorf("Pos: %d, want 1", pos) + } + if l := s.Len(); l != 1 { + t.Errorf("Len: %d, want 1", l) + } + + s.VisitIncomplete(func(s *Stub[stubHolder]) { panic("unreachable") }) + }) + + t.Run("overrun", func(t *testing.T) { + ot := &overrideT{T: t} + ot.fatal.Store(checkFatal(t, "New: track overrun")) + s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{ + {"New", ExpectArgs{}, nil, nil}, + {"panic", ExpectArgs{"unreachable"}, nil, nil}, + }}) + func() { defer HandleExit(); s.New(func(k stubHolder) { panic("unreachable") }) }() + + var visit int + s.VisitIncomplete(func(s *Stub[stubHolder]) { + visit++ + if visit > 1 { + panic("unexpected visit count") + } + + want := Call{"panic", ExpectArgs{"unreachable"}, nil, nil} + if got := s.want.Calls[s.pos]; !reflect.DeepEqual(got, want) { + t.Errorf("VisitIncomplete: %#v, want %#v", got, want) + } + }) + }) + + t.Run("expects", func(t *testing.T) { + t.Run("overrun", func(t *testing.T) { + ot := &overrideT{T: t} + ot.fatal.Store(checkFatal(t, "Expects: advancing beyond expected calls")) + s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{}) + func() { defer HandleExit(); s.Expects("unreachable") }() + }) + + t.Run("separator", func(t *testing.T) { + t.Run("overrun", func(t *testing.T) { + ot := &overrideT{T: t} + ot.fatalf.Store(checkFatalf(t, "Expects: func = %s, separator overrun", "meow")) + s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{ + {CallSeparator, ExpectArgs{}, nil, nil}, + }}) + func() { defer HandleExit(); s.Expects("meow") }() + }) + + t.Run("mismatch", func(t *testing.T) { + ot := &overrideT{T: t} + ot.fatalf.Store(checkFatalf(t, "Expects: separator, want %s", "panic")) + s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{ + {"panic", ExpectArgs{}, nil, nil}, + }}) + func() { defer HandleExit(); s.Expects(CallSeparator) }() + }) + }) + + t.Run("mismatch", func(t *testing.T) { + ot := &overrideT{T: t} + ot.fatalf.Store(checkFatalf(t, "Expects: func = %s, want %s", "meow", "nya")) + s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{ + {"nya", ExpectArgs{}, nil, nil}, + }}) + func() { defer HandleExit(); s.Expects("meow") }() + }) + }) + }) +} + +func TestCheckArg(t *testing.T) { + t.Run("oob negative", func(t *testing.T) { + defer func() { + want := "invalid call to CheckArg" + if r := recover(); r != want { + t.Errorf("recover: %v, want %v", r, want) + } + }() + s := New(t, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{}) + CheckArg(s, "unreachable", struct{}{}, 0) + }) + + ot := &overrideT{T: t} + s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{ + {"panic", ExpectArgs{PanicExit}, nil, nil}, + {"meow", ExpectArgs{-1}, nil, nil}, + }}) + t.Run("match", func(t *testing.T) { + s.Expects("panic") + if !CheckArg(s, "v", PanicExit, 0) { + t.Errorf("CheckArg: unexpected false") + } + }) + t.Run("mismatch", func(t *testing.T) { + defer HandleExit() + s.Expects("meow") + ot.errorf.Store(checkFatalf(t, "%s: %s = %#v, want %#v (%d)", "meow", "time", 0, -1, 1)) + if CheckArg(s, "time", 0, 0) { + t.Errorf("CheckArg: unexpected true") + } + }) + t.Run("oob", func(t *testing.T) { + s.pos++ + defer func() { + want := "invalid call to CheckArg" + if r := recover(); r != want { + t.Errorf("recover: %v, want %v", r, want) + } + }() + CheckArg(s, "unreachable", struct{}{}, 0) + }) +} + +func TestCheckArgReflect(t *testing.T) { + t.Run("oob lower", func(t *testing.T) { + defer func() { + want := "invalid call to CheckArgReflect" + if r := recover(); r != want { + t.Errorf("recover: %v, want %v", r, want) + } + }() + s := New(t, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{}) + CheckArgReflect(s, "unreachable", struct{}{}, 0) + }) + + ot := &overrideT{T: t} + s := New(ot, func(s *Stub[stubHolder]) stubHolder { return stubHolder{s} }, Expect{Calls: []Call{ + {"panic", ExpectArgs{PanicExit}, nil, nil}, + {"meow", ExpectArgs{-1}, nil, nil}, + }}) + t.Run("match", func(t *testing.T) { + s.Expects("panic") + if !CheckArgReflect(s, "v", PanicExit, 0) { + t.Errorf("CheckArgReflect: unexpected false") + } + }) + t.Run("mismatch", func(t *testing.T) { + defer HandleExit() + s.Expects("meow") + ot.errorf.Store(checkFatalf(t, "%s: %s = %#v, want %#v (%d)", "meow", "time", 0, -1, 1)) + if CheckArgReflect(s, "time", 0, 0) { + t.Errorf("CheckArgReflect: unexpected true") + } + }) + t.Run("oob", func(t *testing.T) { + s.pos++ + defer func() { + want := "invalid call to CheckArgReflect" + if r := recover(); r != want { + t.Errorf("recover: %v, want %v", r, want) + } + }() + CheckArgReflect(s, "unreachable", struct{}{}, 0) + }) +} + +func checkFatal(t *testing.T, wantArgs ...any) *func(args ...any) { + var called bool + f := func(args ...any) { + if called { + panic("invalid call to fatal") + } + called = true + + if !reflect.DeepEqual(args, wantArgs) { + t.Errorf("Fatal: %#v, want %#v", args, wantArgs) + } + panic(PanicExit) + } + return &f +} + +func checkFatalf(t *testing.T, wantFormat string, wantArgs ...any) *func(format string, args ...any) { + var called bool + f := func(format string, args ...any) { + if called { + panic("invalid call to fatalf") + } + called = true + + if format != wantFormat { + t.Errorf("Fatalf: format = %q, want %q", format, wantFormat) + } + if !reflect.DeepEqual(args, wantArgs) { + t.Errorf("Fatalf: args = %#v, want %#v", args, wantArgs) + } + panic(PanicExit) + } + return &f +}