hakurei/internal/app/spcontainer_test.go
Ophestra f5a597c406
All checks were successful
Test / Create distribution (push) Successful in 33s
Test / Sandbox (push) Successful in 2m13s
Test / Hakurei (push) Successful in 3m3s
Test / Hpkg (push) Successful in 3m57s
Test / Sandbox (race detector) (push) Successful in 4m30s
Test / Hakurei (race detector) (push) Successful in 5m16s
Test / Flake checks (push) Successful in 1m20s
hst: rename /.hakurei constant
This provides disambiguation from fhs.AbsTmp.

Signed-off-by: Ophestra <cat@gensokyo.uk>
2025-10-11 14:32:35 +09:00

141 lines
4.7 KiB
Go

package app
import (
"maps"
"os"
"reflect"
"testing"
"hakurei.app/container"
"hakurei.app/container/bits"
"hakurei.app/container/fhs"
"hakurei.app/container/seccomp"
"hakurei.app/container/stub"
"hakurei.app/hst"
)
func TestSpParamsOp(t *testing.T) {
config := hst.Template()
checkOpBehaviour(t, []opBehaviourTestCase{
{"invalid program path", func(isShim, _ bool) outcomeOp {
if !isShim {
return new(spParamsOp)
}
return &spParamsOp{Term: "xterm", TermSet: true}
}, func() *hst.Config {
c := hst.Template()
c.Container.Path = nil
return c
}, nil, []stub.Call{
call("lookupEnv", stub.ExpectArgs{"TERM"}, "xterm", nil),
}, newI().
Ensure(m(container.Nonexistent+"/tmp/hakurei.0"), 0711), nil, nil, nil, []stub.Call{
// this op configures the container state and does not make calls during toContainer
}, nil, nil, &hst.AppError{
Step: "finalise",
Err: os.ErrInvalid,
Msg: "invalid program path",
}},
{"success defaultargs secure", func(isShim, _ bool) outcomeOp {
if !isShim {
return new(spParamsOp)
}
return &spParamsOp{Term: "xterm", TermSet: true}
}, func() *hst.Config {
c := hst.Template()
c.Container.Args = nil
c.Container.Multiarch = false
c.Container.SeccompCompat = false
c.Container.Devel = false
c.Container.Userns = false
c.Container.Tty = false
c.Container.Device = false
return c
}, nil, []stub.Call{
call("lookupEnv", stub.ExpectArgs{"TERM"}, "xterm", nil),
}, newI().
Ensure(m(container.Nonexistent+"/tmp/hakurei.0"), 0711), nil, nil, nil, []stub.Call{
// this op configures the container state and does not make calls during toContainer
}, &container.Params{
Hostname: config.Container.Hostname,
HostNet: config.Container.HostNet,
HostAbstract: config.Container.HostAbstract,
Path: config.Container.Path,
Args: []string{config.Container.Path.String()},
SeccompPresets: bits.PresetExt | bits.PresetDenyDevel | bits.PresetDenyNS | bits.PresetDenyTTY,
Uid: 1000,
Gid: 100,
Ops: new(container.Ops).
Root(m("/var/lib/hakurei/base/org.debian"), bits.BindWritable).
Proc(fhs.AbsProc).Tmpfs(hst.AbsPrivateTmp, 1<<12, 0755).
DevWritable(fhs.AbsDev, true).
Tmpfs(fhs.AbsDev.Append("shm"), 0, 01777),
}, func(t *testing.T, state *outcomeStateParams) {
wantEnv := map[string]string{
"TERM": "xterm",
}
maps.Copy(wantEnv, config.Container.Env)
if !maps.Equal(state.env, wantEnv) {
t.Errorf("toContainer: env = %#v, want %#v", state.env, wantEnv)
}
const wantAutoEtcPrefix = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
if state.as.AutoEtcPrefix != wantAutoEtcPrefix {
t.Errorf("toContainer: as.AutoEtcPrefix = %q, want %q", state.as.AutoEtcPrefix, wantAutoEtcPrefix)
}
wantFilesystems := config.Container.Filesystem[1:]
if !reflect.DeepEqual(state.filesystem, wantFilesystems) {
t.Errorf("toContainer: filesystem = %#v, want %#v", state.filesystem, wantFilesystems)
}
}, nil},
{"success", func(isShim, _ bool) outcomeOp {
if !isShim {
return new(spParamsOp)
}
return &spParamsOp{Term: "xterm", TermSet: true}
}, hst.Template, nil, []stub.Call{
call("lookupEnv", stub.ExpectArgs{"TERM"}, "xterm", nil),
}, newI().
Ensure(m(container.Nonexistent+"/tmp/hakurei.0"), 0711), nil, nil, nil, []stub.Call{
// this op configures the container state and does not make calls during toContainer
}, &container.Params{
Hostname: config.Container.Hostname,
RetainSession: config.Container.Tty,
HostNet: config.Container.HostNet,
HostAbstract: config.Container.HostAbstract,
Path: config.Container.Path,
Args: config.Container.Args,
SeccompFlags: seccomp.AllowMultiarch,
Uid: 1000,
Gid: 100,
Ops: new(container.Ops).
Root(m("/var/lib/hakurei/base/org.debian"), bits.BindWritable).
Proc(fhs.AbsProc).Tmpfs(hst.AbsPrivateTmp, 1<<12, 0755).
Bind(fhs.AbsDev, fhs.AbsDev, bits.BindWritable|bits.BindDevice).
Tmpfs(fhs.AbsDev.Append("shm"), 0, 01777),
}, func(t *testing.T, state *outcomeStateParams) {
wantEnv := map[string]string{
"TERM": "xterm",
}
maps.Copy(wantEnv, config.Container.Env)
if !maps.Equal(state.env, wantEnv) {
t.Errorf("toContainer: env = %#v, want %#v", state.env, wantEnv)
}
const wantAutoEtcPrefix = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
if state.as.AutoEtcPrefix != wantAutoEtcPrefix {
t.Errorf("toContainer: as.AutoEtcPrefix = %q, want %q", state.as.AutoEtcPrefix, wantAutoEtcPrefix)
}
wantFilesystems := config.Container.Filesystem[1:]
if !reflect.DeepEqual(state.filesystem, wantFilesystems) {
t.Errorf("toContainer: filesystem = %#v, want %#v", state.filesystem, wantFilesystems)
}
}, nil},
})
}