internal/outcome/shim: check full behaviour
All checks were successful
Test / Create distribution (push) Successful in 24s
Test / Hakurei (push) Successful in 42s
Test / Sandbox (push) Successful in 38s
Test / Hakurei (race detector) (push) Successful in 42s
Test / Sandbox (race detector) (push) Successful in 38s
Test / Hpkg (push) Successful in 39s
Test / Flake checks (push) Successful in 1m21s
All checks were successful
Test / Create distribution (push) Successful in 24s
Test / Hakurei (push) Successful in 42s
Test / Sandbox (push) Successful in 38s
Test / Hakurei (race detector) (push) Successful in 42s
Test / Sandbox (race detector) (push) Successful in 38s
Test / Hpkg (push) Successful in 39s
Test / Flake checks (push) Successful in 1m21s
This took significant effort to stub out, and achieves full coverage after c5aefe5e9d.
Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -106,8 +106,8 @@ func TestShimEntrypoint(t *testing.T) {
|
||||
Remount(fhs.AbsRoot, syscall.MS_RDONLY),
|
||||
}
|
||||
|
||||
templateState := outcomeState{
|
||||
Shim: &shimParams{PrivPID: 0xbad, WaitDelay: 0xf, Verbose: true, Ops: []outcomeOp{
|
||||
newShimParams := func() *shimParams {
|
||||
return &shimParams{PrivPID: 0xbad, WaitDelay: 0xf, Verbose: true, Ops: []outcomeOp{
|
||||
&spParamsOp{"xterm-256color", true},
|
||||
&spRuntimeOp{sessionTypeWayland},
|
||||
spTmpdirOp{},
|
||||
@@ -116,8 +116,11 @@ func TestShimEntrypoint(t *testing.T) {
|
||||
&spPulseOp{(*[pulseCookieSizeMax]byte)(bytes.Repeat([]byte{0}, pulseCookieSizeMax)), pulseCookieSizeMax},
|
||||
&spDBusOp{true},
|
||||
&spFilesystemOp{},
|
||||
}},
|
||||
}}
|
||||
}
|
||||
|
||||
templateState := outcomeState{
|
||||
Shim: newShimParams(),
|
||||
ID: &checkExpectInstanceId,
|
||||
Identity: hst.IdentityMax,
|
||||
UserID: 10,
|
||||
@@ -128,6 +131,333 @@ func TestShimEntrypoint(t *testing.T) {
|
||||
}
|
||||
|
||||
checkSimple(t, "shimEntrypoint", []simpleTestCase{
|
||||
{"dumpable", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, new(log.Logger), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, stub.UniqueError(11)),
|
||||
call("fatalf", stub.ExpectArgs{"cannot set SUID_DUMP_DISABLE: %v", []any{stub.UniqueError(11)}}, nil, nil),
|
||||
}}, nil},
|
||||
|
||||
{"receive fd", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", outcomeState{}, nil}, nil, syscall.EBADF),
|
||||
call("fatal", stub.ExpectArgs{[]any{"invalid config descriptor"}}, nil, nil),
|
||||
}}, nil},
|
||||
|
||||
{"receive env", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", outcomeState{}, nil}, nil, container.ErrReceiveEnv),
|
||||
call("fatal", stub.ExpectArgs{[]any{"HAKUREI_SHIM not set"}}, nil, nil),
|
||||
}}, nil},
|
||||
|
||||
{"receive strange", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", outcomeState{}, nil}, nil, stub.UniqueError(10)),
|
||||
call("fatalf", stub.ExpectArgs{"cannot receive shim setup params: %v", []any{stub.UniqueError(10)}}, nil, nil),
|
||||
}}, nil},
|
||||
|
||||
{"invalid state", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", func() outcomeState {
|
||||
state := templateState
|
||||
state.Shim = newShimParams()
|
||||
state.Shim.PrivPID = 0
|
||||
return state
|
||||
}(), nil}, nil, nil),
|
||||
call("swapVerbose", stub.ExpectArgs{true}, false, nil),
|
||||
call("fatal", stub.ExpectArgs{[]any{"impossible outcome state reached\n"}}, nil, nil),
|
||||
}}, nil},
|
||||
|
||||
{"sigaction pipe", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", templateState, nil}, nil, nil),
|
||||
call("swapVerbose", stub.ExpectArgs{true}, false, nil),
|
||||
call("verbosef", stub.ExpectArgs{"process share directory at %q, runtime directory at %q", []any{m("/tmp/hakurei.10"), m("/run/user/1000/hakurei")}}, nil, nil),
|
||||
call("setupContSignal", stub.ExpectArgs{0xbad}, 0, &os.SyscallError{Syscall: "pipe2", Err: stub.UniqueError(9)}),
|
||||
call("fatal", stub.ExpectArgs{[]any{"pipe2: unique error 9 injected by the test suite"}}, nil, nil),
|
||||
}}, nil},
|
||||
|
||||
{"sigaction cgo", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", templateState, nil}, nil, nil),
|
||||
call("swapVerbose", stub.ExpectArgs{true}, false, nil),
|
||||
call("verbosef", stub.ExpectArgs{"process share directory at %q, runtime directory at %q", []any{m("/tmp/hakurei.10"), m("/run/user/1000/hakurei")}}, nil, nil),
|
||||
call("setupContSignal", stub.ExpectArgs{0xbad}, 0, syscall.ENOTRECOVERABLE),
|
||||
call("fatalf", stub.ExpectArgs{"cannot install SIGCONT handler: %v", []any{syscall.ENOTRECOVERABLE}}, nil, nil),
|
||||
}}, nil},
|
||||
|
||||
{"sigaction strange", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", templateState, nil}, nil, nil),
|
||||
call("swapVerbose", stub.ExpectArgs{true}, false, nil),
|
||||
call("verbosef", stub.ExpectArgs{"process share directory at %q, runtime directory at %q", []any{m("/tmp/hakurei.10"), m("/run/user/1000/hakurei")}}, nil, nil),
|
||||
call("setupContSignal", stub.ExpectArgs{0xbad}, 0, stub.UniqueError(8)),
|
||||
call("fatalf", stub.ExpectArgs{"cannot set up exit request: %v", []any{stub.UniqueError(8)}}, nil, nil),
|
||||
}}, nil},
|
||||
|
||||
{"prctl", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", templateState, nil}, nil, nil),
|
||||
call("swapVerbose", stub.ExpectArgs{true}, false, nil),
|
||||
call("verbosef", stub.ExpectArgs{"process share directory at %q, runtime directory at %q", []any{m("/tmp/hakurei.10"), m("/run/user/1000/hakurei")}}, nil, nil),
|
||||
call("setupContSignal", stub.ExpectArgs{0xbad}, 0, nil),
|
||||
call("prctl", stub.ExpectArgs{uintptr(syscall.PR_SET_PDEATHSIG), uintptr(syscall.SIGCONT), uintptr(0)}, nil, stub.UniqueError(7)),
|
||||
call("fatalf", stub.ExpectArgs{"cannot set parent-death signal: %v", []any{stub.UniqueError(7)}}, nil, nil),
|
||||
|
||||
// deferred
|
||||
call("wKeepAlive", stub.ExpectArgs{}, nil, nil),
|
||||
}}, nil},
|
||||
|
||||
{"toContainer", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", func() outcomeState {
|
||||
state := templateState
|
||||
state.Shim = newShimParams()
|
||||
state.Shim.Ops = []outcomeOp{errorOp(6)}
|
||||
return state
|
||||
}(), nil}, nil, nil),
|
||||
call("swapVerbose", stub.ExpectArgs{true}, false, nil),
|
||||
call("verbosef", stub.ExpectArgs{"process share directory at %q, runtime directory at %q", []any{m("/tmp/hakurei.10"), m("/run/user/1000/hakurei")}}, nil, nil),
|
||||
call("setupContSignal", stub.ExpectArgs{0xbad}, 0, nil),
|
||||
call("prctl", stub.ExpectArgs{uintptr(syscall.PR_SET_PDEATHSIG), uintptr(syscall.SIGCONT), uintptr(0)}, nil, nil),
|
||||
call("fatal", stub.ExpectArgs{[]any{"cannot create container state: unique error 6 injected by the test suite\n"}}, nil, nil),
|
||||
|
||||
// deferred
|
||||
call("wKeepAlive", stub.ExpectArgs{}, nil, nil),
|
||||
}}, nil},
|
||||
|
||||
{"bad ops", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", func() outcomeState {
|
||||
state := templateState
|
||||
state.Shim = newShimParams()
|
||||
state.Shim.Ops = nil
|
||||
return state
|
||||
}(), nil}, nil, nil),
|
||||
call("swapVerbose", stub.ExpectArgs{true}, false, nil),
|
||||
call("verbosef", stub.ExpectArgs{"process share directory at %q, runtime directory at %q", []any{m("/tmp/hakurei.10"), m("/run/user/1000/hakurei")}}, nil, nil),
|
||||
call("setupContSignal", stub.ExpectArgs{0xbad}, 0, nil),
|
||||
call("prctl", stub.ExpectArgs{uintptr(syscall.PR_SET_PDEATHSIG), uintptr(syscall.SIGCONT), uintptr(0)}, nil, nil),
|
||||
call("fatal", stub.ExpectArgs{[]any{"invalid container state"}}, nil, nil),
|
||||
|
||||
// deferred
|
||||
call("wKeepAlive", stub.ExpectArgs{}, nil, nil),
|
||||
}}, nil},
|
||||
|
||||
{"start", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", templateState, nil}, nil, nil),
|
||||
call("swapVerbose", stub.ExpectArgs{true}, false, nil),
|
||||
call("verbosef", stub.ExpectArgs{"process share directory at %q, runtime directory at %q", []any{m("/tmp/hakurei.10"), m("/run/user/1000/hakurei")}}, nil, nil),
|
||||
call("setupContSignal", stub.ExpectArgs{0xbad}, 0, nil),
|
||||
call("prctl", stub.ExpectArgs{uintptr(syscall.PR_SET_PDEATHSIG), uintptr(syscall.SIGCONT), uintptr(0)}, nil, nil),
|
||||
call("New", stub.ExpectArgs{}, nil, nil),
|
||||
call("closeReceive", stub.ExpectArgs{}, nil, nil),
|
||||
call("notifyContext", stub.ExpectArgs{context.Background(), []os.Signal{os.Interrupt, syscall.SIGTERM}}, -1, nil),
|
||||
call("containerStart", stub.ExpectArgs{templateParams}, nil, stub.UniqueError(5)),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("verbose", stub.ExpectArgs{[]any{"cannot start container: unique error 5 injected by the test suite\n"}}, nil, nil),
|
||||
call("exit", stub.ExpectArgs{hst.ExitFailure}, stub.PanicExit, nil),
|
||||
|
||||
// deferred
|
||||
call("wKeepAlive", stub.ExpectArgs{}, nil, nil),
|
||||
}, Tracks: []stub.Expect{{Calls: []stub.Call{
|
||||
call("rcRead", stub.ExpectArgs{}, nil, nil), // stub terminates this goroutine
|
||||
}}}}, nil},
|
||||
|
||||
{"start logger signalread", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", templateState, nil}, nil, nil),
|
||||
call("swapVerbose", stub.ExpectArgs{true}, false, nil),
|
||||
call("verbosef", stub.ExpectArgs{"process share directory at %q, runtime directory at %q", []any{m("/tmp/hakurei.10"), m("/run/user/1000/hakurei")}}, nil, nil),
|
||||
call("setupContSignal", stub.ExpectArgs{0xbad}, 0, nil),
|
||||
call("prctl", stub.ExpectArgs{uintptr(syscall.PR_SET_PDEATHSIG), uintptr(syscall.SIGCONT), uintptr(0)}, nil, nil),
|
||||
call("New", stub.ExpectArgs{}, nil, nil),
|
||||
call("closeReceive", stub.ExpectArgs{}, nil, nil),
|
||||
call("notifyContext", stub.ExpectArgs{context.Background(), []os.Signal{os.Interrupt, syscall.SIGTERM}}, -1, nil),
|
||||
call("containerStart", stub.ExpectArgs{templateParams}, nil, stub.UniqueError(5)),
|
||||
call("getLogger", stub.ExpectArgs{}, log.Default(), nil),
|
||||
call("exit", stub.ExpectArgs{hst.ExitFailure}, stub.PanicExit, nil),
|
||||
|
||||
// deferred
|
||||
call("wKeepAlive", stub.ExpectArgs{}, nil, nil),
|
||||
}, Tracks: []stub.Expect{{Calls: []stub.Call{
|
||||
call("rcRead", stub.ExpectArgs{}, []byte{}, stub.UniqueError(4)),
|
||||
call("fatalf", stub.ExpectArgs{"cannot read from signal pipe: %v", []any{stub.UniqueError(4)}}, nil, nil),
|
||||
}}}}, nil},
|
||||
|
||||
{"serve", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", templateState, nil}, nil, nil),
|
||||
call("swapVerbose", stub.ExpectArgs{true}, false, nil),
|
||||
call("verbosef", stub.ExpectArgs{"process share directory at %q, runtime directory at %q", []any{m("/tmp/hakurei.10"), m("/run/user/1000/hakurei")}}, nil, nil),
|
||||
call("setupContSignal", stub.ExpectArgs{0xbad}, 0, nil),
|
||||
call("prctl", stub.ExpectArgs{uintptr(syscall.PR_SET_PDEATHSIG), uintptr(syscall.SIGCONT), uintptr(0)}, nil, nil),
|
||||
call("New", stub.ExpectArgs{}, nil, nil),
|
||||
call("closeReceive", stub.ExpectArgs{}, nil, nil),
|
||||
call("notifyContext", stub.ExpectArgs{context.Background(), []os.Signal{os.Interrupt, syscall.SIGTERM}}, -1, nil),
|
||||
call("containerStart", stub.ExpectArgs{templateParams}, nil, nil),
|
||||
call("containerServe", stub.ExpectArgs{templateParams}, nil, stub.UniqueError(3)),
|
||||
call("fatal", stub.ExpectArgs{[]any{"cannot configure container: unique error 3 injected by the test suite\n"}}, nil, nil),
|
||||
|
||||
// deferred
|
||||
call("wKeepAlive", stub.ExpectArgs{}, nil, nil),
|
||||
}, Tracks: []stub.Expect{{Calls: []stub.Call{
|
||||
call("rcRead", stub.ExpectArgs{}, nil, nil), // stub terminates this goroutine
|
||||
}}}}, nil},
|
||||
|
||||
{"seccomp", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", templateState, nil}, nil, nil),
|
||||
call("swapVerbose", stub.ExpectArgs{true}, false, nil),
|
||||
call("verbosef", stub.ExpectArgs{"process share directory at %q, runtime directory at %q", []any{m("/tmp/hakurei.10"), m("/run/user/1000/hakurei")}}, nil, nil),
|
||||
call("setupContSignal", stub.ExpectArgs{0xbad}, 0, nil),
|
||||
call("prctl", stub.ExpectArgs{uintptr(syscall.PR_SET_PDEATHSIG), uintptr(syscall.SIGCONT), uintptr(0)}, nil, nil),
|
||||
call("New", stub.ExpectArgs{}, nil, nil),
|
||||
call("closeReceive", stub.ExpectArgs{}, nil, nil),
|
||||
call("notifyContext", stub.ExpectArgs{context.Background(), []os.Signal{os.Interrupt, syscall.SIGTERM}}, -1, nil),
|
||||
call("containerStart", stub.ExpectArgs{templateParams}, nil, nil),
|
||||
call("containerServe", stub.ExpectArgs{templateParams}, nil, nil),
|
||||
call("seccompLoad", stub.ExpectArgs{shimPreset, seccomp.AllowMultiarch}, nil, stub.UniqueError(2)),
|
||||
call("fatalf", stub.ExpectArgs{"cannot load syscall filter: %v", []any{stub.UniqueError(2)}}, nil, nil),
|
||||
|
||||
// deferred
|
||||
call("wKeepAlive", stub.ExpectArgs{}, nil, nil),
|
||||
}, Tracks: []stub.Expect{{Calls: []stub.Call{
|
||||
call("rcRead", stub.ExpectArgs{}, nil, nil), // stub terminates this goroutine
|
||||
}}}}, nil},
|
||||
|
||||
{"exited closesetup earlyrequested", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", templateState, nil}, nil, nil),
|
||||
call("swapVerbose", stub.ExpectArgs{true}, false, nil),
|
||||
call("verbosef", stub.ExpectArgs{"process share directory at %q, runtime directory at %q", []any{m("/tmp/hakurei.10"), m("/run/user/1000/hakurei")}}, nil, nil),
|
||||
call("setupContSignal", stub.ExpectArgs{0xbad}, 0, nil),
|
||||
call("prctl", stub.ExpectArgs{uintptr(syscall.PR_SET_PDEATHSIG), uintptr(syscall.SIGCONT), uintptr(0)}, nil, nil),
|
||||
call("New", stub.ExpectArgs{}, nil, nil),
|
||||
call("closeReceive", stub.ExpectArgs{}, nil, stub.UniqueError(1)),
|
||||
call("verbosef", stub.ExpectArgs{"cannot close setup pipe: %v", []any{stub.UniqueError(1)}}, nil, nil),
|
||||
call("notifyContext", stub.ExpectArgs{context.Background(), []os.Signal{os.Interrupt, syscall.SIGTERM}}, 0, nil),
|
||||
call("containerStart", stub.ExpectArgs{templateParams}, nil, nil),
|
||||
call("containerServe", stub.ExpectArgs{templateParams}, nil, nil),
|
||||
call("seccompLoad", stub.ExpectArgs{shimPreset, seccomp.AllowMultiarch}, nil, nil),
|
||||
call("containerWait", stub.ExpectArgs{templateParams}, nil, makeExitError(1<<8)),
|
||||
call("exit", stub.ExpectArgs{1}, stub.PanicExit, nil),
|
||||
|
||||
// deferred
|
||||
call("wKeepAlive", stub.ExpectArgs{}, nil, nil),
|
||||
}, Tracks: []stub.Expect{{Calls: []stub.Call{
|
||||
call("rcRead", stub.ExpectArgs{}, []byte{shimMsgExitRequested}, nil),
|
||||
call("exit", stub.ExpectArgs{hst.ExitRequest}, stub.PanicExit, unblockNotifyContext),
|
||||
}}}}, nil},
|
||||
|
||||
{"exited requested", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", templateState, nil}, nil, nil),
|
||||
call("swapVerbose", stub.ExpectArgs{true}, false, nil),
|
||||
call("verbosef", stub.ExpectArgs{"process share directory at %q, runtime directory at %q", []any{m("/tmp/hakurei.10"), m("/run/user/1000/hakurei")}}, nil, nil),
|
||||
call("setupContSignal", stub.ExpectArgs{0xbad}, 0, nil),
|
||||
call("prctl", stub.ExpectArgs{uintptr(syscall.PR_SET_PDEATHSIG), uintptr(syscall.SIGCONT), uintptr(0)}, nil, nil),
|
||||
call("New", stub.ExpectArgs{}, nil, nil),
|
||||
call("closeReceive", stub.ExpectArgs{}, nil, nil),
|
||||
call("notifyContext", stub.ExpectArgs{context.Background(), []os.Signal{os.Interrupt, syscall.SIGTERM}}, 0, nil),
|
||||
call("containerStart", stub.ExpectArgs{templateParams}, nil, nil),
|
||||
call("containerServe", stub.ExpectArgs{templateParams}, nil, nil),
|
||||
call("seccompLoad", stub.ExpectArgs{shimPreset, seccomp.AllowMultiarch}, nil, nil),
|
||||
call("containerWait", stub.ExpectArgs{templateParams}, nil, makeExitError(1<<8)),
|
||||
call("exit", stub.ExpectArgs{1}, stub.PanicExit, nil),
|
||||
|
||||
// deferred
|
||||
call("wKeepAlive", stub.ExpectArgs{}, nil, nil),
|
||||
}, Tracks: []stub.Expect{{Calls: []stub.Call{
|
||||
call("rcRead", stub.ExpectArgs{}, []byte{shimMsgExitRequested}, unblockNotifyContext),
|
||||
call("notifyContextStop", stub.ExpectArgs{}, nil, nil),
|
||||
call("rcRead", stub.ExpectArgs{}, nil, nil), // stub terminates this goroutine
|
||||
}}}}, nil},
|
||||
|
||||
{"canceled orphaned", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", templateState, nil}, nil, nil),
|
||||
call("swapVerbose", stub.ExpectArgs{true}, false, nil),
|
||||
call("verbosef", stub.ExpectArgs{"process share directory at %q, runtime directory at %q", []any{m("/tmp/hakurei.10"), m("/run/user/1000/hakurei")}}, nil, nil),
|
||||
call("setupContSignal", stub.ExpectArgs{0xbad}, 0, nil),
|
||||
call("prctl", stub.ExpectArgs{uintptr(syscall.PR_SET_PDEATHSIG), uintptr(syscall.SIGCONT), uintptr(0)}, nil, nil),
|
||||
call("New", stub.ExpectArgs{}, nil, nil),
|
||||
call("closeReceive", stub.ExpectArgs{}, nil, nil),
|
||||
call("notifyContext", stub.ExpectArgs{context.Background(), []os.Signal{os.Interrupt, syscall.SIGTERM}}, -1, nil),
|
||||
call("containerStart", stub.ExpectArgs{templateParams}, nil, nil),
|
||||
call("containerServe", stub.ExpectArgs{templateParams}, nil, nil),
|
||||
call("seccompLoad", stub.ExpectArgs{shimPreset, seccomp.AllowMultiarch}, nil, nil),
|
||||
call("containerWait", stub.ExpectArgs{templateParams}, nil, context.Canceled),
|
||||
call("exit", stub.ExpectArgs{hst.ExitCancel}, stub.PanicExit, nil),
|
||||
|
||||
// deferred
|
||||
call("wKeepAlive", stub.ExpectArgs{}, nil, nil),
|
||||
}, Tracks: []stub.Expect{{Calls: []stub.Call{
|
||||
call("rcRead", stub.ExpectArgs{}, []byte{shimMsgOrphaned}, nil),
|
||||
call("exit", stub.ExpectArgs{hst.ExitOrphan}, stub.PanicExit, nil),
|
||||
}}}}, nil},
|
||||
|
||||
{"strangewait invalidmsg", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
call("setDumpable", stub.ExpectArgs{uintptr(container.SUID_DUMP_DISABLE)}, nil, nil),
|
||||
call("receive", stub.ExpectArgs{"HAKUREI_SHIM", templateState, nil}, nil, nil),
|
||||
call("swapVerbose", stub.ExpectArgs{true}, false, nil),
|
||||
call("verbosef", stub.ExpectArgs{"process share directory at %q, runtime directory at %q", []any{m("/tmp/hakurei.10"), m("/run/user/1000/hakurei")}}, nil, nil),
|
||||
call("setupContSignal", stub.ExpectArgs{0xbad}, 0, nil),
|
||||
call("prctl", stub.ExpectArgs{uintptr(syscall.PR_SET_PDEATHSIG), uintptr(syscall.SIGCONT), uintptr(0)}, nil, nil),
|
||||
call("New", stub.ExpectArgs{}, nil, nil),
|
||||
call("closeReceive", stub.ExpectArgs{}, nil, nil),
|
||||
call("notifyContext", stub.ExpectArgs{context.Background(), []os.Signal{os.Interrupt, syscall.SIGTERM}}, -1, nil),
|
||||
call("containerStart", stub.ExpectArgs{templateParams}, nil, nil),
|
||||
call("containerServe", stub.ExpectArgs{templateParams}, nil, nil),
|
||||
call("seccompLoad", stub.ExpectArgs{shimPreset, seccomp.AllowMultiarch}, nil, nil),
|
||||
call("containerWait", stub.ExpectArgs{templateParams}, nil, stub.UniqueError(0)),
|
||||
call("verbosef", stub.ExpectArgs{"cannot wait: %v", []any{stub.UniqueError(0)}}, nil, nil),
|
||||
call("exit", stub.ExpectArgs{127}, stub.PanicExit, nil),
|
||||
|
||||
// deferred
|
||||
call("wKeepAlive", stub.ExpectArgs{}, nil, nil),
|
||||
}, Tracks: []stub.Expect{{Calls: []stub.Call{
|
||||
call("rcRead", stub.ExpectArgs{}, []byte{0xff}, nil),
|
||||
call("fatalf", stub.ExpectArgs{"got invalid message %d from signal handler", []any{byte(0xff)}}, nil, nil),
|
||||
}}}}, nil},
|
||||
|
||||
{"success", func(k *kstub) error { shimEntrypoint(k); return nil }, stub.Expect{Calls: []stub.Call{
|
||||
call("getMsg", stub.ExpectArgs{}, nil, nil),
|
||||
call("getLogger", stub.ExpectArgs{}, (*log.Logger)(nil), nil),
|
||||
@@ -139,7 +469,7 @@ func TestShimEntrypoint(t *testing.T) {
|
||||
call("prctl", stub.ExpectArgs{uintptr(syscall.PR_SET_PDEATHSIG), uintptr(syscall.SIGCONT), uintptr(0)}, nil, nil),
|
||||
call("New", stub.ExpectArgs{}, nil, nil),
|
||||
call("closeReceive", stub.ExpectArgs{}, nil, nil),
|
||||
call("notifyContext", stub.ExpectArgs{context.Background(), []os.Signal{os.Interrupt, syscall.SIGTERM}}, nil, nil),
|
||||
call("notifyContext", stub.ExpectArgs{context.Background(), []os.Signal{os.Interrupt, syscall.SIGTERM}}, -1, nil),
|
||||
call("containerStart", stub.ExpectArgs{templateParams}, nil, nil),
|
||||
call("containerServe", stub.ExpectArgs{templateParams}, nil, nil),
|
||||
call("seccompLoad", stub.ExpectArgs{shimPreset, seccomp.AllowMultiarch}, nil, nil),
|
||||
@@ -156,3 +486,9 @@ func TestShimEntrypoint(t *testing.T) {
|
||||
}}}}, nil},
|
||||
})
|
||||
}
|
||||
|
||||
// errorOp implements a noop outcomeOp that unconditionally returns [stub.UniqueError].
|
||||
type errorOp stub.UniqueError
|
||||
|
||||
func (e errorOp) toSystem(*outcomeStateSys) error { return stub.UniqueError(e) }
|
||||
func (e errorOp) toContainer(*outcomeStateParams) error { return stub.UniqueError(e) }
|
||||
|
||||
Reference in New Issue
Block a user